JOGL v2.6.0-rc-20250706
JOGL, High-Performance Graphics Binding for Java™ (public API).
GLProfile.java
Go to the documentation of this file.
1/*
2 * Copyright (c) 2010-2023 JogAmp Community. All rights reserved.
3 * Copyright (c) 2003 Sun Microsystems, Inc. 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
38package com.jogamp.opengl;
39
40import jogamp.opengl.Debug;
41import jogamp.opengl.GLDrawableFactoryImpl;
42import jogamp.opengl.GLDynamicLookupHelper;
43
44import com.jogamp.common.ExceptionUtils;
45import com.jogamp.common.GlueGenVersion;
46import com.jogamp.common.jvm.JNILibLoaderBase;
47import com.jogamp.common.os.Platform;
48import com.jogamp.common.util.PropertyAccess;
49import com.jogamp.common.util.ReflectionUtil;
50import com.jogamp.common.util.SecurityUtil;
51import com.jogamp.common.util.VersionUtil;
52import com.jogamp.common.util.cache.TempJarCache;
53import com.jogamp.common.util.locks.LockFactory;
54import com.jogamp.common.util.locks.RecursiveThreadGroupLock;
55import com.jogamp.gluegen.runtime.FunctionAddressResolver;
56import com.jogamp.nativewindow.NativeWindowVersion;
57
58import com.jogamp.nativewindow.AbstractGraphicsDevice;
59import com.jogamp.nativewindow.NativeWindowFactory;
60import com.jogamp.opengl.fixedfunc.GLPointerFunc;
61
62import java.lang.reflect.Constructor;
63import java.security.PrivilegedAction;
64import java.util.HashMap;
65import java.util.List;
66import java.util.Map;
67
68/**
69 * Specifies the the OpenGL profile.
70 *
71 * This class static singleton initialization queries the availability of all OpenGL Profiles
72 * and instantiates singleton GLProfile objects for each available profile.
73 *
74 * The platform default profile may be used, using {@link GLProfile#GetProfileDefault()},
75 * or more specialized versions using the other static GetProfile methods.
76 */
77public class GLProfile {
78
79 public static final boolean DEBUG;
80
81 /**
82 * In case no native OpenGL core profiles are required
83 * and if one platform may have a buggy implementation,
84 * setting the property <code>jogl.disable.openglcore</code> disables querying possible existing native OpenGL core profiles.
85 * <p>
86 * This exclusion is disabled for {@link Platform.OSType#MACOS} and {@link Platform.OSType#IOS}.
87 * </p>
88 */
89 public static final boolean disableOpenGLCore;
90
91 /**
92 * In case the implementation of the <i>ARB_create_context</i>
93 * context creation extension is buggy on one platform,
94 * setting the property <code>jogl.disable.openglarbcontext</code> disables utilizing it.
95 * <p>
96 * This exclusion also disables {@link #disableOpenGLES OpenGL ES}.
97 * </p>
98 * <p>
99 * This exclusion is disabled for {@link Platform.OSType#MACOS} and {@link Platform.OSType#IOS}.
100 * </p>
101 */
102 public static final boolean disableOpenGLARBContext;
103
104 /**
105 * In case no OpenGL ES profiles are required
106 * and if one platform may have a buggy implementation,
107 * setting the property <code>jogl.disable.opengles</code> disables querying possible existing OpenGL ES profiles.
108 */
109 public static final boolean disableOpenGLES;
110
111 /**
112 * In case no OpenGL desktop profiles are required
113 * and if one platform may have a buggy implementation,
114 * setting the property <code>jogl.disable.opengldesktop</code> disables querying possible existing OpenGL desktop profiles.
115 */
116 public static final boolean disableOpenGLDesktop;
117
118 /**
119 * In case no EGL implementation is available
120 * like on the {@link Platform.OSType#IOS} platform,
121 * this is set to {@code true}.
122 */
123 public static final boolean disabledEGL;
124
125 /**
126 * Disable surfaceless OpenGL context capability and its probing
127 * by setting the property <code>jogl.disable.surfacelesscontext</code>.
128 * <p>
129 * By default surfaceless OpenGL context capability is probed,
130 * i.e. whether an OpenGL context can be made current without a default framebuffer.
131 * </p>
132 * <p>
133 * If probing fails or if this property is set, the {@link GLRendererQuirks quirk} {@link GLRendererQuirks#NoSurfacelessCtx}
134 * is being set.
135 * </p>
136 */
137 public static final boolean disableSurfacelessContext;
138
139 /**
140 * We have to disable support for ANGLE, the D3D ES2 emulation on Windows provided w/ Firefox and Chrome.
141 * When run in the mentioned browsers, the eglInitialize(..) implementation crashes.
142 * <p>
143 * This can be overridden by explicitly enabling ANGLE on Windows by setting the property
144 * <code>jogl.enable.ANGLE</code>.
145 * </p>
146 */
147 public static final boolean enableANGLE;
148
149 static {
150 // Also initializes TempJarCache if shall be used.
151 Platform.initSingleton();
152 final boolean isIOS = Platform.OSType.IOS == Platform.getOSType();
153 final boolean isOSXorIOS = Platform.OSType.MACOS == Platform.getOSType() || isIOS;
154
155 DEBUG = Debug.debug("GLProfile");
156 disabledEGL = isIOS;
157 disableOpenGLCore = PropertyAccess.isPropertyDefined("jogl.disable.openglcore", true) && !isOSXorIOS;
158 disableOpenGLARBContext = PropertyAccess.isPropertyDefined("jogl.disable.openglarbcontext", true) && !isOSXorIOS;
159 disableOpenGLES = disableOpenGLARBContext || PropertyAccess.isPropertyDefined("jogl.disable.opengles", true);
160 disableOpenGLDesktop = PropertyAccess.isPropertyDefined("jogl.disable.opengldesktop", true);
161 disableSurfacelessContext = PropertyAccess.isPropertyDefined("jogl.disable.surfacelesscontext", true);
162 enableANGLE = PropertyAccess.isPropertyDefined("jogl.enable.ANGLE", true);
163 }
164
165 /**
166 * @return <code>true</code> if JOGL has been initialized, i.e. manually via {@link #initSingleton()} or implicit,
167 * otherwise returns <code>false</code>.
168 *
169 * @since 2.2.1
170 */
171 public static boolean isInitialized() {
172 initLock.lock();
173 try {
174 return initialized;
175 } finally {
176 initLock.unlock();
177 }
178 }
179
180 /**
181 * Static initialization of JOGL.
182 *
183 * <p>
184 * This method shall not need to be called for other reasons than having a defined initialization sequence.
185 * </p>
186 *
187 * <P>
188 * In case this method is not invoked, GLProfile is initialized implicit by
189 * the first call to {@link #getDefault()}, {@link #get(java.lang.String)}.
190 * <P>
191 *
192 * <p>
193 * To initialize JOGL at startup ASAP, this method may be invoked in the <i>main class</i>'s
194 * static initializer block, in the <i>static main() method</i> or in the <i>Applet init() method</i>.
195 * </p>
196 *
197 * <p>
198 * Since JOGL's initialization is complex and involves multi threading, it is <b>not</b> recommended
199 * to be have it invoked on the AWT EDT thread. In case all JOGL usage is performed
200 * on the AWT EDT, invoke this method outside the AWT EDT - see above.
201 * </p>
202 *
203 */
204 public static void initSingleton() {
205 final boolean justInitialized;
206 initLock.lock();
207 try {
208 if(!initialized) {
209 initialized = true;
210 justInitialized = true;
211 if(DEBUG) {
212 System.err.println("GLProfile.initSingleton() - thread "+Thread.currentThread().getName());
213 ExceptionUtils.dumpStack(System.err);
214 }
215
216 if(ReflectionUtil.DEBUG_STATS_FORNAME) {
217 ReflectionUtil.resetForNameCount();
218 }
219
220 // run the whole static initialization privileged to speed up,
221 // since this skips checking further access
222 SecurityUtil.doPrivileged(new PrivilegedAction<Object>() {
223 @Override
224 public Object run() {
225 Platform.initSingleton();
226
227 if( TempJarCache.isInitialized(true) ) {
228 final ClassLoader cl = GLProfile.class.getClassLoader();
229 final String newtDebugClassName = "jogamp.newt.Debug";
230 final Class<?>[] classesFromJavaJars = new Class<?>[] { jogamp.nativewindow.Debug.class, jogamp.opengl.Debug.class, null };
231 if( ReflectionUtil.isClassAvailable(newtDebugClassName, cl) ) {
232 classesFromJavaJars[2] = ReflectionUtil.getClass(newtDebugClassName, false, cl);
233 }
234 JNILibLoaderBase.addNativeJarLibsJoglCfg(classesFromJavaJars);
235 }
236 initProfilesForDefaultDevices();
237 return null;
238 }
239 });
240 if( ReflectionUtil.DEBUG_STATS_FORNAME ) {
241 if( justInitialized ) {
242 System.err.println(ReflectionUtil.getForNameStats(null).toString());
243 }
244 }
245 } else {
246 justInitialized = false;
247 }
248 } finally {
249 initLock.unlock();
250 }
251 if(DEBUG) {
252 if( justInitialized && ( hasGL234Impl || hasGL234OnMobileImpl || hasGLES1Impl || hasGLES3Impl ) ) {
253 System.err.println(JoglVersion.getDefaultOpenGLInfo(defaultDevice, null, true));
254 }
255 }
256 }
257
258 /**
259 * Trigger eager initialization of GLProfiles for the given device,
260 * in case it isn't done yet.
261 *
262 * @throws GLException if no profile for the given device is available.
263 */
264 public static void initProfiles(final AbstractGraphicsDevice device) throws GLException {
265 getProfileMap(device, true);
266 }
267
268 /**
269 * Manual shutdown method, may be called after your last JOGL use
270 * within the running JVM.<br>
271 * It releases all temporary created resources, ie issues {@link com.jogamp.opengl.GLDrawableFactory#shutdown()}.<br>
272 * The shutdown implementation is called via the JVM shutdown hook, if not manually invoked.<br>
273 * <p>
274 * This method shall not need to be called for other reasons than issuing a proper shutdown of resources at a defined time.
275 * </p>
276 */
277 public static void shutdown() {
278 initLock.lock();
279 try {
280 if(initialized) {
281 initialized = false;
282 if(DEBUG) {
283 System.err.println("GLProfile.shutdown() - thread "+Thread.currentThread().getName());
284 ExceptionUtils.dumpStack(System.err);
285 }
287 }
288 } finally {
289 initLock.unlock();
290 }
291 }
292
293 //
294 // Query platform available OpenGL implementation
295 //
296
297 /**
298 * Returns the availability of a profile on a device.
299 *
300 * @param device a valid AbstractGraphicsDevice, or <code>null</null> for the default device.
301 * @param profile a valid GLProfile name ({@link #GL4bc}, {@link #GL4}, {@link #GL2}, ..),
302 * or <code>[ null, GL ]</code> for the default profile.
303 * @return true if the profile is available for the device, otherwise false.
304 */
305 public static boolean isAvailable(final AbstractGraphicsDevice device, final String profile) {
307 return isAvailableImpl(getProfileMap(device, false), profile);
308 }
309 private static boolean isAvailableImpl(final HashMap<String /*GLProfile_name*/, GLProfile> map, final String profile) {
310 return null != map && null != map.get(profile);
311 }
312
313 /**
314 * Returns the availability of a profile on the default device.
315 *
316 * @param profile a valid GLProfile name ({@link #GL4bc}, {@link #GL4}, {@link #GL2}, ..),
317 * or <code>[ null, GL ]</code> for the default profile.
318 * @return true if the profile is available for the default device, otherwise false.
319 */
320 public static boolean isAvailable(final String profile) {
321 return isAvailable(null, profile);
322 }
323
324 /**
325 * Returns the availability of any profile on the default device.
326 *
327 * @return true if any profile is available for the default device, otherwise false.
328 */
329 public static boolean isAnyAvailable() {
330 return isAvailable(null, null);
331 }
332
333 public static String glAvailabilityToString(final AbstractGraphicsDevice device) {
334 return glAvailabilityToString(device, null).toString();
335 }
336
337 public static StringBuilder glAvailabilityToString(final AbstractGraphicsDevice device, final StringBuilder sb) {
338 return glAvailabilityToString(device, sb, null, 0);
339 }
340 private static StringBuilder doIndent(final StringBuilder sb, final String indent, int indentCount) {
341 while(indentCount>0) {
342 sb.append(indent);
343 indentCount--;
344 }
345 return sb;
346 }
347 public static StringBuilder glAvailabilityToString(AbstractGraphicsDevice device, StringBuilder sb, final String indent, int indentCount) {
348 boolean avail;
349 if(null == sb) {
350 sb = new StringBuilder();
351 }
352 final boolean useIndent = null != indent;
353
355
356 int allCount = 0;
357 int nativeCount = 0;
358
359 if(null==device) {
360 device = defaultDevice;
361 }
362 final HashMap<String /*GLProfile_name*/, GLProfile> map = getProfileMap(device, false);
363
364 if(useIndent) {
365 doIndent(sb, indent, indentCount).append("Natives");
366 indentCount++;
367 doIndent(sb.append(Platform.getNewline()), indent, indentCount).append(GL4bc+" ").append(indent);
368 } else {
369 sb.append("Natives["+GL4bc+" ");
370 }
371 avail=isAvailableImpl(map, GL4bc);
372 sb.append(avail);
373 if(avail) {
374 nativeCount++;
375 glAvailabilityToString(device, sb.append(" "), 4, GLContext.CTX_PROFILE_COMPAT);
376 }
377 allCount++;
378
379 if(useIndent) {
380 doIndent(sb.append(Platform.getNewline()), indent, indentCount).append(GL4+" ").append(indent);
381 } else {
382 sb.append(", "+GL4+" ");
383 }
384 avail=isAvailableImpl(map, GL4);
385 sb.append(avail);
386 if(avail) {
387 nativeCount++;
388 glAvailabilityToString(device, sb.append(" "), 4, GLContext.CTX_PROFILE_CORE);
389 }
390 allCount++;
391
392 if(useIndent) {
393 doIndent(sb.append(Platform.getNewline()), indent, indentCount).append(GLES3+" ").append(indent);
394 } else {
395 sb.append(", "+GLES3+" ");
396 }
397 avail=isAvailableImpl(map, GLES3);
398 sb.append(avail);
399 if(avail) {
400 nativeCount++;
401 glAvailabilityToString(device, sb.append(" "), 3, GLContext.CTX_PROFILE_ES);
402 }
403 allCount++;
404
405 if(useIndent) {
406 doIndent(sb.append(Platform.getNewline()), indent, indentCount).append(GL3bc+" ").append(indent);
407 } else {
408 sb.append(", "+GL3bc+" ");
409 }
410 avail=isAvailableImpl(map, GL3bc);
411 sb.append(avail);
412 if(avail) {
413 nativeCount++;
414 glAvailabilityToString(device, sb.append(" "), 3, GLContext.CTX_PROFILE_COMPAT);
415 }
416 allCount++;
417
418 if(useIndent) {
419 doIndent(sb.append(Platform.getNewline()), indent, indentCount).append(GL3+" ").append(indent);
420 } else {
421 sb.append(", "+GL3+" ");
422 }
423 avail=isAvailableImpl(map, GL3);
424 sb.append(avail);
425 if(avail) {
426 nativeCount++;
427 glAvailabilityToString(device, sb.append(" "), 3, GLContext.CTX_PROFILE_CORE);
428 }
429 allCount++;
430
431 if(useIndent) {
432 doIndent(sb.append(Platform.getNewline()), indent, indentCount).append(GL2+" ").append(indent);
433 } else {
434 sb.append(", "+GL2+" ");
435 }
436 avail=isAvailableImpl(map, GL2);
437 sb.append(avail);
438 if(avail) {
439 nativeCount++;
440 glAvailabilityToString(device, sb.append(" "), 2, GLContext.CTX_PROFILE_COMPAT);
441 }
442 allCount++;
443
444 if(useIndent) {
445 doIndent(sb.append(Platform.getNewline()), indent, indentCount).append(GLES2+" ").append(indent);
446 } else {
447 sb.append(", "+GLES2+" ");
448 }
449 avail=isAvailableImpl(map, GLES2);
450 sb.append(avail);
451 if(avail) {
452 nativeCount++;
453 glAvailabilityToString(device, sb.append(" "), 2, GLContext.CTX_PROFILE_ES);
454 }
455 allCount++;
456
457 if(useIndent) {
458 doIndent(sb.append(Platform.getNewline()), indent, indentCount).append(GLES1+" ").append(indent);
459 } else {
460 sb.append(", "+GLES1+" ");
461 }
462 avail=isAvailableImpl(map, GLES1);
463 sb.append(avail);
464 if(avail) {
465 nativeCount++;
466 glAvailabilityToString(device, sb.append(" "), 1, GLContext.CTX_PROFILE_ES);
467 }
468 allCount++;
469
470 if(useIndent) {
471 doIndent(sb.append(Platform.getNewline()), indent, indentCount).append("Count\t"+nativeCount+" / "+allCount);
472 indentCount--;
473 doIndent(sb.append(Platform.getNewline()), indent, indentCount).append("Common");
474 indentCount++;
475 } else {
476 sb.append(", count "+nativeCount+" / "+allCount+"], Common[");
477 }
478
479 if(useIndent) {
480 doIndent(sb.append(Platform.getNewline()), indent, indentCount).append(GL4ES3+" ").append(indent);
481 } else {
482 sb.append(", "+GL4ES3+" ");
483 }
484 sb.append(isAvailableImpl(map, GL4ES3));
485 allCount++;
486
487 if(useIndent) {
488 doIndent(sb.append(Platform.getNewline()), indent, indentCount).append(GL2GL3+" ").append(indent);
489 } else {
490 sb.append(", "+GL2GL3+" ");
491 }
492 sb.append(isAvailableImpl(map, GL2GL3));
493 allCount++;
494
495 if(useIndent) {
496 doIndent(sb.append(Platform.getNewline()), indent, indentCount).append(GL2ES2+" ").append(indent);
497 } else {
498 sb.append(", "+GL2ES2+" ");
499 }
500 sb.append(isAvailableImpl(map, GL2ES2));
501 allCount++;
502
503 if(useIndent) {
504 doIndent(sb.append(Platform.getNewline()), indent, indentCount).append(GL2ES1+" ").append(indent);
505 } else {
506 sb.append(", "+GL2ES1+" ");
507 }
508 sb.append(isAvailableImpl(map, GL2ES1));
509 allCount++;
510
511 if(useIndent) {
512 indentCount--;
513 doIndent(sb.append(Platform.getNewline()), indent, indentCount).append("Mappings");
514 indentCount++;
515 } else {
516 sb.append("], Mappings[");
517 }
518
519 int profileCount = 0;
520
521 if(null != map) {
522 for (final Map.Entry<String,GLProfile> entry : map.entrySet()) {
523 if( GL_DEFAULT != entry.getKey() ) {
524 if(useIndent) {
525 doIndent(sb.append(Platform.getNewline()), indent, indentCount);
526 }
527 sb.append(entry.getKey()+(useIndent?" \t":" ")+entry.getValue());
528 if(!useIndent) {
529 sb.append(", ");
530 }
531 profileCount++;
532 }
533 }
534 if(useIndent) {
535 doIndent(sb.append(Platform.getNewline()), indent, indentCount).append("default ");
536 } else {
537 sb.append(", default ");
538 }
539 try {
540 sb.append(getDefault(device));
541 } catch (final GLException gle) {
542 sb.append("n/a");
543 }
544 }
545 if(useIndent) {
546 doIndent(sb.append(Platform.getNewline()), indent, indentCount).append("Count\t"+profileCount+" / "+allCount);
547 sb.append(Platform.getNewline());
548 } else {
549 sb.append(", count "+profileCount+" / "+allCount+"]");
550 }
551
552 return sb;
553 }
554
555 /** Uses the default device */
556 public static String glAvailabilityToString() {
557 return glAvailabilityToString(null);
558 }
559
560 //
561 // Public (user-visible) profiles
562 //
563
564 /** The desktop OpenGL compatibility profile 4.x, with x >= 0, ie GL2 plus GL4.<br>
565 <code>bc</code> stands for backward compatibility. */
566 public static final String GL4bc = "GL4bc"; // Implicitly intern(), see Bug 1059
567
568 /** The desktop OpenGL core profile 4.x, with x >= 0 */
569 public static final String GL4 = "GL4"; // Implicitly intern(), see Bug 1059
570
571 /** The desktop OpenGL compatibility profile 3.x, with x >= 1, ie GL2 plus GL3.<br>
572 <code>bc</code> stands for backward compatibility. */
573 public static final String GL3bc = "GL3bc"; // Implicitly intern(), see Bug 1059
574
575 /** The desktop OpenGL core profile 3.x, with x >= 1 */
576 public static final String GL3 = "GL3"; // Implicitly intern(), see Bug 1059
577
578 /** The desktop OpenGL profile 1.x up to 3.0 */
579 public static final String GL2 = "GL2"; // Implicitly intern(), see Bug 1059
580
581 /** The embedded OpenGL profile ES 1.x, with x >= 0 */
582 public static final String GLES1 = "GLES1"; // Implicitly intern(), see Bug 1059
583
584 /** The embedded OpenGL profile ES 2.x, with x >= 0 */
585 public static final String GLES2 = "GLES2"; // Implicitly intern(), see Bug 1059
586
587 /** The embedded OpenGL profile ES 3.x, with x >= 0 */
588 public static final String GLES3 = "GLES3"; // Implicitly intern(), see Bug 1059
589
590 /** The intersection of the desktop GL2 and embedded ES1 profile */
591 public static final String GL2ES1 = "GL2ES1"; // Implicitly intern(), see Bug 1059
592
593 /** The intersection of the desktop GL3, GL2 and embedded ES2 profile */
594 public static final String GL2ES2 = "GL2ES2"; // Implicitly intern(), see Bug 1059
595
596 /** The intersection of the desktop GL3 and GL2 profile */
597 public static final String GL2GL3 = "GL2GL3"; // Implicitly intern(), see Bug 1059
598
599 /** The intersection of the desktop GL4 and ES3 profile, available only if either ES3 or GL4 w/ <code>GL_ARB_ES3_compatibility</code> is available. */
600 public static final String GL4ES3 = "GL4ES3"; // Implicitly intern(), see Bug 1059
601
602 /** The default profile, used for the device default profile map */
603 private static final String GL_DEFAULT = "GL_DEFAULT"; // Implicitly intern(), see Bug 1059
604 /** The default profile, used for the device default profile map */
605 private static final String GL_GL = "GL"; // Implicitly intern(), see Bug 1059
606
607 /**
608 * All GL Profiles in the order of default detection.
609 * Desktop compatibility profiles (the one with fixed function pipeline) comes first
610 * from highest to lowest version.
611 * <p> This includes the generic subset profiles GL2GL3, GL2ES2 and GL2ES1.</p>
612 *
613 * <ul>
614 * <li> GL4bc </li>
615 * <li> GL3bc </li>
616 * <li> GL2 </li>
617 * <li> GL4 </li>
618 * <li> GL3 </li>
619 * <li> GLES3 </li>
620 * <li> GL4ES3 </li>
621 * <li> GL2GL3 </li>
622 * <li> GLES2 </li>
623 * <li> GL2ES2 </li>
624 * <li> GLES1 </li>
625 * <li> GL2ES1 </li>
626 * </ul>
627 *
628 */
629 public static final String[] GL_PROFILE_LIST_ALL = new String[] { GL4bc, GL3bc, GL2, GL4, GL3, GLES3, GL4ES3, GL2GL3, GLES2, GL2ES2, GLES1, GL2ES1 };
630
631 /**
632 * Order of maximum profiles.
633 *
634 * <ul>
635 * <li> GL4bc </li>
636 * <li> GL4 </li>
637 * <li> GL3bc </li>
638 * <li> GL3 </li>
639 * <li> GLES3 </li>
640 * <li> GL2 </li>
641 * <li> GLES2 </li>
642 * <li> GLES1 </li>
643 * </ul>
644 *
645 */
646 public static final String[] GL_PROFILE_LIST_MAX = new String[] { GL4bc, GL4, GL3bc, GL3, GLES3, GL2, GLES2, GLES1 };
647
648 /**
649 * Order of minimum profiles.
650 *
651 * <ul>
652 * <li> GLES1 </li>
653 * <li> GLES2 </li>
654 * <li> GL2 </li>
655 * <li> GLES3 </li>
656 * <li> GL3 </li>
657 * <li> GL3bc </li>
658 * <li> GL4 </li>
659 * <li> GL4bc </li>
660 * </ul>
661 *
662 */
663 public static final String[] GL_PROFILE_LIST_MIN = new String[] { GLES1, GLES2, GL2, GLES3, GL3, GL3bc, GL4, GL4bc };
664
665 /**
666 * Order of minimum original desktop profiles.
667 *
668 * <ul>
669 * <li> GL2 </li>
670 * <li> GL3bc </li>
671 * <li> GL4bc </li>
672 * <li> GL3 </li>
673 * <li> GL4 </li>
674 * </ul>
675 *
676 */
677 public static final String[] GL_PROFILE_LIST_MIN_DESKTOP = new String[] { GL2, GL3bc, GL4bc, GL3, GL4 };
678
679 /**
680 * Order of maximum original mobile profiles.
681 *
682 * <ul>
683 * <li> GLES3 </li>
684 * <li> GLES2 </li>
685 * <li> GLES1 </li>
686 * </ul>
687 *
688 */
689 public static final String[] GL_PROFILE_LIST_MAX_MOBILE = new String[] { GLES3, GLES2, GLES1 };
690
691 /**
692 * Order of maximum fixed function profiles
693 *
694 * <ul>
695 * <li> GL4bc </li>
696 * <li> GL3bc </li>
697 * <li> GL2 </li>
698 * <li> GLES1 </li>
699 * </ul>
700 *
701 */
702 public static final String[] GL_PROFILE_LIST_MAX_FIXEDFUNC = new String[] { GL4bc, GL3bc, GL2, GLES1 };
703
704 /**
705 * Order of maximum programmable shader profiles
706 *
707 * <ul>
708 * <li> GL4bc </li>
709 * <li> GL4 </li>
710 * <li> GL3bc </li>
711 * <li> GL3 </li>
712 * <li> GLES3 </li>
713 * <li> GL2 </li>
714 * <li> GLES2 </li>
715 * </ul>
716 *
717 */
718 public static final String[] GL_PROFILE_LIST_MAX_PROGSHADER = new String[] { GL4bc, GL4, GL3bc, GL3, GLES3, GL2, GLES2 };
719
720 /**
721 * Order of maximum programmable shader <i>core only</i> profiles
722 *
723 * <ul>
724 * <li> GL4 </li>
725 * <li> GL3 </li>
726 * <li> GLES3 </li>
727 * <li> GLES2 </li>
728 * </ul>
729 *
730 */
731 public static final String[] GL_PROFILE_LIST_MAX_PROGSHADER_CORE = new String[] { GL4, GL3, GLES3, GLES2 };
732
733 /** Returns a default GLProfile object, reflecting the best for the running platform.
734 * It selects the first of the set {@link GLProfile#GL_PROFILE_LIST_ALL}
735 * and favors hardware acceleration.
736 * @throws GLException if no profile is available for the device.
737 * @see #GL_PROFILE_LIST_ALL
738 */
739 public static GLProfile getDefault(final AbstractGraphicsDevice device) {
740 final GLProfile glp = get(device, GL_DEFAULT);
741 return glp;
742 }
743
744 /** Returns a default GLProfile object, reflecting the best for the running platform.
745 * It selects the first of the set {@link GLProfile#GL_PROFILE_LIST_ALL}
746 * and favors hardware acceleration.
747 * <p>Uses the default device.</p>
748 * @throws GLException if no profile is available for the default device.
749 */
750 public static GLProfile getDefault() {
751 return getDefault(defaultDevice);
752 }
753
754 /**
755 * Returns the highest profile.
756 * It selects the first of the set: {@link GLProfile#GL_PROFILE_LIST_MAX}
757 *
758 * @throws GLException if no profile is available for the device.
759 * @see #GL_PROFILE_LIST_MAX
760 */
761 public static GLProfile getMaximum(final AbstractGraphicsDevice device, final boolean favorHardwareRasterizer)
762 throws GLException
763 {
764 return get(device, GL_PROFILE_LIST_MAX, favorHardwareRasterizer);
765 }
766
767 /** Uses the default device
768 * @throws GLException if no profile is available for the default device.
769 * @see #GL_PROFILE_LIST_MAX
770 */
771 public static GLProfile getMaximum(final boolean favorHardwareRasterizer)
772 throws GLException
773 {
774 return get(GL_PROFILE_LIST_MAX, favorHardwareRasterizer);
775 }
776
777 /**
778 * Returns the lowest profile.
779 * It selects the first of the set: {@link GLProfile#GL_PROFILE_LIST_MIN}
780 *
781 * @throws GLException if no desktop profile is available for the device.
782 * @see #GL_PROFILE_LIST_MIN
783 */
784 public static GLProfile getMinimum(final AbstractGraphicsDevice device, final boolean favorHardwareRasterizer)
785 throws GLException
786 {
787 return get(device, GL_PROFILE_LIST_MIN, favorHardwareRasterizer);
788 }
789
790 /** Uses the default device
791 * @throws GLException if no desktop profile is available for the default device.
792 * @see #GL_PROFILE_LIST_MIN
793 */
794 public static GLProfile getMinimum(final boolean favorHardwareRasterizer)
795 throws GLException
796 {
797 return get(GL_PROFILE_LIST_MIN, favorHardwareRasterizer);
798 }
799
800
801 /**
802 * Returns the highest profile, implementing the fixed function pipeline.
803 * It selects the first of the set: {@link GLProfile#GL_PROFILE_LIST_MAX_FIXEDFUNC}
804 *
805 * @throws GLException if no fixed function profile is available for the device.
806 * @see #GL_PROFILE_LIST_MAX_FIXEDFUNC
807 */
808 public static GLProfile getMaxFixedFunc(final AbstractGraphicsDevice device, final boolean favorHardwareRasterizer)
809 throws GLException
810 {
811 return get(device, GL_PROFILE_LIST_MAX_FIXEDFUNC, favorHardwareRasterizer);
812 }
813
814 /** Uses the default device
815 * @throws GLException if no fixed function profile is available for the default device.
816 * @see #GL_PROFILE_LIST_MAX_FIXEDFUNC
817 */
818 public static GLProfile getMaxFixedFunc(final boolean favorHardwareRasterizer)
819 throws GLException
820 {
821 return get(GL_PROFILE_LIST_MAX_FIXEDFUNC, favorHardwareRasterizer);
822 }
823
824 /**
825 * Returns the highest profile, implementing the programmable shader pipeline.
826 * It selects the first of the set: {@link GLProfile#GL_PROFILE_LIST_MAX_PROGSHADER}
827 *
828 * @throws GLException if no programmable profile is available for the device.
829 * @see #GL_PROFILE_LIST_MAX_PROGSHADER
830 */
831 public static GLProfile getMaxProgrammable(final AbstractGraphicsDevice device, final boolean favorHardwareRasterizer)
832 throws GLException
833 {
834 return get(device, GL_PROFILE_LIST_MAX_PROGSHADER, favorHardwareRasterizer);
835 }
836
837 /** Uses the default device
838 * @throws GLException if no programmable profile is available for the default device.
839 * @see #GL_PROFILE_LIST_MAX_PROGSHADER
840 */
841 public static GLProfile getMaxProgrammable(final boolean favorHardwareRasterizer)
842 throws GLException
843 {
844 return get(GL_PROFILE_LIST_MAX_PROGSHADER, favorHardwareRasterizer);
845 }
846
847 /**
848 * Returns the highest profile, implementing the programmable shader <i>core</i> pipeline <i>only</i>.
849 * It selects the first of the set: {@link GLProfile#GL_PROFILE_LIST_MAX_PROGSHADER_CORE}
850 *
851 * @throws GLException if no programmable core profile is available for the device.
852 * @see #GL_PROFILE_LIST_MAX_PROGSHADER_CORE
853 */
854 public static GLProfile getMaxProgrammableCore(final AbstractGraphicsDevice device, final boolean favorHardwareRasterizer)
855 throws GLException
856 {
857 return get(device, GL_PROFILE_LIST_MAX_PROGSHADER_CORE, favorHardwareRasterizer);
858 }
859
860 /** Uses the default device
861 * @throws GLException if no programmable core profile is available for the default device.
862 * @see #GL_PROFILE_LIST_MAX_PROGSHADER_CORE
863 */
864 public static GLProfile getMaxProgrammableCore(final boolean favorHardwareRasterizer)
865 throws GLException
866 {
867 return get(GL_PROFILE_LIST_MAX_PROGSHADER_CORE, favorHardwareRasterizer);
868 }
869
870 /**
871 * Returns the GL2ES1 profile implementation, hence compatible w/ GL2ES1.<br/>
872 * It returns:
873 * <pre>
874 * GLProfile.get(device, GLProfile.GL2ES1).getImpl());
875 * </pre>
876 * <p>Selection favors hardware rasterizer.</p>
877 *
878 * @throws GLException if no GL2ES1 compatible profile is available for the default device.
879 * @see #isGL2ES1()
880 * @see #get(AbstractGraphicsDevice, String)
881 * @see #getImpl()
882 */
883 public static GLProfile getGL2ES1(final AbstractGraphicsDevice device)
884 throws GLException
885 {
886 return get(device, GL2ES1).getImpl();
887 }
888
889 /**
890 * Calls {@link #getGL2ES1(AbstractGraphicsDevice)} using the default device.
891 * <p>Selection favors hardware rasterizer.</p>
892 * @see #getGL2ES1(AbstractGraphicsDevice)
893 */
894 public static GLProfile getGL2ES1()
895 throws GLException
896 {
897 return get(defaultDevice, GL2ES1).getImpl();
898 }
899
900 /**
901 * Returns the GL2ES2 profile implementation, hence compatible w/ GL2ES2.<br/>
902 * It returns:
903 * <pre>
904 * GLProfile.get(device, GLProfile.GL2ES2).getImpl());
905 * </pre>
906 * <p>Selection favors hardware rasterizer.</p>
907 *
908 * @throws GLException if no GL2ES2 compatible profile is available for the default device.
909 * @see #isGL2ES2()
910 * @see #get(AbstractGraphicsDevice, String)
911 * @see #getImpl()
912 */
913 public static GLProfile getGL2ES2(final AbstractGraphicsDevice device)
914 throws GLException
915 {
916 return get(device, GL2ES2).getImpl();
917 }
918
919 /**
920 * Calls {@link #getGL2ES2(AbstractGraphicsDevice)} using the default device.
921 * <p>Selection favors hardware rasterizer.</p>
922 * @see #getGL2ES2(AbstractGraphicsDevice)
923 */
924 public static GLProfile getGL2ES2()
925 throws GLException
926 {
927 return get(defaultDevice, GL2ES2).getImpl();
928 }
929
930 /**
931 * Returns the GL4ES3 profile implementation, hence compatible w/ GL4ES3.<br/>
932 * It returns:
933 * <pre>
934 * GLProfile.get(device, GLProfile.GL4ES3).getImpl());
935 * </pre>
936 * <p>Selection favors hardware rasterizer.</p>
937 *
938 * @throws GLException if no GL4ES3 compatible profile is available for the default device.
939 * @see #isGL4ES3()
940 * @see #get(AbstractGraphicsDevice, String)
941 * @see #getImpl()
942 */
943 public static GLProfile getGL4ES3(final AbstractGraphicsDevice device)
944 throws GLException
945 {
946 return get(device, GL4ES3).getImpl();
947 }
948
949 /**
950 * Calls {@link #getGL4ES3(AbstractGraphicsDevice)} using the default device.
951 * <p>Selection favors hardware rasterizer.</p>
952 * @see #getGL4ES3(AbstractGraphicsDevice)
953 */
954 public static GLProfile getGL4ES3()
955 throws GLException
956 {
957 return get(defaultDevice, GL4ES3).getImpl();
958 }
959
960 /**
961 * Returns the GL2GL3 profile implementation, hence compatible w/ GL2GL3.<br/>
962 * It returns:
963 * <pre>
964 * GLProfile.get(device, GLProfile.GL2GL3).getImpl());
965 * </pre>
966 * <p>Selection favors hardware rasterizer.</p>
967 *
968 * @throws GLException if no GL2GL3 compatible profile is available for the default device.
969 * @see #isGL2GL3()
970 * @see #get(AbstractGraphicsDevice, String)
971 * @see #getImpl()
972 */
973 public static GLProfile getGL2GL3(final AbstractGraphicsDevice device)
974 throws GLException
975 {
976 return get(device, GL2GL3).getImpl();
977 }
978
979 /**
980 * Calls {@link #getGL2GL3(AbstractGraphicsDevice)} using the default device.
981 * <p>Selection favors hardware rasterizer.</p>
982 * @see #getGL2GL3(AbstractGraphicsDevice)
983 */
984 public static GLProfile getGL2GL3()
985 throws GLException
986 {
987 return get(defaultDevice, GL2GL3).getImpl();
988 }
989
990 /** Returns a GLProfile object.
991 * verifies the given profile and chooses an appropriate implementation.
992 * A generic value of <code>null</code> or <code>GL</code> will result in
993 * the default profile.
994 *
995 * @param device a valid AbstractGraphicsDevice, or <code>null</null> for the default device.
996 * @param profile a valid GLProfile name ({@link #GL4bc}, {@link #GL4}, {@link #GL2}, ..),
997 * or <code>[ null, GL ]</code> for the default profile.
998 * @throws GLException if the requested profile is not available for the device.
999 */
1000 public static GLProfile get(final AbstractGraphicsDevice device, String profile)
1001 throws GLException
1002 {
1003 if(null==profile || profile == GL_GL) {
1004 profile = GL_DEFAULT;
1005 }
1006 final HashMap<String /*GLProfile_name*/, GLProfile> glpMap = getProfileMap(device, true);
1007 final GLProfile glp = glpMap.get(profile);
1008 if(null == glp) {
1009 throw new GLException("Profile "+profile+" is not available on "+device+", but: "+glpMap.values());
1010 }
1011 return glp;
1012 }
1013
1014 /** Uses the default device
1015 * @param profile a valid GLProfile name ({@link #GL4bc}, {@link #GL4}, {@link #GL2}, ..),
1016 * or <code>[ null, GL ]</code> for the default profile.
1017 * @throws GLException if the requested profile is not available for the default device.
1018 */
1019 public static GLProfile get(final String profile)
1020 throws GLException
1021 {
1022 return get(defaultDevice, profile);
1023 }
1024
1025 /**
1026 * Returns the first profile from the given list,
1027 * where an implementation is available.
1028 *
1029 * @param device a valid AbstractGraphicsDevice, or <code>null</null> for the default device.
1030 * @param profiles array of valid GLProfile name ({@link #GL4bc}, {@link #GL4}, {@link #GL2}, ..)
1031 * @param favorHardwareRasterizer set to true, if hardware rasterizer shall be favored, otherwise false.
1032 * @throws GLException if the non of the requested profiles is available for the device.
1033 */
1034 public static GLProfile get(final AbstractGraphicsDevice device, final String[] profiles, final boolean favorHardwareRasterizer)
1035 throws GLException
1036 {
1037 GLProfile glProfileAny = null;
1038
1039 final HashMap<String /*GLProfile_name*/, GLProfile> map = getProfileMap(device, true);
1040 for(int i=0; i<profiles.length; i++) {
1041 final GLProfile glProfile = map.get(profiles[i]);
1042 if(null!=glProfile) {
1043 if(!favorHardwareRasterizer) {
1044 return glProfile;
1045 }
1046 if(glProfile.isHardwareRasterizer()) {
1047 return glProfile;
1048 }
1049 if(null==glProfileAny) {
1050 glProfileAny = glProfile;
1051 }
1052 }
1053 }
1054 if(null!=glProfileAny) {
1055 return glProfileAny;
1056 }
1057 throw new GLException("Profiles "+array2String(profiles)+" not available on device "+device);
1058 }
1059
1060 /** Uses the default device
1061 * @param profiles array of valid GLProfile name ({@link #GL4bc}, {@link #GL4}, {@link #GL2}, ..)
1062 * @param favorHardwareRasterizer set to true, if hardware rasterizer shall be favored, otherwise false.
1063 * @throws GLException if the non of the requested profiles is available for the default device.
1064 */
1065 public static GLProfile get(final String[] profiles, final boolean favorHardwareRasterizer)
1066 throws GLException
1067 {
1068 return get(defaultDevice, profiles, favorHardwareRasterizer);
1069 }
1070
1071 /** Indicates whether the native OpenGL ES1 profile is in use.
1072 * This requires an EGL interface.
1073 */
1074 public static boolean usesNativeGLES1(final String profileImpl) {
1075 return GLES1 == profileImpl;
1076 }
1077
1078 /** Indicates whether the native OpenGL ES3 or ES2 profile is in use.
1079 * This requires an EGL, ES3 or ES2 compatible interface.
1080 */
1081 public static boolean usesNativeGLES2(final String profileImpl) {
1082 return GLES3 == profileImpl || GLES2 == profileImpl;
1083 }
1084
1085 /** Indicates whether the native OpenGL ES2 profile is in use.
1086 * This requires an EGL, ES3 compatible interface.
1087 */
1088 public static boolean usesNativeGLES3(final String profileImpl) {
1089 return GLES3 == profileImpl;
1090 }
1091
1092 /** Indicates whether either of the native OpenGL ES profiles are in use. */
1093 public static boolean usesNativeGLES(final String profileImpl) {
1094 return usesNativeGLES2(profileImpl) || usesNativeGLES1(profileImpl);
1095 }
1096
1097 /** @return {@link com.jogamp.nativewindow.NativeWindowFactory#isAWTAvailable()} and
1098 JOGL's AWT part */
1099 public static boolean isAWTAvailable() { return isAWTAvailable; }
1100
1101 public static String getGLTypeName(final int type) {
1102 switch (type) {
1103 case GL.GL_UNSIGNED_BYTE:
1104 return "GL_UNSIGNED_BYTE";
1105 case GL.GL_BYTE:
1106 return "GL_BYTE";
1107 case GL.GL_UNSIGNED_SHORT:
1108 return "GL_UNSIGNED_SHORT";
1109 case GL.GL_SHORT:
1110 return "GL_SHORT";
1111 case GL.GL_FLOAT:
1112 return "GL_FLOAT";
1113 case GL.GL_FIXED:
1114 return "GL_FIXED";
1115 case com.jogamp.opengl.GL2ES2.GL_INT:
1116 return "GL_INT";
1117 case GL.GL_UNSIGNED_INT:
1118 return "GL_UNSIGNED_INT";
1119 case com.jogamp.opengl.GL2GL3.GL_DOUBLE:
1120 return "GL_DOUBLE";
1121 case com.jogamp.opengl.GL2.GL_2_BYTES:
1122 return "GL_2_BYTES";
1123 case com.jogamp.opengl.GL2.GL_3_BYTES:
1124 return "GL_3_BYTES";
1125 case com.jogamp.opengl.GL2.GL_4_BYTES:
1126 return "GL_4_BYTES";
1127 }
1128 return null;
1129 }
1130
1131 public static String getGLArrayName(final int array) {
1132 switch(array) {
1134 return "GL_VERTEX_ARRAY";
1136 return "GL_NORMAL_ARRAY";
1138 return "GL_COLOR_ARRAY";
1140 return "GL_TEXTURE_COORD_ARRAY";
1141 }
1142 return null;
1143 }
1144
1145 public final String getGLImplBaseClassName() {
1147 }
1148 private static final String getGLImplBaseClassName(final String profileImpl) {
1149 if( GLES2 == profileImpl || GLES3 == profileImpl ) {
1150 return "jogamp.opengl.es3.GLES3";
1151 } else if( GLES1 == profileImpl ) {
1152 return "jogamp.opengl.es1.GLES1";
1153 } else if ( GL4bc == profileImpl ||
1154 GL4 == profileImpl ||
1155 GL3bc == profileImpl ||
1156 GL3 == profileImpl ||
1157 GL2 == profileImpl ) {
1158 return "jogamp.opengl.gl4.GL4bc";
1159 } else {
1160 throw new GLException("unsupported profile \"" + profileImpl + "\"");
1161 }
1162 }
1163
1164 public final Constructor<?> getGLCtor(final boolean glObject) {
1165 return getGLCtor(getImplName(), glObject);
1166 }
1167 private static final Constructor<?> getGLCtor(final String profileImpl, final boolean glObject) {
1168 if( GLES2 == profileImpl || GLES3 == profileImpl ) {
1169 return glObject ? ctorGLES3Impl : ctorGLES3ProcAddr;
1170 } else if( GLES1 == profileImpl ) {
1171 return glObject ? ctorGLES1Impl : ctorGLES1ProcAddr;
1172 } else if ( GL4bc == profileImpl ||
1173 GL4 == profileImpl ||
1174 GL3bc == profileImpl ||
1175 GL3 == profileImpl ||
1176 GL2 == profileImpl ) {
1177 return glObject ? ctorGL234Impl : ctorGL234ProcAddr;
1178 } else {
1179 throw new GLException("unsupported profile \"" + profileImpl + "\"");
1180 }
1181 }
1182
1183 /**
1184 * @param o GLProfile object to compare with
1185 * @return true if given Object is a GLProfile and
1186 * if both, profile and profileImpl is equal with this.
1187 */
1188 @Override
1189 public final boolean equals(final Object o) {
1190 if(this==o) { return true; }
1191 if(o instanceof GLProfile) {
1192 final GLProfile glp = (GLProfile)o;
1193 return getName() == glp.getName() && getImplName() == glp.getImplName() ; // uses .intern()!
1194 }
1195 return false;
1196 }
1197
1198 @Override
1199 public int hashCode() {
1200 int hash = 5;
1201 hash = 97 * hash + getImplName().hashCode();
1202 hash = 97 * hash + getName().hashCode();
1203 return hash;
1204 }
1205
1206 /**
1207 * @param glp GLProfile to compare with
1208 * @throws GLException if given GLProfile and this aren't equal
1209 */
1210 public final void verifyEquality(final GLProfile glp) throws GLException {
1211 if(!this.equals(glp)) {
1212 throw new GLException("GLProfiles are not equal: "+this+" != "+glp);
1213 }
1214 }
1215
1216 /** return this profiles name */
1217 public final String getName() {
1218 return profile;
1219 }
1220
1221 /** return this profiles implementation, eg. GL2ES2 -> GL2, or GL3 -> GL3 */
1222 public final GLProfile getImpl() {
1223 return null != profileImpl ? profileImpl : this;
1224 }
1225
1226 /** return true if impl. is a hardware rasterizer, otherwise false. */
1227 public final boolean isHardwareRasterizer() {
1228 return isHardwareRasterizer;
1229 }
1230
1231 /**
1232 * return this profiles implementation name, eg. GL2ES2 -> GL2, or GL3 -> GL3
1233 */
1234 public final String getImplName() {
1235 return null != profileImpl ? profileImpl.getName() : getName();
1236 }
1237
1238 /** Indicates whether this profile is capable of GL4bc. <p>Includes [ GL4bc ].</p> */
1239 public final boolean isGL4bc() {
1240 return GL4bc == profile;
1241 }
1242
1243 /** Indicates whether this profile is capable of GL4. <p>Includes [ GL4bc, GL4 ].</p> */
1244 public final boolean isGL4() {
1245 return isGL4bc() || GL4 == profile;
1246 }
1247
1248 /** Indicates whether this profile is capable of GL3bc. <p>Includes [ GL4bc, GL3bc ].</p> */
1249 public final boolean isGL3bc() {
1250 return isGL4bc() || GL3bc == profile;
1251 }
1252
1253 /** Indicates whether this profile is capable of GL3. <p>Includes [ GL4bc, GL4, GL3bc, GL3 ].</p> */
1254 public final boolean isGL3() {
1255 return isGL4() || isGL3bc() || GL3 == profile;
1256 }
1257
1258 /** Indicates whether this profile is capable of GL2 . <p>Includes [ GL4bc, GL3bc, GL2 ].</p> */
1259 public final boolean isGL2() {
1260 return isGL3bc() || GL2 == profile;
1261 }
1262
1263 /** Indicates whether this profile is capable of GLES1. <p>Includes [ GLES1 ].</p> */
1264 public final boolean isGLES1() {
1265 return GLES1 == profile;
1266 }
1267
1268 /** Indicates whether this profile is capable of GLES2. <p>Includes [ GLES2, GLES3 ].</p> */
1269 public final boolean isGLES2() {
1270 return isGLES3() || GLES2 == profile;
1271 }
1272
1273 /** Indicates whether this profile is capable of GLES3. <p>Includes [ GLES3 ].</p> */
1274 public final boolean isGLES3() {
1275 return GLES3 == profile;
1276 }
1277
1278 /** Indicates whether this profile is capable of GLES. <p>Includes [ GLES1, GLES2, GLES3 ].</p> */
1279 public final boolean isGLES() {
1280 return GLES3 == profile || GLES2 == profile || GLES1 == profile;
1281 }
1282
1283 /** Indicates whether this profile is capable of GL2ES1. <p>Includes [ GL4bc, GL3bc, GL2, GLES1, GL2ES1 ].</p> */
1284 public final boolean isGL2ES1() {
1285 return GL2ES1 == profile || isGLES1() || isGL2();
1286 }
1287
1288 /** Indicates whether this profile is capable of GL2GL3. <p>Includes [ GL4bc, GL4, GL3bc, GL3, GL2, GL2GL3 ].</p> */
1289 public final boolean isGL2GL3() {
1290 return GL2GL3 == profile || isGL3() || isGL2();
1291 }
1292
1293 /** Indicates whether this profile is capable of GL2ES2. <p>Includes [ GL4bc, GL4, GL3bc, GL3, GLES3, GL2, GL2GL3, GL2ES2, GLES2 ].</p> */
1294 public final boolean isGL2ES2() {
1295 return GL2ES2 == profile || isGLES2() || isGL2GL3();
1296 }
1297
1298 /**
1299 * Indicates whether this profile is capable of GL2ES3. <p>Includes [ GL4bc, GL4, GL3bc, GL3, GLES3, GL3ES3, GL2, GL2GL3 ].</p>
1300 * @see #isGL3ES3()
1301 * @see #isGL2GL3()
1302 */
1303 public final boolean isGL2ES3() {
1304 return isGL3ES3() || isGL2GL3();
1305 }
1306
1307 /** Indicates whether this profile is capable of GL3ES3. <p>Includes [ GL4bc, GL4, GL3bc, GL3, GLES3 ].</p> */
1308 public final boolean isGL3ES3() {
1309 return isGL4ES3() || isGL3();
1310 }
1311
1312 /** Indicates whether this profile is capable of GL4ES3. <p>Includes [ GL4bc, GL4, GLES3 ].</p> */
1313 public final boolean isGL4ES3() {
1314 return GL4ES3 == profile || isGLES3() || isGL4();
1315 }
1316
1317 /** Indicates whether this profile supports GLSL, i.e. {@link #isGL2ES2()}. */
1318 public final boolean hasGLSL() {
1319 return isGL2ES2() ;
1320 }
1321
1322 /** Indicates whether this profile uses the native OpenGL ES1 implementations. */
1323 public final boolean usesNativeGLES1() {
1324 return GLES1 == getImplName();
1325 }
1326
1327 /** Indicates whether this profile uses the native OpenGL ES2 implementations. */
1328 public final boolean usesNativeGLES2() {
1329 return GLES2 == getImplName();
1330 }
1331
1332 /** Indicates whether this profile uses the native OpenGL ES3 implementations. */
1333 public final boolean usesNativeGLES3() {
1334 return GLES3 == getImplName();
1335 }
1336
1337 /** Indicates whether this profile uses either of the native OpenGL ES implementations. */
1338 public final boolean usesNativeGLES() {
1340 }
1341
1342 /**
1343 * General validation if type is a valid GL data type for the current profile.
1344 * <p>
1345 * Disclaimer: The validation might not satisfy updated OpenGL specifications.
1346 * </p>
1347 */
1348 public boolean isValidDataType(final int type, final boolean throwException) {
1349 switch(type) {
1350 case GL.GL_UNSIGNED_BYTE:
1351 case GL.GL_BYTE:
1352 case GL.GL_UNSIGNED_SHORT:
1353 case GL.GL_SHORT:
1354 case GL.GL_FLOAT:
1355 case GL.GL_FIXED:
1356 return true;
1357 case com.jogamp.opengl.GL2ES2.GL_INT:
1358 case GL.GL_UNSIGNED_INT:
1359 if( isGL2ES2() ) {
1360 return true;
1361 }
1362 case com.jogamp.opengl.GL2GL3.GL_DOUBLE:
1363 if( isGL3() ) {
1364 return true;
1365 }
1366 case com.jogamp.opengl.GL2.GL_2_BYTES:
1367 case com.jogamp.opengl.GL2.GL_3_BYTES:
1368 case com.jogamp.opengl.GL2.GL_4_BYTES:
1369 if( isGL2() ) {
1370 return true;
1371 }
1372 }
1373 if(throwException) {
1374 throw new GLException("Illegal data type on profile "+this+": "+type);
1375 }
1376 return false;
1377 }
1378
1379 /**
1380 * General validation if index, comps and type are valid for the current profile.
1381 * <p>
1382 * Disclaimer: The validation might not satisfy updated OpenGL specifications.
1383 * </p>
1384 */
1385 public boolean isValidArrayDataType(final int index, final int comps, final int type,
1386 final boolean isVertexAttribPointer, final boolean throwException) {
1387 if( isGLES1() ) {
1388 if(isVertexAttribPointer) {
1389 if(throwException) {
1390 throw new GLException("Illegal array type for "+getGLArrayName(index)+" on profile GLES1: VertexAttribPointer");
1391 }
1392 return false;
1393 }
1394 switch(index) {
1397 switch(type) {
1398 case GL.GL_BYTE:
1399 case GL.GL_SHORT:
1400 case GL.GL_FIXED:
1401 case GL.GL_FLOAT:
1402 break;
1403 default:
1404 if(throwException) {
1405 throw new GLException("Illegal data type for "+getGLArrayName(index)+" on profile GLES1: "+type);
1406 }
1407 return false;
1408 }
1409 switch(comps) {
1410 case 0:
1411 case 2:
1412 case 3:
1413 case 4:
1414 break;
1415 default:
1416 if(throwException) {
1417 throw new GLException("Illegal component number for "+getGLArrayName(index)+" on profile GLES1: "+comps);
1418 }
1419 return false;
1420 }
1421 break;
1423 switch(type) {
1424 case GL.GL_BYTE:
1425 case GL.GL_SHORT:
1426 case GL.GL_FIXED:
1427 case GL.GL_FLOAT:
1428 break;
1429 default:
1430 if(throwException) {
1431 throw new GLException("Illegal data type for "+getGLArrayName(index)+" on profile GLES1: "+type);
1432 }
1433 return false;
1434 }
1435 switch(comps) {
1436 case 0:
1437 case 3:
1438 break;
1439 default:
1440 if(throwException) {
1441 throw new GLException("Illegal component number for "+getGLArrayName(index)+" on profile GLES1: "+comps);
1442 }
1443 return false;
1444 }
1445 break;
1447 switch(type) {
1448 case GL.GL_UNSIGNED_BYTE:
1449 case GL.GL_FIXED:
1450 case GL.GL_FLOAT:
1451 break;
1452 default:
1453 if(throwException) {
1454 throw new GLException("Illegal data type for "+getGLArrayName(index)+" on profile GLES1: "+type);
1455 }
1456 return false;
1457 }
1458 switch(comps) {
1459 case 0:
1460 case 4:
1461 break;
1462 default:
1463 if(throwException) {
1464 throw new GLException("Illegal component number for "+getGLArrayName(index)+" on profile GLES1: "+comps);
1465 }
1466 return false;
1467 }
1468 break;
1469 }
1470 } else if( isGLES3() ) {
1471 // simply ignore !isVertexAttribPointer case, since it is simulated anyway ..
1472 switch(type) {
1473 case GL.GL_UNSIGNED_BYTE:
1474 case GL.GL_BYTE:
1475 case GL.GL_UNSIGNED_SHORT:
1476 case GL.GL_SHORT:
1477 case com.jogamp.opengl.GL2ES2.GL_INT:
1478 case GL.GL_UNSIGNED_INT:
1479 case GL.GL_HALF_FLOAT:
1480 case GL.GL_FLOAT:
1481 case GL.GL_FIXED:
1483 case com.jogamp.opengl.GL2ES2.GL_UNSIGNED_INT_2_10_10_10_REV:
1485 break;
1486 default:
1487 if(throwException) {
1488 throw new GLException("Illegal data type on profile GLES3: "+type);
1489 }
1490 return false;
1491 }
1492 /** unable to validate .. could be any valid type/component combination
1493 switch(comps) {
1494 case 0:
1495 case 1:
1496 case 2:
1497 case 3:
1498 case 4:
1499 break;
1500 default:
1501 if(throwException) {
1502 throw new GLException("Illegal component number on profile GLES3: "+comps);
1503 }
1504 return false;
1505 } */
1506 } else if( isGLES2() ) {
1507 // simply ignore !isVertexAttribPointer case, since it is simulated anyway ..
1508 switch(type) {
1509 case GL.GL_UNSIGNED_BYTE:
1510 case GL.GL_BYTE:
1511 case GL.GL_UNSIGNED_SHORT:
1512 case GL.GL_SHORT:
1513 case GL.GL_FLOAT:
1514 case GL.GL_FIXED:
1515 break;
1516 default:
1517 if(throwException) {
1518 throw new GLException("Illegal data type on profile GLES2: "+type);
1519 }
1520 return false;
1521 }
1522 /** unable to validate .. could be any valid type/component combination
1523 switch(comps) {
1524 case 0:
1525 case 1:
1526 case 2:
1527 case 3:
1528 case 4:
1529 break;
1530 default:
1531 if(throwException) {
1532 throw new GLException("Illegal component number on profile GLES2: "+comps);
1533 }
1534 return false;
1535 } */
1536 } else if( isGL2ES2() ) {
1537 if(isVertexAttribPointer) {
1538 switch(type) {
1539 case GL.GL_UNSIGNED_BYTE:
1540 case GL.GL_BYTE:
1541 case GL.GL_UNSIGNED_SHORT:
1542 case GL.GL_SHORT:
1543 case com.jogamp.opengl.GL2ES2.GL_INT:
1544 case GL.GL_UNSIGNED_INT:
1545 case GL.GL_HALF_FLOAT:
1546 case GL.GL_FLOAT:
1547 case GL.GL_FIXED:
1549 case com.jogamp.opengl.GL2ES2.GL_UNSIGNED_INT_2_10_10_10_REV:
1550 case com.jogamp.opengl.GL2GL3.GL_DOUBLE:
1552 break;
1553 default:
1554 if(throwException) {
1555 throw new GLException("Illegal data type on profile GL2: "+type);
1556 }
1557 return false;
1558 }
1559 switch(comps) {
1560 case 0:
1561 case 1:
1562 case 2:
1563 case 3:
1564 case 4:
1565 break;
1566 default:
1567 if(throwException) {
1568 throw new GLException("Illegal component number on profile GL2: "+comps);
1569 }
1570 return false;
1571 }
1572 } else {
1573 switch(index) {
1575 switch(type) {
1576 case GL.GL_SHORT:
1577 case GL.GL_FLOAT:
1578 case com.jogamp.opengl.GL2ES2.GL_INT:
1579 case com.jogamp.opengl.GL2GL3.GL_DOUBLE:
1580 break;
1581 default:
1582 if(throwException) {
1583 throw new GLException("Illegal data type for "+getGLArrayName(index)+" on profile GL2: "+type);
1584 }
1585 return false;
1586 }
1587 switch(comps) {
1588 case 0:
1589 case 2:
1590 case 3:
1591 case 4:
1592 break;
1593 default:
1594 if(throwException) {
1595 throw new GLException("Illegal component number for "+getGLArrayName(index)+" on profile GL2: "+comps);
1596 }
1597 return false;
1598 }
1599 break;
1601 switch(type) {
1602 case GL.GL_BYTE:
1603 case GL.GL_SHORT:
1604 case GL.GL_FLOAT:
1605 case com.jogamp.opengl.GL2ES2.GL_INT:
1606 case com.jogamp.opengl.GL2GL3.GL_DOUBLE:
1607 break;
1608 default:
1609 if(throwException) {
1610 throw new GLException("Illegal data type for "+getGLArrayName(index)+" on profile GL2: "+type);
1611 }
1612 return false;
1613 }
1614 switch(comps) {
1615 case 0:
1616 case 3:
1617 break;
1618 default:
1619 if(throwException) {
1620 throw new GLException("Illegal component number for "+getGLArrayName(index)+" on profile GLES1: "+comps);
1621 }
1622 return false;
1623 }
1624 break;
1626 switch(type) {
1627 case GL.GL_UNSIGNED_BYTE:
1628 case GL.GL_BYTE:
1629 case GL.GL_UNSIGNED_SHORT:
1630 case GL.GL_SHORT:
1631 case GL.GL_FLOAT:
1632 case com.jogamp.opengl.GL2ES2.GL_INT:
1633 case GL.GL_UNSIGNED_INT:
1634 case com.jogamp.opengl.GL2GL3.GL_DOUBLE:
1635 break;
1636 default:
1637 if(throwException) {
1638 throw new GLException("Illegal data type for "+getGLArrayName(index)+" on profile GL2: "+type);
1639 }
1640 return false;
1641 }
1642 switch(comps) {
1643 case 0:
1644 case 3:
1645 case 4:
1646 break;
1647 default:
1648 if(throwException) {
1649 throw new GLException("Illegal component number for "+getGLArrayName(index)+" on profile GL2: "+comps);
1650 }
1651 return false;
1652 }
1653 break;
1655 switch(type) {
1656 case GL.GL_SHORT:
1657 case GL.GL_FLOAT:
1658 case com.jogamp.opengl.GL2ES2.GL_INT:
1659 case com.jogamp.opengl.GL2GL3.GL_DOUBLE:
1660 break;
1661 default:
1662 if(throwException) {
1663 throw new GLException("Illegal data type for "+getGLArrayName(index)+" on profile GL2: "+type);
1664 }
1665 return false;
1666 }
1667 switch(comps) {
1668 case 0:
1669 case 1:
1670 case 2:
1671 case 3:
1672 case 4:
1673 break;
1674 default:
1675 if(throwException) {
1676 throw new GLException("Illegal component number for "+getGLArrayName(index)+" on profile GL2: "+comps);
1677 }
1678 return false;
1679 }
1680 break;
1681 }
1682 }
1683 }
1684 return true;
1685 }
1686
1687 @Override
1688 public String toString() {
1689 return "GLProfile[" + getName() + "/" + getImplName() + "."+(this.isHardwareRasterizer?"hw":"sw")+(isCustom?".custom":"")+"]";
1690 }
1691
1692 private static /*final*/ boolean isAWTAvailable;
1693
1694 private static /*final*/ boolean hasDesktopGLFactory;
1695 private static /*final*/ boolean hasGL234Impl;
1696 private static /*final*/ boolean hasMobileFactory;
1697 private static /*final*/ boolean hasGLES3Impl;
1698 private static /*final*/ boolean hasGLES1Impl;
1699 private static /*final*/ boolean hasGL234OnMobileImpl;
1700 private static /*final*/ Constructor<?> ctorGL234Impl;
1701 private static /*final*/ Constructor<?> ctorGLES3Impl;
1702 private static /*final*/ Constructor<?> ctorGLES1Impl;
1703 private static /*final*/ Constructor<?> ctorGL234ProcAddr;
1704 private static /*final*/ Constructor<?> ctorGLES3ProcAddr;
1705 private static /*final*/ Constructor<?> ctorGLES1ProcAddr;
1706
1707 private static /*final*/ GLDrawableFactoryImpl mobileFactory = null;
1708 private static /*final*/ GLDrawableFactoryImpl desktopFactory = null;
1709 private static /*final*/ AbstractGraphicsDevice defaultDevice = null;
1710
1711 private static boolean initialized = false;
1712 private static final RecursiveThreadGroupLock initLock = LockFactory.createRecursiveThreadGroupLock();
1713
1714 private static final Class<?>[] ctorGLArgs = new Class<?>[] { GLProfile.class, jogamp.opengl.GLContextImpl.class };
1715 private static final Class<?>[] ctorProcArgs = new Class<?>[] { FunctionAddressResolver.class };
1716 private static final String GL4bcImplClassName = "jogamp.opengl.gl4.GL4bcImpl";
1717 private static final String GL4bcProcClassName = "jogamp.opengl.gl4.GL4bcProcAddressTable";
1718 private static final String GLES1ImplClassName = "jogamp.opengl.es1.GLES1Impl";
1719 private static final String GLES1ProcClassName = "jogamp.opengl.es1.GLES1ProcAddressTable";
1720 private static final String GLES3ImplClassName = "jogamp.opengl.es3.GLES3Impl";
1721 private static final String GLES3ProcClassName = "jogamp.opengl.es3.GLES3ProcAddressTable";
1722
1723 private static final Constructor<?> getCtor(final String clazzName, final boolean glObject, final ClassLoader cl) {
1724 try {
1725 return ReflectionUtil.getConstructor(clazzName, glObject ? ctorGLArgs : ctorProcArgs, false, cl);
1726 } catch (final Throwable t) {
1727 if( DEBUG ) {
1728 System.err.println("Caught: "+t.getMessage());
1729 t.printStackTrace();
1730 }
1731 return null;
1732 }
1733 }
1734
1735 private static final void initGLCtorImpl() {
1736 final ClassLoader classloader = GLProfile.class.getClassLoader();
1737
1738 // depends on hasDesktopGLFactory
1739 {
1740 final Constructor<?> ctorGL = getCtor(GL4bcImplClassName, true, classloader);
1741 final Constructor<?> ctorProc = null != ctorGL ? getCtor(GL4bcProcClassName, false, classloader) : null;
1742 if( null != ctorProc ) {
1743 hasGL234Impl = true;
1744 ctorGL234Impl = ctorGL;
1745 ctorGL234ProcAddr = ctorProc;
1746 } else {
1747 hasGL234Impl = false;
1748 ctorGL234Impl = null;
1749 ctorGL234ProcAddr = null;
1750 }
1751 }
1752 hasGL234OnMobileImpl = hasGL234Impl;
1753
1754 // depends on hasEGLFactory
1755 {
1756 final Constructor<?> ctorGL = getCtor(GLES1ImplClassName, true, classloader);
1757 final Constructor<?> ctorProc = null != ctorGL ? getCtor(GLES1ProcClassName, false, classloader) : null;
1758 if( null != ctorProc ) {
1759 hasGLES1Impl = true;
1760 ctorGLES1Impl = ctorGL;
1761 ctorGLES1ProcAddr = ctorProc;
1762 } else {
1763 hasGLES1Impl = false;
1764 ctorGLES1Impl = null;
1765 ctorGLES1ProcAddr = null;
1766 }
1767 }
1768 {
1769 final Constructor<?> ctorGL = getCtor(GLES3ImplClassName, true, classloader);
1770 final Constructor<?> ctorProc = null != ctorGL ? getCtor(GLES3ProcClassName, false, classloader) : null;
1771 if( null != ctorProc ) {
1772 hasGLES3Impl = true;
1773 ctorGLES3Impl = ctorGL;
1774 ctorGLES3ProcAddr = ctorProc;
1775 } else {
1776 hasGLES3Impl = false;
1777 ctorGLES3Impl = null;
1778 ctorGLES3ProcAddr = null;
1779 }
1780 }
1781 }
1782
1783 /**
1784 * Tries the profiles implementation and native libraries.
1785 */
1786 private static void initProfilesForDefaultDevices() {
1787 NativeWindowFactory.initSingleton();
1788 if(DEBUG) {
1789 System.err.println("GLProfile.init - thread: " + Thread.currentThread().getName());
1790 System.err.println(VersionUtil.getPlatformInfo());
1791 System.err.println(GlueGenVersion.getInstance());
1792 System.err.println(NativeWindowVersion.getInstance());
1793 System.err.println(JoglVersion.getInstance());
1794 }
1795
1796 final ClassLoader classloader = GLProfile.class.getClassLoader();
1797
1798 isAWTAvailable = NativeWindowFactory.isAWTAvailable() &&
1799 ReflectionUtil.isClassAvailable("com.jogamp.opengl.awt.GLCanvas", classloader) ; // JOGL
1800
1801 initGLCtorImpl();
1802
1803 //
1804 // Iteration of desktop GL availability detection
1805 // utilizing the detected GL version in the shared context.
1806 //
1807 // - Instantiate GLDrawableFactory incl its shared dummy drawable/context,
1808 // which will register at GLContext ..
1809 //
1810 GLDrawableFactory.initSingleton();
1811
1812 Throwable t=null;
1813 // if successfull it has a shared dummy drawable and context created
1814 try {
1815 desktopFactory = (GLDrawableFactoryImpl) GLDrawableFactory.getFactoryImpl(GL2);
1816 if(null != desktopFactory) {
1817 final GLDynamicLookupHelper glLookupHelper = desktopFactory.getGLDynamicLookupHelper(2, GLContext.CTX_PROFILE_COMPAT);
1818 hasGL234Impl = null!=glLookupHelper && glLookupHelper.isLibComplete() && hasGL234Impl;
1819 hasDesktopGLFactory = hasGL234Impl;
1820 }
1821 } catch (final LinkageError le) {
1822 t=le;
1823 } catch (final RuntimeException re) {
1824 t=re;
1825 } catch (final Throwable tt) {
1826 t=tt;
1827 }
1828 if(DEBUG) {
1829 if(null!=t) {
1830 t.printStackTrace();
1831 }
1832 }
1833
1834 final AbstractGraphicsDevice defaultDesktopDevice;
1835 if(null == desktopFactory) {
1836 hasDesktopGLFactory = false;
1837 hasGL234Impl = false;
1838 defaultDesktopDevice = null;
1839 if(DEBUG) {
1840 System.err.println("Info: GLProfile.init - Desktop GLDrawable factory not available");
1841 }
1842 } else {
1843 defaultDesktopDevice = desktopFactory.getDefaultDevice();
1844 }
1845
1846 t=null;
1847 try {
1848 mobileFactory = (GLDrawableFactoryImpl) GLDrawableFactory.getFactoryImpl(GLES2);
1849 if(null != mobileFactory) {
1850 // update hasGLES1Impl, hasGLES3Impl, hasGL234OnEGLImpl based on library completion
1851 final GLDynamicLookupHelper es2DynLookup = mobileFactory.getGLDynamicLookupHelper(2, GLContext.CTX_PROFILE_ES);
1852 final GLDynamicLookupHelper es1DynLookup = mobileFactory.getGLDynamicLookupHelper(1, GLContext.CTX_PROFILE_ES);
1853 final GLDynamicLookupHelper glXDynLookup = mobileFactory.getGLDynamicLookupHelper(3, GLContext.CTX_PROFILE_CORE);
1854 hasGLES3Impl = null!=es2DynLookup && es2DynLookup.isLibComplete() && hasGLES3Impl;
1855 hasGLES1Impl = null!=es1DynLookup && es1DynLookup.isLibComplete() && hasGLES1Impl;
1856 hasGL234OnMobileImpl = null!=glXDynLookup && glXDynLookup.isLibComplete() && hasGL234OnMobileImpl;
1857 hasMobileFactory = hasGLES3Impl || hasGLES1Impl || hasGL234OnMobileImpl;
1858 }
1859 } catch (final LinkageError le) {
1860 t=le;
1861 } catch (final SecurityException se) {
1862 t=se;
1863 } catch (final NullPointerException npe) {
1864 t=npe;
1865 } catch (final RuntimeException re) {
1866 t=re;
1867 }
1868 if(DEBUG) {
1869 if(null!=t) {
1870 t.printStackTrace();
1871 }
1872 }
1873
1874 final AbstractGraphicsDevice defaultMobileDevice;
1875 if(null == mobileFactory) {
1876 hasMobileFactory = false;
1877 hasGL234OnMobileImpl= false;
1878 hasGLES3Impl = false;
1879 hasGLES1Impl = false;
1880 defaultMobileDevice = null;
1881 if(DEBUG) {
1882 System.err.println("Info: GLProfile.init - Mobile GLDrawable factory not available");
1883 }
1884 } else {
1885 defaultMobileDevice = mobileFactory.getDefaultDevice();
1886 }
1887
1888 if( null != defaultDesktopDevice ) {
1889 defaultDevice = defaultDesktopDevice;
1890 if(DEBUG) {
1891 System.err.println("Info: GLProfile.init - Default device is desktop derived: "+defaultDevice);
1892 }
1893 } else if ( null != defaultMobileDevice ) {
1894 defaultDevice = defaultMobileDevice;
1895 if(DEBUG) {
1896 System.err.println("Info: GLProfile.init - Default device is mobile derived: "+defaultDevice);
1897 }
1898 } else {
1899 if(DEBUG) {
1900 System.err.println("Info: GLProfile.init - Default device not available");
1901 }
1902 defaultDevice = null;
1903 }
1904
1905 // we require to initialize the EGL device 1st, if available
1906 final boolean addedMobileProfile = null != defaultMobileDevice ? initProfilesForDevice(defaultMobileDevice) : false;
1907 final boolean addedDesktopProfile = null != defaultDesktopDevice ? initProfilesForDevice(defaultDesktopDevice) : false;
1908 final boolean addedAnyProfile = addedMobileProfile || addedDesktopProfile ;
1909
1910 if(DEBUG) {
1911 System.err.println("GLProfile.init addedAnyProfile "+addedAnyProfile+" (desktop: "+addedDesktopProfile+", mobile "+addedMobileProfile+")");
1912 System.err.println("GLProfile.init isAWTAvailable "+isAWTAvailable);
1913 System.err.println("GLProfile.init hasDesktopGLFactory "+hasDesktopGLFactory);
1914 System.err.println("GLProfile.init hasGL234Impl "+hasGL234Impl);
1915 System.err.println("GLProfile.init hasMobileFactory "+hasMobileFactory);
1916 System.err.println("GLProfile.init hasGLES1Impl "+hasGLES1Impl);
1917 System.err.println("GLProfile.init hasGLES3Impl "+hasGLES3Impl);
1918 System.err.println("GLProfile.init hasGL234OnEGLImpl "+hasGL234OnMobileImpl);
1919 System.err.println("GLProfile.init defaultDevice "+defaultDevice);
1920 System.err.println("GLProfile.init defaultDevice Desktop "+defaultDesktopDevice);
1921 System.err.println("GLProfile.init defaultDevice Mobile "+defaultMobileDevice);
1922 System.err.println("GLProfile.init profile order "+array2String(GL_PROFILE_LIST_ALL));
1923 }
1924 }
1925
1926 /**
1927 * @param device the device for which profiles shall be initialized
1928 * @return true if any profile for the device exists, otherwise false
1929 */
1930 private static boolean initProfilesForDevice(final AbstractGraphicsDevice device) {
1931 if(null == device) {
1932 return false;
1933 }
1934 initLock.lock();
1935 try {
1936 final GLDrawableFactory factory = GLDrawableFactory.getFactory(device);
1937 if( null != factory ) {
1938 factory.enterThreadCriticalZone();
1939 try {
1940 return initProfilesForDeviceCritical(device);
1941 } finally {
1942 factory.leaveThreadCriticalZone();
1943 }
1944 }
1945 } finally {
1946 initLock.unlock();
1947 }
1948 return false;
1949 }
1950 private static boolean initProfilesForDeviceCritical(final AbstractGraphicsDevice device) {
1951 final boolean isSet = GLContext.getAvailableGLVersionsSet(device);
1952
1953 if(DEBUG) {
1954 System.err.println("Info: GLProfile.initProfilesForDevice: "+device+" ("+device.getClass().getName()+"), isSet "+isSet+", hasDesktopGLFactory "+hasDesktopGLFactory+", hasEGLFactory "+hasMobileFactory);
1955 }
1956 if(isSet) {
1957 // Avoid recursion and check whether impl. is sane!
1958 final String deviceKey = device.getUniqueID();
1959 final HashMap<String /*GLProfile_name*/, GLProfile> map = deviceConn2ProfileMap.get(deviceKey);
1960 if( null == map ) {
1961 throw new InternalError("GLContext Avail. GLVersion is set - but no profile map for device: "+device);
1962 }
1963 return null != map.get(GL_DEFAULT);
1964 }
1965
1966 HashMap<String, GLProfile> mappedDesktopProfiles = null;
1967 boolean addedDesktopProfile = false;
1968 HashMap<String, GLProfile> mappedEGLProfiles = null;
1969 boolean addedMobileProfile = false;
1970
1971 final boolean deviceIsDesktopCompatible = hasDesktopGLFactory && desktopFactory.getIsDeviceCompatible(device);
1972
1973 if( deviceIsDesktopCompatible ) {
1974 // 1st pretend we have all Desktop and EGL profiles ..
1975 computeProfileMap(device, true /* desktopCtxUndef*/, true /* esCtxUndef */);
1976
1977 // Triggers eager initialization of share context in GLDrawableFactory for the device,
1978 // hence querying all available GLProfiles
1979 final Thread sharedResourceThread = desktopFactory.getSharedResourceThread();
1980 final boolean initLockOwnerAdded;
1981 if(null != sharedResourceThread) {
1982 if( !initLock.isOriginalOwner(sharedResourceThread) ) {
1983 initLock.addOwner(sharedResourceThread);
1984 initLockOwnerAdded = true;
1985 } else {
1986 initLockOwnerAdded = false;
1987 }
1988 } else {
1989 initLockOwnerAdded = false;
1990 }
1991 final boolean desktopSharedCtxAvail = desktopFactory.createSharedResource(device);
1992 if( initLockOwnerAdded ) {
1993 initLock.removeOwner(sharedResourceThread);
1994 }
1995 if( desktopSharedCtxAvail ) {
1996 if( !GLContext.getAvailableGLVersionsSet(device) ) {
1997 throw new InternalError("Available GLVersions not set for "+device);
1998 }
1999 mappedDesktopProfiles = computeProfileMap(device, false /* desktopCtxUndef*/, false /* esCtxUndef */);
2000 addedDesktopProfile = mappedDesktopProfiles.size() > 0;
2001 if (DEBUG) {
2002 System.err.println("GLProfile.initProfilesForDevice: "+device+": desktop Shared Ctx "+desktopSharedCtxAvail+
2003 ", profiles: "+(addedDesktopProfile ? mappedDesktopProfiles.size() : 0));
2004 }
2005 }
2006 }
2007
2008 final boolean deviceIsMobileCompatible = hasMobileFactory && mobileFactory.getIsDeviceCompatible(device);
2009
2010 // also test GLES1, GLES2 and GLES3 on desktop, since we have implementations / emulations available.
2011 if( deviceIsMobileCompatible ) {
2012 // 1st pretend we have all EGL profiles ..
2013 computeProfileMap(device, true /* desktopCtxUndef*/, true /* esCtxUndef */);
2014
2015 // Triggers eager initialization of share context in GLDrawableFactory for the device,
2016 // hence querying all available GLProfiles
2017 final Thread sharedResourceThread = mobileFactory.getSharedResourceThread();
2018 final boolean initLockOwnerAdded;
2019 if(null != sharedResourceThread) {
2020 if( !initLock.isOriginalOwner(sharedResourceThread) ) {
2021 initLock.addOwner(sharedResourceThread);
2022 initLockOwnerAdded = true;
2023 } else {
2024 initLockOwnerAdded = false;
2025 }
2026 } else {
2027 initLockOwnerAdded = false;
2028 }
2029 final boolean eglSharedCtxAvail = mobileFactory.createSharedResource(device);
2030 if( initLockOwnerAdded ) {
2031 initLock.removeOwner(sharedResourceThread);
2032 }
2033 if( eglSharedCtxAvail ) {
2034 if( !GLContext.getAvailableGLVersionsSet(device) ) {
2035 throw new InternalError("Available GLVersions not set for "+device);
2036 }
2037 mappedEGLProfiles = computeProfileMap(device, false /* desktopCtxUndef*/, false /* esCtxUndef */);
2038 addedMobileProfile = mappedEGLProfiles.size() > 0;
2039 }
2040 if (DEBUG) {
2041 System.err.println("GLProfile.initProfilesForDevice: "+device+": mobile Shared Ctx "+eglSharedCtxAvail+
2042 ", profiles: "+(addedMobileProfile ? mappedEGLProfiles.size() : 0));
2043 }
2044 }
2045
2046 final HashMap<String, GLProfile> mappedAllProfiles;
2047 if( addedMobileProfile ) {
2048 // If run on actual desktop device, e.g. '.x11_:0_0',
2049 // GLContextImpl.remapAvailableGLVersion('.egl_:0_0' -> '.x11_:0_0')
2050 // ensures EGL profiles being mapped to upstream desktop device '.x11_:0_0'.
2051 mappedAllProfiles = mappedEGLProfiles;
2052 } else if( addedDesktopProfile ) {
2053 mappedAllProfiles = mappedDesktopProfiles;
2054 } else {
2055 mappedAllProfiles = new HashMap<String /*GLProfile_name*/, GLProfile>(); // empty
2056 if(DEBUG) {
2057 System.err.println("GLProfile: device could not be initialized: "+device);
2058 System.err.println("GLProfile: compatible w/ desktop: "+deviceIsDesktopCompatible+
2059 ", mobile "+deviceIsMobileCompatible);
2060 System.err.println("GLProfile: desktoplFactory "+desktopFactory);
2061 System.err.println("GLProfile: mobileFactory "+mobileFactory);
2062 System.err.println("GLProfile: hasGLES1Impl "+hasGLES1Impl);
2063 System.err.println("GLProfile: hasGLES3Impl "+hasGLES3Impl);
2064 }
2065 }
2066 setProfileMap(device, mappedAllProfiles); // merged mappedEGLProfiles if available, otherwise mappedDesktopProfiles
2067
2068 GLContext.setAvailableGLVersionsSet(device, true);
2069
2070 if (DEBUG) {
2071 System.err.println("GLProfile.initProfilesForDevice: "+device.getUniqueID()+": added profile(s): desktop "+addedDesktopProfile+", mobile "+addedMobileProfile);
2072 System.err.println("GLProfile.initProfilesForDevice: "+device.getUniqueID()+": "+glAvailabilityToString(device));
2073 if(addedDesktopProfile) {
2074 dumpGLInfo(desktopFactory, device);
2075 final List<GLCapabilitiesImmutable> availCaps = desktopFactory.getAvailableCapabilities(device);
2076 for(int i=0; i<availCaps.size(); i++) {
2077 System.err.println(availCaps.get(i));
2078 }
2079 } else if(addedMobileProfile) {
2080 dumpGLInfo(mobileFactory, device);
2081 final List<GLCapabilitiesImmutable> availCaps = mobileFactory.getAvailableCapabilities(device);
2082 for(int i=0; i<availCaps.size(); i++) {
2083 System.err.println(availCaps.get(i));
2084 }
2085 }
2086 }
2087
2088 return addedDesktopProfile || addedMobileProfile;
2089 }
2090
2091 private static void dumpGLInfo(final GLDrawableFactoryImpl factory, final AbstractGraphicsDevice device) {
2092 final GLContext ctx = factory.getOrCreateSharedContext(device);
2093 if(null != ctx) {
2094 System.err.println("GLProfile.dumpGLInfo: "+ctx);
2095 if( GLContext.CONTEXT_NOT_CURRENT != ctx.makeCurrent() ) {
2096 try {
2097 System.err.println(JoglVersion.getGLInfo(ctx.getGL(), null));
2098 } finally {
2099 ctx.release();
2100 }
2101 } else {
2102 System.err.println("GLProfile.dumpGLInfo: Couldn't make context current");
2103 }
2104 } else {
2105 System.err.println("GLProfile.dumpGLInfo: shared context n/a");
2106 System.err.println(device.getClass().getSimpleName()+"[type "+
2107 device.getType()+", connection "+device.getConnection()+"]:");
2108 System.err.println(GLProfile.glAvailabilityToString(device, null, "\t", 1).toString());
2109 }
2110 }
2111
2113 initSingleton();
2114 return defaultDevice;
2115 }
2116
2117 private static String array2String(final String[] list) {
2118 final StringBuilder msg = new StringBuilder();
2119 msg.append("[");
2120 for (int i = 0; i < list.length; i++) {
2121 if (i > 0)
2122 msg.append(", ");
2123 msg.append(list[i]);
2124 }
2125 msg.append("]");
2126 return msg.toString();
2127 }
2128
2129 private static void glAvailabilityToString(final AbstractGraphicsDevice device, final StringBuilder sb, final int major, final int profile) {
2130 final String str = GLContext.getAvailableGLVersionAsString(device, major, profile);
2131 if(null==str) {
2132 throw new GLException("Internal Error");
2133 }
2134 sb.append("[");
2135 sb.append(str);
2136 sb.append("]");
2137 }
2138
2139 private static HashMap<String, GLProfile> computeProfileMap(final AbstractGraphicsDevice device, final boolean desktopCtxUndef, final boolean esCtxUndef) {
2140 if (DEBUG) {
2141 System.err.println("GLProfile.init map "+device.getUniqueID()+", desktopCtxUndef "+desktopCtxUndef+", esCtxUndef "+esCtxUndef);
2142 }
2143 final boolean isHardwareRasterizer[] = new boolean[1];
2144 GLProfile defaultGLProfileAny = null;
2145 GLProfile defaultGLProfileHW = null;
2146 final HashMap<String, GLProfile> _mappedProfiles = new HashMap<String, GLProfile>(GL_PROFILE_LIST_ALL.length + 1 /* default */);
2147 for(int i=0; i<GL_PROFILE_LIST_ALL.length; i++) {
2148 final String profile = GL_PROFILE_LIST_ALL[i];
2149 final String profileImpl = computeProfileImpl(device, profile, desktopCtxUndef, esCtxUndef, isHardwareRasterizer);
2150 if( null != profileImpl ) {
2151 final GLProfile glProfile;
2152 if( profile.equals( profileImpl ) ) {
2153 glProfile = new GLProfile(profile, null, isHardwareRasterizer[0], false /* custom */);
2154 } else {
2155 final GLProfile _mglp = _mappedProfiles.get( profileImpl );
2156 if( null == _mglp ) {
2157 // Bug 1383: We may consider allowing cross mapping here,
2158 // i.e. mapping on actually non-supported (implementation) profiles
2159 throw new InternalError("XXX0 profile["+i+"]: "+profile+" -> profileImpl "+profileImpl+" !!! not mapped ");
2160 }
2161 glProfile = new GLProfile(profile, _mglp, isHardwareRasterizer[0], false /* custom */);
2162 }
2163 _mappedProfiles.put(profile, glProfile);
2164 if (DEBUG) {
2165 System.err.println("GLProfile.init map "+glProfile+" on device "+device.getUniqueID());
2166 }
2167 if( null == defaultGLProfileHW && isHardwareRasterizer[0] ) {
2168 defaultGLProfileHW=glProfile;
2169 if (DEBUG) {
2170 System.err.println("GLProfile.init map defaultHW "+glProfile+" on device "+device.getUniqueID());
2171 }
2172 } else if( null == defaultGLProfileAny ) {
2173 defaultGLProfileAny=glProfile;
2174 if (DEBUG) {
2175 System.err.println("GLProfile.init map defaultAny "+glProfile+" on device "+device.getUniqueID());
2176 }
2177 }
2178 } else {
2179 if (DEBUG) {
2180 System.err.println("GLProfile.init map *** no mapping for "+profile+" on device "+device.getUniqueID());
2181 }
2182 }
2183 }
2184 if( null != defaultGLProfileHW ) {
2185 _mappedProfiles.put(GL_DEFAULT, defaultGLProfileHW);
2186 } else if( null != defaultGLProfileAny ) {
2187 _mappedProfiles.put(GL_DEFAULT, defaultGLProfileAny);
2188 }
2189 setProfileMap(device, _mappedProfiles);
2190 return _mappedProfiles;
2191 }
2192
2193 /**
2194 * Returns the profile implementation
2195 */
2196 private static String computeProfileImpl(final AbstractGraphicsDevice device, final String profile, final boolean desktopCtxUndef, final boolean esCtxUndef, final boolean isHardwareRasterizer[]) {
2197 final boolean hasAnyGL234Impl = hasGL234Impl || hasGL234OnMobileImpl;
2198 final boolean hardwareRasterizer[] = new boolean[1];
2199 if ( GL2ES1 == profile ) {
2200 final boolean gles1Available;
2201 final boolean gles1HWAvailable;
2202 if( hasGLES1Impl ) {
2203 gles1Available = esCtxUndef || GLContext.isGLES1Available(device, hardwareRasterizer);
2204 gles1HWAvailable = gles1Available && hardwareRasterizer[0] ;
2205 } else {
2206 gles1Available = false;
2207 gles1HWAvailable = false;
2208 }
2209 if( hasAnyGL234Impl ) {
2210 final boolean gl3bcAvailable = GLContext.isGL3bcAvailable(device, hardwareRasterizer);
2211 final boolean gl3bcHWAvailable = gl3bcAvailable && hardwareRasterizer[0] ;
2212 final boolean gl2Available = GLContext.isGL2Available(device, hardwareRasterizer);
2213 final boolean gl2HWAvailable = gl2Available && hardwareRasterizer[0] ;
2214 final boolean glAnyHWAvailable = gl3bcHWAvailable || gl2HWAvailable ||
2215 gles1HWAvailable ;
2216
2217 if( GLContext.isGL4bcAvailable(device, isHardwareRasterizer) &&
2218 ( isHardwareRasterizer[0] || !glAnyHWAvailable ) ) {
2219 return GL4bc;
2220 }
2221 if( gl3bcAvailable && ( gl3bcHWAvailable || !glAnyHWAvailable ) ) {
2222 isHardwareRasterizer[0] = gl3bcHWAvailable;
2223 return GL3bc;
2224 }
2225 if( ( desktopCtxUndef || gl2Available ) && ( gl2HWAvailable || !glAnyHWAvailable ) ) {
2226 isHardwareRasterizer[0] = gl2HWAvailable;
2227 return GL2;
2228 }
2229 }
2230 if( gles1Available ) {
2231 isHardwareRasterizer[0] = gles1HWAvailable;
2232 return GLES1;
2233 }
2234 } else if ( GL2ES2 == profile ) {
2235 final boolean gles2Available, gles3Available;
2236 final boolean gles2HWAvailable, gles3HWAvailable;
2237 if( hasGLES3Impl ) {
2238 gles2Available = esCtxUndef || GLContext.isGLES2Available(device, hardwareRasterizer);
2239 gles2HWAvailable = gles2Available && hardwareRasterizer[0] ;
2240 gles3Available = esCtxUndef || GLContext.isGLES3Available(device, hardwareRasterizer);
2241 gles3HWAvailable = gles3Available && hardwareRasterizer[0] ;
2242 } else {
2243 gles2Available = false;
2244 gles2HWAvailable = false;
2245 gles3Available = false;
2246 gles3HWAvailable = false;
2247 }
2248 if( hasAnyGL234Impl ) {
2249 final boolean gl4bcAvailable = GLContext.isGL4bcAvailable(device, hardwareRasterizer);
2250 final boolean gl4bcHWAvailable = gl4bcAvailable && hardwareRasterizer[0] ;
2251 final boolean gl3Available = GLContext.isGL3Available(device, hardwareRasterizer);
2252 final boolean gl3HWAvailable = gl3Available && hardwareRasterizer[0] ;
2253 final boolean gl3bcAvailable = GLContext.isGL3bcAvailable(device, hardwareRasterizer);
2254 final boolean gl3bcHWAvailable = gl3bcAvailable && hardwareRasterizer[0] ;
2255 final boolean gl2Available = GLContext.isGL2Available(device, hardwareRasterizer);
2256 final boolean gl2HWAvailable = gl2Available && hardwareRasterizer[0] ;
2257 final boolean glAnyHWAvailable = gl4bcHWAvailable || gl3HWAvailable || gl3bcHWAvailable || gl2HWAvailable ||
2258 gles3HWAvailable || gles2HWAvailable ;
2259
2260 if( GLContext.isGL4Available(device, isHardwareRasterizer) &&
2261 ( isHardwareRasterizer[0] || !glAnyHWAvailable ) ) {
2262 return GL4;
2263 }
2264 if( gl4bcAvailable && ( gl4bcHWAvailable || !glAnyHWAvailable ) ) {
2265 isHardwareRasterizer[0] = gl4bcHWAvailable;
2266 return GL4bc;
2267 }
2268 if( gl3Available && ( gl3HWAvailable || !glAnyHWAvailable ) ) {
2269 isHardwareRasterizer[0] = gl3HWAvailable;
2270 return GL3;
2271 }
2272 if( gl3bcAvailable && ( gl3bcHWAvailable || !glAnyHWAvailable ) ) {
2273 isHardwareRasterizer[0] = gl3bcHWAvailable;
2274 return GL3bc;
2275 }
2276 if( ( desktopCtxUndef || gl2Available ) && ( gl2HWAvailable || !glAnyHWAvailable ) ) {
2277 isHardwareRasterizer[0] = gl2HWAvailable;
2278 return GL2;
2279 }
2280 }
2281 if( gles3Available && ( gles3HWAvailable || !gles2HWAvailable ) ) {
2282 isHardwareRasterizer[0] = gles3HWAvailable;
2283 return GLES3;
2284 }
2285 if( gles2Available ) {
2286 isHardwareRasterizer[0] = gles2HWAvailable;
2287 return GLES2;
2288 }
2289 } else if (GL4ES3 == profile) {
2290 final boolean gles3CompatAvail = GLContext.isGLES3CompatibleAvailable(device);
2291 if( desktopCtxUndef || esCtxUndef || gles3CompatAvail ) {
2292 final boolean es3HardwareRasterizer[] = new boolean[1];
2293 final boolean gles3Available = hasGLES3Impl && ( esCtxUndef || GLContext.isGLES3Available(device, es3HardwareRasterizer) );
2294 final boolean gles3HWAvailable = gles3Available && es3HardwareRasterizer[0] ;
2295 if( hasAnyGL234Impl ) {
2296 final boolean gl4bcAvailable = GLContext.isGL4bcAvailable(device, hardwareRasterizer);
2297 final boolean gl4bcHWAvailable = gl4bcAvailable && hardwareRasterizer[0] ;
2298 final boolean glAnyHWAvailable = gl4bcHWAvailable ||
2299 gles3HWAvailable;
2300
2301 if( GLContext.isGL4Available(device, isHardwareRasterizer) &&
2302 ( isHardwareRasterizer[0] || !glAnyHWAvailable ) ) {
2303 return GL4;
2304 }
2305 if( ( desktopCtxUndef || gl4bcAvailable ) && ( gl4bcHWAvailable || !glAnyHWAvailable ) ) {
2306 isHardwareRasterizer[0] = gl4bcHWAvailable;
2307 return GL4bc;
2308 }
2309 }
2310 if(gles3Available) {
2311 isHardwareRasterizer[0] = es3HardwareRasterizer[0];
2312 return GLES3;
2313 }
2314 }
2315 } else if(GL2GL3 == profile) {
2316 if( hasAnyGL234Impl ) {
2317 final boolean gl4Available = GLContext.isGL4Available(device, hardwareRasterizer);
2318 final boolean gl4HWAvailable = gl4Available && hardwareRasterizer[0] ;
2319 final boolean gl3Available = GLContext.isGL3Available(device, hardwareRasterizer);
2320 final boolean gl3HWAvailable = gl3Available && hardwareRasterizer[0] ;
2321 final boolean gl3bcAvailable = GLContext.isGL3bcAvailable(device, hardwareRasterizer);
2322 final boolean gl3bcHWAvailable = gl3bcAvailable && hardwareRasterizer[0] ;
2323 final boolean gl2Available = GLContext.isGL2Available(device, hardwareRasterizer);
2324 final boolean gl2HWAvailable = gl2Available && hardwareRasterizer[0] ;
2325 final boolean glAnyHWAvailable = gl4HWAvailable || gl3HWAvailable || gl3bcHWAvailable || gl2HWAvailable;
2326
2327 if( GLContext.isGL4bcAvailable(device, isHardwareRasterizer) &&
2328 ( isHardwareRasterizer[0] || !glAnyHWAvailable ) ) {
2329 return GL4bc;
2330 }
2331 if( gl4Available && ( gl4HWAvailable || !glAnyHWAvailable ) ) {
2332 isHardwareRasterizer[0] = gl4HWAvailable;
2333 return GL4;
2334 }
2335 if( gl3bcAvailable && ( gl3bcHWAvailable || !glAnyHWAvailable ) ) {
2336 isHardwareRasterizer[0] = gl3bcHWAvailable;
2337 return GL3bc;
2338 }
2339 if( gl3Available && ( gl3HWAvailable || !glAnyHWAvailable ) ) {
2340 isHardwareRasterizer[0] = gl3HWAvailable;
2341 return GL3;
2342 }
2343 if( desktopCtxUndef || gl2Available ) {
2344 isHardwareRasterizer[0] = gl2HWAvailable;
2345 return GL2;
2346 }
2347 }
2348 } else if(GL4bc == profile && hasAnyGL234Impl && ( desktopCtxUndef || GLContext.isGL4bcAvailable(device, isHardwareRasterizer))) {
2349 return desktopCtxUndef ? GL4bc : GLContext.getAvailableGLProfileName(device, 4, GLContext.CTX_PROFILE_COMPAT);
2350 } else if(GL4 == profile && hasAnyGL234Impl && ( desktopCtxUndef || GLContext.isGL4Available(device, isHardwareRasterizer))) {
2351 return desktopCtxUndef ? GL4 : GLContext.getAvailableGLProfileName(device, 4, GLContext.CTX_PROFILE_CORE);
2352 } else if(GL3bc == profile && hasAnyGL234Impl && ( desktopCtxUndef || GLContext.isGL3bcAvailable(device, isHardwareRasterizer))) {
2353 return desktopCtxUndef ? GL3bc : GLContext.getAvailableGLProfileName(device, 3, GLContext.CTX_PROFILE_COMPAT);
2354 } else if(GL3 == profile && hasAnyGL234Impl && ( desktopCtxUndef || GLContext.isGL3Available(device, isHardwareRasterizer))) {
2355 return desktopCtxUndef ? GL3 : GLContext.getAvailableGLProfileName(device, 3, GLContext.CTX_PROFILE_CORE);
2356 } else if(GL2 == profile && hasAnyGL234Impl && ( desktopCtxUndef || GLContext.isGL2Available(device, isHardwareRasterizer))) {
2357 // return desktopCtxUndef ? GL2 : GLContext.getAvailableGLProfileName(device, 2, GLContext.CTX_PROFILE_COMPAT);
2358 if( desktopCtxUndef ) {
2359 return GL2;
2360 } else {
2361 final String gl2_impl = GLContext.getAvailableGLProfileName(device, 2, GLContext.CTX_PROFILE_COMPAT);
2362 if( GL3bc == gl2_impl && !GLContext.isGL3bcAvailable(device, isHardwareRasterizer) ) {
2363 return GL2;
2364 } else {
2365 return gl2_impl;
2366 }
2367 }
2368 } else if(GLES3 == profile && hasGLES3Impl && ( esCtxUndef || GLContext.isGLES3Available(device, isHardwareRasterizer))) {
2369 return esCtxUndef ? GLES3 : GLContext.getAvailableGLProfileName(device, 3, GLContext.CTX_PROFILE_ES);
2370 } else if(GLES2 == profile && hasGLES3Impl && ( esCtxUndef || GLContext.isGLES2Available(device, isHardwareRasterizer))) {
2371 return esCtxUndef ? GLES2 : GLContext.getAvailableGLProfileName(device, 2, GLContext.CTX_PROFILE_ES);
2372 } else if(GLES1 == profile && hasGLES1Impl && ( esCtxUndef || GLContext.isGLES1Available(device, isHardwareRasterizer))) {
2373 return esCtxUndef ? GLES1 : GLContext.getAvailableGLProfileName(device, 1, GLContext.CTX_PROFILE_ES);
2374 }
2375 return null;
2376 }
2377
2378 private static /*final*/ HashMap<String /*device_connection*/, HashMap<String /*GLProfile_name*/, GLProfile>> deviceConn2ProfileMap =
2379 new HashMap<String /*device_connection*/, HashMap<String /*GLProfile_name*/, GLProfile>>();
2380
2381 /**
2382 * This implementation support lazy initialization, while avoiding recursion/deadlocks.<br>
2383 * If no mapping 'device -> GLProfiles-Map' exists yet, it triggers<br>
2384 * - create empty mapping device -> GLProfiles-Map <br>
2385 * - initialization<br<
2386 *
2387 * @param device the key 'device -> GLProfiles-Map'
2388 * @param throwExceptionOnZeroProfile true if <code>GLException</code> shall be thrown in case of no mapped profile, otherwise false.
2389 * @return the GLProfile HashMap if exists, otherwise null
2390 * @throws GLException if no profile for the given device is available.
2391 */
2392 private static HashMap<String /*GLProfile_name*/, GLProfile> getProfileMap(AbstractGraphicsDevice device, final boolean throwExceptionOnZeroProfile)
2393 throws GLException
2394 {
2395 initSingleton();
2396
2397 if(null==defaultDevice) { // avoid NPE and notify of incomplete initialization
2398 throw new GLException("No default device available");
2399 }
2400
2401 if(null==device) {
2402 device = defaultDevice;
2403 }
2404
2405 final String deviceKey = device.getUniqueID();
2406 HashMap<String /*GLProfile_name*/, GLProfile> map = deviceConn2ProfileMap.get(deviceKey);
2407 if( null != map ) {
2408 return map;
2409 }
2410 if( !initProfilesForDevice(device) ) {
2411 if( throwExceptionOnZeroProfile ) {
2412 throw new GLException("No Profile available for "+device);
2413 } else {
2414 return null;
2415 }
2416 }
2417 map = deviceConn2ProfileMap.get(deviceKey);
2418 if( null == map && throwExceptionOnZeroProfile ) {
2419 throw new InternalError("initProfilesForDevice(..) didn't setProfileMap(..) for "+device);
2420 }
2421 return map;
2422 }
2423
2424 private static void setProfileMap(final AbstractGraphicsDevice device, final HashMap<String /*GLProfile_name*/, GLProfile> mappedProfiles) {
2425 synchronized ( deviceConn2ProfileMap ) {
2426 deviceConn2ProfileMap.put(device.getUniqueID(), mappedProfiles);
2427 }
2428 }
2429
2430 private GLProfile(final String profile, final GLProfile profileImpl, final boolean isHardwareRasterizer, final boolean isCustom) {
2431 this.profile = profile;
2432 this.profileImpl = profileImpl;
2433 this.isHardwareRasterizer = isHardwareRasterizer;
2434 this.isCustom = isCustom;
2435 }
2436
2437 public static GLProfile createCustomGLProfile(final String profile, final GLProfile profileImpl) {
2438 return new GLProfile(profile, profileImpl, profileImpl.isHardwareRasterizer, true);
2439 }
2440
2441 private final GLProfile profileImpl;
2442 private final String profile;
2443 private final boolean isHardwareRasterizer;
2444 private final boolean isCustom;
2445}
Abstraction for an OpenGL rendering context.
Definition: GLContext.java:74
static final int CTX_PROFILE_COMPAT
ARB_create_context related: desktop compatibility profile.
Definition: GLContext.java:172
static final int CTX_PROFILE_ES
ARB_create_context related: ES profile.
Definition: GLContext.java:176
static final int CTX_PROFILE_CORE
ARB_create_context related: desktop core profile.
Definition: GLContext.java:174
A generic exception for OpenGL errors used throughout the binding as a substitute for RuntimeExceptio...
Specifies the the OpenGL profile.
Definition: GLProfile.java:77
static boolean isAvailable(final AbstractGraphicsDevice device, final String profile)
Returns the availability of a profile on a device.
Definition: GLProfile.java:305
final boolean isGLES3()
Indicates whether this profile is capable of GLES3.
static final boolean disableSurfacelessContext
Disable surfaceless OpenGL context capability and its probing by setting the property jogl....
Definition: GLProfile.java:137
static GLProfile getMinimum(final boolean favorHardwareRasterizer)
Uses the default device.
Definition: GLProfile.java:794
static final String GLES3
The embedded OpenGL profile ES 3.x, with x >= 0.
Definition: GLProfile.java:588
static GLProfile getMaxFixedFunc(final AbstractGraphicsDevice device, final boolean favorHardwareRasterizer)
Returns the highest profile, implementing the fixed function pipeline.
Definition: GLProfile.java:808
static GLProfile getMaximum(final boolean favorHardwareRasterizer)
Uses the default device.
Definition: GLProfile.java:771
static final String GL2ES2
The intersection of the desktop GL3, GL2 and embedded ES2 profile.
Definition: GLProfile.java:594
static final boolean disableOpenGLDesktop
In case no OpenGL desktop profiles are required and if one platform may have a buggy implementation,...
Definition: GLProfile.java:116
static final String[] GL_PROFILE_LIST_MAX_FIXEDFUNC
Order of maximum fixed function profiles.
Definition: GLProfile.java:702
final boolean isGLES2()
Indicates whether this profile is capable of GLES2.
static GLProfile getGL2GL3(final AbstractGraphicsDevice device)
Returns the GL2GL3 profile implementation, hence compatible w/ GL2GL3.
Definition: GLProfile.java:973
static String getGLArrayName(final int array)
static final String[] GL_PROFILE_LIST_ALL
All GL Profiles in the order of default detection.
Definition: GLProfile.java:629
final boolean isHardwareRasterizer()
return true if impl.
static final String GL3
The desktop OpenGL core profile 3.x, with x >= 1.
Definition: GLProfile.java:576
static GLProfile getMaxProgrammableCore(final boolean favorHardwareRasterizer)
Uses the default device.
Definition: GLProfile.java:864
final boolean isGL4ES3()
Indicates whether this profile is capable of GL4ES3.
final boolean usesNativeGLES1()
Indicates whether this profile uses the native OpenGL ES1 implementations.
final String getGLImplBaseClassName()
static StringBuilder glAvailabilityToString(final AbstractGraphicsDevice device, final StringBuilder sb)
Definition: GLProfile.java:337
final boolean usesNativeGLES3()
Indicates whether this profile uses the native OpenGL ES3 implementations.
static final boolean disableOpenGLES
In case no OpenGL ES profiles are required and if one platform may have a buggy implementation,...
Definition: GLProfile.java:109
static void shutdown()
Manual shutdown method, may be called after your last JOGL use within the running JVM.
Definition: GLProfile.java:277
static final String GLES2
The embedded OpenGL profile ES 2.x, with x >= 0.
Definition: GLProfile.java:585
static final boolean enableANGLE
We have to disable support for ANGLE, the D3D ES2 emulation on Windows provided w/ Firefox and Chrome...
Definition: GLProfile.java:147
final boolean isGL2ES2()
Indicates whether this profile is capable of GL2ES2.
static boolean usesNativeGLES3(final String profileImpl)
Indicates whether the native OpenGL ES2 profile is in use.
final GLProfile getImpl()
return this profiles implementation, eg.
static final String[] GL_PROFILE_LIST_MAX_MOBILE
Order of maximum original mobile profiles.
Definition: GLProfile.java:689
static GLProfile getMaxProgrammable(final AbstractGraphicsDevice device, final boolean favorHardwareRasterizer)
Returns the highest profile, implementing the programmable shader pipeline.
Definition: GLProfile.java:831
static boolean usesNativeGLES(final String profileImpl)
Indicates whether either of the native OpenGL ES profiles are in use.
static final boolean disableOpenGLCore
In case no native OpenGL core profiles are required and if one platform may have a buggy implementati...
Definition: GLProfile.java:89
static GLProfile getMaxProgrammable(final boolean favorHardwareRasterizer)
Uses the default device.
Definition: GLProfile.java:841
static boolean isAWTAvailable()
static GLProfile getGL4ES3()
Calls getGL4ES3(AbstractGraphicsDevice) using the default device.
Definition: GLProfile.java:954
static GLProfile getDefault()
Returns a default GLProfile object, reflecting the best for the running platform.
Definition: GLProfile.java:750
static String glAvailabilityToString(final AbstractGraphicsDevice device)
Definition: GLProfile.java:333
static final String GL4bc
The desktop OpenGL compatibility profile 4.x, with x >= 0, ie GL2 plus GL4.
Definition: GLProfile.java:566
final boolean isGL4bc()
Indicates whether this profile is capable of GL4bc.
static final String GL2GL3
The intersection of the desktop GL3 and GL2 profile.
Definition: GLProfile.java:597
final boolean isGLES1()
Indicates whether this profile is capable of GLES1.
static final boolean disabledEGL
In case no EGL implementation is available like on the Platform.OSType#IOS platform,...
Definition: GLProfile.java:123
static GLProfile getMaximum(final AbstractGraphicsDevice device, final boolean favorHardwareRasterizer)
Returns the highest profile.
Definition: GLProfile.java:761
final boolean usesNativeGLES2()
Indicates whether this profile uses the native OpenGL ES2 implementations.
static GLProfile getGL2ES1()
Calls getGL2ES1(AbstractGraphicsDevice) using the default device.
Definition: GLProfile.java:894
final boolean isGL4()
Indicates whether this profile is capable of GL4.
final boolean isGL3ES3()
Indicates whether this profile is capable of GL3ES3.
final boolean usesNativeGLES()
Indicates whether this profile uses either of the native OpenGL ES implementations.
static GLProfile getDefault(final AbstractGraphicsDevice device)
Returns a default GLProfile object, reflecting the best for the running platform.
Definition: GLProfile.java:739
boolean isValidArrayDataType(final int index, final int comps, final int type, final boolean isVertexAttribPointer, final boolean throwException)
General validation if index, comps and type are valid for the current profile.
boolean isValidDataType(final int type, final boolean throwException)
General validation if type is a valid GL data type for the current profile.
static String glAvailabilityToString()
Uses the default device.
Definition: GLProfile.java:556
final boolean isGLES()
Indicates whether this profile is capable of GLES.
static GLProfile createCustomGLProfile(final String profile, final GLProfile profileImpl)
static boolean isAvailable(final String profile)
Returns the availability of a profile on the default device.
Definition: GLProfile.java:320
static GLProfile getMinimum(final AbstractGraphicsDevice device, final boolean favorHardwareRasterizer)
Returns the lowest profile.
Definition: GLProfile.java:784
static GLProfile getGL2ES2()
Calls getGL2ES2(AbstractGraphicsDevice) using the default device.
Definition: GLProfile.java:924
final boolean hasGLSL()
Indicates whether this profile supports GLSL, i.e.
final boolean isGL2GL3()
Indicates whether this profile is capable of GL2GL3.
static boolean usesNativeGLES2(final String profileImpl)
Indicates whether the native OpenGL ES3 or ES2 profile is in use.
static AbstractGraphicsDevice getDefaultDevice()
static final String[] GL_PROFILE_LIST_MAX_PROGSHADER_CORE
Order of maximum programmable shader core only profiles.
Definition: GLProfile.java:731
final Constructor<?> getGLCtor(final boolean glObject)
static GLProfile getGL2ES1(final AbstractGraphicsDevice device)
Returns the GL2ES1 profile implementation, hence compatible w/ GL2ES1.
Definition: GLProfile.java:883
static GLProfile getMaxFixedFunc(final boolean favorHardwareRasterizer)
Uses the default device.
Definition: GLProfile.java:818
static GLProfile getGL4ES3(final AbstractGraphicsDevice device)
Returns the GL4ES3 profile implementation, hence compatible w/ GL4ES3.
Definition: GLProfile.java:943
final boolean equals(final Object o)
static GLProfile get(final AbstractGraphicsDevice device, String profile)
Returns a GLProfile object.
static final boolean disableOpenGLARBContext
In case the implementation of the ARB_create_context context creation extension is buggy on one platf...
Definition: GLProfile.java:102
static final String GL3bc
The desktop OpenGL compatibility profile 3.x, with x >= 1, ie GL2 plus GL3.
Definition: GLProfile.java:573
static final String GL2
The desktop OpenGL profile 1.x up to 3.0.
Definition: GLProfile.java:579
static final boolean DEBUG
Definition: GLProfile.java:79
static final String[] GL_PROFILE_LIST_MAX
Order of maximum profiles.
Definition: GLProfile.java:646
final boolean isGL2ES1()
Indicates whether this profile is capable of GL2ES1.
static GLProfile getMaxProgrammableCore(final AbstractGraphicsDevice device, final boolean favorHardwareRasterizer)
Returns the highest profile, implementing the programmable shader core pipeline only.
Definition: GLProfile.java:854
static boolean isAnyAvailable()
Returns the availability of any profile on the default device.
Definition: GLProfile.java:329
final boolean isGL3bc()
Indicates whether this profile is capable of GL3bc.
static GLProfile getGL2ES2(final AbstractGraphicsDevice device)
Returns the GL2ES2 profile implementation, hence compatible w/ GL2ES2.
Definition: GLProfile.java:913
static String getGLTypeName(final int type)
static final String[] GL_PROFILE_LIST_MIN
Order of minimum profiles.
Definition: GLProfile.java:663
static boolean isInitialized()
Definition: GLProfile.java:171
final void verifyEquality(final GLProfile glp)
static GLProfile getGL2GL3()
Calls getGL2GL3(AbstractGraphicsDevice) using the default device.
Definition: GLProfile.java:984
static final String GLES1
The embedded OpenGL profile ES 1.x, with x >= 0.
Definition: GLProfile.java:582
final String getImplName()
return this profiles implementation name, eg.
static final String[] GL_PROFILE_LIST_MAX_PROGSHADER
Order of maximum programmable shader profiles.
Definition: GLProfile.java:718
static final String[] GL_PROFILE_LIST_MIN_DESKTOP
Order of minimum original desktop profiles.
Definition: GLProfile.java:677
static final String GL4ES3
The intersection of the desktop GL4 and ES3 profile, available only if either ES3 or GL4 w/ GL_ARB_ES...
Definition: GLProfile.java:600
static void initSingleton()
Static initialization of JOGL.
Definition: GLProfile.java:204
static final String GL4
The desktop OpenGL core profile 4.x, with x >= 0.
Definition: GLProfile.java:569
static boolean usesNativeGLES1(final String profileImpl)
Indicates whether the native OpenGL ES1 profile is in use.
final boolean isGL3()
Indicates whether this profile is capable of GL3.
final boolean isGL2ES3()
Indicates whether this profile is capable of GL2ES3.
final boolean isGL2()
Indicates whether this profile is capable of GL2 .
static final String GL2ES1
The intersection of the desktop GL2 and embedded ES1 profile.
Definition: GLProfile.java:591
static void initProfiles(final AbstractGraphicsDevice device)
Trigger eager initialization of GLProfiles for the given device, in case it isn't done yet.
Definition: GLProfile.java:264
final String getName()
return this profiles name
static StringBuilder glAvailabilityToString(AbstractGraphicsDevice device, StringBuilder sb, final String indent, int indentCount)
Definition: GLProfile.java:347
static StringBuilder getDefaultOpenGLInfo(AbstractGraphicsDevice device, StringBuilder sb, final boolean withCapabilitiesInfo)
A interface describing a graphics device in a toolkit-independent manner.
String getUniqueID()
Returns a unique ID object of this device using type, connection and unitID as it's key components.
static final int GL_INT_2_10_10_10_REV
GL_ARB_vertex_type_2_10_10_10_rev, GL_VERSION_3_3, GL_ES_VERSION_3_0 Define "GL_INT_2_10_10_10_REV" w...
Definition: GL3ES3.java:501
static final int GL_UNSIGNED_INT_10F_11F_11F_REV
Part of GL_ES_VERSION_3_0, GL_VERSION_3_0; GL_EXT_packed_float
Definition: GL.java:1283
static final int GL_FIXED
GL_ARB_ES2_compatibility, GL_ES_VERSION_2_0, GL_VERSION_4_1, GL_VERSION_ES_1_0, GL_OES_fixed_point Al...
Definition: GL.java:148
static final int GL_SHORT
GL_ES_VERSION_2_0, GL_VERSION_1_1, GL_VERSION_1_0, GL_VERSION_ES_1_0 Define "GL_SHORT" with expressio...
Definition: GL.java:125
static final int GL_UNSIGNED_INT
GL_ES_VERSION_2_0, GL_VERSION_1_1, GL_VERSION_1_0, GL_OES_element_index_uint Define "GL_UNSIGNED_INT"...
Definition: GL.java:294
static final int GL_FLOAT
GL_ES_VERSION_2_0, GL_VERSION_1_1, GL_VERSION_1_0, GL_VERSION_ES_1_0 Define "GL_FLOAT" with expressio...
Definition: GL.java:786
static final int GL_UNSIGNED_SHORT
GL_ES_VERSION_2_0, GL_VERSION_1_1, GL_VERSION_1_0, GL_VERSION_ES_1_0 Define "GL_UNSIGNED_SHORT" with ...
Definition: GL.java:346
static final int GL_HALF_FLOAT
Part of GL_ARB_half_float_vertex; GL_NV_half_float; GL_ARB_half_float_pixel, earmarked for ES 3....
Definition: GL.java:1278
static final int GL_UNSIGNED_BYTE
GL_ES_VERSION_2_0, GL_VERSION_1_1, GL_VERSION_1_0, GL_VERSION_ES_1_0 Define "GL_UNSIGNED_BYTE" with e...
Definition: GL.java:284
static final int GL_BYTE
GL_ES_VERSION_2_0, GL_VERSION_1_1, GL_VERSION_1_0, GL_VERSION_ES_1_0 Define "GL_BYTE" with expression...
Definition: GL.java:159