AWTGLCanvas and context

Started by Pogomon, January 06, 2006, 12:03:17

Previous topic - Next topic

elias

Hm, I think I'll need that simple test program this time :). If you could modify an existing LWJGL test (AWTTest or AWTGears) to exhibit that NPE I would be grateful :) I'm glad you're helping us to iron out all those pesky AWTGLCanvas bugs!

- elias

elias

We can block, but how are you going to tell the other thread to release its context if paint() doesn't release the context every time?

- elias

Evil-Devil

Quote from: "elias"Evil-Devil: Because you can't force another thread to release the context.

- elias
I don't need another thread to release the context. If the other thread give my awt thread a sign that the context should be released it should be fine. Mainly I designed my AWTGL Apps the way that every drawing stuff is done within a scenegraph or simple class that implements a specific interface that is known by the AWTGlCanvas.

//edit: I will work on a example for 0.99 with 2 or more threads, ok?

renanse

Ok, here's your lwjgl only repeatable test.  :)

Edit AWTGears and make the following additions:


       add(canvas0 = new AWTGLCanvas() {
            long startTime = 0;
            long fps = 0;
+            boolean show;           
            public void paintGL() {


                   GL11.glPopMatrix();     
+                    
+                    if (show) {
+                        show = false;
+                        JOptionPane.showMessageDialog(AWTGears.this, "tick!");
+                    }
+                    
                    swapBuffers();
                } catch (LWJGLException e) {
                    throw new RuntimeException(e);
                }
                if (startTime > System.currentTimeMillis()) {
                    fps++;
                } else {
+                    show = true;
                    long timeUsed = 5000 + (startTime - System.currentTimeMillis());


Every time the code computes a fps, the next render loop will throw up a dialog.  Each time you see that and push ok it shows an IllegalStateException.  My guess is that the dialog blocks the current paint event but the repaint thread continues generating new paint events somehow killing the context for the original paint event's subsequent call to swapBuffers?

renanse

PS: The exception will be java.lang.IllegalStateException in this test, but the root cause between this and the npe is the same...  The npe happens simply because a different call besides swapbuffers (one that uses the context capabilities without checking for null for example) is encountered first.

renanse

FYI, the unmodified AWTGears now flickers like crazy on my Mac Powerbook (G4 1.5 w/ Radeon 9700 OSX 10.4.6 with latest patches)

elias

Ok,  I think I fixed both the flickering and the problem with dialog boxes. Please run "ant jars" from the updated subversion tree and test with the new lwjgl.jar (no native code changes necessary). I'm not currently able to upload one myself, sorry.

- elias

renanse

That seems to solve both problems on both mac and win32.  Our linux setup is b0rked at the moment.  Anyhow, thanks elias!

edit: and by b0rked, I mean in general, not related to this issue.  :)

Evil-Devil

Elias, could you add a flag for enabling/disabling the workaround? I think that  would be the best for all. So there is no need to write a AWTGLCanvas from scrap yourself if someone want full control of the thread handling.

coasternuts

I'm now getting this IllegalStateException in my code.  I downloaded beta3 but that didn't solve it.

Is there a final fix for this coming later or have I uncovered another problem?  

Here is the callstack:

Exception in thread "AWT-EventQueue-0" java.lang.IllegalStateException: From thr
ead Thread[AWT-EventQueue-0,6,main]: Thread[AWT-EventQueue-0,6,] already has the
context current
       at org.lwjgl.opengl.Context.checkAccess(Context.java:181)
       at org.lwjgl.opengl.Context.makeCurrent(Context.java:188)
       at org.lwjgl.opengl.AWTGLCanvas.paint(AWTGLCanvas.java:284)
       at org.lwjgl.opengl.AWTGLCanvas.update(AWTGLCanvas.java:313)
       at sun.awt.RepaintArea.updateComponent(Unknown Source)
       at sun.awt.RepaintArea.paint(Unknown Source)
       at sun.awt.windows.WComponentPeer.handleEvent(Unknown Source)
       at java.awt.Component.dispatchEventImpl(Unknown Source)
       at java.awt.Component.dispatchEvent(Unknown Source)
       at java.awt.EventQueue.dispatchEvent(Unknown Source)
       at java.awt.EventDispatchThread.pumpOneEventForHierarchy(Unknown Source)

       at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
       at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
       at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
       at java.awt.EventDispatchThread.run(Unknown Source)

My paintGL routine is the following:

protected void paintGL() 
   {
      if(!initialized) 
      {
         if (renderThread == null) 
         {
            renderThread = new Thread(this);
            renderThread.setName("Charting-Renderer");
            renderThread.start();
         }

         initialized = true;
         initialize();
      }

      synchronized (this) 
      {
         try {
            makeCurrent();
            render();
            swapBuffers();
            releaseContext();
         } catch (LWJGLException le) {
            le.printStackTrace();
         }
      }

      if (startTime > System.currentTimeMillis()) {
         fps++;
      } else {
         long timeUsed = 5000 + (startTime - System.currentTimeMillis());
         startTime = System.currentTimeMillis() + 5000;
         // parent.updateFPS((fps / (timeUsed / 1000f)));
         fps = 0;
      }					
   }

elias

I'll need a complete minimal test to figure out what is wrong. Be careful with the makeCurrent/releaseContext calls, they're only supposed to be called from AWTGLCanvas itself.

- elias

coasternuts

Thanks elias.

You made me make sure I found my bug.  :)