AWT GLCanvas: More strict GLDrawable realization [on AWT-EDT], skip if creation is not possible on AWT-EDT.
The Intel HD3000 OpenGL driver on Windows will deadlock @ SwapBuffers in case the drawable is created on a thread other than the window owner thread.
We are aware of such possibilities, nevertheless the AWTEDTExecutor.singleton.invoke(..) allowed to execute the runnable in case it cannot be invoked on AWT-EDT. The latter is the case if the current thread is not the AWT-EDT _and_ is holding the AWT tree-lock.
With GlueGen commit 0b43b43f889ad7fc220942b0076e2001ca3cf13f, the invoke method now consumes an argument allowing to restrict the execution to AWT-EDT only.
In such case, the drawable will be realized at a later time from the AWT-EDT.
Such a situation could be triggered if a Frame's setVisible(true) is not issued from the AWT-EDT, as it should be! However, to relax such use cases - we better recognize such possible dealock and avoid it.
- Add GLRendererQuirks.GLNonCompliant, marking a GL context/profile non compliant. Currently: 'Mesa DRI Intel(R) Sandybridge Desktop' && 3.1 compat profile
- Fix Bug 658 (Mesa 9.0 3.1 Intel compat quirk, 3.1 core only) Detect case using new GLRendererQuirks.GLNonCompliant in setGLFunctionAvailability() and return 'false'.
- No PROFILE_ALIASING compat -> core Use true core GL profiles / context if available to ensure proper API behavior across platforms due to different functionality. E.g. don't use GL3bc if GL3 is requested.
- Fix setGLFunctionAvailability(..) failure path @ profile query Destroy temp context & zero result to cont. iterating through GL versions. This missing cleanup lead to returning the faulty GL context handle and it's mapping/usage.
Enhance PMVMatrix: Use FloatStack to implement PushMatrix and PopMatrix (Bug 657)
One FloatStack for each, MV, P and T, with initialialSize zero to save memore and growSizes: MV = 16 arrays, P = 2 arrays, T = 2 arrays, with array = 16 floats.
This shall save performance due to the preallocated stack when used and growing only in the above mentioned grow intervals.
ExclusiveContextThread (ECT) allows user to dedicate a GLContext to a given thread. Only the ECT will be allowed to claim the GLContext, hence releasing must be done on the ECT itself.
The core feature is accessible via GLAutoDrawable, while it can be conveniently enabled and disabled via an AnimatorBase implementation. The latter ensures it's being released on the ECT and waits for the result.
Note that ECT cannot be guaranteed to work correctly w/ native (heavyweight) AWT components due to resource locking and AWT-EDT access. This is disabled in all new tests per default and noted on the API doc.
- AnimatorBase: Add setModeBits/MODE_EXPECT_AWT_RENDERING_THREAD Allows user to pre-determine whether AWT rendering is expected before starting the animator. If AWT is excluded, a more simple and transaction correct impl. will be used.
- FPSAnimator: Make transactions deterministic. FPSAnimator previously did not ensure whether a transaction was completed. A deterministic transaction is required to utilize ECT. FPSAnimator now uses same mechanism like Animator to ensure completeness, i.e. Condition and 'finishLifecycleAction(..)'. Both are moved to AnimatorBase.
Tested manually on Linux/NV, Linux/AMD, Windows/NV and OSX/NV. - All new tests validated correctness. - All new tests shows an performance increase of ~3x w/ single GLWindow, where multiple GLWindows don't show a perf. increase.
Adding GEOMETRY_SHADER support in ShaderCode, adding core GL3/GEOMETRY_SHADER unit tests. ; Simplified GLContext version number
- Adding GEOMETRY_SHADER support in ShaderCode, adding core GL3/GEOMETRY_SHADER unit tests
Chuck Ritola reported in December 2012 that we lack support of GEOMETRY_SHADER and he provided a test case.
The latter is cleaned up to use GL3 core profile features only tesing a pass-through and the flip-XYZ geometry shader.
ShaderUtil is fixed.
- Simplified GLContext version number The OpenGL major/minor version is now hold in a VersionNumber instance to simplify usage. Also expose it via getGLVersionNumber() while marking getGLVersionMajor() and getGLVersionMinor() deprecated.
- API update 'float getWheelRotation()': Usually a wheel rotation of > 0.0f is up, and < 0.0f is down.
Usually a wheel rotations is considered a vertical scroll. If isShiftDown(), a wheel rotations is considered a horizontal scroll, where shift-up = left = > 0.0f, and shift-down = right = < 0.0f.
However, on some OS this might be flipped due to the OS default behavior. The latter is true for OS X 10.7 (Lion) for example.
The events will be send usually in steps of one, ie. -1.0f and 1.0f. Higher values may result due to fast scrolling. Fractional values may result due to slow scrolling with high resolution devices.
- X11/Horiz: Keep using button1 and set SHIFT modifier
- OSX/Horiz: - PAD: Use highes absolute scrolling value (Axis1/Axis2) and set SHIFT modifier for horizontal scrolling (Axis2) - XXX: Use deltaX for horizontal scrolling, detected by SHIFT modifier. (traditional)
- Windows/Horiz: - Add WM_MOUSEHWHEEL support (-> set SHIFT modifier), but it's rarely impl. for trackpads! - Add exp. WM_HSCROLL, but it will only be delivered if windows has WS_HSCROLL, hence dead code!
- Android: - Add ACTION_SCROLL (API Level 12), only used if layout is a scroll layout
- Using GestureDetector to detect scroll even w/ pointerCount > 2, while: - skipping 1st scroll event (value too high) - skipping other events while in-scroll mode - waiting until all pointers were released before cont. normally - using View config's 1/touchSlope as scale factor
- Fix Bug 639: High-Res Mouse-Wheel - getWheelRotation() return value changed: int -> float allowing fractions, see API doc changes above.
- Fractions are currently supported natively (API) on - Windows - OSX - Android
- AndroidNewtEventFactory ir refactored (requires an instance now) and AndroidNewtEventTranslator (event listener) is pulled our of Android WindowDriver.
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(..).
NEWT/Android: Full Lifecycle for WindowDriver; Using static ViewGroup; AWTRobotUtil: More tolerant for non AWT env.; Fix adb-launch-*
- NEWT/Android WindowDriver - Full Lifecycle, remove refs on closeNative() - Respect isFullscreen() - Using static ViewGroup if available and surface not ready, allows running from main()
- AWTRobotUtil: More tolerant for non AWT env. - Check for NEWT first - Only use AWT iff available, which allows running on Android
Android: Allow selection of native window formats RGBA8888, RGBX8888 and RGB565; Fix HiSilicon/Vivante/Immersion.16 EGLConfig selection (zero depth buffer @ visualID)
- NEWT/Android Fix PixelFormat/NativeWindowFormat/VisualID Selection - Fix allows proper selection of native window formats: RGBA8888, RGBX8888 and RGB565
- Selection is performed in 3 steps: 1) @ Construction (non native): SurfaceHolder.setFormat( getSurfaceHolderFormat( caps ) ) 2) @ Native Surface Creation: getANativeWindowFormat( androidFormat) -> ANativeWindow_setBuffersGeometry(..) Note: The set native format is revalidated, i.e. read out via ANativeWindow_getFormat(..). 3) @ EGL Creation: ANativeWindow_getFormat(..) -> fixCaps(..) - simply fixing the chosen caps.
- NEWT GLWindow.GLLifecycleHook.resetCounter: - Also reset GLAnimatorControl's counter, if attached.
- ProxySurface: Add 'NativeSurface getUpstreamSurface()' allowing querying direct access of a backing surface representing this instance. - Use case: EGLWrappedSurface - Default impl. returns null
- ProxySurfaceImpl: Don't cache 'displayHandle' - getDisplayHandle() is 'final', no more 'shortcut' code allowed due to re-association incl. display handle.
- See commit b738983638703bb721ee4c9820c8ef43e2252e73
Refine GL[Auto]Drawable 'realized' state in API doc, and relax it's realized requirement in GL[Offscreen]AutoDrawableDelegate*
Compatible w/ 'before'.
TODO: Contemplate about GLDrawableFactory.createOffscreenAutoDrawable(..) whether it: - should better return an unrealized [auto]drawable - or adding another API method for such case
Goal: Allow passing vector of [device/context/..] for use cases such as re-using an onscreen destructed surface and on-/offscreen hopping.
Bug 665 (part 3) - Allow dis-association of GLContext's GLDrawable .. - Add EGL/ES2 tests, attempt to fix wrapped EGL case
- Bug 665 (part 2) was commit 7fd5f76e1eb4bbf93fe9b1171744bd755d8f96e4
- Add EGL/ES2 tests in - TestGLContextDrawableSwitch01NEWT - TestGLContextDrawableSwitch11NEWT
- Attempt to fix wrapped EGL case (incomplete) - Using EGL/ES w/ non native EGL device/surface, but natively wrapped instances (most of the cases), a 'complicated' delegation of Native-Upstream -> EGL-Proxy -> EGL-Instance is being used heavily relying on the objects lifecycle. GLEventListenerState tries to roll back the realized state and even sets the upstream device handle, but this doesn't seem to be sufficient on X11.
Discussion:
It might turn out that we only can implement the survival of GLContext and it's display device reliable w/ EGL within the GLAutoDrawable implementation, which can hold the previous not destructed instances.
Fix Bug 678: Deliver key-char value for printable chars on all KeyEventListener (-> On Windows as well)
The following is observed, where t0 and t1 refer to subsequent different timestamps: NEWT delivery order: PRESSED (t0), RELEASED (t1) and TYPED (t1)
WINDOWS delivery order: PRESSED (t0), TYPED (t0) and RELEASED (t1) Windows Auto-Repeat: PRESSED (t0), TYPED (t0)
Hence we changed the event reorder-code in NEWT to trigger NEWT-PRESSED on Windows-TYPED for printable chars, assuring key-char values on all listener callbacks.
- KeyEvent.getKeyChar(): Removed disclaimer dedicated for Windows - Keyevent.isActionKey(): Completed for all NEWT non-printable action keys; Added static variant - Keyevent.isPrintableKey(): NEW: returns !isModifierKey(keyCode) && !isActionKey(keyCode) ; With static variant
- Windows WindowDriver: - EVENT_KEY_PRESSED handles non-printable chars only - EVENT_KEY_TYPE handles printable chars only - Native: VK_DELETE passes keyCode
Fix AWTKeyAdapter: Reorder AWT events to NEWT order - also ensuring TYPED is always sent.
This foremost fixes an issue w/ OSX/Java7 and NewtCanvasAWT offscreen CALayer usage, which utilizes AWTKeyAdapter and AWTNewtEventFactory (AWT -> NEWT) key events.
Fix OSX CALayer Bug 690 and Bug 691: Occasional Freeze on CVDisplayLinkStop; Layers and native GL-Context are _not_ Released ; Java Side wait for Main-Thread
- Fix Bug 690: Occasional Freeze on CVDisplayLinkStop - NSOpenGLLayer.disableAnimation() shall not claim the renderLock mutex, since the CVDisplayLink callback could be waiting for the lock. This waiting callback could freeze the call to CVDisplayLinkStop.
- Fix Bug 691: Layers and native GL-Context are _not_ Released - Following proper release cycle:
- Java Side wait for Main-Thread - Waiting for the delegated Main-Thread on the Java side eases debugging and won't block the Main-Thread in native code.
Fix Bug 691 (part-2): Extra '[subLayer release]' is wrong, since 'CGL.releaseNSOpenGLLayer' triggers release - but very late w/ AWT usage.
OSXUtil_RemoveCASublayer0's added '[subLayer release]' in commit f6e6fab2a7ddfb5c9b614cb072c27ff697629161 is wrong, since 'CGL.releaseNSOpenGLLayer' actually does trigger it's release. This was not seen w/ AWT tests, since it happens very later. A NewtCanvasAWT test disclosed this error -> removed that extra release call.
The culprit for the late release w/ AWT usage was CGL.createNSOpenGLLayer's call in the current thread. Moving it to the Main-Thread fixed the problem.
All CALayer lifecycle calls are issued on the Main-Thread now.
NSOpenGLLayer's CVDisplayLink OpenGL fitting via 'CVDisplayLinkSetCurrentCGDisplayFromOpenGLContext' is now performed at it's context creation in 'NSOpenGLLayer::openGLContextForPixelFormat'.
The 'extra' release of the NSOpenGLLayer's NSOpenGLContext as introduced in commit f6e6fab2a7ddfb5c9b614cb072c27ff697629161 is still valid.
- Fix Bug 675: NPE w/ Beans.setDesignTime(true) - Carefully consider Beans.isDesginTime() fixes NPE - added unit test
- Fix GLCanvas.destroy(): Don't issue removeNotify(), delete drawable and context only! - AWT removeNotify() shall only be issued via AWT itself, not manually - Add 'destroyImpl(boolean destroyJAWTWindowAndAWTDevice)' to be called by - GLCanvas.destroy(): destroyImpl( false ); - GLCanvas.removeNotify(): destroyImpl( true ); - Ensures JAWTWindow and AWTDevice are created and destroyed via the AWT callbacks addNotify() and removeNotify() only.
Fix Bug 691 (part-3): NSOpenGLLayer::openGLContextForPixelFormat(..) on main-thread deadlock'ed due to locked shared context
NSOpenGLLayer::openGLContextForPixelFormat(..) is performed on main-thread at 1st NSOpenGLLayer display method. This happened irregulary, i.e. sometimes (T0) right after NSOpenGLLayer creation and attachSurfaceLayer()/AddCASublayer(..), sometimes later (T1).
NSOpenGLLayer::openGLContextForPixelFormat(..) uses the passed shared user context. The shared user context is locked at NSOpenGLLayer's creation (T0) and if performed at this early time the call deadlocks due to pthread_mutex wait for the shared user context.
This fix performs NSOpenGLLayer creation and layer attachment while the shared user context is kept unlocked and enforces NSOpenGLLayer display and hence NSOpenGLLayer::openGLContextForPixelFormat(..).
Added CGL.setNSOpenGLLayerEnabled(..) to enable/disable NSOpenGLLayer - currently not used.
- Passed AddRemove tests for GLCanvas/Swing and GLWindow/NewtCanvasAWT w/ 100 loops on Java6 and Java7 on OSX. - Passed Instruments Leaks test w/ 10 loops on Java6 and Java7
Fix TestWindowClosingProtocol01AWT: GLCanvas closing operation 'destroy' will no more call removeNotify() - see commit 3567e7e8519f82720f98b0b2ac30456cbfeddc0d
Bug 678 (fix), Bug 641 (API + Windows Impl.), Bug 688 (prep): Update NEWT's KeyEvent handling while distinguish keyCode (kbd layout independent) and keySym (kbd layout dependent)
API Changes:
- Virtual key codes and symbols are of type short.
- KeyEvent.keySymbol() shall return a layout dependent value (Bug 641) - Method returns former keyCode() value, which was layout dependent. - Returns 'short' value
- KeyEvent.keyCode() returns a short value, instead of int
- KeyEvent.keyCode() shall return a layout independent value (Bug 641) - To ease implementation, we only 'require' the scan code to be mapped to a 'US Keyboard layout', which allows reusing layout dependent code while preserving the goal to have a fixed physical key association
- Implementation status: - Windows OK - X11 TODO - OSX: 50/50 TODO - Using layout independent 'action keys' - Using layout dependent 'printable keys' - returning above semantics for both, keyCode and keySym
- Android 50/50 TODO - Returning the layout independent keyCode - Mapping probably incomplete
- KeyEvent.EVENT_KEY_TYPED and KeyListener.keyTyped(KeyEvent) (Bug 688) - Marked DEPRECATED - No more called for auto-repeat events - Synthesized in WindowImpl.consumeKeyEvent(..): No more injection by native- or java driver code
- NEWTEvent.eventType: int -> short - field, as well as all method involving eventType changed to short.
- NEWTEvent.isSystemEvent: REMOVED - Never used as well as never being implemented properly
Internal Changes:
- Simplified keyEvent driver code - Especially the Windows native driver's mapping code could be simplified using scanCode and MapVirtualKeyEx
- NEWT Event Factories: hashMap -> switch/case
Unit Tests: - - Added NewtCanvasAWT Offscreen Layer Tests important to test the AWT -> NEWT translation on OSX/CALayer: - TestNewtKeyCodeModifiersAWT - TestNewtKeyCodesAWT - TestNewtKeyEventAutoRepeatAWT - TestNewtKeyEventOrderAWT - TestNewtKeyPressReleaseUnmaskRepeatAWT
GLProfile: Adding convenient query for highest programmable core only GL profile
As suggested @ http://forum.jogamp.org/How-to-force-core-profile-tp4028307.html
However, one could always get a dedicated core profile via: - GLProfile.get(GLProfile.GLES2) - GLProfile.get(GLProfile.GL3) - GLProfile.get(GLProfile.GL4)
- Fix CALayer animation: - All CALayer animations are set to nil via overriding 'actionForKey'
- Fix CALayer pos/size bug:
- Fix root and sub CALayer position to 0/0 and size on the main-thread w/o blocking.
- If the sub CALayer implements the Objective-C NativeWindow protocol NWDedicatedSize (e.g. JOGL's MyNSOpenGLLayer), the dedicated size is passed to the layer, which propagates it appropriately.
- On OSX/Java7 our root CALayer's frame position and size gets corrupted by its NSView, hence we have created the NWDedicatedSize protocol.
NEWT/OSX Fix: Child positioning ; NewtCanvasAWT: Change reparent time and use actual component size while setting min/pref. size at setup
- NEWT/OSX Fix: Child positioning - If !Offscreen and has-parent: Gather screen location by traversing through parent and set native position (was removed w/ commit 7d5c51b635e0795d9b170342bdebe8e7e0bbd01d since still buggy).
- NewtCanvasAWT: Change reparent time and use actual component size while setting min/pref. size at setup - Analog to AWT GLCanvas - validates and reparents at reshape(..), paint(..) and update(..) - reshape(..) also trigers jawtWindow.layoutSurfaceLayer() -
Fix NEWT/AWT WindowClosing Unit Tests ; Review/Cleanup NEWT WindowClosing mechanism
Due to a NEWT WindowClosing event regression cause by NewtCanvasAWT changes a review of our WindowClosing event mechanism was required.
Important cleanups are marked w/ '(*)' below.
I would have preferred to change the 'WindowListener.windowDestroyNotify(WindowEvent)' method to pass a WindowCloseEvent object exposing more information like toolkit or programmatic destruction and passing whether a 'closing' or 'nop' action will be performed based on the WindowClosingMode. For now I postponed this idea .. since it would change the API again, but may reconsider it after merging the Android 'closing' patch.
- InputEvent.consumedTag -> NEWTEvent.consumedTag
- Window - (*) Promote setWindowDestroyNotifyAction(Runnable) to public, former WindowImpl.setHandleDestroyNotify(boolean). Using a Runnable action for WindowImpl.windowDestroyNotify(boolean) allows a setting defined alternative for destroy() and gets rid of [ab]using WindowListener.windowDestroyNotify(WindowEvent) for lifecycle actions. Used in: - GLWindow - GLAutoDrawableDelegate impl.
- WindowImpl - Respect NEWTEvent.consumedTag for WindowEvents as well
- (*) Impl. setHandleDestroyNotify(boolean) (see above)
- (*) destroy() simply sends out pre- and post- destruction Window events, where windowDestroyNotify(boolean) sends out the pre-destruction event if NOP.
- (*) windowDestroyNotify(boolean) is public now, allowing other impl. details to follow proper destruction using handleDestroyNotify Runnable (-> NewtCanvasAWT).
- AWTWindowClosingProtocol: - addClosingListenerOneShot() -> addClosingListener() - calling addClosingListener() at addNotify() - calling removeClosingListener() at removeNotify()
- AWTWindowClosingProtocol ctor taking NOP runnable, allowing to send WindowEvent.EVENT_WINDOW_DESTROY_NOTIFY at WindowClosingMode.DO_NOTHING_ON_CLOSE
- Also fwd windowClosed in window closing fwd'ing.
- NewtCanvasAWT - (*) Utilize AWTWindowClosingProtocol NOP runnable (see above) to fwd closing-NOP event to NEWT
- (*) Unify remove/destroy code in destroyImpl(..) - !removeNotify -> destroy NEWT child programatic or as toolkit event - removeNotify || windowClosing -> destroy jawtWindow
- (*) Remove AWTWindowAdapter/AWTParentWindowAdapter's windowClosingListener, since we utilize AWTWindowClosingProtocol
- DisplayImpl - Adding 'final void dispatchMessage(final NEWTEvent event)' allowing to remove the NEWTEventTask wrapping for no reason in enqueueEvent(..) if on EDT and waiting.
Fix Bug 677: NEWT/Android: Add support for Android's KeyEvent.KEYCODE_BACK
Original author: Eric Brayet <ericb@daysofwonder.com> Revised by: Sven Gothel <sgothel@jausoft.com>
I took the freedom to cleanup the three original patches from https://github.com/Pooouf/jogl.git branch 'bug_677': - 7449d4726633d524a3bb79efffd04cfd0ca25e58 (removed by followup patch!) - 68c739a4f03e46deecdbb71c125b4586aec08d63 (removes previous patch!) - c2813dfc325a1482d18b6fc304e4e483f5633964
Further more I was able to reduce the 'extra' code while utilizing - Window's isKeyboardVisible() and using keyboardVisibilityChanged(false) to update the hidden keyboard state. - Moving the key-handling code to the containing WindowDriver class avoiding passing a reference to the inner view. - Using AndroidNewtEventFactory for NEWT KeyEvent creation
+++
- Handle KeyEvent.KEYCODE_BACK w/ jogamp.newt.driver.android.WindowDriver.MSurfaceView.onKeyPreIme(..): if( soft keyboard is up ) [1] Update keyboard visibility state and return NEWT KeyEvent.VK_KEYBOARD_INVISIBLE; else [2] call WindowImpl.windowDestroyNotify(true)
[3] then cont. processing, i.e. return false;
- Turns out respecting WindowClosingMode might be - too complicated - interfere w/ Android UI behavior
- AndroidNewtEventFactory - createKeyEvent - static - adding boolean param 'inclSysKeys', if true, KEYCODE_BACK and KEYCODE_HOME are mapped
- Unit tests: GearsES2 + MovieCubeActivity0 shows keyboard if pressure > 0.6f - pressure on Android shall be between [0..1], however we have to figure out badly calibrated touchpads/Android device where we could experience pressure > 2.0f !
Due to high fluctuation (lack of normalized) pressure values on Android devices, an option to query the normalized value and access to the current known maximum pressure is required.
MouseEvent: - getMaxPressure() returning the [self calibrated] known maximum pressure
Fix Bug 695: WGLExt.wglChoosePixelFormatARB causes buffer underflow due to a higher reported number of configs than buffer size
"I encountered a case on an NVidia Quadro 3500 fx where the call to WGLExt.wglChoosePixelFormatARB in WindowsWGLGraphicsConfiguration (currently line 355) returns 264 in numFormatsTmp despite 256 being passed in for the maximum number of formats. This results in a buffer underflow on line 368 since pformatsTmp only has 256 values and it's trying to copy 264 values."
Fixed in WindowsWGLGraphicsConfiguration and WindowsPbufferWGLDrawable.
- Add DEBUG_VIEWPORT flag Via explicit property 'jogl.debug.GLJPanel.Viewport' (not via jogl.debug=all) Traces the current GL Viewport in OffscreenBackend.postGL(..)
- Add USE_GLSL_TEXTURE_RASTERIZER flag Via explicit property 'jogl.gljpanel.noglsl'. Disables use of GLSL FBO flipping.