1 /* 2 * Copyright (c) 2002-2014 LWJGL Project 3 * 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 * * Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 12 * * Redistributions 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 'LWJGL' nor the names of 17 * its contributors may be used to endorse or promote products derived 18 * from this software without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 24 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 25 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 26 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 27 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 28 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 29 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 30 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 */ 32 package org.lwjgl.opengl; 33 34 import org.lwjgl.BufferUtils; 35 import org.lwjgl.LWJGLUtil; 36 37 import java.nio.IntBuffer; 38 import java.util.LinkedHashMap; 39 import java.util.Map.Entry; 40 41 /** 42 * This class represents the context attributes passed to CreateContextAttribs of the ARB_create_context extension. 43 * <p/> 44 * The attributes supported are described in the following extensions:<br> 45 * <ul> 46 * <li><a href="http://www.opengl.org/registry/specs/ARB/wgl_create_context.txt">WGL_ARB_create_context(_profile)</a> and <a href="http://www.opengl.org/registry/specs/ARB/glx_create_context.txt">GLX_ARB_create_context(_profile)</a></li> 47 * <li><a href="http://www.opengl.org/registry/specs/ARB/wgl_create_context_robustness.txt">WGL_ARB_create_context_robustness</a> and <a href="http://www.opengl.org/registry/specs/ARB/glx_create_context_robustness.txt">GLX_ARB_create_context_robustness</a></li> 48 * <li><a href="http://www.opengl.org/registry/specs/ARB/wgl_robustness_isolation.txt">WGL_ARB_robustness_isolation</a> and <a href="http://www.opengl.org/registry/specs/ARB/glx_robustness_isolation.txt">GLX_ARB_robustness_isolation</a></li> 49 * <li><a href="http://www.opengl.org/registry/specs/ARB/wgl_create_context_es2_profile.txt">WGL_EXT_create_context_es2_profile</a> and <a href="http://www.opengl.org/registry/specs/ARB/glx_create_context_es2_profile.txt">GLX_EXT_create_context_es2_profile</a></li> 50 * <li><a href="http://www.opengl.org/registry/specs/ARB/context_flush_control.txt">KHR_context_flush_control</a></li> 51 * </ul> 52 * <p/> 53 * Use of this class is optional. If an OpenGL context is created without passing an instance of this class 54 * (or ARB_create_context is not supported), the old context creation code will be used. Support for debug and forward 55 * compatible mobes is not guaranteed by the OpenGL implementation. Developers may encounter debug contexts being the same 56 * as non-debug contexts or forward compatible contexts having support for deprecated functionality. 57 * <p/> 58 * If the {@link #CONTEXT_FORWARD_COMPATIBLE_BIT_ARB} flag is used, LWJGL will not load the deprecated functionality (as defined in the OpenGL 3.0 59 * specification), even if the driver exposes the corresponding entry points. 60 * <p/> 61 * This extension is not supported on MacOS X. However, in order to enable the GL 3.2 context on MacOS X 10.7 or newer, an instance of this class must be passed 62 * to LWJGL. The only valid configuration is <code>ContextAttribs(3, 2, CONTEXT_CORE_PROFILE_BIT_ARB)</code>, anything else will be ignored. 63 * 64 * @author spasi <spasi@users.sourceforge.net> 65 */ 66 public final class ContextAttribs { 67 68 // ATTRIBUTES 69 70 public static final int CONTEXT_MAJOR_VERSION_ARB = 0x2091; 71 public static final int CONTEXT_MINOR_VERSION_ARB = 0x2092; 72 73 public static final int CONTEXT_PROFILE_MASK_ARB = 0x9126, 74 CONTEXT_CORE_PROFILE_BIT_ARB = 0x00000001, 75 CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB = 0x00000002, 76 CONTEXT_ES2_PROFILE_BIT_EXT = 0x00000004; 77 78 public static final int CONTEXT_FLAGS_ARB = 0x2094, 79 CONTEXT_DEBUG_BIT_ARB = 0x0001, 80 CONTEXT_FORWARD_COMPATIBLE_BIT_ARB = 0x0002, 81 CONTEXT_ROBUST_ACCESS_BIT_ARB = 0x00000004, 82 CONTEXT_RESET_ISOLATION_BIT_ARB = 0x00000008; 83 84 public static final int CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB = 0x8256, 85 NO_RESET_NOTIFICATION_ARB = 0x8261, 86 LOSE_CONTEXT_ON_RESET_ARB = 0x8252; 87 88 public static final int CONTEXT_RELEASE_BEHABIOR_ARB = 0x2097, 89 CONTEXT_RELEASE_BEHAVIOR_NONE_ARB = 0x0000, 90 CONTEXT_RELEASE_BEHAVIOR_FLUSH_ARB = 0x2098; 91 92 public static final int CONTEXT_LAYER_PLANE_ARB = 0x2093; // WGL-only 93 94 // STATE 95 96 private int majorVersion; 97 private int minorVersion; 98 99 private int profileMask; 100 private int contextFlags; 101 102 private int contextResetNotificationStrategy = NO_RESET_NOTIFICATION_ARB; 103 private int contextReleaseBehavior = CONTEXT_RELEASE_BEHAVIOR_FLUSH_ARB; 104 105 private int layerPlane; 106 107 // CONSTRUCTORS 108 109 /** Creates the default ContextAttribs instance. No special attributes will be used when creating the OpenGL context. */ ContextAttribs()110 public ContextAttribs() { 111 this(1, 0); 112 } 113 114 /** Creates a ContextAttribs instance for the given OpenGL version. */ ContextAttribs(int majorVersion, int minorVersion)115 public ContextAttribs(int majorVersion, int minorVersion) { 116 this(majorVersion, minorVersion, 0, 0); 117 } 118 119 /** 120 * Creates a new ContextAttribs instance with the given attributes. 121 * 122 * @param majorVersion the major OpenGL version 123 * @param minorVersion the minor OpenGL version 124 * @param profileMask the context profile mask. One of:<br>{@link #CONTEXT_CORE_PROFILE_BIT_ARB}, {@link #CONTEXT_FORWARD_COMPATIBLE_BIT_ARB}, {@link #CONTEXT_ES2_PROFILE_BIT_EXT} 125 */ ContextAttribs(int majorVersion, int minorVersion, int profileMask)126 public ContextAttribs(int majorVersion, int minorVersion, int profileMask) { 127 this(majorVersion, minorVersion, 0, profileMask); 128 } 129 130 /** 131 * Creates a new ContextAttribs instance with the given attributes. 132 * 133 * @param majorVersion the major OpenGL version 134 * @param minorVersion the minor OpenGL version 135 * @param profileMask the context profile mask. One of:<br>{@link #CONTEXT_CORE_PROFILE_BIT_ARB}, {@link #CONTEXT_FORWARD_COMPATIBLE_BIT_ARB}, {@link #CONTEXT_ES2_PROFILE_BIT_EXT} 136 * @param contextFlags the context flags, a bitfield value. One or more of:<br>{@link #CONTEXT_DEBUG_BIT_ARB}, {@link #CONTEXT_FORWARD_COMPATIBLE_BIT_ARB}, {@link #CONTEXT_ROBUST_ACCESS_BIT_ARB}, {@link #CONTEXT_RESET_ISOLATION_BIT_ARB} 137 */ ContextAttribs(int majorVersion, int minorVersion, int profileMask, int contextFlags)138 public ContextAttribs(int majorVersion, int minorVersion, int profileMask, int contextFlags) { 139 if ( majorVersion < 0 || 4 < majorVersion || 140 minorVersion < 0 || 141 (majorVersion == 4 && 5 < minorVersion) || 142 (majorVersion == 3 && 3 < minorVersion) || 143 (majorVersion == 2 && 1 < minorVersion) || 144 (majorVersion == 1 && 5 < minorVersion) ) 145 throw new IllegalArgumentException("Invalid OpenGL version specified: " + majorVersion + '.' + minorVersion); 146 147 if ( LWJGLUtil.CHECKS ) { 148 if ( 1 < Integer.bitCount(profileMask) || CONTEXT_ES2_PROFILE_BIT_EXT < profileMask ) 149 throw new IllegalArgumentException("Invalid profile mask specified: " + Integer.toBinaryString(profileMask)); 150 151 if ( 0xF < contextFlags ) 152 throw new IllegalArgumentException("Invalid context flags specified: " + Integer.toBinaryString(profileMask)); 153 } 154 155 this.majorVersion = majorVersion; 156 this.minorVersion = minorVersion; 157 158 this.profileMask = profileMask; 159 this.contextFlags = contextFlags; 160 } 161 162 // Copy constructor ContextAttribs(ContextAttribs other)163 private ContextAttribs(ContextAttribs other) { 164 this.majorVersion = other.majorVersion; 165 this.minorVersion = other.minorVersion; 166 167 this.profileMask = other.profileMask; 168 this.contextFlags = other.contextFlags; 169 170 this.contextResetNotificationStrategy = other.contextResetNotificationStrategy; 171 this.contextReleaseBehavior = other.contextReleaseBehavior; 172 173 this.layerPlane = other.layerPlane; 174 } 175 176 // GETTERS 177 178 /** Returns the {@link #CONTEXT_MAJOR_VERSION_ARB} value. */ getMajorVersion()179 public int getMajorVersion() { 180 return majorVersion; 181 } 182 183 /** Returns the {@link #CONTEXT_MINOR_VERSION_ARB} value. */ getMinorVersion()184 public int getMinorVersion() { 185 return minorVersion; 186 } 187 188 /** Returns the {@link #CONTEXT_PROFILE_MASK_ARB} value. */ getProfileMask()189 public int getProfileMask() { 190 return profileMask; 191 } 192 hasMask(int mask)193 private boolean hasMask(int mask) { 194 return profileMask == mask; 195 } 196 197 /** Returns true if the {@link #CONTEXT_CORE_PROFILE_BIT_ARB} has been set. */ isProfileCore()198 public boolean isProfileCore() { 199 return hasMask(CONTEXT_CORE_PROFILE_BIT_ARB); 200 } 201 202 /** Returns true if the {@link #CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB} has been set. */ isProfileCompatibility()203 public boolean isProfileCompatibility() { 204 return hasMask(CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB); 205 } 206 207 /** Returns true if the {@link #CONTEXT_ES2_PROFILE_BIT_EXT} has been set. */ isProfileES()208 public boolean isProfileES() { 209 return hasMask(CONTEXT_ES2_PROFILE_BIT_EXT); 210 } 211 212 /** Returns the {@link #CONTEXT_FLAGS_ARB} value. */ getContextFlags()213 public int getContextFlags() { 214 return contextFlags; 215 } 216 hasFlag(int flag)217 private boolean hasFlag(int flag) { 218 return (contextFlags & flag) != 0; 219 } 220 221 /** Returns true if the {@link #CONTEXT_DEBUG_BIT_ARB} has been set. */ isDebug()222 public boolean isDebug() { 223 return hasFlag(CONTEXT_DEBUG_BIT_ARB); 224 } 225 226 /** Returns true if the {@link #CONTEXT_FORWARD_COMPATIBLE_BIT_ARB} has been set. */ isForwardCompatible()227 public boolean isForwardCompatible() { 228 return hasFlag(CONTEXT_FORWARD_COMPATIBLE_BIT_ARB); 229 } 230 231 /** Returns true if the {@link #CONTEXT_ROBUST_ACCESS_BIT_ARB} has been set. */ isRobustAccess()232 public boolean isRobustAccess() { return hasFlag(CONTEXT_ROBUST_ACCESS_BIT_ARB); } 233 234 /** Returns true if the {@link #CONTEXT_RESET_ISOLATION_BIT_ARB} has been set. */ isContextResetIsolation()235 public boolean isContextResetIsolation() { 236 return hasFlag(CONTEXT_RESET_ISOLATION_BIT_ARB); 237 } 238 239 /** Returns the {@link #CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB} value. */ getContextResetNotificationStrategy()240 public int getContextResetNotificationStrategy() { 241 return contextResetNotificationStrategy; 242 } 243 244 /** 245 * Returns true if the {@link #CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB} has been set to {@link #LOSE_CONTEXT_ON_RESET_ARB}. 246 * 247 * @deprecated use {@link #getContextResetNotificationStrategy} instead 248 */ isLoseContextOnReset()249 public boolean isLoseContextOnReset() { return contextResetNotificationStrategy == LOSE_CONTEXT_ON_RESET_ARB; } 250 251 /** Returns the {@link #CONTEXT_RELEASE_BEHABIOR_ARB} value. */ getContextReleaseBehavior()252 public int getContextReleaseBehavior() { 253 return contextReleaseBehavior; 254 } 255 256 /** Returns the {@link #CONTEXT_LAYER_PLANE_ARB} value. */ getLayerPlane()257 public int getLayerPlane() { 258 return layerPlane; 259 } 260 261 // CHAIN CONFIGURATION PATTERN 262 toggleMask(int mask, boolean value)263 private ContextAttribs toggleMask(int mask, boolean value) { 264 if ( value == hasMask(mask) ) 265 return this; 266 267 ContextAttribs attribs = new ContextAttribs(this); 268 attribs.profileMask = value ? mask : 0; 269 return attribs; 270 } 271 272 /** 273 * Returns a new {@code ContextAttribs} instance with the {@link #CONTEXT_CORE_PROFILE_BIT_ARB} bit in {@link #CONTEXT_PROFILE_MASK_ARB} set to the given value. 274 * If {@code profileCore} is true, all other bits in the mask are cleared. 275 */ withProfileCore(boolean profileCore)276 public ContextAttribs withProfileCore(boolean profileCore) { 277 if ( majorVersion < 3 || (majorVersion == 3 && minorVersion < 2) ) 278 throw new IllegalArgumentException("Profiles are only supported on OpenGL version 3.2 or higher."); 279 280 return toggleMask(CONTEXT_CORE_PROFILE_BIT_ARB, profileCore); 281 } 282 283 /** 284 * Returns a new {@code ContextAttribs} instance with the {@link #CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB} bit in {@link #CONTEXT_PROFILE_MASK_ARB} set to the given value. 285 * If {@code profileCompatibility} is true, all other bits in the mask are cleared. 286 */ withProfileCompatibility(boolean profileCompatibility)287 public ContextAttribs withProfileCompatibility(boolean profileCompatibility) { 288 if ( majorVersion < 3 || (majorVersion == 3 && minorVersion < 2) ) 289 throw new IllegalArgumentException("Profiles are only supported on OpenGL version 3.2 or higher."); 290 291 return toggleMask(CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB, profileCompatibility); 292 } 293 294 /** 295 * Returns a new {@code ContextAttribs} instance with the {@link #CONTEXT_ES2_PROFILE_BIT_EXT} bit in {@link #CONTEXT_PROFILE_MASK_ARB} set to the given value. 296 * If {@code profileES} is true, all other bits in the mask are cleared. 297 */ withProfileES(boolean profileES)298 public ContextAttribs withProfileES(boolean profileES) { 299 if ( !(majorVersion == 2 && minorVersion == 0) ) 300 throw new IllegalArgumentException("The OpenGL ES profile is only supported on OpenGL version 2.0."); 301 302 return toggleMask(CONTEXT_ES2_PROFILE_BIT_EXT, profileES); 303 } 304 toggleFlag(int flag, boolean value)305 private ContextAttribs toggleFlag(int flag, boolean value) { 306 if ( value == hasFlag(flag) ) 307 return this; 308 309 ContextAttribs attribs = new ContextAttribs(this); 310 attribs.contextFlags ^= flag; // toggle bit 311 return attribs; 312 } 313 314 /** Returns a new {@code ContextAttribs} instance with the {@link #CONTEXT_DEBUG_BIT_ARB} bit in {@link #CONTEXT_FLAGS_ARB} set to the given value. */ withDebug(boolean debug)315 public ContextAttribs withDebug(boolean debug) { return toggleFlag(CONTEXT_DEBUG_BIT_ARB, debug); } 316 317 /** Returns a new {@code ContextAttribs} instance with the {@link #CONTEXT_FORWARD_COMPATIBLE_BIT_ARB} bit in {@link #CONTEXT_FLAGS_ARB} set to the given value. */ withForwardCompatible(boolean forwardCompatible)318 public ContextAttribs withForwardCompatible(boolean forwardCompatible) { return toggleFlag(CONTEXT_FORWARD_COMPATIBLE_BIT_ARB, forwardCompatible); } 319 320 /** Returns a new {@code ContextAttribs} instance with the {@link #CONTEXT_ROBUST_ACCESS_BIT_ARB} bit in {@link #CONTEXT_FLAGS_ARB} set to the given value. */ withRobustAccess(boolean robustAccess)321 public ContextAttribs withRobustAccess(boolean robustAccess) { return toggleFlag(CONTEXT_ROBUST_ACCESS_BIT_ARB, robustAccess); } 322 323 /** Returns a new {@code ContextAttribs} instance with the {@link #CONTEXT_RESET_ISOLATION_BIT_ARB} bit in {@link #CONTEXT_FLAGS_ARB} set to the given value. */ withContextResetIsolation(boolean contextResetIsolation)324 public ContextAttribs withContextResetIsolation(boolean contextResetIsolation) { return toggleFlag(CONTEXT_RESET_ISOLATION_BIT_ARB, contextResetIsolation); } 325 326 /** 327 * Returns a ContextAttribs instance with {@link #CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB} set to the given strategy. The default context reset notification 328 * strategy is {@link #NO_RESET_NOTIFICATION_ARB}. 329 * 330 * @param strategy the context reset notification strategy. One of:<br>{@link #NO_RESET_NOTIFICATION_ARB}, {@link #LOSE_CONTEXT_ON_RESET_ARB} 331 * 332 * @return the new ContextAttribs 333 */ withResetNotificationStrategy(int strategy)334 public ContextAttribs withResetNotificationStrategy(int strategy) { 335 if ( strategy == contextResetNotificationStrategy ) 336 return this; 337 338 if ( LWJGLUtil.CHECKS && !(strategy == NO_RESET_NOTIFICATION_ARB || strategy == LOSE_CONTEXT_ON_RESET_ARB) ) 339 throw new IllegalArgumentException("Invalid context reset notification strategy specified: 0x" + LWJGLUtil.toHexString(strategy)); 340 341 ContextAttribs attribs = new ContextAttribs(this); 342 attribs.contextResetNotificationStrategy = strategy; 343 return attribs; 344 } 345 346 /** 347 * Returns a ContextAttribs instance with {@link #CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB} set to {@link #LOSE_CONTEXT_ON_RESET_ARB} if the parameter is 348 * true or to {@link #NO_RESET_NOTIFICATION_ARB} if the parameter is false. 349 * 350 * @param loseContextOnReset the context reset notification strategy 351 * 352 * @return the new ContextAttribs 353 * 354 * @deprecated use {@link #withResetNotificationStrategy} instead 355 */ withLoseContextOnReset(boolean loseContextOnReset)356 public ContextAttribs withLoseContextOnReset(boolean loseContextOnReset) { 357 return withResetNotificationStrategy(loseContextOnReset ? LOSE_CONTEXT_ON_RESET_ARB : NO_RESET_NOTIFICATION_ARB); 358 } 359 360 /** 361 * Returns a ContextAttribs instance with {@link #CONTEXT_RELEASE_BEHABIOR_ARB} set to the given behavior. The default context release behavior is 362 * {@link #CONTEXT_RELEASE_BEHAVIOR_FLUSH_ARB}. 363 * 364 * @param behavior the context release behavior. One of:<br>{@link #CONTEXT_RELEASE_BEHAVIOR_FLUSH_ARB}, {@link #CONTEXT_RELEASE_BEHAVIOR_NONE_ARB} 365 * 366 * @return the new ContextAttribs 367 */ withContextReleaseBehavior(int behavior)368 public ContextAttribs withContextReleaseBehavior(int behavior) { 369 if ( behavior == contextReleaseBehavior ) 370 return this; 371 372 if ( LWJGLUtil.CHECKS && !(behavior == CONTEXT_RELEASE_BEHAVIOR_FLUSH_ARB || behavior == CONTEXT_RELEASE_BEHAVIOR_NONE_ARB) ) 373 throw new IllegalArgumentException("Invalid context release behavior specified: 0x" + LWJGLUtil.toHexString(behavior)); 374 375 ContextAttribs attribs = new ContextAttribs(this); 376 attribs.contextReleaseBehavior = behavior; 377 return attribs; 378 } 379 380 /** Returns a new {@code ContextAttribs} instance with {@link #CONTEXT_LAYER_PLANE_ARB} set to the given value. */ withLayer(int layerPlane)381 public ContextAttribs withLayer(int layerPlane) { 382 if ( LWJGLUtil.getPlatform() != LWJGLUtil.PLATFORM_WINDOWS ) 383 throw new IllegalArgumentException("The CONTEXT_LAYER_PLANE_ARB attribute is supported only on the Windows platform."); 384 385 if ( layerPlane == this.layerPlane ) 386 return this; 387 388 if ( layerPlane < 0 ) 389 throw new IllegalArgumentException("Invalid layer plane specified: " + layerPlane); 390 391 ContextAttribs attribs = new ContextAttribs(this); 392 attribs.layerPlane = layerPlane; 393 return attribs; 394 } 395 getAttribList()396 IntBuffer getAttribList() { 397 if ( LWJGLUtil.getPlatform() == LWJGLUtil.PLATFORM_MACOSX ) 398 return null; 399 400 LinkedHashMap<Integer, Integer> map = new LinkedHashMap<Integer, Integer>(8); 401 402 if ( !(majorVersion == 1 && minorVersion == 0) ) { 403 map.put(CONTEXT_MAJOR_VERSION_ARB, majorVersion); 404 map.put(CONTEXT_MINOR_VERSION_ARB, minorVersion); 405 } 406 407 if ( contextFlags != 0 ) 408 map.put(CONTEXT_FLAGS_ARB, contextFlags); 409 410 if ( profileMask != 0 ) 411 map.put(CONTEXT_PROFILE_MASK_ARB, profileMask); 412 413 if ( contextResetNotificationStrategy != NO_RESET_NOTIFICATION_ARB ) 414 map.put(CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB, contextResetNotificationStrategy); 415 416 if ( contextReleaseBehavior != CONTEXT_RELEASE_BEHAVIOR_FLUSH_ARB ) 417 map.put(CONTEXT_RELEASE_BEHABIOR_ARB, contextReleaseBehavior); 418 419 if ( layerPlane != 0 ) 420 map.put(CONTEXT_LAYER_PLANE_ARB, layerPlane); 421 422 if ( map.isEmpty() ) 423 return null; 424 425 IntBuffer attribs = BufferUtils.createIntBuffer((map.size() * 2) + 1); 426 for ( Entry<Integer, Integer> attrib : map.entrySet() ) { 427 attribs 428 .put(attrib.getKey()) 429 .put(attrib.getValue()); 430 } 431 attribs.put(0); 432 attribs.rewind(); 433 return attribs; 434 } 435 toString()436 public String toString() { 437 StringBuilder sb = new StringBuilder(32); 438 439 sb.append("ContextAttribs:"); 440 sb.append(" Version=").append(majorVersion).append('.').append(minorVersion); 441 442 if ( profileMask != 0 ) { 443 sb.append(", Profile="); 444 if ( hasMask(CONTEXT_CORE_PROFILE_BIT_ARB) ) 445 sb.append("CORE"); 446 else if ( hasMask(CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB) ) 447 sb.append("COMPATIBLITY"); 448 else if ( hasMask(CONTEXT_ES2_PROFILE_BIT_EXT) ) 449 sb.append("ES2"); 450 else 451 sb.append("*unknown*"); 452 } 453 454 if ( contextFlags != 0 ) { 455 if ( hasFlag(CONTEXT_DEBUG_BIT_ARB) ) 456 sb.append(", DEBUG"); 457 if ( hasFlag(CONTEXT_FORWARD_COMPATIBLE_BIT_ARB) ) 458 sb.append(", FORWARD_COMPATIBLE"); 459 if ( hasFlag(CONTEXT_ROBUST_ACCESS_BIT_ARB) ) 460 sb.append(", ROBUST_ACCESS"); 461 if ( hasFlag(CONTEXT_RESET_ISOLATION_BIT_ARB) ) 462 sb.append(", RESET_ISOLATION"); 463 } 464 465 if ( contextResetNotificationStrategy != NO_RESET_NOTIFICATION_ARB ) 466 sb.append(", LOSE_CONTEXT_ON_RESET"); 467 if ( contextReleaseBehavior != CONTEXT_RELEASE_BEHAVIOR_FLUSH_ARB ) 468 sb.append(", RELEASE_BEHAVIOR_NONE"); 469 470 if ( layerPlane != 0 ) 471 sb.append(", Layer=").append(layerPlane); 472 473 return sb.toString(); 474 } 475 476 }