Posted by
Sven Gothel on
Aug 25, 2014; 10:47pm
URL: https://forum.jogamp.org/Where-when-is-it-ok-to-call-setFullscreen-tp4032828p4032931.html
On 08/25/2014 11:55 PM, Marian Schedenig [via jogamp] wrote:
> Ok, I solved it. I failed to reproduce it in a test case, unfortunately, but
> trying to port over bits and pieces at least showed me roughly where the crash
> originated. I'm still not exactly sure what causes it, I can just describe the
> general situation.
>
> I have several listeners on my GLWindow. The input listeners for the keyboard
> and mouse just translate input events to internal data structures and add them
> to an input queue. Then during my main loop, which is triggered once per frame
> by the display() callback method, I do the following:
>
> 1) Clear the screen via glClear().
> 2) Iterate through the queued input events.
> 3) Update my game logic (fixed rate loop).
> 4) Render a frame.
> 5) Return whether to keep running or quit the application.
>
> Then back in display(), if the main loop returned false, I stop the animator
> and quit.
>
> I have a custom set of GUI classes for drawing windows, labels, buttons etc.
> and handle input events for them. These are all processed during step 1.
> Fullscreen mode is toggled via a button that can be clicked (mouse down inside
> the button, followed by a mouse up inside the same button) or focused and
> triggered with the Enter key (keyDown event - keyUp is handled as well, but
> not used to trigger the button).
You shall trigger fullscreen off-thread, i.e. not within
input event callback _or_ display(),
look at our unit test, e.g.
new Thread() { public void run() { glw.setFullscreen(true); } }.run();
>
> I was certain that both a mouse click and an Enter press trigged the crash,
> but it turned out that everything worked fine when I used only the mouse.
> Either I was mistaken, or during my first tests there were still more problems
> that also caused crashes with the mouse, and I'd "accidentally" fixed them
> while trying to figure out the problem. In any case, only the keyboard was
> causing the crashes. The button called a setFullscreen() method in my window
> wrapper class. Directly checking for the "f" key in the window listener's
> keyDown callback and calling setFullscreen() from there instead of queuing the
> key press also worked just fine.
>
> So I removed the direct call to setFullscreen() from my button click callback.
> Instead, I now set a flag on my window class, and after calling the main loop,
> I check that flag in display() (let's call that step 6) and call that same
> setFullscreen() method if the flag is set. And it's solid as a rock this way.
Interesting that this works, since the context is still current
and the surface locked.
>
> The odd thing about it is that the mouse click and key presses trigger the
> same callback method. And it's all happening in step 2. There should be no
> drawing code whatsoever outside step 4, except for step 1. So both the input
> events and the drawing are completely decoupled from the part where I used to
> trigger setFullscreen(). And even if I move step 6 between steps 1 and 2, it
> runs just fine.
>
> I expect it must be something very specific to my code (there's probably a
> stray call to some minor graphics update somewhere in my game logic that I
> haven't been able to find) and won't be of much help to anyone, but this is
> what I've been able to boil it down to, for what it's worth.
Pls try manipulating the NEWT window (GLWindow here) not:
A - within input event callback, or
B - while the surface is locked (within display())
A) b/c this 'might' be a native callback and 'complicated' lifecycle
operations or 'long' operations shall not happen here, think interrupt.
If it works, it may not be stable on all platforms.
B) Manipulating the lifecycle (fullscreen may change resources)
shall not happen from within a locked surface, e.g. display().
E.g. we may even create a new surface/drawable
with this operation (OSX/NewtCanvasAWT),
or at least perform native reparenting.
If it works, it may not be stable on all platforms.
We may need to emphasize this in the API docs.
If you glance over our many unit tests (do a calltrace of setFullscreen(..)),
you see how we safely do it.
Sorry for the inconvenience.
Hope this helps.
~Sven