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 41 package com.jogamp.opengl; 42 43 import java.nio.IntBuffer; 44 import java.util.HashMap; 45 import java.util.IdentityHashMap; 46 import java.util.Iterator; 47 import java.util.List; 48 import java.util.Set; 49 50 import com.jogamp.nativewindow.AbstractGraphicsDevice; 51 import com.jogamp.nativewindow.NativeSurface; 52 53 import jogamp.opengl.Debug; 54 import jogamp.opengl.GLContextImpl; 55 import jogamp.opengl.GLContextShareSet; 56 57 import com.jogamp.common.os.Platform; 58 import com.jogamp.common.util.VersionNumber; 59 import com.jogamp.common.util.VersionNumberString; 60 import com.jogamp.common.util.locks.LockFactory; 61 import com.jogamp.common.util.locks.RecursiveLock; 62 import com.jogamp.opengl.GLExtensions; 63 import com.jogamp.opengl.GLRendererQuirks; 64 65 /** Abstraction for an OpenGL rendering context. In order to perform 66 OpenGL rendering, a context must be "made current" on the current 67 thread. OpenGL rendering semantics specify that only one context 68 may be current on the current thread at any given time, and also 69 that a given context may be current on only one thread at any 70 given time. Because components can be added to and removed from 71 the component hierarchy at any time, it is possible that the 72 underlying OpenGL context may need to be destroyed and recreated 73 multiple times over the lifetime of a given component. This 74 process is handled by the implementation, and the GLContext 75 abstraction provides a stable object which clients can use to 76 refer to a given context. */ 77 public abstract class GLContext { 78 79 public static final boolean DEBUG = Debug.debug("GLContext"); 80 public static final boolean TRACE_SWITCH = Debug.isPropertyDefined("jogl.debug.GLContext.TraceSwitch", true); 81 public static final boolean DEBUG_TRACE_SWITCH = DEBUG || TRACE_SWITCH; 82 83 /** 84 * If <code>true</code> (default), bootstrapping the available GL profiles 85 * will use the highest compatible GL context for each profile, 86 * hence skipping querying lower profiles if a compatible higher one is found: 87 * <ul> 88 * <li>4.2-core -> 4.2-core, 3.3-core</li> 89 * <li>4.2-comp -> 4.2-comp, 3.3-comp, 2</li> 90 * </ul> 91 * Otherwise the dedicated GL context would be queried and used: 92 * <ul> 93 * <li>4.2-core -> 4.2-core</li> 94 * <li>3.3-core -> 3.3-core</li> 95 * <li>4.2-comp -> 4.2-comp</li> 96 * <li>3.3-comp -> 3.3-comp</li> 97 * <li>3.0-comp -> 2</li> 98 * </ul> 99 * Using aliasing speeds up initialization about: 100 * <ul> 101 * <li>Linux x86_64 - Nvidia: 28%, 700ms down to 500ms</li> 102 * <li>Linux x86_64 - AMD : 40%, 1500ms down to 900ms</li> 103 * <p> 104 * Can be turned off with property <code>jogl.debug.GLContext.NoProfileAliasing</code>. 105 * </p> 106 */ 107 public static final boolean PROFILE_ALIASING = !Debug.isPropertyDefined("jogl.debug.GLContext.NoProfileAliasing", true); 108 109 protected static final boolean FORCE_NO_FBO_SUPPORT = Debug.isPropertyDefined("jogl.fbo.force.none", true); 110 protected static final boolean FORCE_MIN_FBO_SUPPORT = Debug.isPropertyDefined("jogl.fbo.force.min", true); 111 protected static final boolean FORCE_NO_COLOR_RENDERBUFFER = Debug.isPropertyDefined("jogl.fbo.force.nocolorrenderbuffer", true); 112 113 /** Reflects property jogl.debug.DebugGL. If true, the debug pipeline is enabled at context creation. */ 114 public static final boolean DEBUG_GL = Debug.isPropertyDefined("jogl.debug.DebugGL", true); 115 /** Reflects property jogl.debug.TraceGL. If true, the trace pipeline is enabled at context creation. */ 116 public static final boolean TRACE_GL = Debug.isPropertyDefined("jogl.debug.TraceGL", true); 117 118 /** Indicates that the context was not made current during the last call to {@link #makeCurrent makeCurrent}, value {@value}. */ 119 public static final int CONTEXT_NOT_CURRENT = 0; 120 /** Indicates that the context was made current during the last call to {@link #makeCurrent makeCurrent}, value {@value}. */ 121 public static final int CONTEXT_CURRENT = 1; 122 /** Indicates that a newly-created context was made current during the last call to {@link #makeCurrent makeCurrent}, value {@value}. */ 123 public static final int CONTEXT_CURRENT_NEW = 2; 124 125 /** Version 1.00, i.e. GLSL 1.00 for ES 2.0. */ 126 public static final VersionNumber Version1_0 = new VersionNumber(1, 0, 0); 127 /** Version 1.10, i.e. GLSL 1.10 for GL 2.0. */ 128 public static final VersionNumber Version1_10 = new VersionNumber(1, 10, 0); 129 /** Version 1.20, i.e. GLSL 1.20 for GL 2.1. */ 130 public static final VersionNumber Version1_20 = new VersionNumber(1, 20, 0); 131 /** Version 1.30, i.e. GLSL 1.30 for GL 3.0. */ 132 public static final VersionNumber Version1_30 = new VersionNumber(1, 30, 0); 133 /** Version 1.40, i.e. GLSL 1.40 for GL 3.1. */ 134 public static final VersionNumber Version1_40 = new VersionNumber(1, 40, 0); 135 /** Version 1.50, i.e. GLSL 1.50 for GL 3.2. */ 136 public static final VersionNumber Version1_50 = new VersionNumber(1, 50, 0); 137 138 /** Version 1.1, i.e. GL 1.1 */ 139 public static final VersionNumber Version1_1 = new VersionNumber(1, 1, 0); 140 141 /** Version 1.2, i.e. GL 1.2 */ 142 public static final VersionNumber Version1_2 = new VersionNumber(1, 2, 0); 143 144 /** Version 1.4, i.e. GL 1.4 */ 145 public static final VersionNumber Version1_4 = new VersionNumber(1, 4, 0); 146 147 /** Version 1.5, i.e. GL 1.5 */ 148 public static final VersionNumber Version1_5 = new VersionNumber(1, 5, 0); 149 150 /** Version 3.0. As an OpenGL version, it qualifies for desktop {@link #isGL2()} only, or ES 3.0. Or GLSL 3.00 for ES 3.0. */ 151 public static final VersionNumber Version3_0 = new VersionNumber(3, 0, 0); 152 153 /** Version 3.1. As an OpenGL version, it qualifies for {@link #isGL3core()}, {@link #isGL3bc()} and {@link #isGL3()} */ 154 public static final VersionNumber Version3_1 = new VersionNumber(3, 1, 0); 155 156 /** Version 3.2. As an OpenGL version, it qualifies for geometry shader */ 157 public static final VersionNumber Version3_2 = new VersionNumber(3, 2, 0); 158 159 /** Version 4.3. As an OpenGL version, it qualifies for <code>GL_ARB_ES3_compatibility</code> */ 160 public static final VersionNumber Version4_3 = new VersionNumber(4, 3, 0); 161 162 protected static final VersionNumber Version8_0 = new VersionNumber(8, 0, 0); 163 164 private static final String S_EMPTY = ""; 165 166 // 167 // Cached keys, bits [0..15] 168 // 169 170 /** Context option bits, full bit mask covering 16 bits [0..15], i.e. <code>0x0000FFFF</code>, {@value}. */ 171 protected static final int CTX_IMPL_FULL_MASK = 0x0000FFFF; 172 173 /** Context option bits, cached bit mask covering 10 bits [0..9], i.e. <code>0x000003FF</code>, {@value}. Leaving 6 bits for non cached options, i.e. 10:6. */ 174 protected static final int CTX_IMPL_CACHE_MASK = 0x000003FF; 175 176 /** <code>ARB_create_context</code> related: created via ARB_create_context. Cache key value. See {@link #getAvailableContextProperties(AbstractGraphicsDevice, GLProfile)}. */ 177 protected static final int CTX_IS_ARB_CREATED = 1 << 0; 178 /** <code>ARB_create_context</code> related: desktop compatibility profile. Cache key value. See {@link #isGLCompatibilityProfile()}, {@link #getAvailableContextProperties(AbstractGraphicsDevice, GLProfile)}. */ 179 protected static final int CTX_PROFILE_COMPAT = 1 << 1; 180 /** <code>ARB_create_context</code> related: desktop core profile. Cache key value. See {@link #isGLCoreProfile()}, {@link #getAvailableContextProperties(AbstractGraphicsDevice, GLProfile)}. */ 181 protected static final int CTX_PROFILE_CORE = 1 << 2; 182 /** <code>ARB_create_context</code> related: ES profile. Cache key value. See {@link #isGLES()}, {@link #getAvailableContextProperties(AbstractGraphicsDevice, GLProfile)}. */ 183 protected static final int CTX_PROFILE_ES = 1 << 3; 184 /** <code>ARB_create_context</code> related: flag forward compatible. Cache key value. See {@link #getAvailableContextProperties(AbstractGraphicsDevice, GLProfile)}. */ 185 protected static final int CTX_OPTION_FORWARD = 1 << 4; 186 /** <code>ARB_create_context</code> related: flag debug. Cache key value. See {@link #setContextCreationFlags(int)}, {@link GLAutoDrawable#setContextCreationFlags(int)}, {@link #getAvailableContextProperties(AbstractGraphicsDevice, GLProfile)}. */ 187 public static final int CTX_OPTION_DEBUG = 1 << 5; 188 /** Context uses software rasterizer, otherwise hardware rasterizer. Cache key value. See {@link #isHardwareRasterizer()}, {@link #getAvailableContextProperties(AbstractGraphicsDevice, GLProfile)}. */ 189 protected static final int CTX_IMPL_ACCEL_SOFT = 1 << 6; 190 191 // 192 // Non cached keys, 6 bits [10..15] 193 // 194 195 /** <code>GL_ARB_ES2_compatibility</code> implementation related: Context is compatible w/ ES2. Not a cache key. See {@link #isGLES2Compatible()}, {@link #getAvailableContextProperties(AbstractGraphicsDevice, GLProfile)}. */ 196 protected static final int CTX_IMPL_ES2_COMPAT = 1 << 10; 197 198 /** <code>GL_ARB_ES3_compatibility</code> implementation related: Context is compatible w/ ES3. Not a cache key. See {@link #isGLES3Compatible()}, {@link #getAvailableContextProperties(AbstractGraphicsDevice, GLProfile)}. */ 199 protected static final int CTX_IMPL_ES3_COMPAT = 1 << 11; 200 201 /** <code>GL_ARB_ES3_1_compatibility</code> implementation related: Context is compatible w/ ES 3.1. Not a cache key. See {@link #isGLES31Compatible()}, {@link #getAvailableContextProperties(AbstractGraphicsDevice, GLProfile)}. */ 202 protected static final int CTX_IMPL_ES31_COMPAT = 1 << 12; 203 204 /** <code>GL_ARB_ES3_2_compatibility</code> implementation related: Context is compatible w/ ES 3.2. Not a cache key. See {@link #isGLES32Compatible()}, {@link #getAvailableContextProperties(AbstractGraphicsDevice, GLProfile)}. */ 205 protected static final int CTX_IMPL_ES32_COMPAT = 1 << 13; 206 207 /** 208 * Context supports basic FBO, details see {@link #hasBasicFBOSupport()}. 209 * Not a cache key. 210 * @see #hasBasicFBOSupport() 211 * @see #getAvailableContextProperties(AbstractGraphicsDevice, GLProfile) 212 */ 213 protected static final int CTX_IMPL_FBO = 1 << 14; 214 215 /** 216 * Context supports <code>OES_single_precision</code>, fp32, fixed function point (FFP) compatibility entry points, 217 * see {@link #hasFP32CompatAPI()}. 218 * Not a cache key. 219 * @see #hasFP32CompatAPI() 220 * @see #getAvailableContextProperties(AbstractGraphicsDevice, GLProfile) 221 */ 222 protected static final int CTX_IMPL_FP32_COMPAT_API = 1 << 15; 223 224 private static final ThreadLocal<GLContext> currentContext = new ThreadLocal<GLContext>(); 225 226 private final HashMap<String, Object> attachedObjects = new HashMap<String, Object>(); 227 228 // RecursiveLock maintains a queue of waiting Threads, ensuring the longest waiting thread will be notified at unlock. 229 protected final RecursiveLock lock = LockFactory.createRecursiveLock(); // FIXME: Move to GLContextImpl when incr. minor version (incompatible change) 230 231 /** The underlying native OpenGL context */ 232 protected volatile long contextHandle; // volatile: avoid locking for read-only access 233 GLContext()234 protected GLContext() { 235 resetStates(true); 236 } 237 238 protected VersionNumber ctxVersion; 239 protected int ctxOptions; 240 protected String ctxVersionString; 241 protected VersionNumberString ctxVendorVersion; 242 protected VersionNumber ctxGLSLVersion; 243 protected GLRendererQuirks glRendererQuirks; 244 245 /** Did the drawable association changed ? see {@link GLRendererQuirks#NoSetSwapIntervalPostRetarget} */ 246 protected boolean drawableRetargeted; 247 248 /** 249 * @param isInit true if called for class initialization, otherwise false (re-init or destruction). 250 */ resetStates(final boolean isInit)251 protected void resetStates(final boolean isInit) { 252 if (DEBUG) { 253 System.err.println(getThreadName() + ": GLContext.resetStates(isInit "+isInit+")"); 254 // Thread.dumpStack(); 255 } 256 ctxVersion = VersionNumberString.zeroVersion; 257 ctxVendorVersion = VersionNumberString.zeroVersion; 258 ctxOptions=0; 259 ctxVersionString=null; 260 ctxGLSLVersion = VersionNumber.zeroVersion; 261 attachedObjects.clear(); 262 contextHandle=0; 263 glRendererQuirks = null; 264 drawableRetargeted = false; 265 } 266 267 /** Returns true if this GLContext is shared, otherwise false. */ isShared()268 public final boolean isShared() { 269 return GLContextShareSet.isShared(this); 270 } 271 272 /** 273 * Returns the shared master GLContext of this GLContext if shared, otherwise return <code>null</code>. 274 * <p> 275 * Returns this GLContext, if it is a shared master. 276 * </p> 277 * @since 2.2.1 278 */ getSharedMaster()279 public final GLContext getSharedMaster() { 280 return GLContextShareSet.getSharedMaster(this); 281 } 282 283 /** Returns a new list of created GLContext shared with this GLContext. */ getCreatedShares()284 public final List<GLContext> getCreatedShares() { 285 return GLContextShareSet.getCreatedShares(this); 286 } 287 288 /** Returns a new list of destroyed GLContext shared with this GLContext. */ getDestroyedShares()289 public final List<GLContext> getDestroyedShares() { 290 return GLContextShareSet.getDestroyedShares(this); 291 } 292 293 /** 294 * Returns the instance of {@link GLRendererQuirks}, allowing one to determine workarounds. 295 * @return instance of {@link GLRendererQuirks} if context was made current once, otherwise <code>null</code>. 296 */ getRendererQuirks()297 public final GLRendererQuirks getRendererQuirks() { return glRendererQuirks; } 298 299 /** 300 * Returns true if the <code>quirk</code> exist in {@link #getRendererQuirks()}, otherwise false. 301 * <p> 302 * Convenience method for: 303 * <pre> 304 * final GLRendererQuirks glrq = ctx.getRendererQuirks(); 305 * boolean hasQuirk = null != glrq ? glrq.exist(quirk) : false ; 306 * </pre> 307 * </p> 308 * @param quirk the quirk to be tested, e.g. {@link GLRendererQuirks#NoDoubleBufferedPBuffer}. 309 * @throws IllegalArgumentException if the quirk is out of range 310 */ hasRendererQuirk(final int quirk)311 public final boolean hasRendererQuirk(final int quirk) throws IllegalArgumentException { 312 return null != glRendererQuirks ? glRendererQuirks.exist(quirk) : false ; 313 } 314 315 /** 316 * Sets the read/write drawable for framebuffer operations, i.e. reassociation of the context's drawable. 317 * <p> 318 * If the arguments reflect the current state of this context 319 * this method is a no-operation and returns the old and current {@link GLDrawable}. 320 * </p> 321 * <p> 322 * Remarks: 323 * <ul> 324 * <li>{@link GL#glFinish() glFinish()} is issued if context {@link #isCreated()} and a {@link #getGLDrawable() previous drawable} was bound before disassociation.</li> 325 * <li>If the context was current on this thread, it is being released before drawable reassociation 326 * and made current afterwards.</li> 327 * <li>Implementation may issue {@link #makeCurrent()} and {@link #release()} while drawable reassociation.</li> 328 * <li>The user shall take extra care of thread synchronization, 329 * i.e. lock the involved {@link GLDrawable#getNativeSurface() drawable's} {@link NativeSurface}s 330 * to avoid a race condition. In case {@link GLAutoDrawable auto-drawable's} are used, 331 * their {@link GLAutoDrawable#getUpstreamLock() upstream-lock} must be locked beforehand 332 * see <a href="GLAutoDrawable.html#locking">GLAutoDrawable Locking</a>.</li> 333 * </ul> 334 * </p> 335 * @param readWrite The read/write drawable for framebuffer operations, maybe <code>null</code> to remove association. 336 * @param setWriteOnly Only change the write-drawable, if <code>setWriteOnly</code> is <code>true</code> and 337 * if the {@link #getGLReadDrawable() read-drawable} differs 338 * from the {@link #getGLDrawable() write-drawable}. 339 * Otherwise set both drawables, read and write. 340 * @return The previous read/write drawable if operation succeeds 341 * 342 * @throws GLException in case <code>null</code> is being passed, 343 * this context is made current on another thread 344 * or operation fails. 345 * 346 * @see #isGLReadDrawableAvailable() 347 * @see #setGLReadDrawable(GLDrawable) 348 * @see #getGLReadDrawable() 349 * @see #setGLDrawable(GLDrawable, boolean) 350 * @see #getGLDrawable() 351 */ setGLDrawable(GLDrawable readWrite, boolean setWriteOnly)352 public abstract GLDrawable setGLDrawable(GLDrawable readWrite, boolean setWriteOnly); 353 354 /** 355 * Returns the write-drawable this context uses for framebuffer operations. 356 * <p> 357 * If the read-drawable has not been changed manually via {@link #setGLReadDrawable(GLDrawable)}, 358 * it equals to the write-drawable (default). 359 * </p> 360 * <p> 361 * Method is only thread-safe while context is {@link #makeCurrent() made current}. 362 * </p> 363 * @see #setGLDrawable(GLDrawable, boolean) 364 * @see #setGLReadDrawable(GLDrawable) 365 */ getGLDrawable()366 public abstract GLDrawable getGLDrawable(); 367 368 /** 369 * Query whether using a distinguished read-drawable is supported. 370 * @return true if using a read-drawable is supported with your driver/OS, otherwise false. 371 */ isGLReadDrawableAvailable()372 public abstract boolean isGLReadDrawableAvailable(); 373 374 /** 375 * Set the read-Drawable for read framebuffer operations.<br> 376 * The caller should query if this feature is supported via {@link #isGLReadDrawableAvailable()}. 377 * <p> 378 * If the context was current on this thread, it is being released before switching the drawable 379 * and made current afterwards. However the user shall take extra care that not other thread 380 * attempts to make this context current. Otherwise a race condition may happen. 381 * </p> 382 * 383 * @param read the read-drawable for read framebuffer operations. 384 * If null is passed, the default write drawable will be set. 385 * @return the previous read-drawable 386 * 387 * @throws GLException in case a read drawable is not supported or 388 * this context is made current on another thread. 389 * 390 * @see #isGLReadDrawableAvailable() 391 * @see #getGLReadDrawable() 392 */ setGLReadDrawable(GLDrawable read)393 public abstract GLDrawable setGLReadDrawable(GLDrawable read); 394 395 /** 396 * Returns the read-Drawable this context uses for read framebuffer operations. 397 * <p> 398 * If the read-drawable has not been changed manually via {@link #setGLReadDrawable(GLDrawable)}, 399 * it equals to the write-drawable (default). 400 * </p> 401 * <p> 402 * Method is only thread-safe while context is {@link #makeCurrent() made current}. 403 * </p> 404 * @see #isGLReadDrawableAvailable() 405 * @see #setGLReadDrawable(GLDrawable) 406 * @see #getGLReadDrawable() 407 */ getGLReadDrawable()408 public abstract GLDrawable getGLReadDrawable(); 409 410 /** 411 * Makes this GLContext current on the calling thread. 412 * <p> 413 * Recursive call to {@link #makeCurrent()} and hence {@link #release()} are supported. 414 * </p> 415 * <p> 416 * There are two return values that indicate success and one that 417 * indicates failure. 418 * </p> 419 * <p> 420 * A return value of {@link #CONTEXT_CURRENT_NEW} 421 * indicates that that context has been made current for the 1st time, 422 * or that the state of the underlying context or drawable has 423 * changed since the last time this context was current. 424 * In this case, the application may wish to initialize the render state. 425 * </p> 426 * <p> 427 * A return value of {@link #CONTEXT_CURRENT} indicates that the context has 428 * been made current, with its previous state restored. 429 * </p> 430 * <p> 431 * If the context could not be made current (for example, because 432 * the underlying drawable has not ben realized on the display) , 433 * a value of {@link #CONTEXT_NOT_CURRENT} is returned. 434 * </p> 435 * <p> 436 * This method is blocking, i.e. waits until another thread has 437 * released the context. 438 * </p> 439 * <p> 440 * The drawable's surface is being locked at entry 441 * and unlocked at {@link #release()} 442 * </p> 443 * 444 * @return <ul> 445 * <li>{@link #CONTEXT_CURRENT_NEW} if the context was successfully made current the 1st time,</li> 446 * <li>{@link #CONTEXT_CURRENT} if the context was successfully made current,</li> 447 * <li>{@link #CONTEXT_NOT_CURRENT} if the context could not be made current.</li> 448 * </ul> 449 * 450 * @throws GLException if the context could not be created 451 * or made current due to non-recoverable, system-specific errors. 452 */ makeCurrent()453 public abstract int makeCurrent() throws GLException; 454 455 /** 456 * Releases control of this GLContext from the current thread. 457 * <p> 458 * Recursive call to {@link #release()} and hence {@link #makeCurrent()} are supported. 459 * </p> 460 * <p> 461 * The drawable's surface is being unlocked at exit, 462 * assumed to be locked by {@link #makeCurrent()}. 463 * </p> 464 * 465 * @throws GLException if the context had not previously been made 466 * current on the current thread 467 */ release()468 public abstract void release() throws GLException; 469 470 /** 471 * Copies selected groups of OpenGL state variables from the 472 * supplied source context into this one. The <code>mask</code> 473 * parameter indicates which groups of state variables are to be 474 * copied. <code>mask</code> contains the bitwise OR of the same 475 * symbolic names that are passed to the GL command {@link 476 * GL2#glPushAttrib glPushAttrib}. The single symbolic constant 477 * {@link GL2#GL_ALL_ATTRIB_BITS GL_ALL_ATTRIB_BITS} can be used to 478 * copy the maximum possible portion of rendering state. <P> 479 * 480 * Not all values for GL state can be copied. For example, pixel 481 * pack and unpack state, render mode state, and select and feedback 482 * state are not copied. The state that can be copied is exactly the 483 * state that is manipulated by the GL command {@link 484 * GL2#glPushAttrib glPushAttrib}. <P> 485 * 486 * On most platforms, this context may not be current to any thread, 487 * including the calling thread, when this method is called. Some 488 * platforms have additional requirements such as whether this 489 * context or the source context must occasionally be made current 490 * in order for the results of the copy to be seen; these 491 * requirements are beyond the scope of this specification. 492 * 493 * @param source the source OpenGL context from which to copy state 494 * @param mask a mask of symbolic names indicating which groups of state to copy 495 496 * @throws GLException if an OpenGL-related error occurred 497 */ copy(GLContext source, int mask)498 public abstract void copy(GLContext source, int mask) throws GLException; 499 500 /** 501 * Returns the GL object bound to this thread current context. 502 * If no context is current, throw an GLException 503 * 504 * @return the current context's GL object on this thread 505 * @throws GLException if no context is current 506 */ getCurrentGL()507 public static GL getCurrentGL() throws GLException { 508 final GLContext glc = getCurrent(); 509 if(null==glc) { 510 throw new GLException(getThreadName()+": No OpenGL context current on this thread"); 511 } 512 return glc.getGL(); 513 } 514 515 /** 516 * Returns this thread current context. 517 * If no context is current, returns null. 518 * 519 * @return the context current on this thread, or null if no context 520 * is current. 521 */ getCurrent()522 public static GLContext getCurrent() { 523 return currentContext.get(); 524 } 525 526 /** 527 * @return true if this GLContext is current on this thread 528 */ isCurrent()529 public final boolean isCurrent() { 530 return getCurrent() == this ; 531 } 532 533 /** 534 * @throws GLException if this GLContext is not current on this thread 535 */ validateCurrent()536 public final void validateCurrent() throws GLException { 537 if(getCurrent() != this) { 538 throw new GLException(getThreadName()+": This context is not current. Current context: "+getCurrent()+", this context "+this); 539 } 540 } 541 542 /** Returns a String representation of the {@link #makeCurrent()} result. */ makeCurrentResultToString(final int res)543 public static final String makeCurrentResultToString(final int res) { 544 switch(res) { 545 case CONTEXT_NOT_CURRENT: return "CONTEXT_NOT_CURRENT"; 546 case CONTEXT_CURRENT: return "CONTEXT_CURRENT"; 547 case CONTEXT_CURRENT_NEW: return "CONTEXT_CURRENT_NEW"; 548 default: return "INVALID_VALUE"; 549 } 550 } 551 552 /** 553 * Sets the thread-local variable returned by {@link #getCurrent} 554 * and has no other side-effects. For use by third parties adding 555 * new GLContext implementations; not for use by end users. 556 */ setCurrent(final GLContext cur)557 protected static void setCurrent(final GLContext cur) { 558 if( TRACE_SWITCH ) { 559 if(null == cur) { 560 System.err.println(getThreadName()+": GLContext.ContextSwitch: - setCurrent() - NULL"); 561 } else { 562 System.err.println(getThreadName()+": GLContext.ContextSwitch: - setCurrent() - obj " + toHexString(cur.hashCode()) + ", ctx " + toHexString(cur.getHandle())); 563 } 564 } 565 currentContext.set(cur); 566 } 567 568 /** 569 * Destroys this OpenGL context and frees its associated 570 * resources. 571 * <p> 572 * The context may be current w/o recursion when calling <code>destroy()</code>, 573 * in which case this method destroys the context and releases the lock. 574 * </p> 575 */ destroy()576 public abstract void destroy(); 577 578 /** 579 * Returns the implementing root GL instance of this GLContext's GL object, 580 * considering a wrapped pipelined hierarchy, see {@link GLBase#getDownstreamGL()}. 581 * @throws GLException if the root instance is not a GL implementation 582 * @see GLBase#getRootGL() 583 * @see GLBase#getDownstreamGL() 584 * @see #getGL() 585 * @see #setGL(GL) 586 */ getRootGL()587 public abstract GL getRootGL(); 588 589 /** 590 * Returns the GL pipeline object for this GLContext. 591 * 592 * @return the aggregated GL instance, or null if this context was not yet made current. 593 */ getGL()594 public abstract GL getGL(); 595 596 /** 597 * Sets the GL pipeline object for this GLContext. 598 * 599 * @return the set GL pipeline or null if not successful 600 */ setGL(GL gl)601 public abstract GL setGL(GL gl); 602 603 /** 604 * Returns the underlying native OpenGL context handle 605 */ getHandle()606 public final long getHandle() { return contextHandle; } 607 608 /** 609 * Indicates whether the underlying native OpenGL context has been created. 610 */ isCreated()611 public final boolean isCreated() { 612 return 0 != contextHandle; 613 } 614 615 /** 616 * Returns the attached user object for the given name to this GLContext. 617 */ getAttachedObject(final String name)618 public final Object getAttachedObject(final String name) { 619 return attachedObjects.get(name); 620 } 621 622 /** 623 * Sets the attached user object for the given name to this GLContext. 624 * Returns the previously set object or null. 625 */ attachObject(final String name, final Object obj)626 public final Object attachObject(final String name, final Object obj) { 627 return attachedObjects.put(name, obj); 628 } 629 detachObject(final String name)630 public final Object detachObject(final String name) { 631 return attachedObjects.remove(name); 632 } 633 634 /** 635 * Classname, GL, GLDrawable 636 */ 637 @Override toString()638 public String toString() { 639 final StringBuilder sb = new StringBuilder(); 640 sb.append(getClass().getSimpleName()); 641 sb.append(" ["); 642 this.append(sb); 643 sb.append("] "); 644 return sb.toString(); 645 } 646 append(final StringBuilder sb)647 public final StringBuilder append(final StringBuilder sb) { 648 sb.append("Version ").append(getGLVersion()).append(" [GL ").append(getGLVersionNumber()).append(", vendor ").append(getGLVendorVersionNumber()); 649 sb.append("], options 0x"); 650 sb.append(Integer.toHexString(ctxOptions)); 651 sb.append(", this "); 652 sb.append(toHexString(hashCode())); 653 sb.append(", handle "); 654 sb.append(toHexString(contextHandle)); 655 sb.append(", isShared "+isShared()+", "); 656 sb.append(getGL()); 657 sb.append(",\n\t quirks: "); 658 if(null != glRendererQuirks) { 659 glRendererQuirks.toString(sb); 660 } else { 661 sb.append("n/a"); 662 } 663 if(getGLDrawable()!=getGLReadDrawable()) { 664 sb.append(",\n\tRead Drawable : "); 665 sb.append(getGLReadDrawable()); 666 sb.append(",\n\tWrite Drawable: "); 667 sb.append(getGLDrawable()); 668 } else { 669 sb.append(",\n\tDrawable: "); 670 sb.append(getGLDrawable()); 671 } 672 return sb; 673 } 674 675 /** 676 * Returns true if the specified OpenGL core- or extension-function can be 677 * successfully called using this GL context given the current host (OpenGL 678 * <i>client</i>) and display (OpenGL <i>server</i>) configuration. 679 * 680 * See {@link GL#isFunctionAvailable(String)} for more details. 681 * 682 * @param glFunctionName the name of the OpenGL function (e.g., use 683 * "glPolygonOffsetEXT" or "glPolygonOffset" to check if the {@link 684 * com.jogamp.opengl.GL#glPolygonOffset(float,float)} is available). 685 */ isFunctionAvailable(String glFunctionName)686 public abstract boolean isFunctionAvailable(String glFunctionName); 687 688 /** 689 * Returns true if the specified OpenGL extension can be 690 * successfully called using this GL context given the current host (OpenGL 691 * <i>client</i>) and display (OpenGL <i>server</i>) configuration. 692 * 693 * See {@link GL#isExtensionAvailable(String)} for more details. 694 * 695 * @param glExtensionName the name of the OpenGL extension (e.g., 696 * "GL_VERTEX_PROGRAM_ARB"). 697 */ isExtensionAvailable(String glExtensionName)698 public abstract boolean isExtensionAvailable(String glExtensionName); 699 700 /** Returns the number of platform extensions */ getPlatformExtensionCount()701 public abstract int getPlatformExtensionCount(); 702 703 /** Returns a non-null (but possibly empty) string containing the 704 space-separated list of available platform-dependent (e.g., WGL, 705 GLX) extensions. Can only be called while this context is 706 current. */ getPlatformExtensionsString()707 public abstract String getPlatformExtensionsString(); 708 709 /** Returns the number of OpenGL extensions */ getGLExtensionCount()710 public abstract int getGLExtensionCount(); 711 712 /** Returns a non-null (but possibly empty) string containing the 713 space-separated list of available extensions. 714 Can only be called while this context is current. 715 This is equivalent to 716 {@link com.jogamp.opengl.GL#glGetString(int) glGetString}({@link com.jogamp.opengl.GL#GL_EXTENSIONS GL_EXTENSIONS}) 717 */ getGLExtensionsString()718 public abstract String getGLExtensionsString(); 719 720 /** 721 * @return Additional context creation flags, supported: {@link GLContext#CTX_OPTION_DEBUG}. 722 */ getContextCreationFlags()723 public abstract int getContextCreationFlags(); 724 725 /** 726 * @param flags Additional context creation flags, supported: {@link GLContext#CTX_OPTION_DEBUG}. 727 * Unsupported flags are masked out. 728 * Only affects this context state if not created yet via {@link #makeCurrent()}. 729 * @see #enableGLDebugMessage(boolean) 730 * @see GLAutoDrawable#setContextCreationFlags(int) 731 */ setContextCreationFlags(int flags)732 public abstract void setContextCreationFlags(int flags); 733 734 /** 735 * Returns a valid OpenGL version string, ie<br> 736 * <pre> 737 * major.minor ([option]?[options,]*) - gl-version 738 * </pre><br> 739 * 740 * <ul> 741 * <li> options 742 * <ul> 743 * <li> <code>ES profile</code> ES profile</li> 744 * <li> <code>Compatibility profile</code> Compatibility profile including fixed function pipeline and deprecated functionality</li> 745 * <li> <code>Core profile</code> Core profile</li> 746 * <li> <code>forward</code> Forward profile excluding deprecated functionality</li> 747 * <li> <code>arb</code> refers to an ARB_create_context created context</li> 748 * <li> <code>debug</code> refers to a debug context</li> 749 * <li> <code>ES2 compatible</code> refers to an ES2 compatible implementation</li> 750 * <li> <code>software</code> refers to a software implementation of the rasterizer</li> 751 * <li> <code>hardware</code> refers to a hardware implementation of the rasterizer</li> 752 * </ul></li> 753 * <li> <i>gl-version</i> the GL_VERSION string</li> 754 * </ul> 755 * 756 * e.g.: 757 * <table border="0"> 758 * <tr> <td></td> <td></td> </tr> 759 * <tr> 760 * <td>row 2, cell 1</td> 761 * <td>row 2, cell 2</td> 762 * </tr> 763 * </table> 764 * 765 * <table border="0"> 766 * <tr><td></td> <td>ES2</td> <td><code>2.0 (ES profile, ES2 compatible, hardware) - 2.0 ES Profile</code></td></tr> 767 * <tr><td>ATI</td><td>GL2</td> <td><code>3.0 (Compatibility profile, arb, hardware) - 3.2.9704 Compatibility Profile Context</code></td></tr> 768 * <tr><td>ATI</td><td>GL3</td> <td><code>3.3 (Core profile, any, new, hardware) - 1.4 (3.2.9704 Compatibility Profile Context)</code></td></tr> 769 * <tr><td>ATI</td><td>GL3bc</td><td><code>3.3 (Compatibility profile, arb, hardware) - 1.4 (3.2.9704 Compatibility Profile Context)</code></td></tr> 770 * <tr><td>NV</td><td>GL2</td> <td><code>3.0 (Compatibility profile, arb, hardware) - 3.0.0 NVIDIA 195.36.07.03</code></td></tr> 771 * <tr><td>NV</td><td>GL3</td> <td><code>3.3 (Core profile, arb, hardware) - 3.3.0 NVIDIA 195.36.07.03</code></td></tr> 772 * <tr><td>NV</td><td>GL3bc</td> <td><code>3.3 (Compatibility profile, arb, hardware) - 3.3.0 NVIDIA 195.36.07.03</code></td></tr> 773 * <tr><td>NV</td><td>GL2</td> <td><code>3.0 (Compatibility profile, arb, ES2 compatible, hardware) - 3.0.0 NVIDIA 290.10</code></td></tr> 774 * </table> 775 */ getGLVersion()776 public final String getGLVersion() { 777 return ctxVersionString; 778 } 779 780 /** 781 * Returns this context OpenGL version. 782 * @see #getGLSLVersionNumber() 783 **/ getGLVersionNumber()784 public final VersionNumber getGLVersionNumber() { return ctxVersion; } 785 /** 786 * Returns the vendor's version, i.e. version number at the end of <code>GL_VERSION</code> not being the GL version. 787 * <p> 788 * In case no such version exists within <code>GL_VERSION</code>, 789 * the {@link VersionNumberString#zeroVersion zero version} instance is returned. 790 * </p> 791 * <p> 792 * The vendor's version is usually the vendor's OpenGL driver version. 793 * </p> 794 */ getGLVendorVersionNumber()795 public final VersionNumberString getGLVendorVersionNumber() { return ctxVendorVersion; } isGLCompatibilityProfile()796 public final boolean isGLCompatibilityProfile() { return ( 0 != ( CTX_PROFILE_COMPAT & ctxOptions ) ); } isGLCoreProfile()797 public final boolean isGLCoreProfile() { return ( 0 != ( CTX_PROFILE_CORE & ctxOptions ) ); } isGLESProfile()798 public final boolean isGLESProfile() { return ( 0 != ( CTX_PROFILE_ES & ctxOptions ) ); } isGLForwardCompatible()799 public final boolean isGLForwardCompatible() { return ( 0 != ( CTX_OPTION_FORWARD & ctxOptions ) ); } isGLDebugEnabled()800 public final boolean isGLDebugEnabled() { return ( 0 != ( CTX_OPTION_DEBUG & ctxOptions ) ); } isCreatedWithARBMethod()801 public final boolean isCreatedWithARBMethod() { return ( 0 != ( CTX_IS_ARB_CREATED & ctxOptions ) ); } 802 803 /** 804 * Returns the matching GLSL version number, queried by this context GL 805 * via {@link GL2ES2#GL_SHADING_LANGUAGE_VERSION} if ≥ ES2.0 or GL2.0, 806 * otherwise a static match is being utilized. 807 * <p> 808 * The context must have been current once, 809 * otherwise the {@link VersionNumberString#zeroVersion zero version} instance is returned. 810 * </p> 811 * <p> 812 * Examples w/ <code>major.minor</code>: 813 * <pre> 814 * 1.00 (ES 2.0), 3.00 (ES 3.0) 815 * 1.10 (GL 2.0), 1.20 (GL 2.1), 1.50 (GL 3.2), 816 * 3.30 (GL 3.3), 4.00 (GL 4.0), 4.10 (GL 4.1), 4.20 (GL 4.2) 817 * </pre > 818 * </p> 819 * <p> 820 * <i>Matching</i> could also refer to the maximum GLSL version usable by this context 821 * since <i>normal</i> GL implementations are capable of using a lower GLSL version as well. 822 * The latter is not true on OSX w/ a GL3 context. 823 * </p> 824 * 825 * @return GLSL version number if context has been made current at least once, 826 * otherwise the {@link VersionNumberString#zeroVersion zero version} instance is returned. 827 * 828 * @see #getGLVersionNumber() 829 */ getGLSLVersionNumber()830 public final VersionNumber getGLSLVersionNumber() { 831 return ctxGLSLVersion; 832 } 833 834 /** 835 * Returns the GLSL version string as to be used in a shader program, including a terminating newline '\n', 836 * i.e. for desktop 837 * <pre> 838 * #version 110 839 * .. 840 * #version 150 core 841 * #version 330 compatibility 842 * ... 843 * </pre> 844 * And for ES: 845 * <pre> 846 * #version 100 847 * #version 300 es 848 * .. 849 * </pre> 850 * <p> 851 * If context has not been made current yet, a string of zero length is returned. 852 * </p> 853 * @see #getGLSLVersionNumber() 854 */ getGLSLVersionString()855 public final String getGLSLVersionString() { 856 if( ctxGLSLVersion.isZero() ) { 857 return S_EMPTY; 858 } 859 final int minor = ctxGLSLVersion.getMinor(); 860 final String profileOpt; 861 if( isGLES() ) { 862 profileOpt = ctxGLSLVersion.compareTo(Version3_0) >= 0 ? " es" : S_EMPTY; 863 } else if( isGLCoreProfile() ) { 864 profileOpt = ctxGLSLVersion.compareTo(Version1_50) >= 0 ? " core" : S_EMPTY; 865 } else if( isGLCompatibilityProfile() ) { 866 profileOpt = ctxGLSLVersion.compareTo(Version1_50) >= 0 ? " compatibility" : S_EMPTY; 867 } else { 868 throw new InternalError("Neither ES, Core nor Compat: "+this); // see validateProfileBits(..) 869 } 870 return "#version " + ctxGLSLVersion.getMajor() + ( minor < 10 ? "0"+minor : minor ) + profileOpt + "\n" ; 871 } 872 getStaticGLSLVersionNumber(final int glMajorVersion, final int glMinorVersion, final int ctxOptions)873 protected static final VersionNumber getStaticGLSLVersionNumber(final int glMajorVersion, final int glMinorVersion, final int ctxOptions) { 874 if( 0 != ( CTX_PROFILE_ES & ctxOptions ) ) { 875 if( 3 == glMajorVersion ) { 876 return Version3_0; // ES 3.0 -> GLSL 3.00 877 } else if( 2 == glMajorVersion ) { 878 return Version1_0; // ES 2.0 -> GLSL 1.00 879 } 880 } else if( 1 == glMajorVersion ) { 881 return Version1_10; // GL 1.x -> GLSL 1.10 882 } else if( 2 == glMajorVersion ) { 883 switch ( glMinorVersion ) { 884 case 0: return Version1_10; // GL 2.0 -> GLSL 1.10 885 default: return Version1_20; // GL 2.1 -> GLSL 1.20 886 } 887 } else if( 3 == glMajorVersion && 2 >= glMinorVersion ) { 888 switch ( glMinorVersion ) { 889 case 0: return Version1_30; // GL 3.0 -> GLSL 1.30 890 case 1: return Version1_40; // GL 3.1 -> GLSL 1.40 891 default: return Version1_50; // GL 3.2 -> GLSL 1.50 892 } 893 } 894 // The new default: GL >= 3.3, ES >= 3.0 895 return new VersionNumber(glMajorVersion, glMinorVersion * 10, 0); // GL M.N -> GLSL M.N 896 } 897 898 /** 899 * @return true if this context is an ES2 context or implements 900 * the extension <code>GL_ARB_ES3_compatibility</code> or <code>GL_ARB_ES2_compatibility</code>, otherwise false 901 */ isGLES2Compatible()902 public final boolean isGLES2Compatible() { 903 return 0 != ( ctxOptions & ( CTX_IMPL_ES3_COMPAT | CTX_IMPL_ES2_COMPAT ) ) ; 904 } 905 906 /** 907 * Return true if this context is an ES3 context or implements 908 * the extension <code>GL_ARB_ES3_compatibility</code>, otherwise false. 909 * <p> 910 * Includes [ GL ≥ 4.3, GL ≥ 3.1 w/ GL_ARB_ES3_compatibility and GLES3 ] 911 * </p> 912 */ isGLES3Compatible()913 public final boolean isGLES3Compatible() { 914 return 0 != ( ctxOptions & CTX_IMPL_ES3_COMPAT ) ; 915 } 916 917 /** 918 * Return true if this context is an ES3 context ≥ 3.1 or implements 919 * the extension <code>GL_ARB_ES3_1_compatibility</code>, otherwise false. 920 * <p> 921 * Includes [ GL ≥ 4.5, GL ≥ 3.1 w/ GL_ARB_ES3_1_compatibility and GLES3 ≥ 3.1 ] 922 * </p> 923 */ isGLES31Compatible()924 public final boolean isGLES31Compatible() { 925 return 0 != ( ctxOptions & CTX_IMPL_ES31_COMPAT ) ; 926 } 927 928 /** 929 * Return true if this context is an ES3 context ≥ 3.2 or implements 930 * the extension <code>GL_ARB_ES3_2_compatibility</code>, otherwise false. 931 * <p> 932 * Includes [ GL ≥ 4.5, GL ≥ 3.1 w/ GL_ARB_ES3_2_compatibility and GLES3 ≥ 3.2 ] 933 * </p> 934 */ isGLES32Compatible()935 public final boolean isGLES32Compatible() { 936 return 0 != ( ctxOptions & CTX_IMPL_ES32_COMPAT ) ; 937 } 938 939 /** 940 * @return true if impl. is a hardware rasterizer, otherwise false. 941 * @see #isHardwareRasterizer(AbstractGraphicsDevice, GLProfile) 942 * @see GLProfile#isHardwareRasterizer() 943 */ isHardwareRasterizer()944 public final boolean isHardwareRasterizer() { 945 return 0 == ( ctxOptions & CTX_IMPL_ACCEL_SOFT ) ; 946 } 947 948 /** 949 * @return true if context supports GLSL, i.e. is either {@link #isGLES3()}, {@link #isGLES2()}, {@link #isGL3()} or {@link #isGL2()} <i>and</i> major-version > 1. 950 * @see GLProfile#hasGLSL() 951 */ hasGLSL()952 public final boolean hasGLSL() { 953 return isGLES3() || 954 isGLES2() || 955 isGL3() || 956 isGL2() && ctxVersion.getMajor()>1 ; 957 } 958 959 /** 960 * Returns <code>true</code> if basic FBO support is available, otherwise <code>false</code>. 961 * <p> 962 * Basic FBO is supported if the context is either GL-ES >= 2.0, GL >= 3.0 [core, compat] or implements the extensions 963 * <code>GL_ARB_ES2_compatibility</code>, <code>GL_ARB_framebuffer_object</code>, <code>GL_EXT_framebuffer_object</code> or <code>GL_OES_framebuffer_object</code>. 964 * </p> 965 * <p> 966 * Basic FBO support may only include one color attachment and no multisampling, 967 * as well as limited internal formats for renderbuffer. 968 * </p> 969 * @see #CTX_IMPL_FBO 970 */ hasBasicFBOSupport()971 public final boolean hasBasicFBOSupport() { 972 return 0 != ( ctxOptions & CTX_IMPL_FBO ) ; 973 } 974 975 /** 976 * Returns <code>true</code> if full FBO support is available, otherwise <code>false</code>. 977 * <p> 978 * Full FBO is supported if the context is either GL >= 3.0 [ES, core, compat] or implements the extensions 979 * <code>ARB_framebuffer_object</code>, or all of 980 * <code>EXT_framebuffer_object</code>, <code>EXT_framebuffer_multisample</code>, 981 * <code>EXT_framebuffer_blit</code>, <code>GL_EXT_packed_depth_stencil</code>. 982 * </p> 983 * <p> 984 * Full FBO support includes multiple color attachments and multisampling. 985 * </p> 986 */ hasFullFBOSupport()987 public final boolean hasFullFBOSupport() { 988 return hasBasicFBOSupport() && !hasRendererQuirk(GLRendererQuirks.NoFullFBOSupport) && 989 ( isGL3ES3() || // GL >= 3.0 [ES, core, compat] 990 isExtensionAvailable(GLExtensions.ARB_framebuffer_object) || // ARB_framebuffer_object 991 ( isExtensionAvailable(GLExtensions.EXT_framebuffer_object) && // All EXT_framebuffer_object* 992 isExtensionAvailable(GLExtensions.EXT_framebuffer_multisample) && 993 isExtensionAvailable(GLExtensions.EXT_framebuffer_blit) && 994 isExtensionAvailable(GLExtensions.EXT_packed_depth_stencil) 995 ) 996 ) ; 997 } 998 999 /** 1000 * Returns <code>true</code> if <code>OES_single_precision</code>, fp32, fixed function point (FFP) compatibility entry points available, 1001 * otherwise <code>false</code>. 1002 * @see #CTX_IMPL_FP32_COMPAT_API 1003 */ hasFP32CompatAPI()1004 public final boolean hasFP32CompatAPI() { 1005 return 0 != ( ctxOptions & CTX_IMPL_FP32_COMPAT_API ) ; 1006 } 1007 1008 /** 1009 * Returns the maximum number of FBO RENDERBUFFER samples 1010 * if {@link #hasFullFBOSupport() full FBO is supported}, otherwise false. 1011 */ getMaxRenderbufferSamples()1012 public final int getMaxRenderbufferSamples() { 1013 if( hasFullFBOSupport() ) { 1014 final GL gl = getGL(); 1015 final int[] val = new int[] { 0 } ; 1016 try { 1017 gl.glGetIntegerv(GL.GL_MAX_SAMPLES, val, 0); 1018 final int glerr = gl.glGetError(); 1019 if(GL.GL_NO_ERROR == glerr) { 1020 return val[0]; 1021 } else if(DEBUG) { 1022 System.err.println("GLContext.getMaxRenderbufferSamples: GL_MAX_SAMPLES query GL Error 0x"+Integer.toHexString(glerr)); 1023 } 1024 } catch (final GLException gle) { gle.printStackTrace(); } 1025 } 1026 return 0; 1027 } 1028 1029 /** Note: The GL impl. may return a const value, ie {@link GLES2#isNPOTTextureAvailable()} always returns <code>true</code>. */ isNPOTTextureAvailable()1030 public boolean isNPOTTextureAvailable() { 1031 return isGL3() || isGLES2Compatible() || isExtensionAvailable(GLExtensions.ARB_texture_non_power_of_two); 1032 } 1033 isTextureFormatBGRA8888Available()1034 public boolean isTextureFormatBGRA8888Available() { 1035 return isGL2GL3() || 1036 isExtensionAvailable(GLExtensions.EXT_texture_format_BGRA8888) || 1037 isExtensionAvailable(GLExtensions.IMG_texture_format_BGRA8888) ; 1038 } 1039 1040 /** 1041 * Indicates whether this GLContext is capable of GL4bc. <p>Includes [ GL4bc ].</p> 1042 * @see GLProfile#isGL4bc() 1043 */ isGL4bc()1044 public final boolean isGL4bc() { 1045 return 0 != (ctxOptions & CTX_PROFILE_COMPAT) && 1046 ctxVersion.getMajor() >= 4; 1047 } 1048 1049 /** 1050 * Indicates whether this GLContext is capable of GL4. <p>Includes [ GL4bc, GL4 ].</p> 1051 * @see GLProfile#isGL4() 1052 */ isGL4()1053 public final boolean isGL4() { 1054 return 0 != (ctxOptions & (CTX_PROFILE_COMPAT|CTX_PROFILE_CORE)) && 1055 ctxVersion.getMajor() >= 4; 1056 } 1057 1058 /** 1059 * Indicates whether this GLContext uses a GL4 core profile. <p>Includes [ GL4 ].</p> 1060 */ isGL4core()1061 public final boolean isGL4core() { 1062 return 0 != ( ctxOptions & CTX_PROFILE_CORE ) && 1063 ctxVersion.getMajor() >= 4; 1064 } 1065 1066 /** 1067 * Indicates whether this GLContext is capable of GL3bc. <p>Includes [ GL4bc, GL3bc ].</p> 1068 * @see GLProfile#isGL3bc() 1069 */ isGL3bc()1070 public final boolean isGL3bc() { 1071 return 0 != (ctxOptions & CTX_PROFILE_COMPAT) && 1072 ctxVersion.compareTo(Version3_1) >= 0 ; 1073 } 1074 1075 /** 1076 * Indicates whether this GLContext is capable of GL3. <p>Includes [ GL4bc, GL4, GL3bc, GL3 ].</p> 1077 * @see GLProfile#isGL3() 1078 */ isGL3()1079 public final boolean isGL3() { 1080 return 0 != (ctxOptions & (CTX_PROFILE_COMPAT|CTX_PROFILE_CORE)) && 1081 ctxVersion.compareTo(Version3_1) >= 0 ; 1082 } 1083 1084 /** 1085 * Indicates whether this GLContext uses a GL3 core profile. <p>Includes [ GL4, GL3 ].</p> 1086 */ isGL3core()1087 public final boolean isGL3core() { 1088 return 0 != ( ctxOptions & CTX_PROFILE_CORE ) && 1089 ctxVersion.compareTo(Version3_1) >= 0; 1090 } 1091 1092 /** 1093 * Indicates whether this GLContext uses a GL core profile. <p>Includes [ GL4, GL3, GLES3, GLES2 ].</p> 1094 */ isGLcore()1095 public final boolean isGLcore() { 1096 return ( 0 != ( ctxOptions & CTX_PROFILE_ES ) && ctxVersion.getMajor() >= 2 ) || 1097 ( 0 != ( ctxOptions & CTX_PROFILE_CORE ) && 1098 ctxVersion.compareTo(Version3_1) >= 0 1099 ) ; 1100 } 1101 1102 /** 1103 * Indicates whether this GLContext allows CPU data sourcing (indices, vertices ..) as opposed to using a GPU buffer source (VBO), 1104 * e.g. {@link GL2#glDrawElements(int, int, int, java.nio.Buffer)}. 1105 * <p>Includes [GL2ES1, GLES2] == [ GL4bc, GL3bc, GL2, GLES1, GL2ES1, GLES2 ].</p> 1106 * <p>See Bug 852 - https://jogamp.org/bugzilla/show_bug.cgi?id=852 </p> 1107 */ isCPUDataSourcingAvail()1108 public final boolean isCPUDataSourcingAvail() { 1109 return isGL2ES1() || isGLES2(); 1110 } 1111 1112 /** 1113 * Indicates whether this GLContext's native profile does not implement a <i>default vertex array object</i> (VAO), 1114 * starting w/ OpenGL 3.1 core. 1115 * <p>Includes [ GL4, GL3 ].</p> 1116 * <pre> 1117 Due to GL 3.1 core spec: E.1. DEPRECATED AND REMOVED FEATURES (p 296), 1118 GL 3.2 core spec: E.2. DEPRECATED AND REMOVED FEATURES (p 331) 1119 there is no more default VAO buffer 0 bound, hence generating and binding one 1120 to avoid INVALID_OPERATION at VertexAttribPointer. 1121 More clear is GL 4.3 core spec: 10.4 (p 307). 1122 * </pre> 1123 * <pre> 1124 ES 3.x is <i>not</i> included here. 1125 Due to it's ES 2.0 backward compatibility it still supports the following features: 1126 <i>client side vertex arrays</i> 1127 <i>default vertex array object</i> 1128 1129 Binding a custom VAO with ES 3.0 would cause <i>client side vertex arrays</i> via {@link GL2ES1#glVertexPointer(int, int, int, java.nio.Buffer) glVertexPointer} 1130 to produce <code>GL_INVALID_OPERATION</code>. 1131 1132 However, they are marked <i>deprecated</i>: 1133 GL ES 3.0 spec F.1. Legacy Features (p 322). 1134 GL ES 3.1 spec F.1. Legacy Features (p 454). 1135 * </pre> 1136 * <p> 1137 * If no default VAO is implemented in the native OpenGL profile, 1138 * an own default VAO is being used, see {@link #getDefaultVAO()}. 1139 * </p> 1140 * @see #getDefaultVAO() 1141 */ hasNoDefaultVAO()1142 public final boolean hasNoDefaultVAO() { 1143 return // ES 3.x not included, see above. ( 0 != ( ctxOptions & CTX_PROFILE_ES ) && ctxVersion.getMajor() >= 3 ) || 1144 ( 0 != ( ctxOptions & CTX_IS_ARB_CREATED ) && 1145 0 != ( ctxOptions & CTX_PROFILE_CORE ) && 1146 ctxVersion.compareTo(Version3_1) >= 0 1147 ) ; 1148 } 1149 1150 /** 1151 * If this GLContext does not implement a default VAO, see {@link #hasNoDefaultVAO()}, 1152 * an <i>own default VAO</i> will be created and bound at context creation. 1153 * <p> 1154 * If this GLContext does implement a default VAO, i.e. {@link #hasNoDefaultVAO()} 1155 * returns <code>false</code>, this method returns <code>0</code>. 1156 * </p> 1157 * <p> 1158 * Otherwise this method returns the VAO object name 1159 * representing this GLContext's <i>own default VAO</i>. 1160 * </p> 1161 * @see #hasNoDefaultVAO() 1162 */ getDefaultVAO()1163 public abstract int getDefaultVAO(); 1164 1165 /** 1166 * Indicates whether this GLContext is capable of GL2. <p>Includes [ GL4bc, GL3bc, GL2 ].</p> 1167 * @see GLProfile#isGL2() 1168 */ isGL2()1169 public final boolean isGL2() { 1170 return 0 != ( ctxOptions & CTX_PROFILE_COMPAT ) && ctxVersion.getMajor()>=1 ; 1171 } 1172 1173 /** 1174 * Indicates whether this GLContext is capable of GL2GL3. <p>Includes [ GL4bc, GL4, GL3bc, GL3, GL2, GL2GL3 ].</p> 1175 * @see GLProfile#isGL2GL3() 1176 */ isGL2GL3()1177 public final boolean isGL2GL3() { 1178 return isGL2() || isGL3(); 1179 } 1180 1181 /** 1182 * Indicates whether this GLContext is capable of GLES1. <p>Includes [ GLES1 ].</p> 1183 * @see GLProfile#isGLES1() 1184 */ isGLES1()1185 public final boolean isGLES1() { 1186 return 0 != ( ctxOptions & CTX_PROFILE_ES ) && ctxVersion.getMajor() == 1 ; 1187 } 1188 1189 /** 1190 * Indicates whether this GLContext is capable of GLES2. <p>Includes [ GLES2, GLES3 ].</p> 1191 * @see GLProfile#isGLES2() 1192 */ isGLES2()1193 public final boolean isGLES2() { 1194 if( 0 != ( ctxOptions & CTX_PROFILE_ES ) ) { 1195 final int major = ctxVersion.getMajor(); 1196 return 2 == major || 3 == major; 1197 } else { 1198 return false; 1199 } 1200 } 1201 1202 /** 1203 * Indicates whether this GLContext is capable of GLES3. <p>Includes [ GLES3 ].</p> 1204 * @see GLProfile#isGLES3() 1205 */ isGLES3()1206 public final boolean isGLES3() { 1207 return 0 != ( ctxOptions & CTX_PROFILE_ES ) && ctxVersion.getMajor() == 3 ; 1208 } 1209 1210 /** 1211 * Indicates whether this GLContext is capable of GLES. <p>Includes [ GLES3, GLES1, GLES2 ].</p> 1212 * @see GLProfile#isGLES() 1213 */ isGLES()1214 public final boolean isGLES() { 1215 return 0 != ( CTX_PROFILE_ES & ctxOptions ) ; 1216 } 1217 1218 /** 1219 * Indicates whether this GLContext is capable of GL2ES1. <p>Includes [ GL4bc, GL3bc, GL2, GLES1, GL2ES1 ].</p> 1220 * @see GLProfile#isGL2ES1() 1221 */ isGL2ES1()1222 public final boolean isGL2ES1() { 1223 return isGLES1() || isGL2(); 1224 } 1225 1226 /** 1227 * Indicates whether this GLContext is capable of GL2ES2. <p>Includes [ GL4bc, GL4, GL3bc, GL3, GLES3, GL2, GL2GL3, GL2ES2, GLES2 ].</p> 1228 * @see GLProfile#isGL2ES2() 1229 */ isGL2ES2()1230 public final boolean isGL2ES2() { 1231 return isGLES2() || isGL2GL3(); 1232 } 1233 1234 /** 1235 * Indicates whether this GLContext is capable of GL2ES3. <p>Includes [ GL4bc, GL4, GL3bc, GL3, GLES3, GL3ES3, GL2, GL2GL3 ].</p> 1236 * @see GLProfile#isGL2ES3() 1237 * @see #isGL3ES3() 1238 * @see #isGL2GL3() 1239 */ isGL2ES3()1240 public final boolean isGL2ES3() { 1241 return isGL3ES3() || isGL2GL3(); 1242 } 1243 1244 /** 1245 * Indicates whether this GLContext is capable of GL3ES3. <p>Includes [ GL4bc, GL4, GL3bc, GL3, GLES3 ].</p> 1246 * @see GLProfile#isGL3ES3() 1247 */ isGL3ES3()1248 public final boolean isGL3ES3() { 1249 return isGL4ES3() || isGL3(); 1250 } 1251 1252 /** 1253 * Returns true if this profile is capable of GL4ES3, i.e. if {@link #isGLES3Compatible()} returns true. 1254 * <p>Includes [ GL ≥ 4.3, GL ≥ 3.1 w/ GL_ARB_ES3_compatibility and GLES3 ]</p> 1255 * @see GLProfile#isGL4ES3() 1256 */ isGL4ES3()1257 public final boolean isGL4ES3() { 1258 return isGLES3Compatible() ; 1259 } 1260 1261 /** 1262 * Set the swap interval of the current context and attached <i>onscreen {@link GLDrawable}</i>. 1263 * <p> 1264 * <i>offscreen {@link GLDrawable}</i> are ignored and {@code false} is returned. 1265 * </p> 1266 * <p> 1267 * The {@code interval} semantics: 1268 * <ul> 1269 * <li><i>0</i> disables the vertical synchronization</li> 1270 * <li><i>≥1</i> is the number of vertical refreshes before a swap buffer occurs</li> 1271 * <li><i><0</i> enables <i>late swaps to occur without synchronization to the video frame</i>, a.k.a <i>EXT_swap_control_tear</i>. 1272 * If supported, the absolute value is the minimum number of 1273 * video frames between buffer swaps. If not supported, the absolute value is being used, see above. 1274 * </li> 1275 * </ul> 1276 * </p> 1277 * @param interval see above 1278 * @return true if the operation was successful, otherwise false 1279 * @throws GLException if the context is not current. 1280 * @see #getSwapInterval() 1281 */ setSwapInterval(final int interval)1282 public /* abstract */ boolean setSwapInterval(final int interval) throws GLException { 1283 // FIXME: Make abstract for next version - just here to *not* break SEMVER! 1284 throw new InternalError("Implemented in GLContextImpl"); 1285 } setSwapIntervalImpl(final int interval)1286 protected boolean setSwapIntervalImpl(final int interval) { 1287 // FIXME: Remove for next version - just here to *not* break SEMVER! 1288 throw new InternalError("Implemented in GLContextImpl"); 1289 } 1290 1291 /** 1292 * Return the current swap interval. 1293 * <p> 1294 * If the context has not been made current at all, 1295 * the default value {@code 0} is returned. 1296 * </p> 1297 * <p> 1298 * For a valid context w/ an <o>onscreen {@link GLDrawable}</i> the default value is {@code 1}, 1299 * otherwise the default value is {@code 0}. 1300 * </p> 1301 * @see #setSwapInterval(int) 1302 */ getSwapInterval()1303 public /* abstract */ int getSwapInterval() { 1304 // FIXME: Make abstract for next version - just here to *not* break SEMVER! 1305 throw new InternalError("Implemented in GLContextImpl"); 1306 } 1307 setDefaultSwapInterval()1308 protected void setDefaultSwapInterval() { 1309 // FIXME: Remove for next version - just here to *not* break SEMVER! 1310 throw new InternalError("Implemented in GLContextImpl"); 1311 } 1312 queryMaxSwapGroups(final int[] maxGroups, final int maxGroups_offset, final int[] maxBarriers, final int maxBarriers_offset)1313 public final boolean queryMaxSwapGroups(final int[] maxGroups, final int maxGroups_offset, 1314 final int[] maxBarriers, final int maxBarriers_offset) { 1315 validateCurrent(); 1316 return queryMaxSwapGroupsImpl(maxGroups, maxGroups_offset, maxBarriers, maxBarriers_offset); 1317 } queryMaxSwapGroupsImpl(final int[] maxGroups, final int maxGroups_offset, final int[] maxBarriers, final int maxBarriers_offset)1318 protected boolean queryMaxSwapGroupsImpl(final int[] maxGroups, final int maxGroups_offset, 1319 final int[] maxBarriers, final int maxBarriers_offset) { return false; } joinSwapGroup(final int group)1320 public final boolean joinSwapGroup(final int group) { 1321 validateCurrent(); 1322 return joinSwapGroupImpl(group); 1323 } joinSwapGroupImpl(final int group)1324 protected boolean joinSwapGroupImpl(final int group) { /** nop per default .. **/ return false; } 1325 protected int currentSwapGroup = -1; // default: not set yet .. getSwapGroup()1326 public int getSwapGroup() { 1327 return currentSwapGroup; 1328 } bindSwapBarrier(final int group, final int barrier)1329 public final boolean bindSwapBarrier(final int group, final int barrier) { 1330 validateCurrent(); 1331 return bindSwapBarrierImpl(group, barrier); 1332 } bindSwapBarrierImpl(final int group, final int barrier)1333 protected boolean bindSwapBarrierImpl(final int group, final int barrier) { /** nop per default .. **/ return false; } 1334 1335 /** 1336 * Return the framebuffer name bound to this context, 1337 * see {@link GL#glBindFramebuffer(int, int)}. 1338 * <p> 1339 * Method is only thread-safe while context is {@link #makeCurrent() made current}. 1340 * </p> 1341 */ getBoundFramebuffer(int target)1342 public abstract int getBoundFramebuffer(int target); 1343 1344 /** 1345 * Return the default draw framebuffer name. 1346 * <p> 1347 * May differ from it's default <code>zero</code> 1348 * in case an framebuffer object ({@link com.jogamp.opengl.FBObject}) based drawable 1349 * is being used. 1350 * </p> 1351 * <p> 1352 * Method is only thread-safe while context is {@link #makeCurrent() made current}. 1353 * </p> 1354 */ getDefaultDrawFramebuffer()1355 public abstract int getDefaultDrawFramebuffer(); 1356 1357 /** 1358 * Return the default read framebuffer name. 1359 * <p> 1360 * May differ from it's default <code>zero</code> 1361 * in case an framebuffer object ({@link com.jogamp.opengl.FBObject}) based drawable 1362 * is being used. 1363 * </p> 1364 * <p> 1365 * Method is only thread-safe while context is {@link #makeCurrent() made current}. 1366 * </p> 1367 */ getDefaultReadFramebuffer()1368 public abstract int getDefaultReadFramebuffer(); 1369 1370 /** 1371 * Returns the default color buffer within the current bound 1372 * {@link #getDefaultReadFramebuffer()}, i.e. GL_READ_FRAMEBUFFER, 1373 * which will be used as the source for pixel reading commands, 1374 * like {@link GL#glReadPixels(int, int, int, int, int, int, java.nio.Buffer) glReadPixels} etc. 1375 * <p> 1376 * For offscreen framebuffer objects this is {@link GL#GL_COLOR_ATTACHMENT0}, 1377 * otherwise this is {@link GL#GL_FRONT} for single buffer configurations 1378 * and {@link GL#GL_BACK} for double buffer configurations. 1379 * </p> 1380 * <p> 1381 * Note-1: Neither ES1 nor ES2 supports selecting the read buffer via glReadBuffer 1382 * and {@link GL#GL_BACK} is the default. 1383 * </p> 1384 * <p> 1385 * Note-2: ES3 only supports {@link GL#GL_BACK}, {@link GL#GL_NONE} or {@link GL#GL_COLOR_ATTACHMENT0}+i 1386 * </p> 1387 * <p> 1388 * Note-3: See {@link com.jogamp.opengl.util.GLDrawableUtil#swapBuffersBeforeRead(GLCapabilitiesImmutable) swapBuffersBeforeRead} 1389 * for read-pixels and swap-buffers implications. 1390 * </p> 1391 * <p> 1392 * Method is only thread-safe while context is {@link #makeCurrent() made current}. 1393 * </p> 1394 */ getDefaultReadBuffer()1395 public abstract int getDefaultReadBuffer(); 1396 1397 /** 1398 * Get the default pixel data type, as required by e.g. {@link GL#glReadPixels(int, int, int, int, int, int, java.nio.Buffer)}. 1399 * <p> 1400 * Method is only thread-safe while context is {@link #makeCurrent() made current}. 1401 * </p> 1402 */ getDefaultPixelDataType()1403 public abstract int getDefaultPixelDataType(); 1404 1405 /** 1406 * Get the default pixel data format, as required by e.g. {@link GL#glReadPixels(int, int, int, int, int, int, java.nio.Buffer)}. 1407 * <p> 1408 * Method is only thread-safe while context is {@link #makeCurrent() made current}. 1409 * </p> 1410 */ getDefaultPixelDataFormat()1411 public abstract int getDefaultPixelDataFormat(); 1412 1413 /** 1414 * @return The extension implementing the GLDebugOutput feature, 1415 * either {@link GLExtensions#ARB_debug_output} or {@link GLExtensions#AMD_debug_output}. 1416 * If unavailable or called before initialized via {@link #makeCurrent()}, <i>null</i> is returned. 1417 */ getGLDebugMessageExtension()1418 public abstract String getGLDebugMessageExtension(); 1419 1420 /** 1421 * @return the current synchronous debug behavior, set via {@link #setGLDebugSynchronous(boolean)}. 1422 */ isGLDebugSynchronous()1423 public abstract boolean isGLDebugSynchronous(); 1424 1425 /** 1426 * Enables or disables the synchronous debug behavior via 1427 * {@link GL2GL3#GL_DEBUG_OUTPUT_SYNCHRONOUS glEnable/glDisable(GL_DEBUG_OUTPUT_SYNCHRONOUS)}, 1428 * if extension is {@link GLExtensions#ARB_debug_output}. 1429 * There is no equivalent for {@link GLExtensions#AMD_debug_output}. 1430 * <p> The default is <code>true</code>, ie {@link GL2GL3#GL_DEBUG_OUTPUT_SYNCHRONOUS}.</p> 1431 * @link {@link #isGLDebugSynchronous()} 1432 */ setGLDebugSynchronous(boolean synchronous)1433 public abstract void setGLDebugSynchronous(boolean synchronous); 1434 1435 /** 1436 * @return true if the GLDebugOutput feature is enabled or not. 1437 */ isGLDebugMessageEnabled()1438 public abstract boolean isGLDebugMessageEnabled(); 1439 1440 /** 1441 * Enables or disables the GLDebugOutput feature of extension {@link GLExtensions#ARB_debug_output} 1442 * or {@link GLExtensions#AMD_debug_output}, if available. 1443 * 1444 * <p>To enable the GLDebugOutput feature {@link #enableGLDebugMessage(boolean) enableGLDebugMessage(true)} 1445 * or {@link #setContextCreationFlags(int) setContextCreationFlags}({@link GLContext#CTX_OPTION_DEBUG}) 1446 * shall be called <b>before</b> context creation via {@link #makeCurrent()}!</p> 1447 * 1448 * <p>In case {@link GLAutoDrawable} are being used, 1449 * {@link GLAutoDrawable#setContextCreationFlags(int) glAutoDrawable.setContextCreationFlags}({@link GLContext#CTX_OPTION_DEBUG}) 1450 * shall be issued before context creation via {@link #makeCurrent()}!</p> 1451 * 1452 * <p>After context creation, the GLDebugOutput feature may be enabled or disabled at any time using this method.</p> 1453 * 1454 * @param enable If true enables, otherwise disables the GLDebugOutput feature. 1455 * 1456 * @throws GLException if this context is not current or GLDebugOutput registration failed (enable) 1457 * 1458 * @see #setContextCreationFlags(int) 1459 * @see #addGLDebugListener(GLDebugListener) 1460 * @see GLAutoDrawable#setContextCreationFlags(int) 1461 */ enableGLDebugMessage(boolean enable)1462 public abstract void enableGLDebugMessage(boolean enable) throws GLException; 1463 1464 /** 1465 * Add {@link GLDebugListener}.<br> 1466 * 1467 * @param listener {@link GLDebugListener} handling {@link GLDebugMessage}s 1468 * @see #enableGLDebugMessage(boolean) 1469 * @see #removeGLDebugListener(GLDebugListener) 1470 */ addGLDebugListener(GLDebugListener listener)1471 public abstract void addGLDebugListener(GLDebugListener listener); 1472 1473 /** 1474 * Remove {@link GLDebugListener}.<br> 1475 * 1476 * @param listener {@link GLDebugListener} handling {@link GLDebugMessage}s 1477 * @see #enableGLDebugMessage(boolean) 1478 * @see #addGLDebugListener(GLDebugListener) 1479 */ removeGLDebugListener(GLDebugListener listener)1480 public abstract void removeGLDebugListener(GLDebugListener listener); 1481 1482 /** 1483 * Generic entry for {@link GL2GL3#glDebugMessageControl(int, int, int, int, IntBuffer, boolean)} 1484 * and {@link GL2GL3#glDebugMessageEnableAMD(int, int, int, IntBuffer, boolean)} of the GLDebugOutput feature. 1485 * @see #enableGLDebugMessage(boolean) 1486 */ glDebugMessageControl(int source, int type, int severity, int count, IntBuffer ids, boolean enabled)1487 public abstract void glDebugMessageControl(int source, int type, int severity, int count, IntBuffer ids, boolean enabled); 1488 1489 /** 1490 * Generic entry for {@link GL2GL3#glDebugMessageControl(int, int, int, int, int[], int, boolean)} 1491 * and {@link GL2GL3#glDebugMessageEnableAMD(int, int, int, int[], int, boolean)} of the GLDebugOutput feature. 1492 * @see #enableGLDebugMessage(boolean) 1493 */ glDebugMessageControl(int source, int type, int severity, int count, int[] ids, int ids_offset, boolean enabled)1494 public abstract void glDebugMessageControl(int source, int type, int severity, int count, int[] ids, int ids_offset, boolean enabled); 1495 1496 /** 1497 * Generic entry for {@link GL2GL3#glDebugMessageInsert(int, int, int, int, int, String)} 1498 * and {@link GL2GL3#glDebugMessageInsertAMD(int, int, int, int, String)} of the GLDebugOutput feature. 1499 * @see #enableGLDebugMessage(boolean) 1500 */ glDebugMessageInsert(int source, int type, int id, int severity, String buf)1501 public abstract void glDebugMessageInsert(int source, int type, int id, int severity, String buf); 1502 1503 public static final int GL_VERSIONS[][] = { 1504 /* 0.*/ { -1 }, 1505 /* 1.*/ { 0, 1, 2, 3, 4, 5 }, 1506 /* 2.*/ { 0, 1 }, 1507 /* 3.*/ { 0, 1, 2, 3 }, 1508 /* 4.*/ { 0, 1, 2, 3, 4, 5 } }; 1509 1510 public static final int ES_VERSIONS[][] = { 1511 /* 0.*/ { -1 }, 1512 /* 1.*/ { 0, 1 }, 1513 /* 2.*/ { 0 }, 1514 /* 3.*/ { 0, 1, 2 } }; 1515 getMaxMajor(final int ctxProfile)1516 public static final int getMaxMajor(final int ctxProfile) { 1517 return ( 0 != ( CTX_PROFILE_ES & ctxProfile ) ) ? ES_VERSIONS.length-1 : GL_VERSIONS.length-1; 1518 } 1519 getMaxMinor(final int ctxProfile, final int major)1520 public static final int getMaxMinor(final int ctxProfile, final int major) { 1521 if( 1>major ) { 1522 return -1; 1523 } 1524 if( ( 0 != ( CTX_PROFILE_ES & ctxProfile ) ) ) { 1525 if( major>=ES_VERSIONS.length ) return -1; 1526 return ES_VERSIONS[major].length-1; 1527 } else { 1528 if( major>=GL_VERSIONS.length ) return -1; 1529 return GL_VERSIONS[major].length-1; 1530 } 1531 } 1532 1533 /** 1534 * Returns true, if the major.minor is not inferior to the lowest 1535 * valid version and does not exceed the highest known major number by more than one. 1536 * <p> 1537 * The minor version number is ignored by the upper limit validation 1538 * and the major version number may exceed by one. 1539 * </p> 1540 * <p> 1541 * The upper limit check is relaxed since we don't want to cut-off 1542 * unforseen new GL version since the release of JOGL. 1543 * </p> 1544 * <p> 1545 * Hence it is important to iterate through GL version from the upper limit 1546 * and {@link #decrementGLVersion(int, int[], int[])} until invalid. 1547 * </p> 1548 */ isValidGLVersion(final int ctxProfile, final int major, final int minor)1549 public static final boolean isValidGLVersion(final int ctxProfile, final int major, final int minor) { 1550 if( 1>major || 0>minor ) { 1551 return false; 1552 } 1553 if( 0 != ( CTX_PROFILE_ES & ctxProfile ) ) { 1554 if( major >= ES_VERSIONS.length + 1 ) return false; 1555 } else { 1556 if( major>=GL_VERSIONS.length + 1 ) return false; 1557 } 1558 return true; 1559 } 1560 1561 /** 1562 * Clip the given GL version to the maximum known valid version if exceeding. 1563 * @return true if clipped, i.e. given value exceeds maximum, otherwise false. 1564 */ clipGLVersion(final int ctxProfile, final int major[], final int minor[])1565 public static final boolean clipGLVersion(final int ctxProfile, final int major[], final int minor[]) { 1566 final int m = major[0]; 1567 final int n = minor[0]; 1568 1569 if( 0 != ( CTX_PROFILE_ES & ctxProfile ) ) { 1570 if( m >= ES_VERSIONS.length ) { 1571 major[0] = ES_VERSIONS.length - 1; 1572 minor[0] = ES_VERSIONS[major[0]].length - 1; 1573 return true; 1574 } 1575 if( n >= ES_VERSIONS[m].length ) { 1576 minor[0] = ES_VERSIONS[m].length - 1; 1577 return true; 1578 } 1579 } else if( m >= GL_VERSIONS.length ) { // !isES 1580 major[0] = GL_VERSIONS.length - 1; 1581 minor[0] = GL_VERSIONS[major[0]].length - 1; 1582 return true; 1583 } else if( n >= GL_VERSIONS[m].length ) { // !isES 1584 minor[0] = GL_VERSIONS[m].length - 1; 1585 return true; 1586 } 1587 return false; 1588 } 1589 1590 /** 1591 * Decrement the given GL version by one 1592 * and return true if still valid, otherwise false. 1593 * <p> 1594 * If the given version exceeds the maximum known valid version, 1595 * it is {@link #clipGLVersion(int, int[], int[]) clipped} and 1596 * true is returned. 1597 * </p> 1598 * 1599 * @param ctxProfile 1600 * @param major 1601 * @param minor 1602 * @return 1603 */ decrementGLVersion(final int ctxProfile, final int major[], final int minor[])1604 public static final boolean decrementGLVersion(final int ctxProfile, final int major[], final int minor[]) { 1605 if( !clipGLVersion(ctxProfile, major, minor) ) { 1606 int m = major[0]; 1607 int n = minor[0] - 1; 1608 if(n < 0) { 1609 if( 0 != ( CTX_PROFILE_ES & ctxProfile ) ) { 1610 if( m >= 3 ) { 1611 m -= 1; 1612 } else { 1613 m = 0; // major decr [1,2] -> 0 1614 } 1615 n = ES_VERSIONS[m].length-1; 1616 } else { 1617 m -= 1; 1618 n = GL_VERSIONS[m].length-1; 1619 } 1620 } 1621 if( !isValidGLVersion(ctxProfile, m, n) ) { 1622 return false; 1623 } 1624 major[0]=m; 1625 minor[0]=n; 1626 } 1627 return true; 1628 } 1629 composeBits(final int a8, final int b8, final int c16)1630 protected static int composeBits(final int a8, final int b8, final int c16) { 1631 return ( ( a8 & 0x000000FF ) << 24 ) | 1632 ( ( b8 & 0x000000FF ) << 16 ) | 1633 ( ( c16 & 0x0000FFFF ) ) ; 1634 } decomposeBits(final int bits32, final int[] ctp)1635 protected static VersionNumber decomposeBits(final int bits32, final int[] ctp) { 1636 final int major = ( bits32 & 0xFF000000 ) >>> 24 ; 1637 final int minor = ( bits32 & 0x00FF0000 ) >>> 16 ; 1638 ctp[0] = ( bits32 & 0x0000FFFF ) ; 1639 return new VersionNumber(major, minor, 0); 1640 } 1641 validateProfileBits(final int bits, final String argName)1642 private static void validateProfileBits(final int bits, final String argName) { 1643 int num = 0; 1644 if( 0 != ( CTX_PROFILE_COMPAT & bits ) ) { num++; } 1645 if( 0 != ( CTX_PROFILE_CORE & bits ) ) { num++; } 1646 if( 0 != ( CTX_PROFILE_ES & bits ) ) { num++; } 1647 if(1!=num) { 1648 throw new GLException("Internal Error: "+argName+": 1 != num-profiles: "+num); 1649 } 1650 } 1651 1652 // 1653 // version mapping 1654 // 1655 1656 /** 1657 * @see #getDeviceVersionAvailableKey(com.jogamp.nativewindow.AbstractGraphicsDevice, int, int) 1658 */ 1659 protected static final IdentityHashMap<String, Integer> deviceVersionAvailable = new IdentityHashMap<String, Integer>(); 1660 1661 /** 1662 * @see #getUniqueDeviceString(com.jogamp.nativewindow.AbstractGraphicsDevice) 1663 */ 1664 private static final IdentityHashMap<String, String> deviceVersionsAvailableSet = new IdentityHashMap<String, String>(); 1665 1666 /** clears the device/context mappings as well as the GL/GLX proc address tables. */ shutdown()1667 protected static void shutdown() { 1668 deviceVersionAvailable.clear(); 1669 deviceVersionsAvailableSet.clear(); 1670 GLContextImpl.shutdownImpl(); // well .. 1671 } 1672 getAvailableGLVersionsSet(final AbstractGraphicsDevice device)1673 protected static boolean getAvailableGLVersionsSet(final AbstractGraphicsDevice device) { 1674 synchronized ( deviceVersionsAvailableSet ) { 1675 return deviceVersionsAvailableSet.containsKey(device.getUniqueID()); 1676 } 1677 } 1678 setAvailableGLVersionsSet(final AbstractGraphicsDevice device, final boolean set)1679 protected static void setAvailableGLVersionsSet(final AbstractGraphicsDevice device, final boolean set) { 1680 synchronized ( deviceVersionsAvailableSet ) { 1681 final String devKey = device.getUniqueID(); 1682 if( set ) { 1683 deviceVersionsAvailableSet.put(devKey, devKey); 1684 } else { 1685 deviceVersionsAvailableSet.remove(devKey); 1686 } 1687 if (DEBUG) { 1688 System.err.println(getThreadName() + ": createContextARB-MapGLVersions SET "+devKey); 1689 System.err.println(GLContext.dumpAvailableGLVersions(null).toString()); 1690 } 1691 } 1692 } 1693 1694 /** 1695 * Returns a unique String object using {@link String#intern()} for the given arguments, 1696 * which object reference itself can be used as a key. 1697 */ getDeviceVersionAvailableKey(final AbstractGraphicsDevice device, final int major, final int profile)1698 protected static String getDeviceVersionAvailableKey(final AbstractGraphicsDevice device, final int major, final int profile) { 1699 final String r = device.getUniqueID() + "-" + toHexString(composeBits(major, profile, 0)); 1700 return r.intern(); 1701 } 1702 1703 /** 1704 * @deprecated Use {@link GLContextImpl#mapAvailableGLVersion(AbstractGraphicsDevice, int, int, VersionNumber, int)} 1705 */ mapAvailableGLVersion(final AbstractGraphicsDevice device, final int reqMajor, final int profile, final int resMajor, final int resMinor, int resCtp)1706 protected static Integer mapAvailableGLVersion(final AbstractGraphicsDevice device, 1707 final int reqMajor, final int profile, final int resMajor, final int resMinor, int resCtp) 1708 { 1709 validateProfileBits(profile, "profile"); 1710 validateProfileBits(resCtp, "resCtp"); 1711 1712 if(FORCE_NO_FBO_SUPPORT) { 1713 resCtp &= ~CTX_IMPL_FBO ; 1714 } 1715 if(DEBUG) { 1716 System.err.println(getThreadName() + ": createContextARB-MapGLVersions MAP "+device+": "+reqMajor+" ("+GLContext.getGLProfile(new StringBuilder(), profile).toString()+ ") -> "+getGLVersion(resMajor, resMinor, resCtp, null)); 1717 } 1718 final String objectKey = getDeviceVersionAvailableKey(device, reqMajor, profile); 1719 final Integer val = Integer.valueOf(composeBits(resMajor, resMinor, resCtp)); 1720 synchronized(deviceVersionAvailable) { 1721 return deviceVersionAvailable.put( objectKey, val ); 1722 } 1723 } 1724 dumpAvailableGLVersions(StringBuilder sb)1725 protected static StringBuilder dumpAvailableGLVersions(StringBuilder sb) { 1726 if(null == sb) { 1727 sb = new StringBuilder(); 1728 } 1729 synchronized(deviceVersionAvailable) { 1730 final Set<String> keys = deviceVersionAvailable.keySet(); 1731 boolean needsSeparator = false; 1732 for(final Iterator<String> keyI = keys.iterator(); keyI.hasNext(); ) { 1733 if(needsSeparator) { 1734 sb.append(Platform.getNewline()); 1735 } 1736 final String key = keyI.next(); 1737 sb.append("MapGLVersions ").append(key).append(": "); 1738 final Integer valI = deviceVersionAvailable.get(key); 1739 if(null != valI) { 1740 final int[] ctp = { 0 }; 1741 final VersionNumber version = decomposeBits(valI.intValue(), ctp); 1742 GLContext.getGLVersion(sb, version, ctp[0], null); 1743 } else { 1744 sb.append("n/a"); 1745 } 1746 needsSeparator = true; 1747 } 1748 } 1749 return sb; 1750 } 1751 1752 /** 1753 * @param device the device to request whether the profile is available for 1754 * @param reqMajor Key Value either 1, 2, 3 or 4 1755 * @param reqProfile Key Value either {@link #CTX_PROFILE_COMPAT}, {@link #CTX_PROFILE_CORE} or {@link #CTX_PROFILE_ES} 1756 * @return the available GL version as encoded with {@link #composeBits(int, int, int), otherwise <code>null</code> 1757 */ getAvailableGLVersion(final AbstractGraphicsDevice device, final int reqMajor, final int reqProfile)1758 protected static Integer getAvailableGLVersion(final AbstractGraphicsDevice device, final int reqMajor, final int reqProfile) { 1759 final String objectKey = getDeviceVersionAvailableKey(device, reqMajor, reqProfile); 1760 Integer val; 1761 synchronized(deviceVersionAvailable) { 1762 val = deviceVersionAvailable.get( objectKey ); 1763 } 1764 return val; 1765 } 1766 1767 /** 1768 * @param reqMajor Key Value either 1, 2, 3 or 4 1769 * @param reqProfile Key Value either {@link #CTX_PROFILE_COMPAT}, {@link #CTX_PROFILE_CORE} or {@link #CTX_PROFILE_ES} 1770 * @param major if not null, returns the used major version 1771 * @param minor if not null, returns the used minor version 1772 * @param ctp if not null, returns the used context profile 1773 */ getAvailableGLVersion(final AbstractGraphicsDevice device, final int reqMajor, final int reqProfile, final int[] major, final int minor[], final int ctp[])1774 protected static boolean getAvailableGLVersion(final AbstractGraphicsDevice device, final int reqMajor, final int reqProfile, 1775 final int[] major, final int minor[], final int ctp[]) { 1776 1777 final Integer valI = getAvailableGLVersion(device, reqMajor, reqProfile); 1778 if(null==valI) { 1779 return false; 1780 } 1781 1782 final int bits32 = valI.intValue(); 1783 1784 if(null!=major) { 1785 major[0] = ( bits32 & 0xFF000000 ) >>> 24 ; 1786 } 1787 if(null!=minor) { 1788 minor[0] = ( bits32 & 0x00FF0000 ) >>> 16 ; 1789 } 1790 if(null!=ctp) { 1791 ctp[0] = ( bits32 & 0x0000FFFF ) ; 1792 } 1793 return true; 1794 } 1795 1796 /** 1797 * returns the highest GLProfile string regarding the implementation version and context profile bits. 1798 * @throws GLException if version and context profile bits could not be mapped to a GLProfile 1799 */ getGLProfile(final int major, final int minor, final int ctp)1800 protected static String getGLProfile(final int major, final int minor, final int ctp) 1801 throws GLException { 1802 if(0 != ( CTX_PROFILE_COMPAT & ctp )) { 1803 if(major >= 4) { return GLProfile.GL4bc; } 1804 else if(major == 3 && minor >= 1) { return GLProfile.GL3bc; } 1805 else { return GLProfile.GL2; } 1806 } else if(0 != ( CTX_PROFILE_CORE & ctp )) { 1807 if(major >= 4) { return GLProfile.GL4; } 1808 else if(major == 3 && minor >= 1) { return GLProfile.GL3; } 1809 } else if(0 != ( CTX_PROFILE_ES & ctp )) { 1810 if(major == 3) { return GLProfile.GLES3; } 1811 else if(major == 2) { return GLProfile.GLES2; } 1812 else if(major == 1) { return GLProfile.GLES1; } 1813 } 1814 throw new GLException("Unhandled OpenGL version/profile: "+GLContext.getGLVersion(major, minor, ctp, null)); 1815 } 1816 1817 /** 1818 * Returns the GLProfile's major version number at reqMajorCTP[0] and it's context property (CTP) at reqMajorCTP[1] for availability mapping request. 1819 */ getRequestMajorAndCompat(final GLProfile glp, final int[ ] reqMajorCTP)1820 protected static final void getRequestMajorAndCompat(final GLProfile glp, final int[/*2*/] reqMajorCTP) { 1821 final GLProfile glpImpl = glp.getImpl(); 1822 if( glpImpl.isGL4() ) { 1823 reqMajorCTP[0]=4; 1824 } else if ( glpImpl.isGL3() || glpImpl.isGLES3() ) { 1825 reqMajorCTP[0]=3; 1826 } else if (glpImpl.isGLES1()) { 1827 reqMajorCTP[0]=1; 1828 } else /* if (glpImpl.isGL2() || glpImpl.isGLES2()) */ { 1829 reqMajorCTP[0]=2; 1830 } 1831 if( glpImpl.isGLES() ) { 1832 reqMajorCTP[1]=CTX_PROFILE_ES; 1833 } else if( glpImpl.isGL2() ) { // incl GL3bc and GL4bc 1834 reqMajorCTP[1]=CTX_PROFILE_COMPAT; 1835 } else { 1836 reqMajorCTP[1]=CTX_PROFILE_CORE; 1837 } 1838 } 1839 1840 /** 1841 * @param device the device the context profile is being requested for 1842 * @param GLProfile the GLProfile the context profile is being requested for 1843 * @return the GLProfile's context property (CTP) if available, otherwise <code>0</code> 1844 */ getAvailableContextProperties(final AbstractGraphicsDevice device, final GLProfile glp)1845 protected static final int getAvailableContextProperties(final AbstractGraphicsDevice device, final GLProfile glp) { 1846 final int[] reqMajorCTP = new int[] { 0, 0 }; 1847 getRequestMajorAndCompat(glp, reqMajorCTP); 1848 1849 final int _major[] = { 0 }; 1850 final int _minor[] = { 0 }; 1851 final int _ctp[] = { 0 }; 1852 if( GLContext.getAvailableGLVersion(device, reqMajorCTP[0], reqMajorCTP[1], _major, _minor, _ctp)) { 1853 return _ctp[0]; 1854 } 1855 return 0; // n/a 1856 } 1857 1858 /** 1859 * @param device the device the profile is being requested 1860 * @param major Key Value either 1, 2, 3 or 4 1861 * @param profile Key Value either {@link #CTX_PROFILE_COMPAT}, {@link #CTX_PROFILE_CORE} or {@link #CTX_PROFILE_ES} 1862 * @return the highest GLProfile for the device regarding availability, version and profile bits. 1863 */ getAvailableGLProfile(final AbstractGraphicsDevice device, final int reqMajor, final int reqProfile)1864 protected static GLProfile getAvailableGLProfile(final AbstractGraphicsDevice device, final int reqMajor, final int reqProfile) 1865 throws GLException { 1866 final String glpName = getAvailableGLProfileName(device, reqMajor, reqProfile); 1867 return null != glpName ? GLProfile.get(device, glpName) : null; 1868 } 1869 1870 /** 1871 * @param device the device the profile is being requested 1872 * @param major Key Value either 1, 2, 3 or 4 1873 * @param profile Key Value either {@link #CTX_PROFILE_COMPAT}, {@link #CTX_PROFILE_CORE} or {@link #CTX_PROFILE_ES} 1874 * @return the highest GLProfile name for the device regarding availability, version and profile bits. 1875 */ getAvailableGLProfileName(final AbstractGraphicsDevice device, final int reqMajor, final int reqProfile)1876 /* package */ static String getAvailableGLProfileName(final AbstractGraphicsDevice device, final int reqMajor, final int reqProfile) 1877 throws GLException { 1878 final int major[] = { 0 }; 1879 final int minor[] = { 0 }; 1880 final int ctp[] = { 0 }; 1881 if(GLContext.getAvailableGLVersion(device, reqMajor, reqProfile, major, minor, ctp)) { 1882 return GLContext.getGLProfile(major[0], minor[0], ctp[0]); 1883 } 1884 return null; 1885 } 1886 1887 /** 1888 * @param device the device the profile is being requested 1889 * @param major Key Value either 1, 2, 3 or 4 1890 * @param profile Key Value either {@link #CTX_PROFILE_COMPAT}, {@link #CTX_PROFILE_CORE} or {@link #CTX_PROFILE_ES} 1891 */ getAvailableGLVersionAsString(final AbstractGraphicsDevice device, final int major, final int profile)1892 protected static String getAvailableGLVersionAsString(final AbstractGraphicsDevice device, final int major, final int profile) { 1893 final int _major[] = { 0 }; 1894 final int _minor[] = { 0 }; 1895 final int _ctp[] = { 0 }; 1896 if(getAvailableGLVersion(device, major, profile, _major, _minor, _ctp)) { 1897 return getGLVersion(_major[0], _minor[0], _ctp[0], null); 1898 } 1899 return null; 1900 } 1901 1902 /** 1903 * Returns true if it is possible to create an <i>framebuffer object</i> (FBO). 1904 * <p> 1905 * FBO feature is implemented in OpenGL, hence it is {@link GLProfile} dependent. 1906 * </p> 1907 * <p> 1908 * FBO support is queried as described in {@link #hasBasicFBOSupport()}. 1909 * </p> 1910 * 1911 * @param device the device to request whether FBO is available for 1912 * @param glp {@link GLProfile} to check for FBO capabilities 1913 * @see GLContext#hasBasicFBOSupport() 1914 */ isFBOAvailable(final AbstractGraphicsDevice device, final GLProfile glp)1915 public static final boolean isFBOAvailable(final AbstractGraphicsDevice device, final GLProfile glp) { 1916 return 0 != ( CTX_IMPL_FBO & getAvailableContextProperties(device, glp) ); 1917 } 1918 1919 /** 1920 * @return <code>1</code> if using a hardware rasterizer, <code>0</code> if using a software rasterizer and <code>-1</code> if not determined yet. 1921 * @see GLContext#isHardwareRasterizer() 1922 * @see GLProfile#isHardwareRasterizer() 1923 */ isHardwareRasterizer(final AbstractGraphicsDevice device, final GLProfile glp)1924 public static final int isHardwareRasterizer(final AbstractGraphicsDevice device, final GLProfile glp) { 1925 final int r; 1926 final int ctp = getAvailableContextProperties(device, glp); 1927 if(0 == ctp) { 1928 r = -1; 1929 } else if( 0 == ( CTX_IMPL_ACCEL_SOFT & ctp ) ) { 1930 r = 1; 1931 } else { 1932 r = 0; 1933 } 1934 return r; 1935 } 1936 1937 /** 1938 * @param device the device to request whether the profile is available for 1939 * @param reqMajor Key Value either 1, 2, 3 or 4 1940 * @param reqProfile Key Value either {@link #CTX_PROFILE_COMPAT}, {@link #CTX_PROFILE_CORE} or {@link #CTX_PROFILE_ES} 1941 * @param isHardware return value of one boolean, whether the profile is a hardware rasterizer or not 1942 * @return true if the requested GL version is available regardless of a software or hardware rasterizer, otherwise false. 1943 */ isGLVersionAvailable(final AbstractGraphicsDevice device, final int reqMajor, final int reqProfile, final boolean isHardware[])1944 protected static boolean isGLVersionAvailable(final AbstractGraphicsDevice device, final int reqMajor, final int reqProfile, final boolean isHardware[]) { 1945 final Integer valI = getAvailableGLVersion(device, reqMajor, reqProfile); 1946 if(null==valI) { 1947 return false; 1948 } 1949 isHardware[0] = 0 == ( valI.intValue() & GLContext.CTX_IMPL_ACCEL_SOFT ) ; 1950 return true; 1951 } 1952 isGLES1Available(final AbstractGraphicsDevice device, final boolean isHardware[])1953 public static boolean isGLES1Available(final AbstractGraphicsDevice device, final boolean isHardware[]) { 1954 return isGLVersionAvailable(device, 1, GLContext.CTX_PROFILE_ES, isHardware); 1955 } 1956 isGLES2Available(final AbstractGraphicsDevice device, final boolean isHardware[])1957 public static boolean isGLES2Available(final AbstractGraphicsDevice device, final boolean isHardware[]) { 1958 return isGLVersionAvailable(device, 2, GLContext.CTX_PROFILE_ES, isHardware); 1959 } 1960 isGLES3Available(final AbstractGraphicsDevice device, final boolean isHardware[])1961 public static boolean isGLES3Available(final AbstractGraphicsDevice device, final boolean isHardware[]) { 1962 return isGLVersionAvailable(device, 3, GLContext.CTX_PROFILE_ES, isHardware); 1963 } 1964 getGL3ctp(final AbstractGraphicsDevice device)1965 private static final int getGL3ctp(final AbstractGraphicsDevice device) { 1966 final int major[] = { 0 }; 1967 final int minor[] = { 0 }; 1968 final int ctp[] = { 0 }; 1969 boolean ok; 1970 1971 ok = GLContext.getAvailableGLVersion(device, 3, GLContext.CTX_PROFILE_ES, major, minor, ctp); 1972 if( !ok ) { 1973 ok = GLContext.getAvailableGLVersion(device, 3, GLContext.CTX_PROFILE_CORE, major, minor, ctp); 1974 } 1975 if( !ok ) { 1976 GLContext.getAvailableGLVersion(device, 3, GLContext.CTX_PROFILE_COMPAT, major, minor, ctp); 1977 } 1978 return ctp[0]; 1979 } 1980 1981 /** 1982 * Returns true if a ES3 compatible profile is available, 1983 * i.e. either a ≥ 4.3 context or a ≥ 3.1 context supporting <code>GL_ARB_ES3_compatibility</code>, 1984 * otherwise false. 1985 * <p> 1986 * Includes [ GL ≥ 4.3, GL ≥ 3.1 w/ GL_ARB_ES3_compatibility and GLES3 ] 1987 * </p> 1988 */ isGLES3CompatibleAvailable(final AbstractGraphicsDevice device)1989 public static final boolean isGLES3CompatibleAvailable(final AbstractGraphicsDevice device) { 1990 return 0 != ( getGL3ctp(device) & CTX_IMPL_ES3_COMPAT ); 1991 } 1992 /** 1993 * Returns true if a ES3 ≥ 3.1 compatible profile is available, 1994 * i.e. either a ≥ 4.5 context or a ≥ 3.1 context supporting <code>GL_ARB_ES3_1_compatibility</code>, 1995 * otherwise false. 1996 * <p> 1997 * Includes [ GL ≥ 4.5, GL ≥ 3.1 w/ GL_ARB_ES3_1_compatibility and GLES3 ≥ 3.1 ] 1998 * </p> 1999 */ isGLES31CompatibleAvailable(final AbstractGraphicsDevice device)2000 public static final boolean isGLES31CompatibleAvailable(final AbstractGraphicsDevice device) { 2001 return 0 != ( getGL3ctp(device) & CTX_IMPL_ES31_COMPAT ); 2002 } 2003 /** 2004 * Returns true if a ES3 ≥ 3.2 compatible profile is available, 2005 * i.e. either a ≥ 4.5 context or a ≥ 3.1 context supporting <code>GL_ARB_ES3_2_compatibility</code>, 2006 * otherwise false. 2007 * <p> 2008 * Includes [ GL ≥ 4.5, GL ≥ 3.1 w/ GL_ARB_ES3_2_compatibility and GLES3 ≥ 3.2 ] 2009 * </p> 2010 */ isGLES32CompatibleAvailable(final AbstractGraphicsDevice device)2011 public static final boolean isGLES32CompatibleAvailable(final AbstractGraphicsDevice device) { 2012 return 0 != ( getGL3ctp(device) & CTX_IMPL_ES32_COMPAT ); 2013 } 2014 isGL4bcAvailable(final AbstractGraphicsDevice device, final boolean isHardware[])2015 public static boolean isGL4bcAvailable(final AbstractGraphicsDevice device, final boolean isHardware[]) { 2016 return isGLVersionAvailable(device, 4, CTX_PROFILE_COMPAT, isHardware); 2017 } 2018 isGL4Available(final AbstractGraphicsDevice device, final boolean isHardware[])2019 public static boolean isGL4Available(final AbstractGraphicsDevice device, final boolean isHardware[]) { 2020 return isGLVersionAvailable(device, 4, CTX_PROFILE_CORE, isHardware); 2021 } 2022 isGL3bcAvailable(final AbstractGraphicsDevice device, final boolean isHardware[])2023 public static boolean isGL3bcAvailable(final AbstractGraphicsDevice device, final boolean isHardware[]) { 2024 return isGLVersionAvailable(device, 3, CTX_PROFILE_COMPAT, isHardware); 2025 } 2026 isGL3Available(final AbstractGraphicsDevice device, final boolean isHardware[])2027 public static boolean isGL3Available(final AbstractGraphicsDevice device, final boolean isHardware[]) { 2028 return isGLVersionAvailable(device, 3, CTX_PROFILE_CORE, isHardware); 2029 } 2030 isGL2Available(final AbstractGraphicsDevice device, final boolean isHardware[])2031 public static boolean isGL2Available(final AbstractGraphicsDevice device, final boolean isHardware[]) { 2032 return isGLVersionAvailable(device, 2, CTX_PROFILE_COMPAT, isHardware); 2033 } 2034 getGLProfile(final StringBuilder sb, final int ctp)2035 protected static StringBuilder getGLProfile(final StringBuilder sb, final int ctp) { 2036 boolean needColon = false; 2037 needColon = appendString(sb, "ES profile", needColon, 0 != ( CTX_PROFILE_ES & ctp )); 2038 needColon = appendString(sb, "Compat profile", needColon, 0 != ( CTX_PROFILE_COMPAT & ctp )); 2039 needColon = appendString(sb, "Core profile", needColon, 0 != ( CTX_PROFILE_CORE & ctp )); 2040 needColon = appendString(sb, "forward", needColon, 0 != ( CTX_OPTION_FORWARD & ctp )); 2041 needColon = appendString(sb, "arb", needColon, 0 != ( CTX_IS_ARB_CREATED & ctp )); 2042 needColon = appendString(sb, "debug", needColon, 0 != ( CTX_OPTION_DEBUG & ctp )); 2043 needColon = appendString(sb, "compat[", needColon, true); 2044 { 2045 needColon = false; 2046 needColon = appendString(sb, "ES2", needColon, 0 != ( CTX_IMPL_ES2_COMPAT & ctp )); 2047 needColon = appendString(sb, "ES3", needColon, 0 != ( CTX_IMPL_ES3_COMPAT & ctp )); 2048 needColon = appendString(sb, "ES31", needColon, 0 != ( CTX_IMPL_ES31_COMPAT & ctp )); 2049 needColon = appendString(sb, "ES32", needColon, 0 != ( CTX_IMPL_ES32_COMPAT & ctp )); 2050 needColon = appendString(sb, "FP32", needColon, 0 != ( CTX_IMPL_FP32_COMPAT_API & ctp )); 2051 needColon = false; 2052 } 2053 needColon = appendString(sb, "]", needColon, true); 2054 needColon = appendString(sb, "FBO", needColon, 0 != ( CTX_IMPL_FBO & ctp )); 2055 if( 0 != ( CTX_IMPL_ACCEL_SOFT & ctp ) ) { 2056 needColon = appendString(sb, "software", needColon, true); 2057 } else { 2058 needColon = appendString(sb, "hardware", needColon, true); 2059 } 2060 return sb; 2061 } getGLVersion(final StringBuilder sb, final VersionNumber version, final int ctp, final String gl_version)2062 protected static StringBuilder getGLVersion(final StringBuilder sb, final VersionNumber version, final int ctp, final String gl_version) { 2063 return getGLVersion(sb, version.getMajor(), version.getMinor(), ctp, gl_version); 2064 } getGLVersion(final StringBuilder sb, final int major, final int minor, final int ctp, final String gl_version)2065 protected static StringBuilder getGLVersion(final StringBuilder sb, final int major, final int minor, final int ctp, final String gl_version) { 2066 sb.append(major); 2067 sb.append("."); 2068 sb.append(minor); 2069 sb.append(" ("); 2070 getGLProfile(sb, ctp); 2071 sb.append(")"); 2072 if(null!=gl_version) { 2073 sb.append(" - "); 2074 sb.append(gl_version); 2075 } 2076 return sb; 2077 } getGLVersion(final int major, final int minor, final int ctp, final String gl_version)2078 protected static String getGLVersion(final int major, final int minor, final int ctp, final String gl_version) { 2079 return getGLVersion(new StringBuilder(), major, minor, ctp, gl_version).toString(); 2080 } 2081 2082 // 2083 // internal string utils 2084 // 2085 toHexString(final int hex)2086 protected static String toHexString(final int hex) { 2087 return "0x" + Integer.toHexString(hex); 2088 } 2089 toHexString(final long hex)2090 protected static String toHexString(final long hex) { 2091 return "0x" + Long.toHexString(hex); 2092 } 2093 appendString(final StringBuilder sb, final String string, boolean needColon, final boolean condition)2094 private static boolean appendString(final StringBuilder sb, final String string, boolean needColon, final boolean condition) { 2095 if(condition) { 2096 if(needColon) { 2097 sb.append(", "); 2098 } 2099 sb.append(string); 2100 needColon=true; 2101 } 2102 return needColon; 2103 } 2104 getThreadName()2105 protected static String getThreadName() { return Thread.currentThread().getName(); } 2106 2107 } 2108 2109