GLAutoDrawable (API CHANGE) allowing atomic operations: - Add class API-doc chapter about 'GLAutoDrawable Locking'
- Add method invoke(..) API-doc description about throwing IllegalStateException in case of a detected deadlock situation ahead (Note: Implemented in GLDrawableHelper.invoke(..) for all implementations)
- Add new methods for proper multithread handling: - public RecursiveLock getUpstreamLock(); - public boolean isThreadGLCapable();
+++
GLEventListenerState/GLDrawableUtil:
- Perform operation in a atomic fashion, i.e. lock GLAutoDrawable during whole operations: - GLDrawableUtil.swapGLContext(..) - GLDrawableUtil.swapGLContextAndAllGLEventListener(..) - GLEventListenerState.moveFrom(..) - GLEventListenerState.moveTo(..)
- ReshapeGLEventListener: - Moved from GLEventListenerState.ReshapeGLEventListener -> GLDrawableUtil.ReshapeGLEventListener - Takes 'displayAfterReshape' case into account.
+++
javax.media.opengl.Threading Clarifications: - Public 'enum Mode', i.e. Threading.Mode
- Public getMode()
- Clarified 'isOpenGLThread()': - Take 'singleThreaded' into account directly, i.e. always return 'true' if singleThreaded == false
Fixed and Changed NVidia Windows Driver Threaded optimization bug workaround of commit 5166d6a6b617ccb15c40fcb8d4eac2800527aa7b
Commit 5166d6a6b617ccb15c40fcb8d4eac2800527aa7b added a workaround for the NVidia driver 260.99 for Window from 2010-12-11 issue.
[1] The workaround sets a process affinity while JOGL initialization to mitigate NVidia driver's 'Threaded optimization := On' race conditions. The process affinity is reset reset after initialization.
[2] The process affinity reset code had a bug, i.e. instead to restore the original process's affinity mask, we restored the system's default affinity mask.
[3] Further more, there seem to be issues with changing a process affinity mask regarding the process group.
This patch: - Solves issue [2] by using the original process affinity mask
- Solves issue [3] by allowing a custom affinity mode via the property 'jogl.debug.windows.cpu_affinity_mode':
- 0 - none (default, no affinity required for Windows NV driver >= 266.58 from 2011-01-24) - 1 - process affinity (was required w/ Windows NV driver 260.99 from 2010-12-11, see commit 5166d6a6b617ccb15c40fcb8d4eac2800527aa7b) - 2 - thread affinity (experimental)
Hence the workaround is disabled by default, since the crash as dicumented in commit 5166d6a6b617ccb15c40fcb8d4eac2800527aa7b could not be reproduced with NV driver 266.58 from 2011-01-24.
Bug 1029 - Memory leak in GLDrawableHelper: 'perThreadInitAction' shall use a WeakReference
Static ThreadLocal 'perThreadInitAction' leaks memory if using a hard reference, utilizing a WeakReference allows the passed 'initAction' owner to be garbage collected.
Bug 1037 - FBObject/GLFBODrawable: Do not assume using a TextureAttachment for a Colorbuffer, also make DEPTH optional.
API Change
+++
In certain cases a TextureAttachment for the FBO's color buffer is not desired, either for performance reasons where texture functionality is not required or to avoid texture restrictions like size, etc.
+++
GLFBODrawable shall use TextureAttachment for the FBO's color buffer and a DEPTH buffer per default. However, the user shall be allowed to use a plain ColorAttachment (renderbuffer) and also no DEPTH buffer.
+++
FBObject Details: - Colorbuffer interface exposes Attachment details like format, size, etc as well as it's implementation specifics, isTextureAttachment() and getTextureAttachment() allowing a clean cast and type query.
- Allow ColorAttachment to be used for non MSAA
- Make TextureAttachment optional for method 'use(GL, TextureAttachment)'
- Only validate size against MAX_TEXTURESIZE if using a TextureAttachment
Bug 1036: NVidia Windows Driver 'Threaded optimization' workaround. [3/3]
Commit 5166d6a6b617ccb15c40fcb8d4eac2800527aa7b added a workaround for NVidia's Windows Driver Threaded optimization bug existing in NVidia driver 260.99 for Window from 2010-12-11.
Commit 007f120cd8d33e4231ef4d207b85ed156d1e0c82 fixed the workaround and made it optional, default: turned off!
Rational of turning the workaround off was due to testing against the original test-case 'Applet and Webstart' with drivers >= 266.58 from 2011-01-24, which did not reproduce this issue.
However, our unit tests reproduced the issue, e.g. test: com.jogamp.opengl.test.junit.jogl.caps.TestTranslucencyNEWT
Hence we have to re-enable the workaround per default.
Added the following documentation of the issue:
+++
Since NV driver 260.99 from 2010-12-11 a 'Threaded optimization' feature has been introduced. The driver spawns off a dedicated thread to off-load certain OpenGL tasks from the calling thread to perform them async and off-thread.
If 'Threaded optimization' is manually enabled 'on', the driver may crash with JOGL's consistent multi-threaded usage - this is a driver bug.
If 'Threaded optimization' is manually disabled 'off', the driver always works correctly.
'Threaded optimization' default setting is 'auto' and the driver may crash without this workaround.
If setting the process affinity to '1' (1st CPU) while initialization and launching the SharedResourceRunner, the driver does not crash anymore in 'auto' mode. This might be either because the driver does not enable 'Threaded optimization' or because the driver's worker thread is bound to the same CPU.
Property integer value <code>jogl.debug.windows.cpu_affinity_mode</code>: 0 - none (no affinity, may cause driver crash with 'Threaded optimization' = ['auto', 'on']) 1 - process affinity (default, workaround for driver crash for 'Threaded optimization' = 'auto', still crashes if set to 'on')
BuildComposablePipeline: Handle synthetic isGL* and getGL* more generic, allow FixedFunctionHook to properly determine it's identity
BuildComposablePipeline: Handle synthetic isGL* and getGL* more generic, allow using a prologue hook as needed for FixedFunctionHook's 'isGL*core()', 'isGLES*Compatible()' and 'getGLProfile()' methods.
The latter FixedFunctionHook take the emulated GL profile GL2ES1 into account, allowing JOGL code to assume only having GL2ES1 available. Otherwise methods like Texture.enable(..) would skip the glEnable(TEXTURE_2D) call and FixedFunctionHook could not enable it's usage.
GLProfile received a 'public static GLProfile createCustomGLProfile(final String profile, final GLProfile profileImpl)' allowing utilities like FixedFunctionHook to create a generic profile.
BuildComposablePipeline sorts the methods before emitting for better readability.
GLContext: Don't map compatibility profiles to core profile if the latter are not available (restrict profile aliasing) ; GLProfile does this - Simplification.
GLContext shall not map compatibility profiles to core profile if the latter is are not available (restrict profile aliasing).
If a user requests a straight GL3 core profile, don't answer with a compatibility profile, e.g. GL4bc.
Hence this patch exposes the true GL profile situation more honestly the the user!
User can already query profile mappings via GLProfile, i.e. - GL2GL3, - GL4ES3, or via - getMaximum - getMaxFixedFunc - getMaxProgrammable - getMaxProgrammableCore
This also fixes an issue when a user requests 'getMaxProgrammableCore' but would receive a GL4bc profile.
Revert "GLContext: Don't map compatibility profiles to core profile if the latter are not available (restrict profile aliasing) ; GLProfile does this - Simplification."
This reverts commit c8b99d197769eaec53c2def562c0ef3fc0e6a9d2.
Bug 1038 - Fix: Allow skipping detection of certain GLProfiles: Skip 'ARB_create_context'
Commit e5a55ede324ce500f50991d56491758803063a58 was incomplete, i.e. it lacked the required mappings for the non ARB profile, i.e.: GL4bc -> GL3bc, etc.
These profile mappings have been added now.
+++
Further more, GLContext's profile queries, isGL*() test the ctxOptions for CTX_IS_ARB_CREATED. This has to be removed to properly work w/ Skip 'ARB_create_context'.
To remove the risk of inconcistency, i.e. context created via ARB and non-ARB, the 'GLX/WGL profile >= GL3 via non ARB' validation removed in commit e5a55ede324ce500f50991d56491758803063a58 has been brought back and refined. Note: if( glp.isGL3() && createContextARBTried ) { // We shall not allow context creation >= GL3 w/ non ARB methods if ARB is used, // otherwise context of similar profile but different creation method may not be share-able. .. THROW EXCEPTON .. } This limited validation removes the possibility of such having a context of same profile, one created via ARB and one without. Hence also validates the isGL*() change, where the CTX_IS_ARB_CREATED criteria is removed.
While analyzing the mapping, it turns out that commit c8b99d197769eaec53c2def562c0ef3fc0e6a9d2 "Don't map compatibility profiles to core profile if the latter are not available (restrict profile aliasing)" is not fully consistent with GLProfile's and GLContext's profile queries, i.e. isGL*(). We may reiterate over this change .. but have it be reverted for now.
Bug 830 - Add Heuristics for to query whether GLDrawableUtil.swapGLContextAndAllGLEventListener is safe (Doesn't work w/ pre MSAA onscreen drawable)
GLDrawableUtil.isSwapGLContextSafe(..) allows user to query whether 'we think' it's safe to utilize swapping of GLContext between GLAutoDrawable instances.
Currently known unsafe cases are: - between on- and offscreen and one of the following: - MSAA involved, or - STEREO involved
Enhanced unit tests in this regard: - TestGLContextDrawableSwitch02AWT - using GLContextDrawableSwitchBase0 - TestGLContextDrawableSwitch02NEWT - using GLContextDrawableSwitchBase0
Refine test ff5dba28610b4f680c9320e9e52669ed54d4de43: Perform context switch on GL capable thread if required. Add API doc note about this requirement.
- invoke(..) forwards a caught exception - if blocking, it forwards an exception happening within the passed GLRunnable(s). Here the exception is caught, printed and then thrown by invoke itself.
- if non-blocking, an exception happening within the passed GLRunnable(s) will be thrown in the thread issuing it's execution, i.e. display() call. Here the exception is not caught and simply thrown by the GLRunnable.
- disposeAllGLEventListener() being invoked by disposeGL(..), catches exception thrown by GLEventListener.dispose(..) and prints them to stderr. The first caught exception is re-thrown at the end as an GLException.
- disposeGL() catches re-thrown GLException by disposeAllGLEventListener() for GLEventListener.dispose(..) and re-throws it when operation is complete.
- disposeGL() catches an exception thrown at context destruction or release and re-throws it when operation is complete. An early exception at context.makeCurrent() is _not_ caught, since it is the first operation which simply shall unwind the stack.
- invokeGLImpl(..) for display() follows disposeGL() mechanism, i.e. it catches exception thrown at GLEventListener's init(..), reshape(..) and display(..) methods and re-throws it when operation is complete.
It also catches an exception thrown at context release and re-throws it when operation is complete. An early exception at context.makeCurrent() is _not_ caught, since it is the first operation which simply shall unwind the stack.
++++
None of the above thrown exception shall be caught and suppressed on the caller side.
If an operation must be completed while an exception is caught, it shall be cached and re-thrown after the operations.
In case multiple exception at multiple places are caught within an operation, they all shall be cached and the first one shall be re-thrown.
In case of multiple exception from the same place, i.e. a loop through all GLEventListener, the first shall be cached and re-thrown after operation is completed.
It has to be determined, whether we like to dump the exceptions, especially the ones who get suppressed in case of multiple exceptions.