Summary: | Recursive GLContext makeCurrent() doesn't work | ||
---|---|---|---|
Product: | [JogAmp] Jogl | Reporter: | Sven Gothel <sgothel> |
Component: | core | Assignee: | Sven Gothel <sgothel> |
Status: | RESOLVED FIXED | ||
Severity: | enhancement | CC: | gouessej, sgothel, skatejoe1 |
Priority: | --- | ||
Version: | 2 | ||
Hardware: | All | ||
OS: | all | ||
Type: | --- | SCM Refs: |
jogl 34687193484b2404d83eebf5d008b71d54e52286
|
Workaround: | --- |
Description
Sven Gothel
2013-01-18 01:36:08 CET
http://jogamp.org/git/?p=jogl.git;a=commit;h=34687193484b2404d83eebf5d008b71d54e52286 Culprit: GLContext's makeCurrent() didn't clear the boolean flag 'unlockContextAndSurface' in case the context is already current (-> recursion). Above case was detected within a code block tailed by a finally block, which acted on mentioned flag, i.e. called lock.unlock() and hence decremented the lock count even though the method return w/ successful state. Fixed. Added debug code: GLContext.release() debug code (DEBUG | TRACE_SWITCH), recording stack trace of last release() call, which is dumped in case no current was current. Added 2 unit tests: - Simple recursive GLContext makeCurrent()/release() from within GLEventListener's display(). Test also validates lock count and lock ownership. - GLAutoDrawable display() of another GLAutoDrawable from within GLEventListener's display(..). Hi i wanted to try out your new fix, (was debugging my slow app with visualvm and noticing that makeCurrent(), release and makeCurrentWithinLock was called every frame in invokeGLImpl) This is the output from the new "TraceSwitch" flag: AWT-EventQueue-0: GLContext.ContextSwitch[makeCurrent.0]: obj 0x400746fe, ctx 0x7fa2140b3400, surf 0x5000012 - <1dc5ee89, 2daf73a4>[count 0, qsz 0, owner <NULL>] AWT-EventQueue-0: GLContext.ContextSwitch: - setCurrent() - obj 0x400746fe, ctx 0x7fa2140b3400 AWT-EventQueue-0: GLContext.ContextSwitch[makeCurrent.X3]: obj 0x400746fe, ctx 0x7fa2140b3400, surf 0x5000012 - switch - CONTEXT_CURRENT - <1dc5ee89, 2daf73a4>[count 1, qsz 0, owner <AWT-EventQueue-0>] AWT-EventQueue-0: GLContext.ContextSwitch[release.0]: obj 0x400746fe, ctx 0x7fa2140b3400, surf 0x5000012, inDestruction: false, <1dc5ee89, 2daf73a4>[count 1, qsz 0, owner <AWT-EventQueue-0>] AWT-EventQueue-0: GLContext.ContextSwitch: - setCurrent() - NULL AWT-EventQueue-0: GLContext.ContextSwitch[release.X]: obj 0x400746fe, ctx 0x7fa2140b3400, surf 0x5000012 - switch - <1dc5ee89, 2daf73a4>[count 0, qsz 0, owner <NULL>] from what i understood from the patch it should go into the state final GLContext current = getCurrent(); if (current != null) { if (current == this) {...} but getCurrent() is always null. please respond if you need more details! regards david this happens using GLCanvas on Ubuntu 12.10 (In reply to comment #2) > Hi i wanted to try out your new fix, (was debugging my slow app with visualvm > and noticing that makeCurrent(), release and makeCurrentWithinLock was called > every frame in invokeGLImpl) > > This is the output from the new "TraceSwitch" flag: > AWT-EventQueue-0: GLContext.ContextSwitch[makeCurrent.0]: obj 0x400746fe, ctx > 0x7fa2140b3400, surf 0x5000012 - <1dc5ee89, 2daf73a4>[count 0, qsz 0, owner > <NULL>] > AWT-EventQueue-0: GLContext.ContextSwitch: - setCurrent() - obj 0x400746fe, ctx > 0x7fa2140b3400 > AWT-EventQueue-0: GLContext.ContextSwitch[makeCurrent.X3]: obj 0x400746fe, ctx > 0x7fa2140b3400, surf 0x5000012 - switch - CONTEXT_CURRENT - <1dc5ee89, > 2daf73a4>[count 1, qsz 0, owner <AWT-EventQueue-0>] > AWT-EventQueue-0: GLContext.ContextSwitch[release.0]: obj 0x400746fe, ctx > 0x7fa2140b3400, surf 0x5000012, inDestruction: false, <1dc5ee89, > 2daf73a4>[count 1, qsz 0, owner <AWT-EventQueue-0>] > AWT-EventQueue-0: GLContext.ContextSwitch: - setCurrent() - NULL > AWT-EventQueue-0: GLContext.ContextSwitch[release.X]: obj 0x400746fe, ctx > 0x7fa2140b3400, surf 0x5000012 - switch - <1dc5ee89, 2daf73a4>[count 0, qsz 0, > owner <NULL>] > > from what i understood from the patch it should go into the state > final GLContext current = getCurrent(); > if (current != null) { > if (current == this) {...} > > but getCurrent() is always null. > > please respond if you need more details! > > regards david (In reply to comment #3) > this happens using GLCanvas on Ubuntu 12.10 Do you reproduce this bug with an existing test case? If not, please provide one. This fix works under GNU Linux. Keep in mind that makeCurrent() may fail, look at the return code. I'm not sure your problem has something to do with this fix. (In reply to comment #2) > Hi i wanted to try out your new fix, (was debugging my slow app with visualvm > and noticing that makeCurrent(), release and makeCurrentWithinLock was called > every frame in invokeGLImpl) > Of course, thats the default behavior. > > from what i understood from the patch it should go into the state > final GLContext current = getCurrent(); > if (current != null) { > if (current == this) {...} > > but getCurrent() is always null. Outside of GLEventListener calls it is intended to be null, otherwise the surface (window, ..) lock would be hold as well. The fix does fix the use cases as described in the new unit tests added w/ 34687193484b2404d83eebf5d008b71d54e52286 - please read! You were probably thinking of an additional feature like the Exclusive Context Thread (ECT) as implemented here: <http://jogamp.org/git/?p=jogl.git;a=commit;h=224fab1b2c71464826594740022fdcbe278867dc> (In reply to comment #4) > (In reply to comment #3) > > this happens using GLCanvas on Ubuntu 12.10 > > Do you reproduce this bug with an existing test case? If not, please provide > one. This fix works under GNU Linux. Keep in mind that makeCurrent() may fail, > look at the return code. I'm not sure your problem has something to do with > this fix. I think it's only a misunderstanding. However .. David, if you think of something else, please provide a full unit test - thx. |