From cf95674e16d34a85191d3af0a35d1357e011fcac Mon Sep 17 00:00:00 2001
From: Sven Gothel <sgothel@jausoft.com>
Date: Fri, 26 Mar 2010 22:24:34 +0100
Subject: http://www.jogamp.org/bugzilla/show_bug.cgi?id=391

As shown below, the concurrent access of GLStateTracker
while being cleared by GLContext.destroy() causes a NPE.

GLContext.destroy() shall disable it first, then clear it.

The state stack pop method shall also swap the mapping
with a most atomic action.

Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
        at com.sun.opengl.impl.GLStateTracker.getInt(GLStateTracker.java:94)
        at com.sun.opengl.impl.gl2.GL2Impl.glGetIntegerv(GL2Impl.java:6102)
        at com.sun.opengl.impl.gl2.GL2Impl.imageSizeInBytes(GL2Impl.java:26000)
        at com.sun.opengl.impl.gl2.GL2Impl.imageSizeInBytes(GL2Impl.java:25713)
        at com.sun.opengl.impl.gl2.GL2Impl.glTexImage2D(GL2Impl.java:18692)
        at glredbook1314.combiner.init(combiner.java:104)
        at com.sun.opengl.impl.GLDrawableHelper.init(GLDrawableHelper.java:88)
        at javax.media.opengl.awt.GLJPanel$Updater.init(GLJPanel.java:557)
        at com.sun.opengl.impl.GLDrawableHelper.init(GLDrawableHelper.java:88)
        at
com.sun.opengl.impl.GLPbufferImpl$InitAction.run(GLPbufferImpl.java:274)
        at
com.sun.opengl.impl.GLDrawableHelper.invokeGL(GLDrawableHelper.java:149)
        at
com.sun.opengl.impl.GLPbufferImpl.maybeDoSingleThreadedWorkaround(GLPbufferImpl.java:267)
        at
com.sun.opengl.impl.GLPbufferImpl.swapBuffers(GLPbufferImpl.java:157)
        at
com.sun.opengl.impl.GLDrawableHelper.invokeGL(GLDrawableHelper.java:159)
        at javax.media.opengl.awt.GLJPanel.dispose(GLJPanel.java:238)

+++
---
 .../classes/com/sun/opengl/impl/GLContextImpl.java |  2 +-
 .../com/sun/opengl/impl/GLStateTracker.java        | 27 ++++++++++++++++------
 2 files changed, 21 insertions(+), 8 deletions(-)

(limited to 'src/jogl/classes/com')

diff --git a/src/jogl/classes/com/sun/opengl/impl/GLContextImpl.java b/src/jogl/classes/com/sun/opengl/impl/GLContextImpl.java
index 97100208d..1d500bb17 100644
--- a/src/jogl/classes/com/sun/opengl/impl/GLContextImpl.java
+++ b/src/jogl/classes/com/sun/opengl/impl/GLContextImpl.java
@@ -240,7 +240,7 @@ public abstract class GLContextImpl extends GLContext {
       }
   
       if (glStateTracker != null) {
-          glStateTracker.clearStates();
+          glStateTracker.clearStates(false);
       }
   
       destroyImpl();
diff --git a/src/jogl/classes/com/sun/opengl/impl/GLStateTracker.java b/src/jogl/classes/com/sun/opengl/impl/GLStateTracker.java
index 698d20c47..d28d39f7f 100755
--- a/src/jogl/classes/com/sun/opengl/impl/GLStateTracker.java
+++ b/src/jogl/classes/com/sun/opengl/impl/GLStateTracker.java
@@ -52,7 +52,7 @@ import javax.media.opengl.*;
 public class GLStateTracker {
   private static final boolean DEBUG = Debug.debug("GLStateTracker");
 
-  private boolean enabled = true;
+  private volatile boolean enabled = true;
 
   private Map/*<Integer,Integer>*/ pixelStateMap = new HashMap/*<Integer,Integer>*/();
 
@@ -75,7 +75,8 @@ public class GLStateTracker {
     resetStates();
   }
 
-  public void clearStates() {
+  public void clearStates(boolean enable) {
+    enabled = enable;    
     pixelStateMap.clear();
   }
 
@@ -91,7 +92,13 @@ public class GLStateTracker {
     if(enabled) {
         Integer key = boxKey(pname);
         if(null!=key) {
-            params[params_offset] = ((Integer) pixelStateMap.get(key)).intValue();
+            Integer value = (Integer) pixelStateMap.get(key);
+            if(null!=value) {
+                params[params_offset] = value.intValue();
+            } else {
+                GLException re = new GLException("Key (0x"+Integer.toHexString(key.intValue())+") is not mapped");
+                throw re;
+            }
             return true;
         }
     }
@@ -102,7 +109,13 @@ public class GLStateTracker {
     if(enabled) {
         Integer key = boxKey(pname);
         if(null!=key) {
-            params.put(params.position(), ((Integer) pixelStateMap.get(key)).intValue());
+            Integer value = (Integer) pixelStateMap.get(key);
+            if(null!=value) {
+                params.put(params.position(), value.intValue());
+            } else {
+                GLException re = new GLException("Key (0x"+Integer.toHexString(key.intValue())+") is not mapped");
+                throw re;
+            }
             return true;
         }
     }
@@ -138,11 +151,11 @@ public class GLStateTracker {
             throw new GLException("null stack element (remaining stack size "+stack.size()+")");
         }
 
-        clearStates();
-
+        Map/*<Integer,Integer>*/ pixelStateMapNew = new HashMap/*<Integer,Integer>*/();
         if ( null != state.getPixelStateMap() ) {
-            pixelStateMap.putAll(state.getPixelStateMap());
+            pixelStateMapNew.putAll(state.getPixelStateMap());
         }
+        pixelStateMap = pixelStateMapNew;
     }
   }
 
-- 
cgit v1.2.3