protected void destroyPbuffer() {
   final MutableSurface ms = (MutableSurface) getNativeSurface();
   final long pBuffer = ms.getSurfaceHandle();
   if (0 != pBuffer) {
     synchronized (createdContexts) {
       for (int i = 0; i < createdContexts.size(); ) {
         final WeakReference<MacOSXCGLContext> ref = createdContexts.get(i);
         final MacOSXCGLContext ctx = ref.get();
         if (ctx != null) {
           ctx.detachPBuffer();
           i++;
         } else {
           createdContexts.remove(i);
         }
       }
     }
     impl.destroy(pBuffer);
     ms.setSurfaceHandle(0);
   }
 }
  private void createPbuffer() {
    final MutableSurface ms = (MutableSurface) getNativeSurface();
    final DefaultGraphicsConfiguration config =
        (DefaultGraphicsConfiguration) ms.getGraphicsConfiguration();
    final GLCapabilitiesImmutable capabilities =
        (GLCapabilitiesImmutable) config.getChosenCapabilities();
    final GLProfile glProfile = capabilities.getGLProfile();
    MacOSXCGLDrawableFactory.SharedResource sr =
        ((MacOSXCGLDrawableFactory) factory)
            .getOrCreateOSXSharedResource(config.getScreen().getDevice());

    if (DEBUG) {
      System.out.println(getThreadName() + ": Pbuffer config: " + config);
      if (null != sr) {
        System.out.println("Pbuffer NPOT Texure  avail: " + sr.isNPOTTextureAvailable());
        System.out.println("Pbuffer RECT Texture avail: " + sr.isRECTTextureAvailable());
      } else {
        System.out.println("Pbuffer no sr, no RECT/NPOT Texture avail");
      }
    }

    if (capabilities.getPbufferRenderToTextureRectangle()
        && null != sr
        && sr.isRECTTextureAvailable()) {
      pBufferTexTarget = GL2GL3.GL_TEXTURE_RECTANGLE;
    } else {
      pBufferTexTarget = GL.GL_TEXTURE_2D;
    }
    if (GL2GL3.GL_TEXTURE_RECTANGLE == pBufferTexTarget
        || (null != sr && sr.isNPOTTextureAvailable())) {
      pBufferTexWidth = getWidth();
      pBufferTexHeight = getHeight();
    } else {
      pBufferTexWidth = GLBuffers.getNextPowerOf2(getWidth());
      pBufferTexHeight = GLBuffers.getNextPowerOf2(getHeight());
    }

    int internalFormat = GL.GL_RGBA;
    if (capabilities.getPbufferFloatingPointBuffers()) {
      if (!glProfile.isGL2GL3() || null == sr || sr.isAppleFloatPixelsAvailable()) {
        throw new GLException("Floating-point support (GL_APPLE_float_pixels) not available");
      }
      switch (capabilities.getRedBits()) {
        case 16:
          internalFormat = GL2.GL_RGBA_FLOAT16_APPLE;
          break;
        case 32:
          internalFormat = GL2.GL_RGBA_FLOAT32_APPLE;
          break;
        default:
          throw new GLException("Invalid floating-point bit depth (only 16 and 32 supported)");
      }
    }

    final long pBuffer = impl.create(pBufferTexTarget, internalFormat, getWidth(), getHeight());
    if (DEBUG) {
      System.err.println(
          "MacOSXPbufferCGLDrawable tex: target "
              + toHexString(pBufferTexTarget)
              + ", pbufferSize "
              + getWidth()
              + "x"
              + getHeight()
              + ", texSize "
              + pBufferTexWidth
              + "x"
              + pBufferTexHeight
              + ", internal-fmt "
              + toHexString(internalFormat));
      System.err.println("MacOSXPbufferCGLDrawable pBuffer: " + toHexString(pBuffer));
      // Thread.dumpStack();
    }
    if (pBuffer == 0) {
      throw new GLException("pbuffer creation error: CGL.createPBuffer() failed");
    }

    ms.setSurfaceHandle(pBuffer);
  }