Crash when creating more than ~15 jogl/awt windows

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

Crash when creating more than ~15 jogl/awt windows

GiGurra
Hi everyone,

I am new to this forum but not to jogl in general. Previously I used JOGL 1 for my current project but I am now in the process of trying JOGL 2.

I wish to run about 50+ windows in my current project (please don't ask why cause I couldn't tell you honestly, just want to let you know I need it and I am already running 150+ no problem utilizing c++ with direct3d)

A long time ago I ran into an issue where JOGL 1 refused to let me have more than about 40 awt windows with jogls GLCanvas inside if an animator was used - The application would simply lock up if I added more (this is regardless of system and java version, though some of my higher end machines can allow more windows before the crash than the lower end machines)

Today I thought I would give JOGL 2 a go and see if it would work, however the results were worse.
Making slight modifications to the simple jogl tutorial code found: http://jogamp.org/wiki/index.php/Using_JOGL_in_AWT_SWT_and_Swing
I created a very simple application (see source below) to test this out, and I'm only able to create about 15 windows before I start seeing lockups/freezes without any error messages. If I try to create more than 25 then i even get an exception in the console output (not just the ordinary lockups). I am using netbeans 7 and the -xmx1536m argument for the vm. Changing this doesn't change the test results.

Do you have any idea what might be causing this? Is it possible AWT and JOGL simply don't get along well?

"Exception in thread "main-AWTAnimator-1" javax.media.opengl.GLException: javax.media.opengl.GLException: Error making temp context current: 0x0x20013, werr: 0"........ (goes on many lines, tell me if I should paste everything)



/***** HelloJogl.java *****/

package hellojogl;

import com.jogamp.opengl.util.Animator;
import javax.media.opengl.GLCapabilities;
import javax.media.opengl.GLProfile;

public class HelloJogl {

    static {
        GLProfile.initSingleton(false);
    }

    public static void main(String[] args) {

        final GLProfile glprofile = GLProfile.getDefault();
        final GLCapabilities glcapabilities = new GLCapabilities(glprofile);

        final int numWindows = 15;
        final Animator animator = new Animator();
        for (int i = 0; i < numWindows; i++) {
            animator.add(new OneTriangleAWT(glprofile, glcapabilities).glcanvas);
        }

        animator.start();
    }
}


/********* OneTriangle.java ******/
package hellojogl;

import javax.media.opengl.GL;
import javax.media.opengl.GL2;
import javax.media.opengl.glu.GLU;

public class OneTriangle {

    protected static void setup(GL2 gl2, int width, int height) {
        gl2.glMatrixMode(GL2.GL_PROJECTION);
        gl2.glLoadIdentity();
        GLU glu = new GLU();
        glu.gluOrtho2D(0.0f, width, 0.0f, height);
        gl2.glMatrixMode(GL2.GL_MODELVIEW);
        gl2.glLoadIdentity();
        gl2.glViewport(0, 0, width, height);
    }

    protected static void render(GL2 gl2, int width, int height) {
        gl2.glClear(GL.GL_COLOR_BUFFER_BIT);
        gl2.glLoadIdentity();
        gl2.glBegin(GL.GL_TRIANGLES);
        gl2.glColor3f(1, 0, 0);
        gl2.glVertex2f(0, 0);
        gl2.glColor3f(0, 1, 0);
        gl2.glVertex2f(width, 0);
        gl2.glColor3f(0, 0, 1);
        gl2.glVertex2f(width / 2, height);
        gl2.glEnd();
    }
}




/****** OneTriangleAWT.java *****/

package hellojogl;

import javax.media.opengl.GLAutoDrawable;
import javax.media.opengl.GLEventListener;
import javax.media.opengl.GLProfile;
import javax.media.opengl.GLCapabilities;
import javax.media.opengl.awt.GLCanvas;

import java.awt.Frame;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

public class OneTriangleAWT {

    final GLCanvas glcanvas;

    public OneTriangleAWT(final GLProfile glprofile, final GLCapabilities glcapabilities) {

        glcanvas = new GLCanvas(glcapabilities);
        glcanvas.addGLEventListener(new GLEventListener() {

            @Override
            public void reshape(GLAutoDrawable glautodrawable, int x, int y, int width, int height) {
                OneTriangle.setup(glautodrawable.getGL().getGL2(), width, height);
            }

            @Override
            public void init(GLAutoDrawable glautodrawable) {
            }

            @Override
            public void dispose(GLAutoDrawable glautodrawable) {
            }

            @Override
            public void display(GLAutoDrawable glautodrawable) {
                OneTriangle.render(glautodrawable.getGL().getGL2(), glautodrawable.getWidth(), glautodrawable.getHeight());
            }
        });

        final Frame frame = new Frame("One Triangle AWT");
        frame.add(glcanvas);
        frame.addWindowListener(new WindowAdapter() {

            public void windowClosing(WindowEvent windowevent) {
                frame.remove(glcanvas);
                frame.dispose();
                System.exit(0);
            }
        });

        frame.setSize(640, 480);
        frame.setVisible(true);

    }
}

Reply | Threaded
Open this post in threaded view
|

Re: Crash when creating more than ~15 jogl/awt windows

gouessej
Administrator
Hi!

Your error is about context switching on Windows, it is windows-specific and I'm almost sure a bug about that has been filled. I found a problem of high memory consumption when using GLCanvas with auto swap buffer mode disabled.

Anyway, if you want to handle many windows without locking problems, rather use NEWT.
Julien Gouesse | Personal blog | Website
Reply | Threaded
Open this post in threaded view
|

Re: Crash when creating more than ~15 jogl/awt windows

GiGurra
Strange though, cause if I launch three separate java processes,each launching 15 windows, that works absolutely fine.
Also there is no crashing if I comment out the line which adds the GLCanvas to the AWT frame.

Are you saying the same thing would happen for example in C/C++ if I let glut open 25 windows? it should also crash?
I think it is some issue with JOGL<->AWT.

I will try to read up on NEWT to see what that is, I assume some window abstraction layer that JOGL can use?
Also I'm able to generate crashes when launching many windows even when not even using an Animator to handle the rendering.
Reply | Threaded
Open this post in threaded view
|

Re: Crash when creating more than ~15 jogl/awt windows

GiGurra
This post was updated on .
I've now tried using NEWT but it also crashes when I hit about 45 windows. Feels like either a JOGL or openGL driver issue.
HOWEVER: Like with AWT, launching windows in separate processes works fine (does not crash)  (4x30 runs fine on NEWT), I can run well over 100 windows without problems.

The entire code I used is visible below:

/********* HelloJogl.java ********/
package hellojogl;

import com.jogamp.newt.event.WindowAdapter;
import com.jogamp.newt.event.WindowEvent;
import com.jogamp.newt.opengl.GLWindow;
import javax.media.opengl.GLCapabilities;
import javax.media.opengl.GLProfile;

public class HelloJogl {

    public static void main(String[] args) throws InterruptedException {

        final GLCapabilities glcapabilities = new GLCapabilities(GLProfile.getDefault());
        for (int i = 0; i < 45; i++) {
            final GLWindow window = GLWindow.create(glcapabilities);
            window.setSize(300, 300);
            window.setTitle("Window " + i);
            window.setVisible(true);      
        }
    }
}

/*********************************/

The error I get is

Detected screen size 1920x1200
Exception in thread "main" java.lang.RuntimeException: javax.media.opengl.GLException: Unable to create temp OpenGL context for device context 0xffffffffb2010ed5
        at jogamp.newt.DefaultEDTUtil.invokeImpl(DefaultEDTUtil.java:185)
        at jogamp.newt.DefaultEDTUtil.invoke(DefaultEDTUtil.java:113)
        at jogamp.newt.DisplayImpl.runOnEDTIfAvail(DisplayImpl.java:199)
        at jogamp.newt.WindowImpl.runOnEDTIfAvail(WindowImpl.java:1423)
        at jogamp.newt.WindowImpl.setVisible(WindowImpl.java:698)
        at com.jogamp.newt.opengl.GLWindow.setVisible(GLWindow.java:285)
        at hellojogl.HelloJogl.main(HelloJogl.java:27)
Caused by: javax.media.opengl.GLException: Unable to create temp OpenGL context for device context 0xffffffffb2010ed5
        at jogamp.opengl.windows.wgl.WindowsWGLContext.createImpl(WindowsWGLContext.java:296)
        at jogamp.opengl.GLContextImpl.makeCurrentLocking(GLContextImpl.java:406)
        at jogamp.opengl.GLContextImpl.makeCurrent(GLContextImpl.java:352)
        at jogamp.opengl.GLDrawableHelper.invokeGL(GLDrawableHelper.java:348)
        at com.jogamp.newt.opengl.GLWindow.display(GLWindow.java:547)
        at com.jogamp.newt.opengl.GLWindow.display(GLWindow.java:523)
        at com.jogamp.newt.opengl.GLWindow$1.windowResized(GLWindow.java:89)
        at jogamp.newt.WindowImpl.consumeWindowEvent(WindowImpl.java:2041)
        at jogamp.newt.WindowImpl.sendWindowEvent(WindowImpl.java:1987)
        at jogamp.newt.WindowImpl.setVisibleActionImpl(WindowImpl.java:670)
        at jogamp.newt.WindowImpl$VisibleAction.run(WindowImpl.java:682)
        at com.jogamp.common.util.RunnableTask.run(RunnableTask.java:93)
        at jogamp.newt.DefaultEDTUtil$EventDispatchThread.run(DefaultEDTUtil.java:282)
Exception in thread "main-Display-Windows_nil-1-EDT-1" javax.media.opengl.GLException: Unable to create temp OpenGL context for device context 0xffffffffb2010ed5Java Result: 1


--------------------

Win64,
gtx580 w latest whql drivers
jogl2 b23
6 gb ram
sun/oracle 32bit jvm 6_26
using netbeans 7 ide
Reply | Threaded
Open this post in threaded view
|

Re: Crash when creating more than ~15 jogl/awt windows

GiGurra
This post was updated on .
Tried to see if running in separate threads would make a diff? - Same result.
But if run in a separate process it works fine :S
So the code below does not help:

        /* Uncomment for NEWT */
        for (int thread = 0; thread < 2; thread++) {
            final Thread t = new Thread(new Runnable() {

                @Override
                public void run() {
                    final GLCapabilities glcapabilities = new GLCapabilities(GLProfile.getDefault());
                    for (int i = 0; i < 30; i++) {
                        final GLWindow window = GLWindow.create(glcapabilities);
                        window.setSize(300, 300);
                        window.setTitle("Window " + i);
                        window.setVisible(true);
                    }
                }
            });
            t.start();
        }


same crash
Reply | Threaded
Open this post in threaded view
|

Re: Crash when creating more than ~15 jogl/awt windows

gouessej
Administrator
You cannot create an infinite number of OpenGL contexts. As far as I know, you create a different context per window.
Julien Gouesse | Personal blog | Website
Reply | Threaded
Open this post in threaded view
|

Re: Crash when creating more than ~15 jogl/awt windows

GiGurra
Im not after creating infinite contexts :)
my minimum requirements are about 50 windows, but it seems jogl cannot do that for one process. (see 4-line newt example above). So now I'm thinking of creating a host process which launches a set of gui slave processes that actually do the rendering with about 5-10 windows each maximum.

5 processes each one hosting 10 seems to work fine. (check the newt example above).
However only being able to make about 45 with newt per process sees awfully low, especially since it doesnt fail on memory, but something else. And I can run 100+ direct3d windows no problem in the same process (never got close to hitting a limit or crash with direct3d)

I wonder if I could create more than 45 windows per process if I was coding OpenGL in C directly
Reply | Threaded
Open this post in threaded view
|

Re: Crash when creating more than ~15 jogl/awt windows

gouessej
Administrator
The bottleneck seems to be the context creation which is not something specific to JOGL. Therefore, if you created OpenGL windows directly in C with a single context per window, you would hit the same limit maybe a very little bit later because Java2D may create an OpenGL context. The maximum total number of contexts is hardware-dependent both in OpenGL and Direct3D.
Julien Gouesse | Personal blog | Website
Reply | Threaded
Open this post in threaded view
|

Re: Crash when creating more than ~15 jogl/awt windows

GiGurra
What I find is wierd is that there seems to be a maximum number of contexts PER PROCESS.
I can easily have over 100 contexts, as long as they are split into separate processes.

What I wonder is, is this normal?

Also if I use JOGL 1, I can run about 40+ in AWT, and in JOGL2 I can only do about 15.
JOGL2 on newt allows creation to about 40.

It is not ment as a complaint, you do not need to defend JOGL :). I am very happy it exists, but I need
to find out its and my limitations on my system to make the necessery design choices for my software
Reply | Threaded
Open this post in threaded view
|

Re: Crash when creating more than ~15 jogl/awt windows

Sven Gothel
Administrator
On Wednesday, June 15, 2011 07:44:22 PM GiGurra [via jogamp] wrote:
>
> What I find is wierd is that there seems to be a maximum number of contexts
> PER PROCESS.
> I can easily have over 100 contexts, as long as they are split into separate
> processes.
>
> What I wonder is, is this normal?

Sorry for having ignored this thread, busy w/ RC3.

I see you have copy/paste your code in an email as a test case I assume,
could you make your question, or bug-statement more clear and
rephrase it as a junit test please ?

Then I will pull it, or copy your attached java files (no copy/paste please)
- to investigate the limitations you mentioned.

For sure Julien is right, there are some native constraints by driver and hardware
which are _not_ specified. In the past multithreading and/or multiple context per windows
were pretty buggy in drivers .. but IMHO this has changed over time until today.

However, having unit tests covering those issues are a great thing to have.

- UC1: n ctx - n drawables - n threads (ctx/draw)
      - normal case, no issue IMHO

- UC2.1: n ctx - 1 drawable - 1 thread

- UC2.2: n ctx - 1 drawable - n thread

- UC3: n ctx - n drawables - n threads, alternate ctx/drawable association
      - ctx1 - draw1, ctx2 - draw2
      - ctx2 - draw1, ctx1 - draw2
      - ..

I can imagine that maybe UC2.2 and UC3 could cause problems w/ some drivers,
at least this was true for some drivers back in 2005.

A maximum number of ctx/threads, well, I don't know.

I would do all of the above using NEWT ofc, as Julien mentioned,
NEWT animation threads will not funnel via one rendering thread.

+++

Using AWT however is a 'bitch' here, since (see above),
it needs to funnel _all_ GL access via the AWT-EDT.

Hence you fill see a saturation phenomenom very easily, ie stottering animation.
No 'error' shall happen though.

+++

You 50 'window/ctx per thread' max looks like a driver limitation .. indeed weird.

Would be awesome to put this in a unit test to see the diff behavior on diff platforms/drivers.


Cheers, Sven
Reply | Threaded
Open this post in threaded view
|

Re: Crash when creating more than ~15 jogl/awt windows

GiGurra
thanks for the response, I will send you an email with attached simplified netbeans project if that helps.
(or just java files, please provide where I should send to)

but PLEASE: NOTE!: The limit is per process, NOT per thread.
Multiple threads do not help as Ive stated earlier in the thread.

Basically the test is super simple for both the AWT and NEWT case.
Set up a for loop and create n windows until you get the error (at for example 40)
Then do 30 windows without error in 4-5 separate processes (so u get 120-150 windows )

You dont need to do any actual rendering, creating the OpenGL windows & contexts is enough
Reply | Threaded
Open this post in threaded view
|

Re: Crash when creating more than ~15 jogl/awt windows

GiGurra
Please provide me an email address where I can send the test case
Reply | Threaded
Open this post in threaded view
|

Re: Crash when creating more than ~15 jogl/awt windows

Wade Walker
Administrator
Hi GiGurra,

If you'd like to submit your code as a unit test, there are instructions at http://jogamp.org/wiki/index.php/Contributing_a_new_feature_or_fix. Submitting this way might be easier on Sven, since it doesn't require him to rework the code into a unit test himself

Reply | Threaded
Open this post in threaded view
|

Re: Crash when creating more than ~15 jogl/awt windows

GiGurra
This post was updated on .
Thank you.

I think though I may have embarrassed myself quite hard right now. :)

The issue has been at least partially solved, and it seems to be memory related after all
I was using -Xmx1536m, but for some reason this only gives my JVM a small fraction of this number to work with.
When i lower it to 1024 or 1280 then I can actually more than double the number of screens I can run.

Quite Frustrating!

So (Yes the order is correct, and very interesting!):
with -Xmx1280m I can generate up to about ~100 newt windows before opengl context creation fails
with -Xmx1536m I can generate up to about ~40 newt windows before opengl context creation fails

with -Xmx1280m I can generate up to about ~50 awt windows before opengl context creation fails
with -Xmx1536m I can generate up to about ~20 awt windows before opengl context creation fails

So it seems the first part at least is an issue with the jvm and memory management. I will not pursue this issue further.
I need about 50 and it seems to be possible now.

EDIT: Ok, talking to a friend here who knows some stuff...seems like I have some reading to do ^^. Sry to bother u.

Edit2: -Xmx512m and 150 windows with both AWT and NEWT, no signs of crashing so far. This is excellent !
Seems like pushing heap size higher kills other stuff. This tells me I might also want to try a 64bit JVM
Reply | Threaded
Open this post in threaded view
|

Re: Crash when creating more than ~15 jogl/awt windows

Wade Walker
Administrator
If you're using a 32-bit JVM on Windows, there is an unexpectedly low limit on heap size. Programs can usually only get maybe 1.5 GB of heap at maximum, depending on how much other memory the program uses (the whole JVM process can only have 2GB at theoretical max on 32-bit Windows). So setting -Xmx to 1.5G might allow the Java heap to crowd out other memory use by the process, which could lead to errors in native/JNI code. Lowering -Xmx might be forcing more frequent garbage collection and leaving more room for non-heap memory use.
Reply | Threaded
Open this post in threaded view
|

Re: Crash when creating more than ~15 jogl/awt windows

Sven Gothel
Administrator
In reply to this post by GiGurra
On Sunday, June 19, 2011 03:46:37 AM GiGurra [via jogamp] wrote:
>
> Thank you.
>
> I think though I may have embarrassed myself quite hard right now. :)
>

On the contrary, you have found another metric/constraint! Kudos.

> The issue has been at least partially solved, and it seems to be memory
> related after all
> I was using -Xmx1536m, but for some reason this only gives my JVM a small
> fraction of this number to work with.
> When i lower it to 1024 or 1280 then I can actually more than double the
> number of screens I can run.
>
> Quite Frustrating!
Maybe, but you the findings you present here, are quite nice,
i.e. NEWT GLWindow requires around half the memory than AWT GLCanvas.

Great stuff.

~Sven

>
> So (Yes the order is correct, and very interesting!):
> with -Xmx1280m I can generate up to about ~100 newt windows before opengl
> context creation fails
> with -Xmx1536m I can generate up to about ~40 newt windows before opengl
> context creation fails
>
> with -Xmx1280m I can generate up to about ~50 awt windows before opengl
> context creation fails
> with -Xmx1536m I can generate up to about ~20 awt windows before opengl
> context creation fails
>
> So it seems the first part at least is an issue with the jvm and memory
> management. I will not pursue this issue further.
> I need about 50 and it seems to be possible now.
Reply | Threaded
Open this post in threaded view
|

Re: Crash when creating more than ~15 jogl/awt windows

gouessej
Administrator
In reply to this post by GiGurra
The problem is not the heap but rather the direct memory...
Julien Gouesse | Personal blog | Website
Reply | Threaded
Open this post in threaded view
|

Re: Crash when creating more than ~15 jogl/awt windows

Wade Walker
Administrator
gouessej wrote
The problem is not the heap but rather the direct memory...
I was guessing that the large heap was leaving not enough space for direct memory (since overall process size must be less than 2GB). Reducing -Xmx would force more garbage collection, leaving more space for direct memory under the 2GB limit.