From cfe62741e19196d973d9b31f2c8f3873705cb74b Mon Sep 17 00:00:00 2001
From: Sven Gothel <sgothel@jausoft.com>
Date: Fri, 12 Apr 2013 20:27:21 +0200
Subject: GLContextImpl: destroy(): Fix null drawable check;
 makeCurrentWithinLock(): Add drawable size validation before attempt to
 create context; MacOSXCGLContext: Explicit exception for Null
 AttachGLLayerCmd.

GLContextImpl:
  - destroy():
    - Fix null drawable check
      Only if the GLContext isCreated(), we require a drawable to be set.

    - Proper name of associateDrawable Exception

  - makeCurrentWithinLock():
    - Add drawable size validation before attempt to create context.
      - 'makeCurrent()' shall never be called w/o proper sized drawable, i.e. > 0x0.
      - returns CONTEXT_NOT_CURRENT, if drawable size is <= 0x0

MacOSXCGLContext:

  - Explicit exception for Null AttachGLLayerCmd.
    In case context creation has failed via makeCurrent(),
    AttachGLLayerCmd may never been issued and hence maybe NULL.
    Catch this case and send a meaningful exception,
    which is catched and fwd in GLContext.destroy().
---
 src/jogl/classes/jogamp/opengl/GLContextImpl.java  | 28 +++++++----
 .../jogamp/opengl/macosx/cgl/MacOSXCGLContext.java | 54 ++++++++++++++++------
 2 files changed, 58 insertions(+), 24 deletions(-)

diff --git a/src/jogl/classes/jogamp/opengl/GLContextImpl.java b/src/jogl/classes/jogamp/opengl/GLContextImpl.java
index 0d8b193af..376b3c0e5 100644
--- a/src/jogl/classes/jogamp/opengl/GLContextImpl.java
+++ b/src/jogl/classes/jogamp/opengl/GLContextImpl.java
@@ -342,23 +342,24 @@ public abstract class GLContextImpl extends GLContext {
 
   @Override
   public final void destroy() {
-      if ( null == drawable ) {
-          throw new GLException("Drawable is null: "+toString());
-      }
       if ( DEBUG_TRACE_SWITCH ) {
+          final long drawH = null != drawable ? drawable.getHandle() : 0;
           System.err.println(getThreadName() + ": GLContextImpl.destroy.0: obj " + toHexString(hashCode()) + ", ctx " + toHexString(contextHandle) +
-                  ", surf "+toHexString(drawable.getHandle())+", isShared "+GLContextShareSet.isShared(this)+" - "+lock);
+                  ", surf "+toHexString(drawH)+", isShared "+GLContextShareSet.isShared(this)+" - "+lock);
       }
-      if ( 0 != contextHandle ) {
+      if ( 0 != contextHandle ) { // isCreated() ?
+          if ( null == drawable ) {
+              throw new GLException("GLContext created but drawable is null: "+toString());
+          }
           final int lockRes = drawable.lockSurface();
           if ( NativeSurface.LOCK_SURFACE_NOT_READY >= lockRes ) {
                 // this would be odd ..
                 throw new GLException("Surface not ready to lock: "+drawable);
           }
-          Throwable drawableContextRealizedException = null;
+          Throwable associateDrawableException = null;
           try {
               if ( !drawable.isRealized() ) {
-                  throw new GLException("Drawable not realized: "+toString());
+                  throw new GLException("GLContext created but drawable not realized: "+toString());
               }
               // Must hold the lock around the destroy operation to make sure we
               // don't destroy the context while another thread renders to it.
@@ -380,7 +381,7 @@ public abstract class GLContextImpl extends GLContext {
                   try {
                       associateDrawable(false);
                   } catch (Throwable t) {
-                      drawableContextRealizedException = t;
+                      associateDrawableException = t;
                   }
                   if ( 0 != defaultVAO ) {
                       int[] tmp = new int[] { defaultVAO };
@@ -410,8 +411,8 @@ public abstract class GLContextImpl extends GLContext {
           } finally {
               drawable.unlockSurface();
           }
-          if(null != drawableContextRealizedException) {
-              throw new GLException("GLContext.destroy() during GLDrawableImpl.contextRealized(this, false)", drawableContextRealizedException);
+          if( null != associateDrawableException ) {
+              throw new GLException("GLContext.destroy() during associateDrawable(false)", associateDrawableException);
           }
       }
       resetStates();
@@ -601,6 +602,13 @@ public abstract class GLContextImpl extends GLContext {
   
   private final int makeCurrentWithinLock(int surfaceLockRes) throws GLException {
       if (!isCreated()) {
+        if( 0 >= drawable.getWidth() || 0 >= drawable.getHeight() ) {
+            if ( DEBUG_TRACE_SWITCH ) {
+                System.err.println(getThreadName() + ": Create GL context REJECTED (zero surface size) obj " + toHexString(hashCode()) + ", surf "+toHexString(drawable.getHandle())+" for " + getClass().getName());
+                System.err.println(drawable.toString());
+            }
+            return CONTEXT_NOT_CURRENT;
+        }
         if(DEBUG_GL) {
             // only impacts w/ createContextARB(..)
             additionalCtxCreationFlags |= GLContext.CTX_OPTION_DEBUG ;
diff --git a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLContext.java b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLContext.java
index a197bd51f..6cab369cf 100644
--- a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLContext.java
+++ b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLContext.java
@@ -622,7 +622,7 @@ public abstract class MacOSXCGLContext extends GLContextImpl
        * Hence this method blocks the main-thread only for a short period of time.
        * </p>
        */                  
-      class AttachNSOpenGLLayer implements Runnable {
+      class AttachGLLayerCmd implements Runnable {
           final OffscreenLayerSurface ols;
           final long ctx;
           final int shaderProgram;
@@ -637,7 +637,7 @@ public abstract class MacOSXCGLContext extends GLContextImpl
           /** Synchronized by instance's monitor */
           boolean valid;
           
-          AttachNSOpenGLLayer(OffscreenLayerSurface ols, long ctx, int shaderProgram, long pfmt, long pbuffer, int texID, boolean isOpaque, int width, int height) {
+          AttachGLLayerCmd(OffscreenLayerSurface ols, long ctx, int shaderProgram, long pfmt, long pbuffer, int texID, boolean isOpaque, int width, int height) {
               this.ols = ols;
               this.ctx = ctx;
               this.shaderProgram = shaderProgram;
@@ -651,6 +651,15 @@ public abstract class MacOSXCGLContext extends GLContextImpl
               this.nsOpenGLLayer = 0;
           }
           
+          public final String contentToString() {
+              return "valid "+valid+", size "+width+"x"+height+", ctx "+toHexString(ctx)+", opaque "+isOpaque+", texID "+texID+", pbuffer "+toHexString(pbuffer)+", nsOpenGLLayer "+toHexString(nsOpenGLLayer);
+          }
+          
+          @Override
+          public final String toString() {
+              return "AttachGLLayerCmd["+contentToString()+"]";
+          }
+          
           @Override
           public void run() {
               synchronized(this) {
@@ -693,14 +702,20 @@ public abstract class MacOSXCGLContext extends GLContextImpl
               }
           }
       }
-      AttachNSOpenGLLayer attachCALayerCmd = null;
+      AttachGLLayerCmd attachGLLayerCmd = null;
       
-      class DetachNSOpenGLLayer implements Runnable {
-        final AttachNSOpenGLLayer cmd;
+      class DetachGLLayerCmd implements Runnable {
+        final AttachGLLayerCmd cmd;
         
-        DetachNSOpenGLLayer(AttachNSOpenGLLayer cmd) {
+        DetachGLLayerCmd(AttachGLLayerCmd cmd) {
             this.cmd = cmd;
         }
+        
+        @Override
+        public final String toString() {
+            return "DetachGLLayerCmd["+cmd.contentToString()+"]";
+        }
+        
         @Override
         public void run() {
             synchronized( cmd ) {
@@ -734,7 +749,8 @@ public abstract class MacOSXCGLContext extends GLContextImpl
           backingLayerHost = NativeWindowFactory.getOffscreenLayerSurface(drawable.getNativeSurface(), true);
           
           if(DEBUG) {
-              System.err.println("MaxOSXCGLContext.NSOpenGLImpl.associateDrawable: "+bound+", ctx "+toHexString(contextHandle)+", hasBackingLayerHost "+(null!=backingLayerHost));
+              System.err.println("MaxOSXCGLContext.NSOpenGLImpl.associateDrawable: "+bound+", ctx "+toHexString(contextHandle)+
+                                 ", hasBackingLayerHost "+(null!=backingLayerHost)+", attachGLLayerCmd "+attachGLLayerCmd);
               // Thread.dumpStack();
           }          
           
@@ -785,10 +801,13 @@ public abstract class MacOSXCGLContext extends GLContextImpl
                   }                                     
                    
                   // All CALayer lifecycle ops are deferred on main-thread
-                  attachCALayerCmd = new AttachNSOpenGLLayer( 
+                  attachGLLayerCmd = new AttachGLLayerCmd( 
                           backingLayerHost, ctx, gl3ShaderProgramName, pixelFormat, pbufferHandle, texID, 
                           chosenCaps.isBackgroundOpaque(), lastWidth, lastHeight );
-                  OSXUtil.RunOnMainThread(false, attachCALayerCmd);
+                  if(DEBUG) {
+                      System.err.println("MaxOSXCGLContext.NSOpenGLImpl.associateDrawable(true): "+attachGLLayerCmd);
+                  }                            
+                  OSXUtil.RunOnMainThread(false, attachGLLayerCmd);
               } else { // -> null == backingLayerHost                  
                   lastWidth = drawable.getWidth();
                   lastHeight = drawable.getHeight();                  
@@ -798,8 +817,11 @@ public abstract class MacOSXCGLContext extends GLContextImpl
               }
           } else { // -> !bound
               if( null != backingLayerHost ) {
-                  final AttachNSOpenGLLayer cmd = attachCALayerCmd;
-                  attachCALayerCmd = null;
+                  final AttachGLLayerCmd cmd = attachGLLayerCmd;
+                  attachGLLayerCmd = null;
+                  if( null == cmd ) {
+                      throw new GLException("Null attachGLLayerCmd: "+drawable);
+                  }
                   if( 0 != cmd.pbuffer ) {
                       CGL.setContextPBuffer(contextHandle, 0);
                   }
@@ -808,7 +830,11 @@ public abstract class MacOSXCGLContext extends GLContextImpl
                           cmd.valid = true; // skip pending creation
                       } else {
                           // All CALayer lifecycle ops are deferred on main-thread
-                          OSXUtil.RunOnMainThread(false, new DetachNSOpenGLLayer(cmd));
+                          final DetachGLLayerCmd dCmd = new DetachGLLayerCmd(cmd);
+                          if(DEBUG) {
+                              System.err.println("MaxOSXCGLContext.NSOpenGLImpl.associateDrawable(false): "+dCmd);
+                          }                            
+                          OSXUtil.RunOnMainThread(false, dCmd);
                           if( null != gl3ShaderProgram ) {
                               gl3ShaderProgram.destroy(MacOSXCGLContext.this.gl.getGL3());
                               gl3ShaderProgram = null;
@@ -903,7 +929,7 @@ public abstract class MacOSXCGLContext extends GLContextImpl
       
       @Override
       public boolean setSwapInterval(int interval) {
-          final AttachNSOpenGLLayer cmd = attachCALayerCmd;
+          final AttachGLLayerCmd cmd = attachGLLayerCmd;
           if(null != cmd) {
               synchronized(cmd) {
                   if( cmd.valid && 0 != cmd.nsOpenGLLayer) {
@@ -932,7 +958,7 @@ public abstract class MacOSXCGLContext extends GLContextImpl
       
       @Override
       public boolean swapBuffers() {
-          final AttachNSOpenGLLayer cmd = attachCALayerCmd;
+          final AttachGLLayerCmd cmd = attachGLLayerCmd;
           if(null != cmd) {
               synchronized(cmd) {
                   if( cmd.valid && 0 != cmd.nsOpenGLLayer) {
-- 
cgit v1.2.3