--- old/src/java.desktop/macosx/classes/sun/java2d/opengl/CGLGraphicsConfig.java 2015-12-29 20:44:25.000000000 +0300 +++ new/src/java.desktop/macosx/classes/sun/java2d/opengl/CGLGraphicsConfig.java 2015-12-29 20:44:25.000000000 +0300 @@ -41,6 +41,7 @@ import java.awt.image.DirectColorModel; import java.awt.image.VolatileImage; import java.awt.image.WritableRaster; +import java.util.HashMap; import sun.awt.CGraphicsConfig; import sun.awt.CGraphicsDevice; @@ -84,6 +85,8 @@ int swapInterval); private static native int getOGLCapabilities(long configInfo); + private static final HashMap pGCRefCounts = new HashMap<>(); + /** * Returns GL_MAX_TEXTURE_SIZE from the shared opengl context. Must be * called under OGLRQ lock, because this method change current context. @@ -106,7 +109,7 @@ this.oglCaps = oglCaps; this.maxTextureSize = maxTextureSize; context = new OGLContext(OGLRenderQueue.getInstance(), this); - + refPConfigInfo(pConfigInfo); // add a record to the Disposer so that we destroy the native // CGLGraphicsConfigInfo data when this object goes away Disposer.addRecord(disposerReferent, @@ -169,6 +172,31 @@ return new CGLGraphicsConfig(device, pixfmt, cfginfo, textureSize, caps); } + static void refPConfigInfo(long pConfigInfo) { + synchronized (pGCRefCounts) { + Integer count = pGCRefCounts.get(pConfigInfo); + if (count == null) count = 0; + count++; + pGCRefCounts.put(pConfigInfo, count); + } + } + + static void deRefPConfigInfo(long pConfigInfo) { + synchronized (pGCRefCounts) { + Integer count = pGCRefCounts.get(pConfigInfo); + if (count != null) { + count--; + if (count == 0) { + OGLRenderQueue.disposeGraphicsConfig(pConfigInfo); + pGCRefCounts.remove(pConfigInfo); + } + else { + pGCRefCounts.put(pConfigInfo, count); + } + } + } + } + public static boolean isCGLAvailable() { return cglAvailable; } @@ -236,7 +264,7 @@ } public void dispose() { if (pCfgInfo != 0) { - OGLRenderQueue.disposeGraphicsConfig(pCfgInfo); + deRefPConfigInfo(pCfgInfo); pCfgInfo = 0; } } --- old/src/java.desktop/macosx/classes/sun/java2d/opengl/CGLSurfaceData.java 2015-12-29 20:44:25.000000000 +0300 +++ new/src/java.desktop/macosx/classes/sun/java2d/opengl/CGLSurfaceData.java 2015-12-29 20:44:25.000000000 +0300 @@ -74,6 +74,7 @@ pPeerData = pView.getAWTView(); isOpaque = pView.isOpaque(); } + CGLGraphicsConfig.refPConfigInfo(pConfigInfo); initOps(pConfigInfo, pPeerData, 0, 0, 0, isOpaque); } @@ -90,6 +91,7 @@ layerPtr = layer.getPointer(); isOpaque = layer.isOpaque(); } + CGLGraphicsConfig.refPConfigInfo(pConfigInfo); initOps(pConfigInfo, 0, layerPtr, 0, 0, isOpaque); } @@ -405,4 +407,9 @@ destroyCGLContext(ctx); } } + + static void dispose(long pData, long pConfigInfo) { + OGLSurfaceData.dispose(pData, pConfigInfo); + CGLGraphicsConfig.deRefPConfigInfo(pConfigInfo); + } } --- old/src/java.desktop/macosx/native/libawt_lwawt/java2d/opengl/CGLSurfaceData.m 2015-12-29 20:44:26.000000000 +0300 +++ new/src/java.desktop/macosx/native/libawt_lwawt/java2d/opengl/CGLSurfaceData.m 2015-12-29 20:44:26.000000000 +0300 @@ -374,6 +374,18 @@ extern UnlockFunc OGLSD_Unlock; extern DisposeFunc OGLSD_Dispose; + +void +CGLSD_Dispose(JNIEnv *env, SurfaceDataOps *ops) +{ + OGLSDOps *oglsdo = (OGLSDOps *)ops; + jlong pConfigInfo = OGLSD_GetNativeConfigInfo(oglsdo); + JNU_CallStaticMethodByName(env, NULL, "sun/java2d/opengl/CGLSurfaceData", + "dispose", "(JJ)V", + ptr_to_jlong(ops), pConfigInfo); +} + + JNIEXPORT void JNICALL Java_sun_java2d_opengl_CGLSurfaceData_initOps (JNIEnv *env, jobject cglsd, @@ -397,7 +409,7 @@ oglsdo->sdOps.Lock = OGLSD_Lock; oglsdo->sdOps.GetRasInfo = OGLSD_GetRasInfo; oglsdo->sdOps.Unlock = OGLSD_Unlock; - oglsdo->sdOps.Dispose = OGLSD_Dispose; + oglsdo->sdOps.Dispose = CGLSD_Dispose; oglsdo->drawableType = OGLSD_UNDEFINED; oglsdo->activeBuffer = GL_FRONT;