| Summary: | GLJPanel's OffscreenDrawable shall not double swap (custom swap by GLEventListener using [AWT]GLReadBufferUtil) | ||
|---|---|---|---|
| Product: | [JogAmp] Jogl | Reporter: | Sven Gothel <sgothel> |
| Component: | awt | Assignee: | Sven Gothel <sgothel> |
| Status: | RESOLVED FIXED | ||
| Severity: | enhancement | ||
| Priority: | --- | ||
| Version: | 2 | ||
| Hardware: | All | ||
| OS: | all | ||
| Type: | --- | SCM Refs: |
908ebd99d1eb57ce773a1fdd67c76886da86b9e6
82f679b064784213591b460fc5eaa1f5f196fbd1
d46d9ad8f998a7128d9f023294d5f489673d6d8a
41190c3830157abdf9649cbf7767e57108f55075
b96fc594f15fcf9ee0fd238ce8d7a10aea781d32
|
| Workaround: | --- | ||
908ebd99d1eb57ce773a1fdd67c76886da86b9e6 fixed as described 82f679b064784213591b460fc5eaa1f5f196fbd1
GLJPanel: Use default auto-swap mechanims
Refines commit 908ebd99d1eb57ce773a1fdd67c76886da86b9e6
Note that the test case decide whether to auto-swap (after read-pixels)
or not auto-swap (manual swap before read-pixels).
See UITestCase.swapBuffersBeforeRead(GLCapabilitiesImmutable chosenCaps):
Determines whether the chosen GLCapabilitiesImmutable requires a swap-buffers before reading pixels.
Usually one uses the default-read-buffer, i.e. GL.GL_FRONT for single-buffer
and GL.GL_BACK for double-buffer GLDrawables
and GL.GL_COLOR_ATTACHMENT0 for offscreen framebuffer objects.
Here swap-buffers shall happen after calling reading pixels, the default.
However, multisampling offscreen GLFBODrawables utilize swap-buffers to downsample
the multisamples into the readable sampling sink.
In this case, we require a swap-buffers before reading pixels.
Returns: chosenCaps.isFBO() && chosenCaps.getSampleBuffers()
+++
+++
- GLJPanel:
- Remove SurfaceUpdatedListener mechanism in favor of
default auto-swap-buffer via GLDrawableHelper.
This removes complexity.
- postGL does not need to perform explicit swapBuffer operation,
but rely on GLDrawableHelper and the default mechanism.
This is also compatible w/ J2D backend.
- Use GLDrawableHelper for setAutoSwapBufferMode(..) and getAutoSwapBufferMode()
+++
UnitTests:
- UITestCase:
- Add 'boolean swapBuffersBeforeRead(GLCapabilitiesImmutable chosenCaps)'
to determine whether swapBuffers() must occure before read-pixels. See above.
- GLReadBuffer00Base*
- remove explicit addSnapshotGLEL/removeSnapshotGLEL
- add TextRendererGLEL, to display frame-count and -dimension
- SnapshotGLEL*
- simply toggle auto-swap in their init(..) and dispose(..) method!
- clear back-buffer if 'swapBuffersBeforeRead'
to test whether the right buffer is being used for read-pixels.
d46d9ad8f998a7128d9f023294d5f489673d6d8a
Bug 975 - GLJPanel's OffscreenDrawable shall not double swap - Refine unit test for visual validation of 'no frame lag'
To validate whether a 'display' command w/o animator results to the desired frame
we introduce a 'userCounter' in TextRendererGLEL.
The latter gets increased and maybe visually validated by a key-press -> display.
Results: In all modes, MSAA or !MSAA, or flip - the result is valid.
Tested on windows and linux.
41190c3830157abdf9649cbf7767e57108f55075
Fix auto-swap mechanism ; Refined API doc getDefaultReadBuffer() ;
Add GLDrawableUtil.swapBuffersBeforeRead
Commit 82f679b064784213591b460fc5eaa1f5f196fbd1 which introduces the default swap-buffers
mechanism is erroneous:
The OffscreenBack backend requires the following operation order:
Order-1:
[1] - GL display
[2] - GL swapBuffers (always due to single-buffer non-MSAA or MSAA offscreen drawable)
[3] - readPixels
+++
Commit 82f679b064784213591b460fc5eaa1f5f196fbd1 however introduced:
Order-2:
[a] - GL display
[b] - readPixels
[c] - GL swapBuffers (always due to single-buffer non-MSAA or MSAA offscreen drawable)
since [a] and [b] happened in Updater's display method, and [c] followed the same
triggered by GLAutoDrawableHelper.
+++
The proof, commit d46d9ad8f998a7128d9f023294d5f489673d6d8a, is faulty,
since it always included the 'snapshot' GL event listener
which turned-off auto-swap and swapped before read-pixels.
TL;DR it enforced proper Order-1.
+++
This fix allows the Backend to intercept disable GLDrawableHelper's setAutoSwapBufferMode(..)
and perform the auto-swap mode itself in the proper Order-1.
The unit test has been refined to optionally disable the snapshot
to validate auto-swap mode.
+++
Refined GLBase and GLContext's API doc for 'getDefaultReadBuffer()'
+++
Add GLDrawableUtil.swapBuffersBeforeRead(..)
and reuse it for TileRendererBase (original impl.).
b96fc594f15fcf9ee0fd238ce8d7a10aea781d32 GLContextImpl/GLDrawableImpl.getDefaultReadBuffer(..): Pass hint whether dedicated read-drawable is being used (double buffering) Test cases: com.jogamp.opengl.test.junit.jogl.acore.TestGLReadBuffer01GLJPanelAWT com.jogamp.opengl.test.junit.jogl.acore.TestGLReadBuffer01GLCanvasAWT com.jogamp.opengl.test.junit.jogl.acore.TestGLReadBuffer01GLWindowNEWT |
When utilizing [AWT]GLReadBufferUtil it is usually desired to read from the front-buffer instead the back-buffer. The latter may not be defined, e.g. when using MSAA. A GLEventListener utilizing [AWT]GLReadBufferUtil, must perform the drawable.swapBuffers() to be able to read from the front-buffer. Usually GLAutoDrawable.setAutoSwapBuffer(false) should be called here, to avoid a double swap - however GLJPanel does not support toggling auto-swap since it requires to control swap for it's own read-pixels. Remedy for GLJPanel: - GLJPanel issues helper.setAutoSwapBufferMode(false) - immutable - Enable GLJPanel.swapBuffer() if initializes This was previously disabled. - GLJPanel's OffscreenBackend listens to surfaceUpdated, to be notified whether postGL needs to swap buffer or the drawable.swapBuffer() was already called between preGL and postGL. See unit tests adding/removing a snapshot GLEventListener performing swapBuffers() and setting auto-swap accordingly.