GLWindow in NewtCanvasAWT - deadlock in GLWindow.setSize

classic Classic list List threaded Threaded
7 messages Options
Reply | Threaded
Open this post in threaded view
|

GLWindow in NewtCanvasAWT - deadlock in GLWindow.setSize

Andrzej
Hi,

This is related to the my previous post: http://forum.jogamp.org/JOGL-without-GLEventListener-GLCanvas-or-GLJPanel-td4038837.html in so far that the setup is the same.

GLWindow in NewtCanvasAWT and a native c++ renderer.

I setup my GLWindow, put it inside the NewtCanvasAWT, and put that in a JFrame, in between two JToolBars. OpenGL content gets displayed correctly, but this happens:

DefaultEDT.run(): Caught exception occured on thread AWT-EventQueue-0-Display-.macosx_nil-1-EDT-2: RunnableTask[executed true, tTotal 19976 ms, tExec 5002 ms, tQueue 14974 ms, attachment null, throwable java.lang.RuntimeException: Waited 5000ms for: <27285f7b, 5ed3053b>[count 132, qsz 0, owner <Thread-6>] - <AWT-EventQueue-0-Display-.macosx_nil-1-EDT-2>]
java.lang.RuntimeException: Waited 5000ms for: <27285f7b, 5ed3053b>[count 132, qsz 0, owner <Thread-6>] - <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:1045)
        at jogamp.newt.DisplayImpl.runOnEDTIfAvail(DisplayImpl.java:435)
        at jogamp.newt.WindowImpl.runOnEDTIfAvail(WindowImpl.java:2133)
        at jogamp.newt.WindowImpl.setSize(WindowImpl.java:1087)
        at com.jogamp.newt.opengl.GLWindow.setSize(GLWindow.java:509)
        at jogamp.newt.awt.event.AWTParentWindowAdapter$1.run(AWTParentWindowAdapter.java:128)
        at com.jogamp.common.util.RunnableTask.run(RunnableTask.java:133)
        at jogamp.newt.DefaultEDTUtil$NEDT.run(DefaultEDTUtil.java:372)

Looks like the newt canvas calls setSize on GLWindow to resize it to fit it within itself, but can't. That's also the effect I see, GLWindow does not fit in its newt canvas container. Any help would be greatly appreciated.

Thanks,

Andrzej
Reply | Threaded
Open this post in threaded view
|

Re: GLWindow in NewtCanvasAWT - deadlock in GLWindow.setSize

gouessej
Administrator
Hey

Provide a SSCCE or don't expect any help. I can't fix a bug that I can't reproduce.
Julien Gouesse | Personal blog | Website
Reply | Threaded
Open this post in threaded view
|

Re: GLWindow in NewtCanvasAWT - deadlock in GLWindow.setSize

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
Reply | Threaded
Open this post in threaded view
|

Re: GLWindow in NewtCanvasAWT - deadlock in GLWindow.setSize

gouessej
Administrator
Don't set the size of the GLWindow, rather set the size of the top level container (JFrame).

Rather use com.jogamp.newt.event.WindowListener.windowResized(WindowEvent) or its AWT equivalent to listen to resize events.

Then, remove your loop (while(true)...) and use a simple animator.

After that, put into the listener a call to GLAutoDrawable.invoke(), use a GLRunnable that calls your native renderer.
Julien Gouesse | Personal blog | Website
Reply | Threaded
Open this post in threaded view
|

Re: GLWindow in NewtCanvasAWT - deadlock in GLWindow.setSize

Andrzej
So the while loop and no animator models my native renderer...

Its an asynchronous renderer in the native c++ lib that renders when needed and there is no one render function. Rather it calls into the platform specific code to make the context current, and then performs all the rendering on the native side. So it is the driver of what is rendered and when, and not a Java side animator. So the Java side here is really thin. I just need to create a gl context and give the native renderer a way to make it current (and handle the resize events, and user input handling).

As I mentioned in my other post, this all works fine when the GLWindow is stand alone, but I get these deadlicks as soon as I try to put this inside a Swing application (via NewtCanvasAWT).
Reply | Threaded
Open this post in threaded view
|

Re: GLWindow in NewtCanvasAWT - deadlock in GLWindow.setSize

Andrzej
So are you saying that this is not going to work and I should work on refactoring my native renderer?

I just want to know which direction to pursue, whether there is some hope/avenue to explore with what I have, or do I have to refactor the native renderer.

I would prefer not to have to do that, as it is used by other platforms (C#, objective-C, C++) without any issues, so I'd prefer not to have to refactor it just for Java, but I'll do it if what you're telling me is that the way I use it is not supported.

Thanks.
Reply | Threaded
Open this post in threaded view
|

Re: GLWindow in NewtCanvasAWT - deadlock in GLWindow.setSize

gouessej
Administrator
AWT and Swing are less flexible than NEWT, I already gave you some indications, what more can I do?
Julien Gouesse | Personal blog | Website