1 /**
2  * Copyright 2010 JogAmp Community. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without modification, are
5  * permitted provided that the following conditions are met:
6  *
7  *    1. Redistributions of source code must retain the above copyright notice, this list of
8  *       conditions and the following disclaimer.
9  *
10  *    2. Redistributions in binary form must reproduce the above copyright notice, this list
11  *       of conditions and the following disclaimer in the documentation and/or other materials
12  *       provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED
15  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
16  * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
19  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
20  * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
21  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
22  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23  *
24  * The views and conclusions contained in the software and documentation are those of the
25  * authors and should not be interpreted as representing official policies, either expressed
26  * or implied, of JogAmp Community.
27  */
28 
29 package jogamp.opengl;
30 
31 import com.jogamp.common.util.VersionNumber;
32 import com.jogamp.common.util.VersionNumberString;
33 
34 /**
35  * A class for storing and comparing OpenGL version numbers.
36  * This only works for desktop OpenGL at the moment.
37  */
38 public class GLVersionNumber extends VersionNumberString {
39 
40     private final boolean valid;
41 
GLVersionNumber(final int[] val, final int strEnd, final short state, final String versionString, final boolean valid)42     private GLVersionNumber(final int[] val, final int strEnd, final short state, final String versionString, final boolean valid) {
43         super(val[0], val[1], val[2], strEnd, state, versionString);
44         this.valid = valid;
45     }
46 
getUnderscorePattern()47     private static java.util.regex.Pattern getUnderscorePattern() {
48         if( null == _Pattern ) { // volatile dbl-checked-locking OK
49             synchronized( VersionNumber.class ) {
50                 if( null == _Pattern ) {
51                     _Pattern = getVersionNumberPattern("_");
52                 }
53             }
54         }
55         return _Pattern;
56     }
57     private static volatile java.util.regex.Pattern _Pattern = null;
58 
create(final String versionString)59     public static final GLVersionNumber create(final String versionString) {
60         final int[] val = new int[] { 0, 0, 0 };
61         int strEnd = 0;
62         short state = 0;
63         boolean valid = false;
64         if (versionString != null && versionString.length() > 0) {
65             try {
66                 final java.util.regex.Pattern versionPattern;
67                 if (versionString.startsWith("GL_VERSION_")) {
68                     versionPattern = getUnderscorePattern();
69                 } else {
70                     versionPattern = VersionNumber.getDefaultVersionNumberPattern();
71                 }
72                 final VersionNumberString version = new VersionNumberString(versionString, versionPattern);
73                 strEnd = version.endOfStringMatch();
74                 val[0] = version.getMajor();
75                 val[1] = version.getMinor();
76                 state = (short) ( ( version.hasMajor() ? VersionNumber.HAS_MAJOR : (short)0 ) |
77                                   ( version.hasMinor() ? VersionNumber.HAS_MINOR : (short)0 ) );
78                 valid = version.hasMajor() && version.hasMinor(); // Requires at least a defined major and minor version component!
79             } catch (final Exception e) {
80                 e.printStackTrace();
81                 System.err.println("Info: ExtensionAvailabilityCache: FunctionAvailabilityCache.Version.<init>: " + e);
82                 val[0] = 1;
83                 val[1] = 0;
84             }
85         }
86         return new GLVersionNumber(val, strEnd, state, versionString, valid);
87     }
88 
isValid()89     public final boolean isValid() {
90         return valid;
91     }
92 
93     /**
94      * Returns the optional vendor version at the end of the
95      * <code>GL_VERSION</code> string if exists, otherwise the {@link VersionNumberString#zeroVersion zero version} instance.
96      * <pre>
97      *   2.1 Mesa 7.0.3-rc2 -> 7.0.3 (7.0.3-rc2)
98      *   2.1 Mesa 7.12-devel (git-d6c318e) -> 7.12.0 (7.12-devel)
99      *   4.2.12171 Compatibility Profile Context 9.01.8 -> 9.1.8 (9.01.8)
100      *   4.2.12198 Compatibility Profile Context 12.102.3.0 -> 12.102.3 (12.102.3.0)
101      *   4.3.0 NVIDIA 310.32 -> 310.32 (310.32)
102      * </pre>
103      */
createVendorVersion(final String versionString)104     public static final VersionNumberString createVendorVersion(final String versionString) {
105         if (versionString == null || versionString.length() <= 0) {
106             return null;
107         }
108 
109         // Skip the 1st GL version
110         String str;
111         {
112             final GLVersionNumber glv = create(versionString);
113             str = versionString.substring(glv.endOfStringMatch()).trim();
114         }
115 
116         while ( str.length() > 0 ) {
117             final VersionNumberString version = new VersionNumberString(str, getDefaultVersionNumberPattern());
118             final int eosm = version.endOfStringMatch();
119             if( 0 < eosm ) {
120                 if( version.hasMajor() && version.hasMinor() ) { // Requires at least a defined major and minor version component!
121                     return version;
122                 }
123                 str = str.substring( eosm ).trim();
124             } else {
125                 break; // no match
126             }
127         }
128         return VersionNumberString.zeroVersion;
129     }
130 }
131