JOGL v2.6.0-rc-20250712
JOGL, High-Performance Graphics Binding for Java™ (public API).
GLDrawableFactory.java
Go to the documentation of this file.
1/*
2 * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
3 * Copyright (c) 2010 JogAmp Community. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met:
8 *
9 * - Redistribution of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 *
12 * - Redistribution in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * Neither the name of Sun Microsystems, Inc. or the names of
17 * contributors may be used to endorse or promote products derived from
18 * this software without specific prior written permission.
19 *
20 * This software is provided "AS IS," without a warranty of any kind. ALL
21 * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
22 * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
23 * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
24 * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
25 * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
26 * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
27 * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
28 * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
29 * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
30 * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
31 * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
32 *
33 * You acknowledge that this software is not designed or intended for use
34 * in the design, construction, operation or maintenance of any nuclear
35 * facility.
36 *
37 * Sun gratefully acknowledges that this software was originally authored
38 * and developed by Kenneth Bradley Russell and Christopher John Kline.
39 */
40
41package com.jogamp.opengl;
42
43import java.util.ArrayList;
44import java.util.List;
45
46import com.jogamp.common.os.Platform;
47import com.jogamp.common.util.PropertyAccess;
48import com.jogamp.common.util.ReflectionUtil;
49import com.jogamp.opengl.GLAutoDrawableDelegate;
50import com.jogamp.opengl.GLRendererQuirks;
51
52import com.jogamp.nativewindow.AbstractGraphicsDevice;
53import com.jogamp.nativewindow.AbstractGraphicsScreen;
54import com.jogamp.nativewindow.AbstractGraphicsConfiguration;
55import com.jogamp.nativewindow.CapabilitiesImmutable;
56import com.jogamp.nativewindow.NativeSurface;
57import com.jogamp.nativewindow.NativeWindowFactory;
58import com.jogamp.nativewindow.ProxySurface;
59import com.jogamp.nativewindow.UpstreamSurfaceHook;
60
61import jogamp.common.os.PlatformPropsImpl;
62import jogamp.opengl.Debug;
63
64/** <p> Provides a virtual machine- and operating system-independent
65 mechanism for creating {@link GLDrawable}s.
66 </p>
67 <p> The {@link com.jogamp.opengl.GLCapabilities} objects passed
68 in to the various factory methods are used as a hint for the
69 properties of the returned drawable. The default capabilities
70 selection algorithm (equivalent to passing in a null {@link
71 GLCapabilitiesChooser}) is described in {@link
72 DefaultGLCapabilitiesChooser}. Sophisticated applications needing
73 to change the selection algorithm may pass in their own {@link
74 GLCapabilitiesChooser} which can select from the available pixel
75 formats. The GLCapabilitiesChooser mechanism may not be supported
76 by all implementations or on all platforms, in which case any
77 passed GLCapabilitiesChooser will be ignored.
78 </p>
79
80 <p> Because of the multithreaded nature of the Java platform's
81 Abstract Window Toolkit, it is typically not possible to immediately
82 reject a given {@link GLCapabilities} as being unsupportable by
83 either returning <code>null</code> from the creation routines or
84 raising a {@link GLException}. The semantics of the rejection
85 process are (unfortunately) left unspecified for now. The current
86 implementation will cause a {@link GLException} to be raised
87 during the first repaint of the {@link com.jogamp.opengl.awt.GLCanvas} or {@link
88 com.jogamp.opengl.awt.GLJPanel} if the capabilities can not be met.<br>
89 {@link GLOffscreenAutoDrawable} are created lazily,
90 see {@link #createOffscreenAutoDrawable(AbstractGraphicsDevice, GLCapabilitiesImmutable, GLCapabilitiesChooser, int, int) createOffscreenAutoDrawable(..)}.
91 </p>
92
93 <p> The concrete GLDrawableFactory subclass instantiated by {@link
94 #getFactory getFactory} can be changed by setting the system
95 property <code>opengl.factory.class.name</code> to the
96 fully-qualified name of the desired class.
97 </p>
98*/
99public abstract class GLDrawableFactory {
100
101 protected static final boolean DEBUG = Debug.debug("GLDrawable");
102
103 private static volatile boolean isInit = false;
104 private static GLDrawableFactory eglFactory;
105 private static GLDrawableFactory nativeOSFactory;
106
107 private static ArrayList<GLDrawableFactory> glDrawableFactories = new ArrayList<GLDrawableFactory>();
108
109 /**
110 * Instantiate singleton factories if available, EGLES1, EGLES2 and the OS native ones.
111 */
112 public static final void initSingleton() {
113 if (!isInit) { // volatile: ok
114 synchronized (GLDrawableFactory.class) {
115 if (!isInit) {
116 isInit=true;
117 initSingletonImpl();
118 }
119 }
120 }
121 }
122 private static final void initSingletonImpl() {
124 NativeWindowFactory.addCustomShutdownHook(false /* head */, new Runnable() {
125 @Override
126 public void run() {
127 shutdown0();
128 }
129 });
130
131 final String nwt = NativeWindowFactory.getNativeWindowType(true);
132 GLDrawableFactory tmp = null;
133 String factoryClassName = PropertyAccess.getProperty("jogl.gldrawablefactory.class.name", true);
134 final ClassLoader cl = GLDrawableFactory.class.getClassLoader();
135 if (null == factoryClassName) {
136 if ( nwt == NativeWindowFactory.TYPE_X11 ) {
137 factoryClassName = "jogamp.opengl.x11.glx.X11GLXDrawableFactory";
138 } else if ( nwt == NativeWindowFactory.TYPE_WINDOWS ) {
139 factoryClassName = "jogamp.opengl.windows.wgl.WindowsWGLDrawableFactory";
140 } else if ( nwt == NativeWindowFactory.TYPE_MACOSX ) {
141 factoryClassName = "jogamp.opengl.macosx.cgl.MacOSXCGLDrawableFactory";
142 } else if ( nwt == NativeWindowFactory.TYPE_IOS ) {
143 factoryClassName = "jogamp.opengl.ios.eagl.IOSEAGLDrawableFactory";
144 } else {
145 // may use egl*Factory ..
146 if (DEBUG || GLProfile.DEBUG) {
147 System.err.println("GLDrawableFactory.static - No native Windowing Factory for: "+nwt+"; May use EGLDrawableFactory, if available." );
148 }
149 }
150 }
151 if ( !GLProfile.disableOpenGLDesktop || GLProfile.disabledEGL ) {
152 if ( null != factoryClassName ) {
153 if (DEBUG || GLProfile.DEBUG) {
154 System.err.println("GLDrawableFactory.static - Native OS Factory for: "+nwt+": "+factoryClassName);
155 }
156 try {
157 tmp = (GLDrawableFactory) ReflectionUtil.createInstance(factoryClassName, cl);
158 } catch (final Exception jre) {
159 if (DEBUG || GLProfile.DEBUG) {
160 System.err.println("Info: GLDrawableFactory.static - Native Platform: "+nwt+" - not available: "+factoryClassName);
161 jre.printStackTrace();
162 }
163 }
164 if(null != tmp && tmp.isComplete()) {
165 nativeOSFactory = tmp;
166 }
167 tmp = null;
168 } else if( DEBUG || GLProfile.DEBUG ) {
169 System.err.println("Info: GLDrawableFactory.static - Desktop GLDrawableFactory unspecified!");
170 }
171 } else if( DEBUG || GLProfile.DEBUG ) {
172 System.err.println("Info: GLDrawableFactory.static - Desktop GLDrawableFactory - disabled!");
173 }
174
175 if(!GLProfile.disableOpenGLES && !GLProfile.disabledEGL) {
176 try {
177 tmp = (GLDrawableFactory) ReflectionUtil.createInstance("jogamp.opengl.egl.EGLDrawableFactory", cl);
178 } catch (final Exception jre) {
179 if (DEBUG || GLProfile.DEBUG) {
180 System.err.println("Info: GLDrawableFactory.static - EGLDrawableFactory - not available");
181 jre.printStackTrace();
182 }
183 }
184 if(null != tmp && tmp.isComplete()) {
185 eglFactory = tmp;
186 }
187 } else if( DEBUG || GLProfile.DEBUG ) {
188 System.err.println("Info: GLDrawableFactory.static - EGLDrawableFactory - disabled!");
189 }
190 }
191
192 protected static void shutdown() {
193 if (isInit) { // volatile: ok
194 synchronized (GLDrawableFactory.class) {
195 if (isInit) {
196 isInit=false;
197 shutdown0();
198 }
199 }
200 }
201 }
202
203 private static void shutdown0() {
204 // Following code will _always_ remain in shutdown hook
205 // due to special semantics of native utils, i.e. X11Utils.
206 // The latter requires shutdown at JVM-Shutdown only.
207 synchronized(glDrawableFactories) {
208 final int gldfCount = glDrawableFactories.size();
209 if( DEBUG ) {
210 System.err.println("GLDrawableFactory.shutdownAll "+gldfCount+" instances, on thread "+getThreadName());
211 }
212 for(int i=0; i<gldfCount; i++) {
213 final GLDrawableFactory gldf = glDrawableFactories.get(i);
214 if( DEBUG ) {
215 System.err.println("GLDrawableFactory.shutdownAll["+(i+1)+"/"+gldfCount+"]: "+gldf.getClass().getName());
216 }
217 try {
218 gldf.resetAllDisplayGammaNoSync();
219 gldf.shutdownImpl();
220 } catch (final Throwable t) {
221 System.err.println("GLDrawableFactory.shutdownImpl: Caught "+t.getClass().getName()+" during factory shutdown #"+(i+1)+"/"+gldfCount+" "+gldf.getClass().getName());
222 if( DEBUG ) {
223 t.printStackTrace();
224 }
225 }
226 }
227 glDrawableFactories.clear();
228
229 // both were members of glDrawableFactories and are shutdown already
230 nativeOSFactory = null;
231 eglFactory = null;
232 }
233 GLContext.shutdown();
234 if( DEBUG ) {
235 System.err.println("GLDrawableFactory.shutdownAll.X on thread "+getThreadName());
236 }
237 }
238
239 protected GLDrawableFactory() {
240 synchronized(glDrawableFactories) {
241 glDrawableFactories.add(this);
242 }
243 }
244
245 protected static String getThreadName() { return Thread.currentThread().getName(); }
246
247 /** Returns true if this factory is complete, i.e. ready to be used. Otherwise return false. */
248 protected abstract boolean isComplete();
249
250 protected void enterThreadCriticalZone() {};
251 protected void leaveThreadCriticalZone() {};
252
253 protected abstract void shutdownImpl();
254
255 /**
256 * Sets the gamma, brightness, and contrast of the display associated with the given <code>surface</code>.
257 * <p>
258 * This functionality is not available on all platforms and
259 * graphics hardware. Returns true if the settings were successfully
260 * changed, false if not. This method may return false for some
261 * values of the incoming arguments even on hardware which does
262 * support the underlying functionality. </p>
263 * <p>
264 * If this method returns true, the display settings will
265 * automatically be reset to their original values upon JVM exit
266 * (assuming the JVM does not crash); if the user wishes to change
267 * the display settings back to normal ahead of time,
268 * use {@link #resetDisplayGamma(NativeSurface)} or {@link #resetAllDisplayGamma()}.
269 * </p>
270 * <p>
271 * It is recommended to call {@link #resetDisplayGamma(NativeSurface)} or {@link #resetAllDisplayGamma()}
272 * before calling e.g. <code>System.exit()</code> from the application rather than
273 * rely on the shutdown hook functionality due to inevitable race
274 * conditions and unspecified behavior during JVM teardown.
275 * </p>
276 * <p>
277 * This method may be called multiple times during the application's
278 * execution, but calling {@link #resetDisplayGamma(NativeSurface)}
279 * will only reset the settings to the values
280 * before the first call to this method. </p>
281 *
282 * @param surface denominates the display device
283 * @param gamma The gamma value, typically > 1.0 (default values vary, but typically roughly 1.0)
284 * @param brightness The brightness value between -1.0 and 1.0, inclusive (default values vary, but typically 0)
285 * @param contrast The contrast, greater than 0.0 (default values vary, but typically 1)
286 *
287 * @return true if gamma settings were successfully changed, false if not
288 * @throws IllegalArgumentException if any of the parameters were out-of-bounds
289 * @see #resetDisplayGamma(NativeSurface)
290 * @see #resetAllDisplayGamma()
291 */
292 public abstract boolean setDisplayGamma(final NativeSurface surface, final float gamma, final float brightness, final float contrast) throws IllegalArgumentException;
293
294 /**
295 * Resets the gamma, brightness and contrast values of the display associated with the given <code>surface</code>
296 * to its original values before {@link #setDisplayGamma(NativeSurface, float, float, float) setDisplayGamma}
297 * was called the first time.
298 * <p>
299 * While it is not explicitly required that this method be called before
300 * exiting manually, calling it is recommended because of the inevitable
301 * unspecified behavior during JVM teardown.
302 * </p>
303 */
304 public abstract void resetDisplayGamma(final NativeSurface surface);
305
306 /**
307 * Resets the gamma, brightness and contrast values of all modified
308 * displays to their original values before {@link #setDisplayGamma(NativeSurface, float, float, float) setDisplayGamma}
309 * was called the first time.
310 * <p>
311 * While it is not explicitly required that this method be called before
312 * exiting manually, calling it is recommended because of the inevitable
313 * unspecified behavior during JVM teardown.
314 * </p>
315 */
316 public abstract void resetAllDisplayGamma();
317
318 protected abstract void resetAllDisplayGammaNoSync();
319
320 /**
321 * Retrieve the default <code>device</code> {@link AbstractGraphicsDevice#getConnection() connection},
322 * {@link AbstractGraphicsDevice#getUnitID() unit ID} and {@link AbstractGraphicsDevice#getUniqueID() unique ID name}. for this factory<br>
323 * The implementation must return a non <code>null</code> default device, which must not be opened, ie. it's native handle is <code>null</code>.
324 * <p>
325 * This method shall return the default device if available
326 * even if the GLDrawableFactory is not functional and hence not compatible.
327 * The latter situation may happen because no native OpenGL implementation is available for the specific implementation.
328 * </p>
329 * @return the default shared device for this factory, eg. :0.0 on X11 desktop.
330 * @see #getIsDeviceCompatible(AbstractGraphicsDevice)
331 */
333
334 /**
335 * @param device which {@link AbstractGraphicsDevice#getConnection() connection} denotes the shared the target device, may be <code>null</code> for the platform's default device.
336 * @return true if the device is compatible with this factory, ie. if it can be used for GLDrawable creation. Otherwise false.
337 * This implies validation whether the implementation is functional.
338 *
339 * @see #getDefaultDevice()
340 */
341 public abstract boolean getIsDeviceCompatible(AbstractGraphicsDevice device);
342
344 if(null==device) {
345 device = getDefaultDevice();
346 if(null==device) {
347 throw new InternalError("no default device available");
348 }
349 if (GLProfile.DEBUG) {
350 System.err.println("Info: "+getClass().getSimpleName()+".validateDevice: using default device : "+device);
351 }
352 }
353
354 // Always validate the device,
355 // since even the default device may not be used by this factory.
356 if( !getIsDeviceCompatible(device) ) {
357 if (GLProfile.DEBUG) {
358 System.err.println("Info: "+getClass().getSimpleName()+".validateDevice: device not compatible : "+device);
359 }
360 return null;
361 }
362 return device;
363 }
364
365 /**
366 * Validate and start the shared resource runner thread if necessary and
367 * if the implementation uses it.
368 *
369 * @return the shared resource runner thread, if implementation uses it.
370 */
371 protected abstract Thread getSharedResourceThread();
372
373 /**
374 * Create the shared resource used internally as a reference for capabilities etc.
375 * <p>
376 * Returns true if a shared resource could be created
377 * for the <code>device</code> {@link AbstractGraphicsDevice#getConnection()}.<br>
378 * This does not imply a shared resource is mapped (ie. made persistent), but is available in general<br>.
379 * </p>
380 *
381 * @param device which {@link AbstractGraphicsDevice#getConnection() connection} denotes the shared the target device, may be <code>null</code> for the platform's default device.
382 * @return true if a shared resource could been created, otherwise false.
383 */
384 protected final boolean createSharedResource(final AbstractGraphicsDevice device) {
385 return createSharedResourceImpl(device);
386 }
387 protected abstract boolean createSharedResourceImpl(AbstractGraphicsDevice device);
388
389 /**
390 * Returns true if the <code>quirk</code> exist in the shared resource's context {@link GLRendererQuirks}.
391 * <p>
392 * Convenience method for:
393 * <pre>
394 final GLRendererQuirks glrq = factory.getRendererQuirks(device);
395 return null != glrq ? glrq.exist(quirk) : false;
396 * </pre>
397 * </p>
398 *
399 * @param device which {@link AbstractGraphicsDevice#getConnection() connection} denotes the shared the target device, may be <code>null</code> for the platform's default device.
400 * @param glp {@link GLProfile} to identify the device's {@link GLRendererQuirks}, maybe {@code null}
401 * @param quirk the quirk to be tested, e.g. {@link GLRendererQuirks#NoDoubleBufferedPBuffer}.
402 * @throws IllegalArgumentException if the quirk is out of range
403 * @see #getRendererQuirks(AbstractGraphicsDevice, GLProfile)
404 * @see GLRendererQuirks
405 */
406 public final boolean hasRendererQuirk(final AbstractGraphicsDevice device, final GLProfile glp, final int quirk) {
407 return GLRendererQuirks.exist(getRendererQuirks(device, glp), quirk);
408 }
409
410 /**
411 * Returns the shared resource's context {@link GLRendererQuirks}.
412 * <p>
413 * Implementation calls {@link GLContext#getRendererQuirks()} on the shared resource context.
414 * </p>
415 * <p>
416 * In case no shared device exist yet or the implementation doesn't support tracking quirks,
417 * the result is always <code>null</code>.
418 * </p>
419 * @param device which {@link AbstractGraphicsDevice#getConnection() connection} denotes the shared the target device, may be <code>null</code> for the platform's default device.
420 * @param glp {@link GLProfile} to identify the device's {@link GLRendererQuirks}, maybe {@code null}
421 * @see GLContext#getRendererQuirks()
422 * @see GLRendererQuirks
423 */
425
426 /**
427 * Method returns {@code true} if underlying implementation may support native desktop OpenGL,
428 * otherwise {@code false}.
429 */
430 public abstract boolean hasOpenGLDesktopSupport();
431
432 /**
433 * Method returns {@code true} if underlying implementation may support native embedded OpenGL ES,
434 * otherwise {@code false}.
435 */
436 public abstract boolean hasOpenGLESSupport();
437
438 /**
439 * Returns the sole GLDrawableFactory instance for the desktop (X11, WGL, ..) if exist or null
440 * <p>
441 * To fetch the appropriate {@link GLDrawableFactory} for native desktop
442 * or mobile, use {@link #getFactory(boolean)}.
443 * </p>
444 * <p>
445 * It is possible that the desktop {@link GLDrawableFactory} will be used for
446 * native mobile GL profiles, e.g. {@link Platform.OSType#IOS}.
447 * </p>
448 * @return the matching {@link GLDrawableFactory} or {@code null} if none is available
449 */
452 return nativeOSFactory;
453 }
454
455 /**
456 * Returns the sole {@link GLDrawableFactory} instance for EGL if exist or null.
457 * <p>
458 * To fetch the appropriate {@link GLDrawableFactory} for native desktop
459 * or mobile, use {@link #getFactory(boolean)}.
460 * </p>
461 * <p>
462 * It is possible that a non EGL {@link GLDrawableFactory} will be used for
463 * native mobile GL profiles, e.g. {@link Platform.OSType#IOS}.
464 * </p>
465 * @return the matching {@link GLDrawableFactory} or {@code null} if none is available
466 */
469 return eglFactory;
470 }
471
472 /**
473 * Returns the sole {@link GLDrawableFactory} instance.
474 *
475 * @param glProfile GLProfile to determine the factory type, ie for native mobile GL or native desktop GL.
476 * @return the matching {@link GLDrawableFactory}
477 * @throws GLException if no matching {@link GLDrawableFactory} exists
478 */
479 public static GLDrawableFactory getFactory(final GLProfile glProfile) throws GLException {
480 final GLDrawableFactory f = getFactoryImpl(glProfile.getImplName());
481 if( null != f ) {
482 return f;
483 }
484 throw new GLException("No GLDrawableFactory available for profile: "+glProfile);
485 }
486 /**
487 * Returns the sole {@link GLDrawableFactory} instance, either for mobile if {@code usesNativeGLES} is true,
488 * or for desktop otherwise.
489 * @param useNativeGLES request native mobile GLES support if true
490 * @return the matching {@link GLDrawableFactory} or {@code null} if none is available
491 */
492 public static GLDrawableFactory getFactory(final boolean useNativeGLES) {
494 return getFactoryImpl( useNativeGLES );
495 }
496 protected static GLDrawableFactory getFactoryImpl(final String glProfileImplName) {
497 return getFactoryImpl( GLProfile.usesNativeGLES(glProfileImplName) );
498 }
499 protected static GLDrawableFactory getFactoryImpl(final boolean useNativeGLES) {
500 if( useNativeGLES ) {
501 if(null!=eglFactory && eglFactory.hasOpenGLESSupport() ) {
502 return eglFactory;
503 }
504 if(null!=nativeOSFactory && nativeOSFactory.hasOpenGLESSupport() ) {
505 return nativeOSFactory;
506 }
507 } else {
508 if(null!=nativeOSFactory && nativeOSFactory.hasOpenGLDesktopSupport() ) {
509 return nativeOSFactory;
510 }
511 }
512 return null;
513 }
514 /**
515 * Returns the sole {@link GLDrawableFactory} matching the given {@link AbstractGraphicsDevice} instance,
516 * which will be suitable either for native mobile or native desktop.
517 * @param device the queries {@link AbstractGraphicsDevice} seeking for its matching factory
518 * @return the matching {@link GLDrawableFactory} or {@code null} if none is available
519 */
521 if(null != nativeOSFactory && nativeOSFactory.getIsDeviceCompatible(device)) {
522 return nativeOSFactory;
523 }
524 if(null != eglFactory && eglFactory.getIsDeviceCompatible(device)) {
525 return eglFactory;
526 }
527 return null;
528 }
529
530 /**
531 * Returns an array of available GLCapabilities for the device.<br>
532 * The list is sorted by the native ID, ascending.<br>
533 * The chosen GLProfile statement in the result may not refer to the maximum available profile
534 * due to implementation constraints, ie using the shared resource.
535 *
536 * @param device which {@link AbstractGraphicsDevice#getConnection() connection} denotes the shared the target device, may be <code>null</code> for the platform's default device.
537 * @return A list of {@link com.jogamp.opengl.GLCapabilitiesImmutable}'s, maybe empty if none is available.
538 */
539 public final List<GLCapabilitiesImmutable> getAvailableCapabilities(AbstractGraphicsDevice device) {
540 device = validateDevice(device);
541 if(null!=device) {
542 return getAvailableCapabilitiesImpl(device);
543 }
544 return null;
545 }
546 protected abstract List<GLCapabilitiesImmutable> getAvailableCapabilitiesImpl(AbstractGraphicsDevice device);
547
548 //----------------------------------------------------------------------
549 // Methods to create high-level objects
550
551 /**
552 * Returns an {@link GLDrawable#isRealized() unrealized} GLDrawable according to it's chosen {@link GLCapabilitiesImmutable},<br>
553 * which determines pixel format, on- and offscreen incl. PBuffer type.
554 * <p>
555 * The chosen {@link GLCapabilitiesImmutable} are referenced within the target
556 * {@link NativeSurface}'s {@link AbstractGraphicsConfiguration}.<p>
557 * </p>
558 * <p>
559 * An onscreen GLDrawable is created if {@link CapabilitiesImmutable#isOnscreen() caps.isOnscreen()} is true.
560 * </p>
561 * <p>
562 * A FBO drawable is created if both {@link GLCapabilitiesImmutable#isFBO() caps.isFBO()}
563 * and {@link GLContext#isFBOAvailable(AbstractGraphicsDevice, GLProfile) canCreateFBO(device, caps.getGLProfile())} is true.
564 * </p>
565 * <p>
566 * A Pbuffer drawable is created if both {@link GLCapabilitiesImmutable#isPBuffer() caps.isPBuffer()}
567 * and {@link #canCreateGLPbuffer(AbstractGraphicsDevice, GLProfile) canCreateGLPbuffer(device)} is true.
568 * </p>
569 * <p>
570 * If not onscreen and neither FBO nor Pbuffer is available,
571 * a simple pixmap/bitmap drawable/surface is created, which is unlikely to be hardware accelerated.
572 * </p>
573 *
574 * @throws IllegalArgumentException if the passed target is null
575 * @throws GLException if any window system-specific errors caused
576 * the creation of the GLDrawable to fail.
577 *
578 * @see #canCreateGLPbuffer(AbstractGraphicsDevice, GLProfile)
579 * @see GLContext#isFBOAvailable(AbstractGraphicsDevice, GLProfile)
580 * @see com.jogamp.opengl.GLCapabilities#isOnscreen()
581 * @see com.jogamp.opengl.GLCapabilities#isFBO()
582 * @see com.jogamp.opengl.GLCapabilities#isPBuffer()
583 * @see GraphicsConfigurationFactory#chooseGraphicsConfiguration(CapabilitiesImmutable, CapabilitiesImmutable, CapabilitiesChooser, AbstractGraphicsScreen, int)
584 */
586 throws IllegalArgumentException, GLException;
587
588 /**
589 * Creates a {@link GLDrawable#isRealized() realized} {@link GLOffscreenAutoDrawable}
590 * incl it's offscreen {@link NativeSurface} with the given capabilities and dimensions.
591 * <p>
592 * The {@link GLOffscreenAutoDrawable}'s {@link GLDrawable} is {@link GLDrawable#isRealized() realized}
593 * <i>without</i> an assigned {@link GLContext}, hence not initialized completely.<br>
594 *
595 * The {@link GLContext} can be assigned later manually via {@link GLAutoDrawable#setContext(GLContext, boolean) setContext(ctx)}
596 * <i>or</i> it will be created <i>lazily</i> at the 1st {@link GLAutoDrawable#display() display()} method call.<br>
597 *
598 * <i>Lazy</i> {@link GLContext} creation will take a shared {@link GLContext} into account
599 * which has been set {@link GLOffscreenAutoDrawable#setSharedContext(GLContext) directly}
600 * or {@link GLOffscreenAutoDrawable#setSharedAutoDrawable(GLAutoDrawable) via another GLAutoDrawable}.
601 * </p>
602 * <p>
603 * In case the passed {@link GLCapabilitiesImmutable} contains default values, i.e.
604 * {@link GLCapabilitiesImmutable#isOnscreen() caps.isOnscreen()} <code> == true</code>,
605 * it is auto-configured. Auto configuration will set {@link GLCapabilitiesImmutable caps} to offscreen
606 * and FBO <i>or</i> Pbuffer, whichever is available in that order.
607 * </p>
608 * <p>
609 * A FBO based auto drawable, {@link GLOffscreenAutoDrawable.FBO}, is created if both {@link GLCapabilitiesImmutable#isFBO() caps.isFBO()}
610 * and {@link GLContext#isFBOAvailable(AbstractGraphicsDevice, GLProfile) canCreateFBO(device, caps.getGLProfile())} is true.
611 * </p>
612 * <p>
613 * A Pbuffer based auto drawable is created if both {@link GLCapabilitiesImmutable#isPBuffer() caps.isPBuffer()}
614 * and {@link #canCreateGLPbuffer(AbstractGraphicsDevice, GLProfile) canCreateGLPbuffer(device)} is true.
615 * </p>
616 * <p>
617 * If neither FBO nor Pbuffer is available,
618 * a simple pixmap/bitmap auto drawable is created, which is unlikely to be hardware accelerated.
619 * </p>
620 * <p>
621 * The resulting {@link GLOffscreenAutoDrawable} has it's own independent device instance using <code>device</code> details.
622 * </p>
623 *
624 * @param device which {@link AbstractGraphicsDevice#getConnection() connection} denotes the shared device to be used, may be <code>null</code> for the platform's default device.
625 * @param caps the requested GLCapabilties
626 * @param chooser the custom chooser, may be null for default
627 * @param width the requested offscreen width
628 * @param height the requested offscreen height
629 * @return the created and realized offscreen {@link GLOffscreenAutoDrawable} instance
630 *
631 * @throws GLException if any window system-specific errors caused
632 * the creation of the Offscreen to fail.
633 *
634 * @see #createOffscreenDrawable(AbstractGraphicsDevice, GLCapabilitiesImmutable, GLCapabilitiesChooser, int, int)
635 */
638 GLCapabilitiesChooser chooser,
639 int width, int height) throws GLException;
640
641 /**
642 * Creates a {@link GLDrawable#isRealized() realized} <i>dummy</i> {@link GLAutoDrawable}
643 * incl it's <i>dummy, invisible</i> {@link NativeSurface}
644 * as created with {@link #createDummyDrawable(AbstractGraphicsDevice, boolean, GLCapabilitiesImmutable, GLCapabilitiesChooser)}.
645 * <p>
646 * The <i>dummy</i> {@link GLAutoDrawable}'s {@link GLDrawable} is {@link GLDrawable#isRealized() realized}
647 * <i>without</i> an assigned {@link GLContext}, hence not initialized completely.<br>
648 * The {@link GLContext} can be assigned later manually via {@link GLAutoDrawable#setContext(GLContext, boolean) setContext(ctx)}
649 * <i>or</i> it will be created <i>lazily</i> at the 1st {@link GLAutoDrawable#display() display()} method call.<br>
650 * <i>Lazy</i> {@link GLContext} creation will take a shared {@link GLContext} into account
651 * which has been set {@link GLOffscreenAutoDrawable#setSharedContext(GLContext) directly}
652 * or {@link GLOffscreenAutoDrawable#setSharedAutoDrawable(GLAutoDrawable) via another GLAutoDrawable}.
653 * </p>
654 *
655 * @param deviceReq which {@link AbstractGraphicsDevice#getConnection() connection} denotes the shared device to be used, may be <code>null</code> for the platform's default device.
656 * @param createNewDevice if <code>true</code> a new independent device instance is created from the <code>deviceReq</code>, otherwise <code>deviceReq</code> is used as-is and must be valid!
657 * @param capsRequested the desired {@link GLCapabilitiesImmutable}, incl. it's {@link GLProfile}.
658 * For shared context, same {@link GLCapabilitiesImmutable#getVisualID(com.jogamp.nativewindow.VisualIDHolder.VIDType)}
659 * across shared drawables will yield best compatibility.
660 * @param chooser the custom chooser, may be null for default
661 * @return the created and realized <i>dummy</i> {@link GLAutoDrawable} instance
662 *
663 * @see #createDummyDrawable(AbstractGraphicsDevice, boolean, GLCapabilitiesImmutable, GLCapabilitiesChooser)
664 */
665 public abstract GLAutoDrawable createDummyAutoDrawable(AbstractGraphicsDevice deviceReq, boolean createNewDevice, GLCapabilitiesImmutable capsRequested, GLCapabilitiesChooser chooser);
666
667 /**
668 * Creates an {@link GLDrawable#isRealized() unrealized} offscreen {@link GLDrawable}
669 * incl it's offscreen {@link NativeSurface} with the given capabilities and dimensions.
670 * <p>
671 * In case the passed {@link GLCapabilitiesImmutable} contains default values, i.e.
672 * {@link GLCapabilitiesImmutable#isOnscreen() caps.isOnscreen()} <code> == true</code>,
673 * it is auto-configured. The latter will set offscreen and also FBO <i>or</i> Pbuffer, whichever is available in that order.
674 * </p>
675 * <p>
676 * A resizeable FBO drawable, {@link GLFBODrawable.Resizeable}, is created if both {@link GLCapabilitiesImmutable#isFBO() caps.isFBO()}
677 * and {@link GLContext#isFBOAvailable(AbstractGraphicsDevice, GLProfile) canCreateFBO(device, caps.getGLProfile())} is true.
678 * </p>
679 * <p>
680 * A Pbuffer drawable is created if both {@link GLCapabilitiesImmutable#isPBuffer() caps.isPBuffer()}
681 * and {@link #canCreateGLPbuffer(AbstractGraphicsDevice, GLProfile) canCreateGLPbuffer(device)} is true.
682 * </p>
683 * <p>
684 * If neither FBO nor Pbuffer is available,
685 * a simple pixmap/bitmap drawable is created, which is unlikely to be hardware accelerated.
686 * </p>
687 * <p>
688 * The resulting {@link GLDrawable} has it's own independent device instance using <code>device</code> details.
689 * </p>
690 *
691 * @param device which {@link AbstractGraphicsDevice#getConnection() connection} denotes the shared device to be used, may be <code>null</code> for the platform's default device.
692 * @param caps the requested GLCapabilties
693 * @param chooser the custom chooser, may be null for default
694 * @param width the requested offscreen width
695 * @param height the requested offscreen height
696 *
697 * @return the created unrealized offscreen {@link GLDrawable}
698 *
699 * @throws GLException if any window system-specific errors caused
700 * the creation of the Offscreen to fail.
701 *
702 * @see #createOffscreenAutoDrawable(AbstractGraphicsDevice, GLCapabilitiesImmutable, GLCapabilitiesChooser, int, int, GLContext)
703 */
706 GLCapabilitiesChooser chooser,
707 int width, int height) throws GLException;
708
709 /**
710 * Creates an {@link GLDrawable#isRealized() unrealized} dummy {@link GLDrawable}.
711 * A dummy drawable is not visible on screen and will not be used to render directly to, it maybe on- or offscreen and implementation prefers creating a surfaceless drawable.
712 * <p>
713 * It is used to allow the creation of a {@link GLContext} to query information.
714 * It also allows creation of framebuffer objects which are used for rendering or creating a shared GLContext w/o actually rendering to this dummy drawable's framebuffer.
715 * </p>
716 * @param deviceReq which {@link AbstractGraphicsDevice#getConnection() connection} denotes the shared device to be used, may be <code>null</code> for the platform's default device.
717 * @param createNewDevice if <code>true</code> a new independent device instance is created from the <code>deviceReq</code>, otherwise <code>deviceReq</code> is used as-is and must be valid!
718 * @param capsRequested the desired {@link GLCapabilitiesImmutable}, incl. it's {@link GLProfile}.
719 * For shared context, same {@link GLCapabilitiesImmutable#getVisualID(com.jogamp.nativewindow.VisualIDHolder.VIDType) visual ID}
720 * or {@link GLCapabilitiesImmutable caps}
721 * across shared drawables will yield best compatibility.
722 * @param chooser the custom chooser, may be null for default
723 * @return the created unrealized dummy {@link GLDrawable}
724 */
725 public abstract GLDrawable createDummyDrawable(AbstractGraphicsDevice deviceReq, boolean createNewDevice, GLCapabilitiesImmutable capsRequested, GLCapabilitiesChooser chooser);
726
727 /**
728 * Creates a proxy {@link NativeSurface} w/ defined surface handle,
729 * i.e. a {@link jogamp.nativewindow.WrappedSurface} or {@link jogamp.nativewindow.windows.GDISurface} instance.
730 * <p>
731 * It's {@link AbstractGraphicsConfiguration} is properly set according to the given
732 * <code>windowHandle</code>'s native visualID if set or the given {@link GLCapabilitiesImmutable}.
733 * </p>
734 * <p>
735 * Lifecycle (creation and destruction) of the given surface handle shall be handled by the caller
736 * via {@link ProxySurface#createNotify()} and {@link ProxySurface#destroyNotify()}.
737 * </p>
738 * <p>
739 * Such surface can be used to instantiate a GLDrawable. With the help of {@link GLAutoDrawableDelegate}
740 * you will be able to implement a new native windowing system binding almost on-the-fly,
741 * see {@link com.jogamp.opengl.swt.GLCanvas}.
742 * </p>
743 * <p>
744 * The resulting {@link GLOffscreenAutoDrawable} has it's own independent device instance using <code>device</code> details
745 * which may be blocking depending on platform and windowing-toolkit requirements.
746 * </p>
747 *
748 * @param device which {@link AbstractGraphicsDevice#getConnection() connection} denotes the shared the target device, may be <code>null</code> for the platform's default device.
749 * Caller has to ensure it is compatible w/ the given <code>windowHandle</code>
750 * @param screenIdx matching screen index of given <code>windowHandle</code>
751 * @param windowHandle the native window handle
752 * @param caps the requested GLCapabilties
753 * @param chooser the custom chooser, may be null for default
754 * @param upstream optional {@link UpstreamSurfaceHook} allowing control of the {@link ProxySurface}'s lifecycle and data it presents.
755 * @return the created {@link ProxySurface} instance w/ defined surface handle.
756 */
758 int screenIdx,
759 long windowHandle,
761
762 /**
763 * Returns true if it is possible to create an <i>framebuffer object</i> (FBO).
764 * <p>
765 * FBO feature is implemented in OpenGL, hence it is {@link GLProfile} dependent.
766 * </p>
767 * <p>
768 * FBO support is queried as described in {@link GLContext#hasBasicFBOSupport()}.
769 * </p>
770 *
771 * @param device which {@link AbstractGraphicsDevice#getConnection() connection} denotes the shared the target device, may be <code>null</code> for the platform's default device.
772 * @param glp {@link GLProfile} to check for FBO capabilities
773 * @see GLContext#hasBasicFBOSupport()
774 */
775 public abstract boolean canCreateFBO(AbstractGraphicsDevice device, GLProfile glp);
776
777 /**
778 * Returns true if it is possible to create an <i>pbuffer surface</i>.
779 * <p>
780 * Some older graphics cards do not have this capability,
781 * as well as some new GL implementation, i.e. OpenGL 3 core on OSX.
782 * </p>
783 *
784 * @param device which {@link AbstractGraphicsDevice#getConnection() connection} denotes the shared the target device, may be <code>null</code> for the platform's default device.
785 * @param glp {@link GLProfile} to check for FBO capabilities
786 */
787 public abstract boolean canCreateGLPbuffer(AbstractGraphicsDevice device, GLProfile glp);
788
789 //----------------------------------------------------------------------
790 // Methods for interacting with third-party OpenGL libraries
791
792 /**
793 * <P> Creates a GLContext object representing an existing OpenGL
794 * context in an external (third-party) OpenGL-based library. This
795 * GLContext object may be used to draw into this preexisting
796 * context using its {@link GL} and {@link
797 * com.jogamp.opengl.glu.GLU} objects. New contexts created through
798 * {@link GLDrawable}s may share textures and display lists with
799 * this external context. </P>
800 *
801 * <P> The underlying OpenGL context must be current on the current
802 * thread at the time this method is called. The user is responsible
803 * for the maintenance of the underlying OpenGL context; calls to
804 * <code>makeCurrent</code> and <code>release</code> on the returned
805 * GLContext object have no effect. If the underlying OpenGL context
806 * is destroyed, the <code>destroy</code> method should be called on
807 * the <code>GLContext</code>. A new <code>GLContext</code> object
808 * should be created for each newly-created underlying OpenGL
809 * context.
810 *
811 * @throws GLException if any window system-specific errors caused
812 * the creation of the external GLContext to fail.
813 */
815 throws GLException;
816
817 /**
818 * Returns true if it is possible to create an external GLDrawable
819 * object via {@link #createExternalGLDrawable}.
820 *
821 * @param device which {@link AbstractGraphicsDevice#getConnection() connection} denotes the shared the target device, may be <code>null</code> for the platform's default device.
822 */
824
825 /**
826 * <P> Creates a {@link GLDrawable} object representing an existing
827 * OpenGL drawable in an external (third-party) OpenGL-based
828 * library. This GLDrawable object may be used to create new,
829 * fully-functional {@link GLContext}s on the OpenGL drawable. This
830 * is useful when interoperating with a third-party OpenGL-based
831 * library and it is essential to not perturb the state of the
832 * library's existing context, even to the point of not sharing
833 * textures or display lists with that context. </P>
834 *
835 * <P> An underlying OpenGL context must be current on the desired
836 * drawable and the current thread at the time this method is
837 * called. The user is responsible for the maintenance of the
838 * underlying drawable. If one or more contexts are created on the
839 * drawable using {@link GLDrawable#createContext}, and the drawable
840 * is deleted by the third-party library, the user is responsible
841 * for calling {@link GLContext#destroy} on these contexts. </P>
842 *
843 * <P> Calls to <code>setSize</code>, <code>getWidth</code> and
844 * <code>getHeight</code> are illegal on the returned GLDrawable. If
845 * these operations are required by the user, they must be performed
846 * by the third-party library. </P>
847 *
848 * <P> It is legal to create both an external GLContext and
849 * GLDrawable representing the same third-party OpenGL entities.
850 * This can be used, for example, to query current state information
851 * using the external GLContext and then create and set up new
852 * GLContexts using the external GLDrawable. </P>
853 *
854 * <P> This functionality may not be available on all platforms and
855 * {@link #canCreateExternalGLDrawable} should be called first to
856 * see if it is present. For example, on X11 platforms, this API
857 * requires the presence of GLX 1.3 or later.
858 *
859 * @throws GLException if any window system-specific errors caused
860 * the creation of the external GLDrawable to fail.
861 */
863 throws GLException;
864}
Provides a pluggable mechanism for arbitrary window toolkits to adapt their components to the NativeW...
static synchronized void initSingleton()
Static one time initialization of this factory.
static void addCustomShutdownHook(final boolean head, final Runnable runnable)
Add a custom shutdown hook to be performed at JVM shutdown before shutting down NativeWindowFactory i...
Abstraction for an OpenGL rendering context.
Definition: GLContext.java:74
static GLDrawableFactory getFactory(final boolean useNativeGLES)
Returns the sole GLDrawableFactory instance, either for mobile if usesNativeGLES is true,...
static GLDrawableFactory getEGLFactory()
Returns the sole GLDrawableFactory instance for EGL if exist or null.
abstract boolean createSharedResourceImpl(AbstractGraphicsDevice device)
abstract boolean canCreateExternalGLDrawable(AbstractGraphicsDevice device)
Returns true if it is possible to create an external GLDrawable object via createExternalGLDrawable.
abstract GLOffscreenAutoDrawable createOffscreenAutoDrawable(AbstractGraphicsDevice device, GLCapabilitiesImmutable caps, GLCapabilitiesChooser chooser, int width, int height)
Creates a realized GLOffscreenAutoDrawable incl it's offscreen NativeSurface with the given capabilit...
abstract boolean hasOpenGLDesktopSupport()
Method returns true if underlying implementation may support native desktop OpenGL,...
abstract boolean hasOpenGLESSupport()
Method returns true if underlying implementation may support native embedded OpenGL ES,...
abstract boolean canCreateGLPbuffer(AbstractGraphicsDevice device, GLProfile glp)
Returns true if it is possible to create an pbuffer surface.
abstract boolean getIsDeviceCompatible(AbstractGraphicsDevice device)
static GLDrawableFactory getFactoryImpl(final boolean useNativeGLES)
abstract void resetDisplayGamma(final NativeSurface surface)
Resets the gamma, brightness and contrast values of the display associated with the given surface to ...
abstract GLDrawable createExternalGLDrawable()
final AbstractGraphicsDevice validateDevice(AbstractGraphicsDevice device)
abstract GLDrawable createOffscreenDrawable(AbstractGraphicsDevice device, GLCapabilitiesImmutable caps, GLCapabilitiesChooser chooser, int width, int height)
Creates an unrealized offscreen GLDrawable incl it's offscreen NativeSurface with the given capabilit...
abstract GLContext createExternalGLContext()
final List< GLCapabilitiesImmutable > getAvailableCapabilities(AbstractGraphicsDevice device)
Returns an array of available GLCapabilities for the device.
static GLDrawableFactory getDesktopFactory()
Returns the sole GLDrawableFactory instance for the desktop (X11, WGL, ..) if exist or null.
abstract void resetAllDisplayGammaNoSync()
abstract ProxySurface createProxySurface(AbstractGraphicsDevice device, int screenIdx, long windowHandle, GLCapabilitiesImmutable caps, GLCapabilitiesChooser chooser, UpstreamSurfaceHook upstream)
Creates a proxy NativeSurface w/ defined surface handle, i.e.
abstract AbstractGraphicsDevice getDefaultDevice()
Retrieve the default device connection, unit ID and unique ID name.
static GLDrawableFactory getFactory(final AbstractGraphicsDevice device)
Returns the sole GLDrawableFactory matching the given AbstractGraphicsDevice instance,...
abstract List< GLCapabilitiesImmutable > getAvailableCapabilitiesImpl(AbstractGraphicsDevice device)
static final void initSingleton()
Instantiate singleton factories if available, EGLES1, EGLES2 and the OS native ones.
abstract Thread getSharedResourceThread()
Validate and start the shared resource runner thread if necessary and if the implementation uses it.
abstract GLDrawable createGLDrawable(NativeSurface target)
Returns an unrealized GLDrawable according to it's chosen GLCapabilitiesImmutable,...
abstract GLDrawable createDummyDrawable(AbstractGraphicsDevice deviceReq, boolean createNewDevice, GLCapabilitiesImmutable capsRequested, GLCapabilitiesChooser chooser)
Creates an unrealized dummy GLDrawable.
final boolean createSharedResource(final AbstractGraphicsDevice device)
Create the shared resource used internally as a reference for capabilities etc.
abstract void resetAllDisplayGamma()
Resets the gamma, brightness and contrast values of all modified displays to their original values be...
static GLDrawableFactory getFactory(final GLProfile glProfile)
Returns the sole GLDrawableFactory instance.
abstract boolean canCreateFBO(AbstractGraphicsDevice device, GLProfile glp)
Returns true if it is possible to create an framebuffer object (FBO).
abstract boolean isComplete()
Returns true if this factory is complete, i.e.
abstract GLAutoDrawable createDummyAutoDrawable(AbstractGraphicsDevice deviceReq, boolean createNewDevice, GLCapabilitiesImmutable capsRequested, GLCapabilitiesChooser chooser)
Creates a realized dummy GLAutoDrawable incl it's dummy, invisible NativeSurface as created with crea...
final boolean hasRendererQuirk(final AbstractGraphicsDevice device, final GLProfile glp, final int quirk)
Returns true if the quirk exist in the shared resource's context GLRendererQuirks.
static GLDrawableFactory getFactoryImpl(final String glProfileImplName)
abstract GLRendererQuirks getRendererQuirks(AbstractGraphicsDevice device, final GLProfile glp)
Returns the shared resource's context GLRendererQuirks.
abstract boolean setDisplayGamma(final NativeSurface surface, final float gamma, final float brightness, final float contrast)
Sets the gamma, brightness, and contrast of the display associated with the given surface.
A generic exception for OpenGL errors used throughout the binding as a substitute for RuntimeExceptio...
Specifies the the OpenGL profile.
Definition: GLProfile.java:77
static boolean usesNativeGLES(final String profileImpl)
Indicates whether either of the native OpenGL ES profiles are in use.
static final boolean DEBUG
Definition: GLProfile.java:79
static void initSingleton()
Static initialization of JOGL.
Definition: GLProfile.java:204
GLRendererQuirks contains information of known bugs of various GL renderer.
final boolean exist(final int quirkBit)
Method tests whether the given quirk exists.
A interface describing a graphics device in a toolkit-independent manner.
Provides low-level information required for hardware-accelerated rendering using a surface in a platf...
Provides a mutable NativeSurface, i.e.
Interface allowing upstream caller to pass lifecycle actions and size info to a ProxySurface instance...
A higher-level abstraction than GLDrawable which supplies an event based mechanism (GLEventListener) ...
Provides a mechanism by which applications can customize the window type selection for a given GLCapa...
Specifies an immutable set of OpenGL capabilities.
An abstraction for an OpenGL rendering target.
Definition: GLDrawable.java:51
Platform-independent GLAutoDrawable specialization, exposing offscreen functionality.