JOGL v2.6.0-rc-20250712
JOGL, High-Performance Graphics Binding for Java™ (public API).
GLRendererQuirks.java
Go to the documentation of this file.
1/**
2 * Copyright 2012 - 2019 JogAmp Community. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without modification, are
5 * permitted provided that the following conditions are met:
6 *
7 * 1. Redistributions of source code must retain the above copyright notice, this list of
8 * conditions and the following disclaimer.
9 *
10 * 2. Redistributions in binary form must reproduce the above copyright notice, this list
11 * of conditions and the following disclaimer in the documentation and/or other materials
12 * provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED
15 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
16 * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
19 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
20 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
21 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
22 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23 *
24 * The views and conclusions contained in the software and documentation are those of the
25 * authors and should not be interpreted as representing official policies, either expressed
26 * or implied, of JogAmp Community.
27 */
28package com.jogamp.opengl;
29
30import java.lang.reflect.Field;
31import java.util.IdentityHashMap;
32
33import com.jogamp.nativewindow.AbstractGraphicsDevice;
34import com.jogamp.opengl.GLCapabilitiesImmutable;
35
36import com.jogamp.common.os.Platform;
37import com.jogamp.common.util.PropertyAccess;
38import com.jogamp.opengl.egl.EGL;
39import com.jogamp.opengl.egl.EGLExt;
40
41/**
42 * GLRendererQuirks contains information of known bugs of various GL renderer.
43 * This information allows us to workaround them.
44 * <p>
45 * Using centralized quirk identifier enables us to
46 * locate code dealing w/ it and hence eases it's maintenance.
47 * </p>
48 * <p>
49 * <i>Some</i> <code>GL_VENDOR</code> and <code>GL_RENDERER</code> strings are
50 * listed here <http://feedback.wildfiregames.com/report/opengl/feature/GL_VENDOR>.
51 * </p>
52 * <p>
53 * For testing purpose or otherwise, you may override the implemented
54 * quirk bit setting behavior using {@link GLRendererQuirks.Override}.
55 * </p>
56 */
57public class GLRendererQuirks {
58 /**
59 * Allow overriding any quirk settings
60 * via the two properties:
61 * <ul>
62 * <li>jogl.quirks.force</li>
63 * <li>jogl.quirks.ignore</li>
64 * </ul>
65 * Both contain a list of capital sensitive quirk names separated by comma.
66 * Example:
67 * <pre>
68 * java -Djogl.quirks.force=GL3CompatNonCompliant,NoFullFBOSupport -cp my_classpath some.main.Class
69 * </pre>
70 * <p>
71 * Naturally, one quirk can only be listed in one override list.
72 * Hence the two override sets force and ignore are unique.
73 * </p>
74 */
75 public static enum Override {
76 /**
77 * No override.
78 */
80 /**
81 * Enforce the quirk, i.e. allowing the code path to be injected w/o actual cause.
82 */
84 /**
85 * Ignore the quirk, i.e. don't set the quirk if otherwise caused.
86 */
87 IGNORE
88 }
89
90 /**
91 * Crashes XServer when using double buffered PBuffer with hardware GL_RENDERER on Mesa < 18.2.2:
92 * <ul>
93 * <li>Mesa DRI Intel(R) Sandybridge Desktop</li>
94 * <li>Mesa DRI Intel(R) Ivybridge Mobile - 3.0 Mesa 8.0.4</li>
95 * <li>Gallium 0.4 on AMD CYPRESS</li>
96 * </ul>
97 * For now, it is safe to disable it w/ hw-acceleration.
98 */
99 public static final int NoDoubleBufferedPBuffer = 0;
100
101 /** On Windows no double buffered bitmaps are guaranteed to be available. */
102 public static final int NoDoubleBufferedBitmap = 1;
103
104 /** Crashes application when trying to set EGL swap interval on Android 4.0.3 / Pandaboard ES / PowerVR SGX 540 */
105 public static final int NoSetSwapInterval = 2;
106
107 /** No offscreen bitmap available, currently true for JOGL's OSX implementation. */
108 public static final int NoOffscreenBitmap = 3;
109
110 /** SIGSEGV on setSwapInterval() after changing the context's drawable w/ Mesa >= 8.0.4 until Mesa < 18.2.2: dri2SetSwapInterval/DRI2 (soft & intel) */
111 public static final int NoSetSwapIntervalPostRetarget = 4;
112
113 /**
114 * GLSL <code>discard</code> command leads to undefined behavior or won't get compiled if being used.
115 * <p>
116 * Appears to <i>have</i> happened on Nvidia Tegra2, but seems to be fine now.<br/>
117 * FIXME: Constrain version.
118 * </p>
119 */
120 public static final int GLSLBuggyDiscard = 5;
121
122 /**
123 * Non compliant OpenGL 3.1+ compatibility profile due to a buggy implementation not suitable for use.
124 * <p>
125 * Mesa versions in the range [9.1.3 .. 18.2.0[ are not fully compliant with the
126 * OpenGL 3.1 compatibility profile.
127 * Most programs will give completely broken output (or no
128 * output at all.
129 * </p>
130 * <p>
131 * The above has been confirmed for the following Mesa 9.* GL_RENDERER strings:
132 * <ul>
133 * <li>Mesa .* Intel(R) Sandybridge Desktop</li>
134 * <li>Gallium 0.4 on AMD RS880</li>
135 * </ul>
136 * </p>
137 * <p>
138 * Default implementation sets this quirk on all Mesa < 18.2.0 drivers.
139 * </p>
140 */
141 public static final int GL3CompatNonCompliant = 6;
142
143 /**
144 * The OpenGL context needs a <code>glFlush()</code> before releasing it, otherwise driver may freeze:
145 * <ul>
146 * <li>OSX < 10.7.3 - NVidia Driver. Bug 533 and Bug 548 @ https://jogamp.org/bugzilla/.</li>
147 * </ul>
148 */
149 public static final int GLFlushBeforeRelease = 7;
150
151 /**
152 * Closing X11 displays may cause JVM crashes or X11 errors with some buggy drivers
153 * while being used in concert w/ OpenGL.
154 * <p>
155 * Some drivers may require X11 displays to be closed in the same order as they were created,
156 * some may not allow them to be closed at all while resources are being used somehow.
157 * </p>
158 * <p>
159 * Drivers known exposing such bug:
160 * <ul>
161 * <li>Mesa &lt; 8.0 _with_ X11 software renderer <code>Mesa X11</code>, not with GLX/DRI renderer.</li>
162 * <li>ATI proprietary Catalyst X11 driver versions:
163 * <ul>
164 * <li>8.78.6</li>
165 * <li>8.881</li>
166 * <li>8.911</li>
167 * <li>9.01.8</li>
168 * </ul></li>
169 * </ul>
170 * </p>
171 * <p>
172 * See Bug 515 - https://jogamp.org/bugzilla/show_bug.cgi?id=515
173 * and {@link jogamp.nativewindow.x11.X11Util#ATI_HAS_XCLOSEDISPLAY_BUG}.
174 * </p>
175 * <p>
176 * See Bug 705 - https://jogamp.org/bugzilla/show_bug.cgi?id=705
177 * </p>
178 */
179 public static final int DontCloseX11Display = 8;
180
181 /**
182 * Need current GL context when calling new ARB <i>pixel format query</i> functions,
183 * otherwise driver crashes the VM.
184 * <p>
185 * Drivers known exposing such bug:
186 * <ul>
187 * <li>ATI proprietary Catalyst driver on Windows version &le; XP.
188 * TODO: Validate if bug actually relates to 'old' ATI Windows drivers for old GPU's like X300
189 * regardless of the Windows version.</li>
190 * </ul>
191 * <p>
192 * See Bug 480 - https://jogamp.org/bugzilla/show_bug.cgi?id=480
193 * </p>
194 */
195 public static final int NeedCurrCtx4ARBPixFmtQueries = 9;
196
197 /**
198 * Need current GL context when calling new ARB <i>CreateContext</i> function,
199 * otherwise driver crashes the VM.
200 * <p>
201 * Drivers known exposing such bug:
202 * <ul>
203 * <li>ATI proprietary Catalyst Windows driver on laptops with a driver version as reported in <i>GL_VERSION</i>:
204 * <ul>
205 * <li> <i>null</i> </li>
206 * <li> &lt; <code>12.102.3.0</code> ( <i>amd_catalyst_13.5_mobility_beta2</i> ) </li>
207 * </ul></li>
208 * </ul>
209 * </p>
210 * <p>
211 * See Bug 706 - https://jogamp.org/bugzilla/show_bug.cgi?id=706<br/>
212 * See Bug 520 - https://jogamp.org/bugzilla/show_bug.cgi?id=520
213 * </p>
214 */
215 public static final int NeedCurrCtx4ARBCreateContext = 10;
216
217 /**
218 * No full FBO support, i.e. not compliant w/
219 * <ul>
220 * <li>GL_ARB_framebuffer_object</li>
221 * <li>EXT_framebuffer_object</li>
222 * <li>EXT_framebuffer_multisample</li>
223 * <li>EXT_framebuffer_blit</li>
224 * <li>EXT_packed_depth_stencil</li>
225 * </ul>.
226 * Drivers known exposing such bug:
227 * <ul>
228 * <li>Mesa <i>7.12-devel</i> on Windows with VMware <i>SVGA3D</i> renderer:
229 * <ul>
230 * <li>GL_VERSION: <i>2.1 Mesa 7.12-devel (git-d6c318e)</i> </li>
231 * <li>GL_RENDERER: <i>Gallium 0.4 on SVGA3D; build: RELEASE;</i> </li>
232 * </ul></li>
233 * </ul>
234 * <p>
235 * Note: Also enabled via {@link #BuggyColorRenderbuffer}.
236 * </p>
237 */
238 public static final int NoFullFBOSupport = 11;
239
240 /**
241 * GLSL is not compliant or even not stable (crash)
242 * <ul>
243 * <li>OSX < 10.7.0 (?) - NVidia Driver. Bug 818 @ https://jogamp.org/bugzilla/.</li>
244 * </ul>
245 */
246 public static final int GLSLNonCompliant = 12;
247
248 /**
249 * GL4 context needs to be requested via GL3 profile attribute
250 * <ul>
251 * <li>OSX >= 10.9.0 - kCGLOGLPVersion_GL4_Core may not produce hw-accel context. Bug 867 @ https://jogamp.org/bugzilla/.</li>
252 * </ul>
253 */
254 public static final int GL4NeedsGL3Request = 13;
255
256 /**
257 * Buggy shared OpenGL context support within a multithreaded use-case, not suitable for stable usage.
258 * <p>
259 * <i>X11 Mesa DRI Intel(R) driver >= 9.2.1</i> cannot handle multithreaded shared GLContext usage
260 * with non-blocking exclusive X11 display connections.
261 * References:
262 * <ul>
263 * <li>Bug 873: https://jogamp.org/bugzilla/show_bug.cgi?id=873</li>
264 * <li>https://bugs.freedesktop.org/show_bug.cgi?id=41736#c8</li>
265 * </ul>
266 * <p>
267 * However, not all multithreaded use-cases are broken, e.g. our GLMediaPlayer does work.
268 * </p>
269 * The above has been confirmed for the following Mesa 9.* strings:
270 * <ul>
271 * <li>GL_VENDOR Intel Open Source Technology Center</li>
272 * <li>GL_RENDERER Mesa DRI Intel(R) Sandybridge Desktop</li>
273 * <li>GL_RENDERER Mesa DRI Intel(R) Ivybridge Mobile</li>
274 * <li>GL_VERSION 3.1 (Core Profile) Mesa 9.2.1</li>
275 * </ul>
276 * </p>
277 * <p>
278 * On Android 4.*, <i>Huawei's Ascend G615 w/ Immersion.16</i> could not make a shared context
279 * current, which uses a pbuffer drawable:
280 * <ul>
281 * <li>Android 4.*</li>
282 * <li>GL_VENDOR Hisilicon Technologies</li>
283 * <li>GL_RENDERER Immersion.16</li>
284 * <li>GL_VERSION OpenGL ES 2.0</li>
285 * </ul>
286 * </p>
287 * <p>
288 * </p>
289 */
290 public static final int GLSharedContextBuggy = 14;
291
292 /**
293 * Bug 925 - Accept an ES3 Context, if reported via GL-Version-String w/o {@link EGLExt#EGL_OPENGL_ES3_BIT_KHR}.
294 * <p>
295 * The ES3 Context can be used via {@link EGL#EGL_OPENGL_ES2_BIT}.
296 * </p>
297 * <p>
298 * The ES3 Context {@link EGL#eglCreateContext(long, long, long, java.nio.IntBuffer) must be created} with version attributes:
299 * <pre>
300 * EGL.EGL_CONTEXT_CLIENT_VERSION, 2, ..
301 * </pre>
302 * </p>
303 * <ul>
304 * <li>Mesa/AMD >= 9.2.1</li>
305 * <li>Some Android ES3 drivers ..</li>
306 * </ul>
307 */
308 public static final int GLES3ViaEGLES2Config = 15;
309
310 /**
311 * Bug 948 - NVIDIA 331.38 (Linux X11) EGL impl. only supports _one_ EGL Device via {@link EGL#eglGetDisplay(long)}.
312 * <p>
313 * Subsequent calls to {@link EGL#eglGetDisplay(long)} fail.
314 * </p>
315 * <p>
316 * Reusing global EGL display works.
317 * </p>
318 * <p>
319 * The quirk is autodetected within EGLDrawableFactory's initial default device setup!
320 * </p>
321 * <p>
322 * Appears on:
323 * <ul>
324 * <li>EGL_VENDOR NVIDIA</li>
325 * <li>EGL_VERSION 1.4</li>
326 * <li>GL_VENDOR NVIDIA Corporation</li>
327 * <li>GL_VERSION OpenGL ES 3.0 331.38 (probably w/ 1st NV EGL lib on x86)</li>
328 * <li>GL_VERSION OpenGL ES 3.1 NVIDIA 355.06 (unstable)</li>
329 * <li>Platform X11</li>
330 * <li>CPU Family {@link Platform.CPUFamily#X86}</li>
331 * </ul>
332 * </p>
333 */
334 public static final int SingletonEGLDisplayOnly = 16;
335
336 /**
337 * No reliable MSAA / FSAA {@link GLCapabilitiesImmutable#getSampleBuffers() multi}
338 * {@link GLCapabilitiesImmutable#getNumSamples() sampling} available,
339 * i.e. driver <i>may crash</i>.
340 * <p>
341 * Appears on:
342 * <ul>
343 * <li>GL_VENDOR nouveau</li>
344 * <li>GL_RENDERER Gallium 0.4 on NV34</li>
345 * </ul>
346 * TODO: We have to determine the exact version range, i.e. not adding the quirk with fixed driver version!
347 * </p>
348 * TODO: Since we currently don't handle this quirk internally, a user may need to do the following:
349 * <pre>
350 * final AbstractGraphicsDevice adevice = GLDrawableFactory.getDesktopFactory(); // or similar
351 * if( GLRendererQuirks.existStickyDeviceQuirk(adevice, GLRendererQuirks.NoMultiSamplingBuffers) ) {
352 * // don't use MSAA
353 * }
354 * </pre>
355 */
356 public static final int NoMultiSamplingBuffers = 17;
357
358 /**
359 * Buggy FBO color renderbuffer target,
360 * i.e. driver <i>may crash</i>.
361 * <p>
362 * Appears on:
363 * <ul>
364 * <li>GL_VENDOR Brian Paul</li>
365 * <li>GL_RENDERER Mesa X11</li>
366 * <li>GL_VERSION 2.1 Mesa 7.2</li>
367 * </ul>
368 * TODO: We have to determine the exact version range, i.e. not adding the quirk with fixed driver version!
369 * </p>
370 * <p>
371 * Note: Also enables {@link #NoFullFBOSupport}.
372 * </p>
373 * <p>
374 * Note: GLFBODrawable always uses texture attachments if set.
375 * </p>
376 */
377 public static final int BuggyColorRenderbuffer = 18;
378
379 /**
380 * No pbuffer supporting accumulation buffers available,
381 * even if driver claims otherwise.
382 * <p>
383 * Some drivers wrongly claim to support pbuffers
384 * with accumulation buffers. However, the creation of such pbuffer fails:
385 * <pre>
386 * com.jogamp.opengl.GLException: pbuffer creation error: Couldn't find a suitable pixel format
387 * </pre>
388 * </p>
389 * <p>
390 * Appears on:
391 * <ul>
392 * <li>GL_VENDOR Intel</li>
393 * <li>GL_RENDERER Intel Bear Lake B</li>
394 * <li>GL_VERSION 1.4.0 - Build 8.14.10.1930</li>
395 * <li>Platform Windows</li>
396 * </ul>
397 * </p>
398 */
399 public static final int NoPBufferWithAccum = 19;
400
401 /**
402 * Need GL objects (VBO, ..) to be synchronized when utilized
403 * concurrently from multiple threads via a shared GL context,
404 * otherwise driver crashes the VM.
405 * <p>
406 * Usually synchronization should not be required, if the shared GL objects
407 * are created and immutable before concurrent usage.<br>
408 * However, using drivers exposing this issue always require the user to
409 * synchronize access of shared GL objects.
410 * </p>
411 * <p>
412 * Synchronization can be avoided if accessing the shared GL objects
413 * exclusively via a queue or {@link com.jogamp.common.util.Ringbuffer Ringbuffer}, see GLMediaPlayerImpl as an example.
414 * </p>
415 * <p>
416 * Appears on:
417 * <ul>
418 * <li>Platform OSX
419 * <ul>
420 * <li>detected on OSX 10.9.5 first</li>
421 * <li>any driver</li>
422 * <li>enabled for all OSX versions</li>
423 * </ul>
424 * </li>
425 * </ul>
426 * </p>
427 * <p>
428 * See Bug 1088 - https://jogamp.org/bugzilla/show_bug.cgi?id=1088
429 * </p>
430 */
431 public static final int NeedSharedObjectSync = 20;
432
433 /**
434 * No reliable ARB_create_context implementation,
435 * even if driver claims otherwise.
436 * <p>
437 * Some drivers wrongly claim to support ARB_create_context.
438 * However, the creation of such context fails:
439 * <pre>
440 * com.jogamp.opengl.GLException: AWT-EventQueue-0: WindowsWGLContex.createContextImpl ctx !ARB, profile > GL2
441 * requested (OpenGL >= 3.0.1). Requested: GLProfile[GL3bc/GL3bc.hw], current: 2.1 (Compat profile, FBO, hardware)
442 * - 2.1.8787
443 * </pre>
444 * </p>
445 * <p>
446 * Appears on:
447 * <ul>
448 * <li>GL_VENDOR ATI Technologies Inc.</li>
449 * <li>GL_RENDERER ATI Radeon 3100 Graphics</li>
450 * <li>GL_VERSION 2.1.8787</li>
451 * <li>Platform Windows</li>
452 * </ul>
453 * </p>
454 */
455 public static final int NoARBCreateContext = 21;
456
457 /**
458 * No support for ES or desktop GL >= 3.0 current context without surface,
459 * i.e. without a default framebuffer as read- and write drawables.
460 * <p>
461 * See <i>OpenGL spec 3.0, chapter 2.1 OpenGL Fundamentals, page 7</i> or<br>
462 * <i>OpenGL ES spec 3.0.2, chapter 2.1 OpenGL Fundamentals, page 6</i>:
463 * <pre>
464 * It is possible to use a GL context without a default framebuffer, in which case
465 * a framebuffer object must be used to perform all rendering. This is useful for
466 * applications neeting to perform offscreen rendering.
467 * </pre>
468 * </p>
469 * <p>
470 * The feature will be attempted at initialization and this quirk will be set if failing.
471 * </p>
472 * <p>
473 * Known drivers failing the specification:
474 * <ul>
475 * <li>GNU/Linux X11 Nvidia proprietary driver
476 * <ul>
477 * <li>GL_VERSION 4.4.0 NVIDIA 340.24</li>
478 * <li>GL_VERSION 4.6.0 NVIDIA 440.36</li>
479 * <li>Platform GNU/Linux X11</li>
480 * </ul></li>
481 * </ul>
482 * </p>
483 */
484 public static final int NoSurfacelessCtx = 22;
485
486 /**
487 * No FBO support at all.
488 * <p>
489 * This quirk currently exist to be injected by the user via the properties only,
490 * see {@link GLRendererQuirks.Override}.
491 * </p>
492 */
493 public static final int NoFBOSupport = 23;
494
495 /**
496 * Don't use the ChooseFBConfig's best match,
497 * instead utilize the given {@link GLCapabilitiesChooser} or {@link DefaultGLCapabilitiesChooser}
498 * without any recommendation.
499 * <p>
500 * The default behavior without this quirk is using a given {@link GLCapabilitiesChooser}
501 * and pass the ChooseFBConfig's best match as a recommendation.
502 * </p>
503 * <p>
504 * This quirk currently exist to be injected by the user via the properties,
505 * see {@link GLRendererQuirks.Override}.
506 * </p>
507 */
508 public static final int DontChooseFBConfigBestMatch = 24;
509
510 /**
511 * On Mesa >= 18.0.0, {@code glXChooseFBConfig} selects <i>better</i>
512 * {@link GLCapabilities} FBConfig than actually supported by
513 * {@link glXCreatePbuffer} and {@code glXCreateGLXPixmap}.
514 * <p>
515 * As tested on Mesa 18.3.6, requesting an RGB 8bit color component
516 * FBConfig for {@code GLX_PBUFFER_BIT} and {@code GLX_PIXMAP_BIT} {@code GLX_DRAWABLE_TYPE}s
517 * via {@code glXChooseFBConfig} returns an RGB 10bit color component
518 * FBConfig as its best match.
519 * Subsequent {@code glXCreatePbuffer} and {@code glXCreateGLXPixmap} calls fail.
520 * </p>
521 * <p>
522 * This bugs seems to occur in Mesa >= 18.0.0 using <i>allow_rgb10_configs</i>, which is the default now.
523 * While the 10 bit color components are not listed for
524 * on-screen {@code GLX.GLX_WINDOW_BIT} {@code GLX_DRAWABLE_TYPE}s,
525 * they are listed for above mentioned off-screen types without {@code XVisualInfo} reference.
526 * </p>
527 * <p>
528 * This quirk disables using any color component > 8 bit for
529 * {@code GLX_PBUFFER_BIT} and {@code GLX_PIXMAP_BIT} types
530 * and forces using an optional given {@link GLCapabilitiesChooser}
531 * or the {@link DefaultGLCapabilitiesChooser}.
532 * </p>
533 * <p>
534 * Note: Also implies {@link #DontChooseFBConfigBestMatch} for {@code GLX_PBUFFER_BIT} and {@code GLX_PIXMAP_BIT} types.
535 * </p>
536 */
537 public static final int No10BitColorCompOffscreen = 25;
538
539 /** Return the number of known quirks, aka quirk bit count. */
540 public static final int getCount() { return 26; }
541
542 private static final String[] _names = new String[] { "NoDoubleBufferedPBuffer", "NoDoubleBufferedBitmap", "NoSetSwapInterval",
543 "NoOffscreenBitmap", "NoSetSwapIntervalPostRetarget", "GLSLBuggyDiscard",
544 "GL3CompatNonCompliant", "GLFlushBeforeRelease", "DontCloseX11Display",
545 "NeedCurrCtx4ARBPixFmtQueries", "NeedCurrCtx4ARBCreateContext",
546 "NoFullFBOSupport", "GLSLNonCompliant", "GL4NeedsGL3Request",
547 "GLSharedContextBuggy", "GLES3ViaEGLES2Config", "SingletonEGLDisplayOnly",
548 "NoMultiSamplingBuffers", "BuggyColorRenderbuffer", "NoPBufferWithAccum",
549 "NeedSharedObjectSync", "NoARBCreateContext", "NoSurfacelessCtx",
550 "NoFBOSupport", "DontChooseFBConfigBestMatch", "No10BitColorCompOffscreen"
551 };
552
553 private static final IdentityHashMap<String, GLRendererQuirks> stickyDeviceQuirks = new IdentityHashMap<String, GLRendererQuirks>();
554
555 /**
556 * Retrieval of sticky {@link AbstractGraphicsDevice}'s {@link GLRendererQuirks}.
557 * <p>
558 * The {@link AbstractGraphicsDevice}s are mapped via their {@link AbstractGraphicsDevice#getUniqueID()}.
559 * </p>
560 * <p>
561 * Not thread safe.
562 * </p>
563 * @see #areSameStickyDevice(AbstractGraphicsDevice, AbstractGraphicsDevice)
564 */
566 final String key = device.getUniqueID();
567 final GLRendererQuirks has = stickyDeviceQuirks.get(key);
568 final GLRendererQuirks res;
569 if( null == has ) {
570 res = new GLRendererQuirks();
571 stickyDeviceQuirks.put(key, res);
572 } else {
573 res = has;
574 }
575 return res;
576 }
577
578 /**
579 * Returns true if both devices have the same {@link AbstractGraphicsDevice#getUniqueID()},
580 * otherwise false.
581 */
582 public static boolean areSameStickyDevice(final AbstractGraphicsDevice device1, final AbstractGraphicsDevice device2) {
583 return device1.getUniqueID() == device2.getUniqueID(); // uses .intern()!
584 }
585
586 /**
587 * {@link #addQuirk(int) Adding given quirk} of sticky {@link AbstractGraphicsDevice}'s {@link GLRendererQuirks}.
588 * <p>
589 * Not thread safe.
590 * </p>
591 * @see #getStickyDeviceQuirks(AbstractGraphicsDevice)
592 */
593 public static void addStickyDeviceQuirk(final AbstractGraphicsDevice device, final int quirk) throws IllegalArgumentException {
594 final GLRendererQuirks sq = getStickyDeviceQuirks(device);
595 sq.addQuirk(quirk);
596 }
597 /**
598 * {@link #addQuirks(GLRendererQuirks) Adding given quirks} of sticky {@link AbstractGraphicsDevice}'s {@link GLRendererQuirks}.
599 * <p>
600 * Not thread safe.
601 * </p>
602 * @see #getStickyDeviceQuirks(AbstractGraphicsDevice)
603 */
604 public static void addStickyDeviceQuirks(final AbstractGraphicsDevice device, final GLRendererQuirks quirks) throws IllegalArgumentException {
605 final GLRendererQuirks sq = getStickyDeviceQuirks(device);
606 sq.addQuirks(quirks);
607 }
608 /**
609 * {@link #exist(int) Query} of sticky {@link AbstractGraphicsDevice}'s {@link GLRendererQuirks}.
610 * <p>
611 * Not thread safe. However, use after changing the sticky quirks is safe.
612 * </p>
613 * @see #getStickyDeviceQuirks(AbstractGraphicsDevice)
614 */
615 public static boolean existStickyDeviceQuirk(final AbstractGraphicsDevice device, final int quirkBit) {
616 return getStickyDeviceQuirks(device).exist(quirkBit);
617 }
618 /**
619 * {@link #addQuirks(GLRendererQuirks) Pushing} the sticky {@link AbstractGraphicsDevice}'s {@link GLRendererQuirks}
620 * to the given {@link GLRendererQuirks destination}.
621 * <p>
622 * Not thread safe. However, use after changing the sticky quirks is safe.
623 * </p>
624 * @see #getStickyDeviceQuirks(AbstractGraphicsDevice)
625 */
626 public static void pushStickyDeviceQuirks(final AbstractGraphicsDevice device, final GLRendererQuirks dest) {
627 dest.addQuirks(getStickyDeviceQuirks(device));
628 }
629
630 public static final Override getOverride(final int quirkBit) throws IllegalArgumentException {
631 validateQuirk(quirkBit);
632 if( 0 != ( ( 1 << quirkBit ) & _bitmaskOverrideForce ) ) {
633 return Override.FORCE;
634 }
635 if( 0 != ( ( 1 << quirkBit ) & _bitmaskOverrideIgnore ) ) {
636 return Override.IGNORE;
637 }
638 return Override.NONE;
639 }
640 private static int _bitmaskOverrideForce = 0;
641 private static int _bitmaskOverrideIgnore = 0;
642 static {
643 _bitmaskOverrideForce = _queryQuirkMaskOfPropertyList("jogl.quirks.force", Override.FORCE);
644 _bitmaskOverrideIgnore = _queryQuirkMaskOfPropertyList("jogl.quirks.ignore", Override.IGNORE);
645 if( 0 != ( _bitmaskOverrideForce & GLRendererQuirks.BuggyColorRenderbuffer) ) {
646 _bitmaskOverrideForce |= GLRendererQuirks.NoFullFBOSupport;
647 }
648
649 final int uniqueTest = _bitmaskOverrideForce & _bitmaskOverrideIgnore;
650 if( 0 != uniqueTest ) {
651 throw new InternalError("Override properties force 0x"+Integer.toHexString(_bitmaskOverrideForce)+
652 " and ignore 0x"+Integer.toHexString(_bitmaskOverrideIgnore)+
653 " have intersecting bits 0x"+Integer.toHexString(uniqueTest)+" "+Integer.toBinaryString(uniqueTest));
654 }
655 }
656 private static int _queryQuirkMaskOfPropertyList(final String propertyName, final Override override) {
657 final String quirkNameList = PropertyAccess.getProperty(propertyName, true);
658 if( null == quirkNameList ) {
659 return 0;
660 }
661 int res = 0;
662 final String quirkNames[] = quirkNameList.split(",");
663 for(int i=0; i<quirkNames.length; i++) {
664 final String name = quirkNames[i].trim();
665 try {
666 final Field field = GLRendererQuirks.class.getField(name);
667 final int quirkBit = field.getInt(null);
668 final Override preOverride = getOverride(quirkBit);
669 if( Override.NONE != preOverride ) {
670 System.err.println("Warning: Quirk '"+name+"' bit "+quirkBit+" skipped for override "+override+" mask, already set for override "+preOverride+". Has been included in given property "+propertyName);
671 } else {
672 res |= 1 << quirkBit;
673 System.err.println("Info: Quirk '"+name+"' bit "+quirkBit+" has been added to Override."+override+" mask as included in given property "+propertyName);
674 }
675 } catch (final NoSuchFieldException e) {
676 System.err.println("Warning: Failed to match given property "+propertyName+"'s quirk '"+name+"' with any supported quirk! "+e.getMessage());
677 } catch (SecurityException | IllegalAccessException e) {
678 System.err.println("Warning: Failed to access given property "+propertyName+"'s quirk '"+name+"' bit value! "+e.getMessage());
679 }
680 }
681 return res;
682 }
683
684 private int _bitmask;
685
687 _bitmask = 0;
688 }
689
690 /**
691 * @param quirkBit valid quirk to be added
692 * @throws IllegalArgumentException if the quirk is out of range
693 */
694 public final void addQuirk(final int quirkBit) throws IllegalArgumentException {
695 validateQuirk(quirkBit);
696 _bitmask |= 1 << quirkBit;
697 }
698
699 /**
700 * @param quirks valid GLRendererQuirks to be added
701 */
702 public final void addQuirks(final GLRendererQuirks quirks) {
703 _bitmask |= quirks._bitmask;
704 }
705
706 /**
707 * Method tests whether the given quirk exists.
708 * <p>
709 * This methods respects the potential {@link GLRendererQuirks.Override}
710 * setting by user properties. Therefor this method returns {@code true}
711 * for {@code FORCE}'ed quirks and {@code false} for {@code IGNORE}'ed quirks.
712 * </p>
713 * @param quirkBit the quirk to be tested
714 * @return true if quirk exist, otherwise false
715 * @throws IllegalArgumentException if quirk is out of range
716 */
717 public final boolean exist(final int quirkBit) throws IllegalArgumentException {
718 validateQuirk(quirkBit);
719 return 0 != ( ( 1 << quirkBit ) & ( ~_bitmaskOverrideIgnore & ( _bitmask | _bitmaskOverrideForce ) ) );
720 }
721
722 /**
723 * Convenient static method to call {@link #exist(int)} on the given {@code quirks}
724 * with an added {@code null} check.
725 * @param quirks {@link GLRendererQuirks} instance, maybe {@code null}
726 * @param quirkBit the quirk to be tested
727 * @return {@code true} if the {@code quirks} is not {@code null} and the given {@code quirkBit} is set, otherwise {@code false}.
728 * @throws IllegalArgumentException if quirk is out of range
729 * @see #exist(int)
730 */
731 public static boolean exist(final GLRendererQuirks quirks, final int quirkBit) throws IllegalArgumentException {
732 return null != quirks && quirks.exist(quirkBit);
733 }
734
735 public final StringBuilder toString(StringBuilder sb) {
736 if(null == sb) {
737 sb = new StringBuilder();
738 }
739 sb.append("[");
740 boolean first=true;
741 for(int i=0; i<getCount(); i++) {
742 // list ignored and forced as well
743 if( 0 != ( ( 1 << i ) & ( _bitmask | _bitmaskOverrideForce ) ) ) {
744 if(!first) { sb.append(", "); }
745 sb.append(toString(i));
746 final Override override = getOverride(i);
747 if( Override.NONE != override ) {
748 sb.append("(").append(override.name().toLowerCase()).append("d)");
749 }
750 first=false;
751 }
752 }
753 sb.append("]");
754 return sb;
755 }
756
757 // @Override
758 public final String toString() {
759 return toString(null).toString();
760 }
761
762 /**
763 * @param quirkBit the quirk to be validated, i.e. whether it is out of range
764 * @throws IllegalArgumentException if quirk is out of range
765 */
766 public static void validateQuirk(final int quirkBit) throws IllegalArgumentException {
767 if( !( 0 <= quirkBit && quirkBit < getCount() ) ) {
768 throw new IllegalArgumentException("Quirks must be in range [0.."+getCount()+"[, but quirk: "+quirkBit);
769 }
770 }
771
772 /**
773 * @param quirkBit the quirk to be converted to String
774 * @return the String equivalent of this quirk
775 * @throws IllegalArgumentException if quirk is out of range
776 */
777 public static final String toString(final int quirkBit) throws IllegalArgumentException {
778 validateQuirk(quirkBit);
779 return _names[quirkBit];
780 }
781}
GLRendererQuirks contains information of known bugs of various GL renderer.
final boolean exist(final int quirkBit)
Method tests whether the given quirk exists.
static final String toString(final int quirkBit)
static final int NoOffscreenBitmap
No offscreen bitmap available, currently true for JOGL's OSX implementation.
static final int NoFBOSupport
No FBO support at all.
static final int GL4NeedsGL3Request
GL4 context needs to be requested via GL3 profile attribute.
static final int NoSetSwapInterval
Crashes application when trying to set EGL swap interval on Android 4.0.3 / Pandaboard ES / PowerVR S...
static void pushStickyDeviceQuirks(final AbstractGraphicsDevice device, final GLRendererQuirks dest)
Pushing the sticky AbstractGraphicsDevice's GLRendererQuirks to the given destination.
static final int GLSLNonCompliant
GLSL is not compliant or even not stable (crash)
static final int DontCloseX11Display
Closing X11 displays may cause JVM crashes or X11 errors with some buggy drivers while being used in ...
static GLRendererQuirks getStickyDeviceQuirks(final AbstractGraphicsDevice device)
Retrieval of sticky AbstractGraphicsDevice's GLRendererQuirks.
static final int NoDoubleBufferedBitmap
On Windows no double buffered bitmaps are guaranteed to be available.
static final int GLES3ViaEGLES2Config
Bug 925 - Accept an ES3 Context, if reported via GL-Version-String w/o EGLExt#EGL_OPENGL_ES3_BIT_KHR.
static final int NeedCurrCtx4ARBPixFmtQueries
Need current GL context when calling new ARB pixel format query functions, otherwise driver crashes t...
static boolean areSameStickyDevice(final AbstractGraphicsDevice device1, final AbstractGraphicsDevice device2)
Returns true if both devices have the same AbstractGraphicsDevice#getUniqueID(), otherwise false.
static final int NoFullFBOSupport
No full FBO support, i.e.
static final int NeedSharedObjectSync
Need GL objects (VBO, ..) to be synchronized when utilized concurrently from multiple threads via a s...
static void validateQuirk(final int quirkBit)
static final int NoSurfacelessCtx
No support for ES or desktop GL >= 3.0 current context without surface, i.e.
static final int NoMultiSamplingBuffers
No reliable MSAA / FSAA multi sampling available, i.e.
final StringBuilder toString(StringBuilder sb)
static final int getCount()
Return the number of known quirks, aka quirk bit count.
static final int SingletonEGLDisplayOnly
Bug 948 - NVIDIA 331.38 (Linux X11) EGL impl.
static boolean existStickyDeviceQuirk(final AbstractGraphicsDevice device, final int quirkBit)
Query of sticky AbstractGraphicsDevice's GLRendererQuirks.
final void addQuirk(final int quirkBit)
static void addStickyDeviceQuirks(final AbstractGraphicsDevice device, final GLRendererQuirks quirks)
Adding given quirks of sticky AbstractGraphicsDevice's GLRendererQuirks.
static final int GLFlushBeforeRelease
The OpenGL context needs a glFlush() before releasing it, otherwise driver may freeze:
static final int BuggyColorRenderbuffer
Buggy FBO color renderbuffer target, i.e.
static final int DontChooseFBConfigBestMatch
Don't use the ChooseFBConfig's best match, instead utilize the given GLCapabilitiesChooser or Default...
static boolean exist(final GLRendererQuirks quirks, final int quirkBit)
Convenient static method to call exist(int) on the given quirks with an added null check.
static final int NeedCurrCtx4ARBCreateContext
Need current GL context when calling new ARB CreateContext function, otherwise driver crashes the VM.
static final int NoARBCreateContext
No reliable ARB_create_context implementation, even if driver claims otherwise.
static void addStickyDeviceQuirk(final AbstractGraphicsDevice device, final int quirk)
Adding given quirk of sticky AbstractGraphicsDevice's GLRendererQuirks.
static final int No10BitColorCompOffscreen
On Mesa >= 18.0.0, glXChooseFBConfig selects better GLCapabilities FBConfig than actually supported b...
static final int NoPBufferWithAccum
No pbuffer supporting accumulation buffers available, even if driver claims otherwise.
static final Override getOverride(final int quirkBit)
static final int NoSetSwapIntervalPostRetarget
SIGSEGV on setSwapInterval() after changing the context's drawable w/ Mesa >= 8.0....
static final int GL3CompatNonCompliant
Non compliant OpenGL 3.1+ compatibility profile due to a buggy implementation not suitable for use.
static final int GLSharedContextBuggy
Buggy shared OpenGL context support within a multithreaded use-case, not suitable for stable usage.
static final int GLSLBuggyDiscard
GLSL discard command leads to undefined behavior or won't get compiled if being used.
final void addQuirks(final GLRendererQuirks quirks)
static final int NoDoubleBufferedPBuffer
Crashes XServer when using double buffered PBuffer with hardware GL_RENDERER on Mesa < 18....
Allow overriding any quirk settings via the two properties:
A interface describing a graphics device in a toolkit-independent manner.
String getUniqueID()
Returns a unique ID object of this device using type, connection and unitID as it's key components.