Reply – Re: GLWindow in NewtCanvasAWT - deadlock in GLWindow.setSize
Your Name
Subject
Message
or Cancel
In Reply To
Re: GLWindow in NewtCanvasAWT - deadlock in GLWindow.setSize
— by Andrzej Andrzej
Yes sorry of course, sorry it took me a while as my render in c++ is pretty complex, but in the end I was able to reproduce the same problem with just Java rendering. The rendering of the triangle is done on a seperate thread, to mimic what my c++ renderer is doing. There are two classes, a JFrame and the Renderer.

The JFrame:

=============

package Test;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Container;
import java.awt.Dimension;

import javax.swing.JFrame;
import javax.swing.JPanel;

import com.jogamp.newt.awt.NewtCanvasAWT;
import com.jogamp.opengl.GLCapabilities;
import com.jogamp.opengl.GLProfile;

public class GLWindowMinimumTestRunner extends JFrame {

    JPanel openGLPanel_;

    private GLWindowMinimumTest openGLSurface_;

    int initialWidth = 800;
    int initialHeight = 600;
   
    public GLWindowMinimumTestRunner() {
       
        getContentPane().setBackground(Color.white);

        setMinimumSize(new Dimension(640, 480));
       
        Container pane = getContentPane();
       
        openGLSurface_ = new GLWindowMinimumTest(initialWidth, initialHeight);
       
        NewtCanvasAWT newtCanvasAWT = new NewtCanvasAWT(openGLSurface_.getGLWindow());

        JPanel openGLPanel = new JPanel();
        openGLPanel.setLayout(new BorderLayout());
        openGLPanel.add(newtCanvasAWT, BorderLayout.CENTER);

         
          pane.add(newtCanvasAWT, BorderLayout.CENTER);

          pack();
          setLocationRelativeTo(null);
          setVisible(true);
         
          openGLSurface_.render();
    }
   
    private GLCapabilities getGLCapabilities() {

        GLProfile glProfile = GLProfile.get("GL2");
        GLCapabilities glCapabilities = new GLCapabilities( glProfile );
        glCapabilities.setDoubleBuffered(true);
        glCapabilities.setHardwareAccelerated(true);
       
        return glCapabilities;
    }
}

=============

and the Renderer

=============

package Test;

import com.jogamp.newt.opengl.GLWindow;
import com.jogamp.opengl.*;

public final class GLWindowMinimumTest
{  
   private GLWindow glWindow_;

   public GLWindowMinimumTest(int initialWidth, int initialHeight)
   {
       glWindow_ = GLWindow.create(getGLCapabilities());
       glWindow_.setVisible(true);
       
       glWindow_.setSize(initialWidth, initialHeight);
   }
   
   public void changeSize(int width,int height)
   {
   }
   
   public GLWindow getGLWindow() {
       return glWindow_;
   }
   
   public void render()
   {  
       
       Thread thread = new Thread(new Runnable() {

           @Override
           public void run() {
               
               while(true) {
                   if(glWindow_.getContext().makeCurrent() == GLContext.CONTEXT_NOT_CURRENT) {
                       System.out.println("\nContext not current");
                   }

                   GL2 gl2 = glWindow_.getGL().getGL2();
                   
                   gl2.glDisable(GL.GL_DEPTH_TEST);
                   gl2.glClearColor(0.0f,1.0f,1.0f,0.0f);   //Background blue
                   gl2.glClear(GL.GL_COLOR_BUFFER_BIT);
                   gl2.glLoadIdentity();  
                   gl2.glColor3f(1.0f, 0.0f, 0.0f);   //Color red
                   gl2.glBegin(GL.GL_TRIANGLES);
                   gl2.glVertex3f(0,0,0.0f);
                   gl2.glVertex3f(1,0,0.0f);
                   gl2.glVertex3f(0,1,0.0f);        
                   gl2.glEnd();
                   
                   glWindow_.display();
                   
                   try {
                    Thread.sleep(200);
                   } catch (InterruptedException e) {
                        e.printStackTrace();
                   }
               }
           }
       });
               
       thread.start();
       
         
   }
   
   private GLCapabilities getGLCapabilities() {

       GLProfile glProfile = GLProfile.get("GL2");
       GLCapabilities glCapabilities = new GLCapabilities( glProfile );
       glCapabilities.setDoubleBuffered(true);
       glCapabilities.setHardwareAccelerated(true);
       
       return glCapabilities;
   }
}

=============

Invoked from a main function like so:

SwingUtilities.invokeLater(() -> {
                GLWindowMinimumTestRunner glWindowMinimumTestRunner = new GLWindowMinimumTestRunner();
});

The exception happens when I resize the window:

RunnableTask.run(): A caught exception occured on thread AWT-EventQueue-0-Display-.macosx_nil-1-EDT-2: RunnableTask[enqueued true[executed false, flushed false], tTotal 0 ms, tExec 0 ms, tQueue 0 ms, attachment null, throwable java.lang.RuntimeException: Waited 5000ms for: <25e1570b, ad48fa6>[count 46, qsz 0, owner <Thread-4>] - <AWT-EventQueue-0-Display-.macosx_nil-1-EDT-2>]
java.lang.RuntimeException: Waited 5000ms for: <25e1570b, ad48fa6>[count 46, qsz 0, owner <Thread-4>] - <AWT-EventQueue-0-Display-.macosx_nil-1-EDT-2>
        at jogamp.common.util.locks.RecursiveLockImpl01Unfairish.lock(RecursiveLockImpl01Unfairish.java:198)
        at jogamp.newt.WindowImpl$SetSizeAction.run(WindowImpl.java:1351)
        at jogamp.newt.DisplayImpl.runOnEDTIfAvail(DisplayImpl.java:450)
        at jogamp.newt.WindowImpl.runOnEDTIfAvail(WindowImpl.java:2782)
        at jogamp.newt.WindowImpl.setSize(WindowImpl.java:1394)
        at com.jogamp.newt.opengl.GLWindow.setSize(GLWindow.java:588)
        at jogamp.newt.awt.event.AWTParentWindowAdapter$1.run(AWTParentWindowAdapter.java:128)
        at com.jogamp.common.util.RunnableTask.run(RunnableTask.java:127)
        at jogamp.newt.DefaultEDTUtil$NEDT.run(DefaultEDTUtil.java:375)

This prevents me from reacting to changes of the container size and calling back into my c++ renderer to resize the framebuffer.

All of this on latest eclipse, latest jogl and latest macos