com.jogamp.opengl.GLRendererQuirks Maven / Gradle / Ivy
Show all versions of jogl Show documentation
/**
* Copyright 2012 JogAmp Community. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those of the
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of JogAmp Community.
*/
package com.jogamp.opengl;
import java.util.IdentityHashMap;
import com.jogamp.nativewindow.AbstractGraphicsDevice;
import com.jogamp.opengl.GLCapabilitiesImmutable;
import com.jogamp.common.os.Platform;
import com.jogamp.opengl.egl.EGL;
import com.jogamp.opengl.egl.EGLExt;
/**
* GLRendererQuirks contains information of known bugs of various GL renderer.
* This information allows us to workaround them.
*
* Using centralized quirk identifier enables us to
* locate code dealing w/ it and hence eases it's maintenance.
*
*
* Some GL_VENDOR
and GL_RENDERER
strings are
* listed here .
*
*/
public class GLRendererQuirks {
/**
* Crashes XServer when using double buffered PBuffer with GL_RENDERER:
*
* - Mesa DRI Intel(R) Sandybridge Desktop
* - Mesa DRI Intel(R) Ivybridge Mobile - 3.0 Mesa 8.0.4
* - Gallium 0.4 on AMD CYPRESS
*
* For now, it is safe to disable it w/ hw-acceleration.
*/
public static final int NoDoubleBufferedPBuffer = 0;
/** On Windows no double buffered bitmaps are guaranteed to be available. */
public static final int NoDoubleBufferedBitmap = 1;
/** Crashes application when trying to set EGL swap interval on Android 4.0.3 / Pandaboard ES / PowerVR SGX 540 */
public static final int NoSetSwapInterval = 2;
/** No offscreen bitmap available, currently true for JOGL's OSX implementation. */
public static final int NoOffscreenBitmap = 3;
/** SIGSEGV on setSwapInterval() after changing the context's drawable w/ 'Mesa 8.0.4' dri2SetSwapInterval/DRI2 (soft & intel) */
public static final int NoSetSwapIntervalPostRetarget = 4;
/**
* GLSL discard
command leads to undefined behavior or won't get compiled if being used.
*
* Appears to have happened on Nvidia Tegra2, but seems to be fine now.
* FIXME: Constrain version.
*
*/
public static final int GLSLBuggyDiscard = 5;
/**
* Non compliant GL context due to a buggy implementation not suitable for use.
*
* Currently, Mesa >= 9.1.3 (may extend back as far as 9.0) OpenGL 3.1 compatibility
* context is not compliant. Most programs will give completely broken output (or no
* output at all. For now, this context is not trusted.
*
* The above has been confirmed for the following Mesa 9.* GL_RENDERER strings:
*
* - Mesa .* Intel(R) Sandybridge Desktop
* - Gallium 0.4 on AMD RS880
*
*
*
* It still has to be verified whether the AMD OpenGL 3.1 core driver is compliant enought.
*/
public static final int GLNonCompliant = 6;
/**
* The OpenGL context needs a glFlush()
before releasing it, otherwise driver may freeze:
*
* - OSX < 10.7.3 - NVidia Driver. Bug 533 and Bug 548 @ https://jogamp.org/bugzilla/.
*
*/
public static final int GLFlushBeforeRelease = 7;
/**
* Closing X11 displays may cause JVM crashes or X11 errors with some buggy drivers
* while being used in concert w/ OpenGL.
*
* Some drivers may require X11 displays to be closed in the same order as they were created,
* some may not allow them to be closed at all while resources are being used somehow.
*
*
* Drivers known exposing such bug:
*
* - Mesa < 8.0 _with_ X11 software renderer
Mesa X11
, not with GLX/DRI renderer.
* - ATI proprietary Catalyst X11 driver versions:
*
* - 8.78.6
* - 8.881
* - 8.911
* - 9.01.8
*
*
*
*
* See Bug 515 - https://jogamp.org/bugzilla/show_bug.cgi?id=515
* and {@link jogamp.nativewindow.x11.X11Util#ATI_HAS_XCLOSEDISPLAY_BUG}.
*
*
* See Bug 705 - https://jogamp.org/bugzilla/show_bug.cgi?id=705
*
*/
public static final int DontCloseX11Display = 8;
/**
* Need current GL context when calling new ARB pixel format query functions,
* otherwise driver crashes the VM.
*
* Drivers known exposing such bug:
*
* - ATI proprietary Catalyst driver on Windows version ≤ XP.
* TODO: Validate if bug actually relates to 'old' ATI Windows drivers for old GPU's like X300
* regardless of the Windows version.
*
*
* See Bug 480 - https://jogamp.org/bugzilla/show_bug.cgi?id=480
*
*/
public static final int NeedCurrCtx4ARBPixFmtQueries = 9;
/**
* Need current GL context when calling new ARB CreateContext function,
* otherwise driver crashes the VM.
*
* Drivers known exposing such bug:
*
* - ATI proprietary Catalyst Windows driver on laptops with a driver version as reported in GL_VERSION:
*
* - null
* - <
12.102.3.0
( amd_catalyst_13.5_mobility_beta2 )
*
*
*
*
* See Bug 706 - https://jogamp.org/bugzilla/show_bug.cgi?id=706
* See Bug 520 - https://jogamp.org/bugzilla/show_bug.cgi?id=520
*
*/
public static final int NeedCurrCtx4ARBCreateContext = 10;
/**
* No full FBO support, i.e. not compliant w/
*
* - GL_ARB_framebuffer_object
* - EXT_framebuffer_object
* - EXT_framebuffer_multisample
* - EXT_framebuffer_blit
* - EXT_packed_depth_stencil
*
.
* Drivers known exposing such bug:
*
* - Mesa 7.12-devel on Windows with VMware SVGA3D renderer:
*
* - GL_VERSION: 2.1 Mesa 7.12-devel (git-d6c318e)
* - GL_RENDERER: Gallium 0.4 on SVGA3D; build: RELEASE;
*
*
*
* Also enabled via {@link #BuggyColorRenderbuffer}.
*
*
* Quirk can also be enabled via property: jogl.fbo.force.min
.
*
*/
public static final int NoFullFBOSupport = 11;
/**
* GLSL is not compliant or even not stable (crash)
*
* - OSX < 10.7.0 (?) - NVidia Driver. Bug 818 @ https://jogamp.org/bugzilla/.
*
*/
public static final int GLSLNonCompliant = 12;
/**
* GL4 context needs to be requested via GL3 profile attribute
*
* - OSX >= 10.9.0 - kCGLOGLPVersion_GL4_Core may not produce hw-accel context. Bug 867 @ https://jogamp.org/bugzilla/.
*
*/
public static final int GL4NeedsGL3Request = 13;
/**
* Buggy shared OpenGL context support within a multithreaded use-case, not suitable for stable usage.
*
* X11 Mesa DRI Intel(R) driver >= 9.2.1 cannot handle multithreaded shared GLContext usage
* with non-blocking exclusive X11 display connections.
* References:
*
* - Bug 873: https://jogamp.org/bugzilla/show_bug.cgi?id=873
* - https://bugs.freedesktop.org/show_bug.cgi?id=41736#c8
*
*
* However, not all multithreaded use-cases are broken, e.g. our GLMediaPlayer does work.
*
* The above has been confirmed for the following Mesa 9.* strings:
*
* - GL_VENDOR Intel Open Source Technology Center
* - GL_RENDERER Mesa DRI Intel(R) Sandybridge Desktop
* - GL_RENDERER Mesa DRI Intel(R) Ivybridge Mobile
* - GL_VERSION 3.1 (Core Profile) Mesa 9.2.1
*
*
*
* On Android 4.*, Huawei's Ascend G615 w/ Immersion.16 could not make a shared context
* current, which uses a pbuffer drawable:
*
* - Android 4.*
* - GL_VENDOR Hisilicon Technologies
* - GL_RENDERER Immersion.16
* - GL_VERSION OpenGL ES 2.0
*
*
*
*
*/
public static final int GLSharedContextBuggy = 14;
/**
* Bug 925 - Accept an ES3 Context, if reported via GL-Version-String w/o {@link EGLExt#EGL_OPENGL_ES3_BIT_KHR}.
*
* The ES3 Context can be used via {@link EGL#EGL_OPENGL_ES2_BIT}.
*
*
* The ES3 Context {@link EGL#eglCreateContext(long, long, long, java.nio.IntBuffer) must be created} with version attributes:
*
* EGL.EGL_CONTEXT_CLIENT_VERSION, 2, ..
*
*
*
* - Mesa/AMD >= 9.2.1
* - Some Android ES3 drivers ..
*
*/
public static final int GLES3ViaEGLES2Config = 15;
/**
* Bug 948 - NVIDIA 331.38 (Linux X11) EGL impl. only supports _one_ EGL Device via {@link EGL#eglGetDisplay(long)}.
*
* Subsequent calls to {@link EGL#eglGetDisplay(long)} fail.
*
*
* Reusing global EGL display works.
*
*
* The quirk is autodetected within EGLDrawableFactory's initial default device setup!
*
*
* Appears on:
*
* - EGL_VENDOR NVIDIA
* - EGL_VERSION 1.4
* - GL_VENDOR NVIDIA Corporation
* - GL_VERSION OpenGL ES 3.0 331.38 (probably w/ 1st NV EGL lib on x86)
* - GL_VERSION OpenGL ES 3.1 NVIDIA 355.06 (unstable)
* - Platform X11
* - CPU Family {@link Platform.CPUFamily#X86}
*
*
*/
public static final int SingletonEGLDisplayOnly = 16;
/**
* No reliable MSAA / FSAA {@link GLCapabilitiesImmutable#getSampleBuffers() multi}
* {@link GLCapabilitiesImmutable#getNumSamples() sampling} available,
* i.e. driver may crash.
*
* Appears on:
*
* - GL_VENDOR nouveau
* - GL_RENDERER Gallium 0.4 on NV34
*
* TODO: We have to determine the exact version range, i.e. not adding the quirk with fixed driver version!
*
* TODO: Since we currently don't handle this quirk internally, a user may need to do the following:
*
* final AbstractGraphicsDevice adevice = GLDrawableFactory.getDesktopFactory(); // or similar
* if( GLRendererQuirks.existStickyDeviceQuirk(adevice, GLRendererQuirks.NoMultiSamplingBuffers) ) {
* // don't use MSAA
* }
*
*/
public static final int NoMultiSamplingBuffers = 17;
/**
* Buggy FBO color renderbuffer target,
* i.e. driver may crash.
*
* Appears on:
*
* - GL_VENDOR Brian Paul
* - GL_RENDERER Mesa X11
* - GL_VERSION 2.1 Mesa 7.2
*
* TODO: We have to determine the exact version range, i.e. not adding the quirk with fixed driver version!
*
*
* Note: Also enables {@link #NoFullFBOSupport}.
*
*
* Note: GLFBODrawable always uses texture attachments if set.
*
*
* Quirk can also be enabled via property: jogl.fbo.force.nocolorrenderbuffer
.
*
*/
public static final int BuggyColorRenderbuffer = 18;
/**
* No pbuffer supporting accumulation buffers available,
* even if driver claims otherwise.
*
* Some drivers wrongly claim to support pbuffers
* with accumulation buffers. However, the creation of such pbuffer fails:
*
* com.jogamp.opengl.GLException: pbuffer creation error: Couldn't find a suitable pixel format
*
*
*
* Appears on:
*
* - GL_VENDOR Intel
* - GL_RENDERER Intel Bear Lake B
* - GL_VERSION 1.4.0 - Build 8.14.10.1930
* - Platform Windows
*
*
*/
public static final int NoPBufferWithAccum = 19;
/**
* Need GL objects (VBO, ..) to be synchronized when utilized
* concurrently from multiple threads via a shared GL context,
* otherwise driver crashes the VM.
*
* Usually synchronization should not be required, if the shared GL objects
* are created and immutable before concurrent usage.
* However, using drivers exposing this issue always require the user to
* synchronize access of shared GL objects.
*
*
* Synchronization can be avoided if accessing the shared GL objects
* exclusively via a queue or {@link com.jogamp.common.util.Ringbuffer Ringbuffer}, see GLMediaPlayerImpl as an example.
*
*
* Appears on:
*
* - Platform OSX
*
* - detected on OSX 10.9.5 first
* - any driver
* - enabled for all OSX versions
*
*
*
*
*
* See Bug 1088 - https://jogamp.org/bugzilla/show_bug.cgi?id=1088
*
*/
public static final int NeedSharedObjectSync = 20;
/**
* No reliable ARB_create_context implementation,
* even if driver claims otherwise.
*
* Some drivers wrongly claim to support ARB_create_context.
* However, the creation of such context fails:
*
* com.jogamp.opengl.GLException: AWT-EventQueue-0: WindowsWGLContex.createContextImpl ctx !ARB, profile > GL2
* requested (OpenGL >= 3.0.1). Requested: GLProfile[GL3bc/GL3bc.hw], current: 2.1 (Compat profile, FBO, hardware)
* - 2.1.8787
*
*
*
* Appears on:
*
* - GL_VENDOR ATI Technologies Inc.
* - GL_RENDERER ATI Radeon 3100 Graphics
* - GL_VERSION 2.1.8787
* - Platform Windows
*
*
*/
public static final int NoARBCreateContext = 21;
/**
* No support for ES or desktop GL >= 3.0 current context without surface,
* i.e. without a default framebuffer as read- and write drawables.
*
* See OpenGL spec 3.0, chapter 2.1 OpenGL Fundamentals, page 7 or
* OpenGL ES spec 3.0.2, chapter 2.1 OpenGL Fundamentals, page 6:
*
* It is possible to use a GL context without a default framebuffer, in which case
* a framebuffer object must be used to perform all rendering. This is useful for
* applications neeting to perform offscreen rendering.
*
*
*
* The feature will be attempted at initialization and this quirk will be set if failing.
*
*
* Known drivers failing the specification:
*
* - GNU/Linux X11 Nvidia proprietary driver
*
* - GL_VERSION 4.4.0 NVIDIA 340.24
* - Platform GNU/Linux X11
*
*
*
*/
public static final int NoSurfacelessCtx = 22;
/** Return the number of known quirks. */
public static final int getCount() { return 23; }
private static final String[] _names = new String[] { "NoDoubleBufferedPBuffer", "NoDoubleBufferedBitmap", "NoSetSwapInterval",
"NoOffscreenBitmap", "NoSetSwapIntervalPostRetarget", "GLSLBuggyDiscard",
"GLNonCompliant", "GLFlushBeforeRelease", "DontCloseX11Display",
"NeedCurrCtx4ARBPixFmtQueries", "NeedCurrCtx4ARBCreateContext",
"NoFullFBOSupport", "GLSLNonCompliant", "GL4NeedsGL3Request",
"GLSharedContextBuggy", "GLES3ViaEGLES2Config", "SingletonEGLDisplayOnly",
"NoMultiSamplingBuffers", "BuggyColorRenderbuffer", "NoPBufferWithAccum",
"NeedSharedObjectSync", "NoARBCreateContext", "NoSurfacelessCtx"
};
private static final IdentityHashMap stickyDeviceQuirks = new IdentityHashMap();
/**
* Retrieval of sticky {@link AbstractGraphicsDevice}'s {@link GLRendererQuirks}.
*
* The {@link AbstractGraphicsDevice}s are mapped via their {@link AbstractGraphicsDevice#getUniqueID()}.
*
*
* Not thread safe.
*
* @see #areSameStickyDevice(AbstractGraphicsDevice, AbstractGraphicsDevice)
*/
public static GLRendererQuirks getStickyDeviceQuirks(final AbstractGraphicsDevice device) {
final String key = device.getUniqueID();
final GLRendererQuirks has = stickyDeviceQuirks.get(key);
final GLRendererQuirks res;
if( null == has ) {
res = new GLRendererQuirks();
stickyDeviceQuirks.put(key, res);
} else {
res = has;
}
return res;
}
/**
* Returns true if both devices have the same {@link AbstractGraphicsDevice#getUniqueID()},
* otherwise false.
*/
public static boolean areSameStickyDevice(final AbstractGraphicsDevice device1, final AbstractGraphicsDevice device2) {
return device1.getUniqueID() == device2.getUniqueID(); // uses .intern()!
}
/**
* {@link #addQuirk(int) Adding given quirk} of sticky {@link AbstractGraphicsDevice}'s {@link GLRendererQuirks}.
*
* Not thread safe.
*
* @see #getStickyDeviceQuirks(AbstractGraphicsDevice)
*/
public static void addStickyDeviceQuirk(final AbstractGraphicsDevice device, final int quirk) throws IllegalArgumentException {
final GLRendererQuirks sq = getStickyDeviceQuirks(device);
sq.addQuirk(quirk);
}
/**
* {@link #addQuirks(int[], int, int) Adding given quirks} of sticky {@link AbstractGraphicsDevice}'s {@link GLRendererQuirks}.
*
* Not thread safe.
*
* @see #getStickyDeviceQuirks(AbstractGraphicsDevice)
*/
public static void addStickyDeviceQuirks(final AbstractGraphicsDevice device, final int[] quirks, final int offset, final int len) throws IllegalArgumentException {
final GLRendererQuirks sq = getStickyDeviceQuirks(device);
sq.addQuirks(quirks, offset, len);
}
/**
* {@link #addQuirks(GLRendererQuirks) Adding given quirks} of sticky {@link AbstractGraphicsDevice}'s {@link GLRendererQuirks}.
*
* Not thread safe.
*
* @see #getStickyDeviceQuirks(AbstractGraphicsDevice)
*/
public static void addStickyDeviceQuirks(final AbstractGraphicsDevice device, final GLRendererQuirks quirks) throws IllegalArgumentException {
final GLRendererQuirks sq = getStickyDeviceQuirks(device);
sq.addQuirks(quirks);
}
/**
* {@link #exist(int) Query} of sticky {@link AbstractGraphicsDevice}'s {@link GLRendererQuirks}.
*
* Not thread safe. However, use after changing the sticky quirks is safe.
*
* @see #getStickyDeviceQuirks(AbstractGraphicsDevice)
*/
public static boolean existStickyDeviceQuirk(final AbstractGraphicsDevice device, final int quirk) {
return getStickyDeviceQuirks(device).exist(quirk);
}
/**
* {@link #addQuirks(GLRendererQuirks) Pushing} the sticky {@link AbstractGraphicsDevice}'s {@link GLRendererQuirks}
* to the given {@link GLRendererQuirks destination}.
*
* Not thread safe. However, use after changing the sticky quirks is safe.
*
* @see #getStickyDeviceQuirks(AbstractGraphicsDevice)
*/
public static void pushStickyDeviceQuirks(final AbstractGraphicsDevice device, final GLRendererQuirks dest) {
dest.addQuirks(getStickyDeviceQuirks(device));
}
private int _bitmask;
public GLRendererQuirks() {
_bitmask = 0;
}
/**
* @param quirks an array of valid quirks
* @param offset offset in quirks array to start reading
* @param len number of quirks to read from offset within quirks array
* @throws IllegalArgumentException if one of the quirks is out of range
*/
public GLRendererQuirks(final int[] quirks, final int offset, final int len) throws IllegalArgumentException {
this();
addQuirks(quirks, offset, len);
}
/**
* @param quirk valid quirk to be added
* @throws IllegalArgumentException if the quirk is out of range
*/
public final void addQuirk(final int quirk) throws IllegalArgumentException {
validateQuirk(quirk);
_bitmask |= 1 << quirk;
}
/**
* @param quirks an array of valid quirks to be added
* @param offset offset in quirks array to start reading
* @param len number of quirks to read from offset within quirks array
* @throws IllegalArgumentException if one of the quirks is out of range
*/
public final void addQuirks(final int[] quirks, final int offset, final int len) throws IllegalArgumentException {
int bitmask = 0;
if( !( 0 <= offset + len && offset + len <= quirks.length ) ) {
throw new IllegalArgumentException("offset and len out of bounds: offset "+offset+", len "+len+", array-len "+quirks.length);
}
for(int i=offset; i