1 /* 2 * Copyright (c) 2002-2008 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.PointerWrapperAbstract; 35 36 /** 37 * Instances of this class are needed to use the callback functionality of the ARB_debug_output extension. 38 * A debug context must be current before creating instances of this class. Users of this class may provide 39 * implementations of the {@code Handler} interface to receive notifications. The same {@code Handler} 40 * instance may be used by different contexts but it is not recommended. Handler notifications are synchronized. 41 * 42 * @author Spasi 43 */ 44 public final class ARBDebugOutputCallback extends PointerWrapperAbstract { 45 46 /** Severity levels. */ 47 private static final int 48 GL_DEBUG_SEVERITY_HIGH_ARB = 0x9146, 49 GL_DEBUG_SEVERITY_MEDIUM_ARB = 0x9147, 50 GL_DEBUG_SEVERITY_LOW_ARB = 0x9148; 51 52 /** Sources. */ 53 private static final int 54 GL_DEBUG_SOURCE_API_ARB = 0x8246, 55 GL_DEBUG_SOURCE_WINDOW_SYSTEM_ARB = 0x8247, 56 GL_DEBUG_SOURCE_SHADER_COMPILER_ARB = 0x8248, 57 GL_DEBUG_SOURCE_THIRD_PARTY_ARB = 0x8249, 58 GL_DEBUG_SOURCE_APPLICATION_ARB = 0x824A, 59 GL_DEBUG_SOURCE_OTHER_ARB = 0x824B; 60 61 /** Types. */ 62 private static final int 63 GL_DEBUG_TYPE_ERROR_ARB = 0x824C, 64 GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR_ARB = 0x824D, 65 GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR_ARB = 0x824E, 66 GL_DEBUG_TYPE_PORTABILITY_ARB = 0x824F, 67 GL_DEBUG_TYPE_PERFORMANCE_ARB = 0x8250, 68 GL_DEBUG_TYPE_OTHER_ARB = 0x8251; 69 70 private static final long CALLBACK_POINTER; 71 72 static { 73 long pointer = 0; 74 try { 75 // Call reflectively so that we can compile this class for the Generator. 76 pointer = (Long)Class.forName("org.lwjgl.opengl.CallbackUtil").getDeclaredMethod("getDebugOutputCallbackARB").invoke(null); 77 } catch (Exception e) { 78 // ignore 79 } 80 CALLBACK_POINTER = pointer; 81 } 82 83 private final Handler handler; 84 85 /** 86 * Creates an ARBDebugOutputCallback with a default callback handler. 87 * The default handler will simply print the message on System.err. 88 */ ARBDebugOutputCallback()89 public ARBDebugOutputCallback() { 90 this(new Handler() { 91 public void handleMessage(final int source, final int type, final int id, final int severity, final String message) { 92 System.err.println("[LWJGL] ARB_debug_output message"); 93 System.err.println("\tID: " + id); 94 95 String description; 96 switch ( source ) { 97 case GL_DEBUG_SOURCE_API_ARB: 98 description = "API"; 99 break; 100 case GL_DEBUG_SOURCE_WINDOW_SYSTEM_ARB: 101 description = "WINDOW SYSTEM"; 102 break; 103 case GL_DEBUG_SOURCE_SHADER_COMPILER_ARB: 104 description = "SHADER COMPILER"; 105 break; 106 case GL_DEBUG_SOURCE_THIRD_PARTY_ARB: 107 description = "THIRD PARTY"; 108 break; 109 case GL_DEBUG_SOURCE_APPLICATION_ARB: 110 description = "APPLICATION"; 111 break; 112 case GL_DEBUG_SOURCE_OTHER_ARB: 113 description = "OTHER"; 114 break; 115 default: 116 description = printUnknownToken(source); 117 } 118 System.err.println("\tSource: " + description); 119 120 switch ( type ) { 121 case GL_DEBUG_TYPE_ERROR_ARB: 122 description = "ERROR"; 123 break; 124 case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR_ARB: 125 description = "DEPRECATED BEHAVIOR"; 126 break; 127 case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR_ARB: 128 description = "UNDEFINED BEHAVIOR"; 129 break; 130 case GL_DEBUG_TYPE_PORTABILITY_ARB: 131 description = "PORTABILITY"; 132 break; 133 case GL_DEBUG_TYPE_PERFORMANCE_ARB: 134 description = "PERFORMANCE"; 135 break; 136 case GL_DEBUG_TYPE_OTHER_ARB: 137 description = "OTHER"; 138 break; 139 default: 140 description = printUnknownToken(type); 141 } 142 System.err.println("\tType: " + description); 143 144 switch ( severity ) { 145 case GL_DEBUG_SEVERITY_HIGH_ARB: 146 description = "HIGH"; 147 break; 148 case GL_DEBUG_SEVERITY_MEDIUM_ARB: 149 description = "MEDIUM"; 150 break; 151 case GL_DEBUG_SEVERITY_LOW_ARB: 152 description = "LOW"; 153 break; 154 default: 155 description = printUnknownToken(severity); 156 } 157 System.err.println("\tSeverity: " + description); 158 159 System.err.println("\tMessage: " + message); 160 } 161 162 private String printUnknownToken(final int token) { 163 return "Unknown (0x" + Integer.toHexString(token).toUpperCase() + ")"; 164 } 165 }); 166 } 167 168 /** 169 * Creates an ARBDebugOutputCallback with the specified callback handler. 170 * The handler's {@code handleMessage} method will be called whenever 171 * debug output is generated by the GL. 172 * 173 * @param handler the callback handler 174 */ ARBDebugOutputCallback(final Handler handler)175 public ARBDebugOutputCallback(final Handler handler) { 176 super(CALLBACK_POINTER); 177 178 this.handler = handler; 179 } 180 getHandler()181 Handler getHandler() { 182 return handler; 183 } 184 185 /** Implementations of this interface can be used to receive ARB_debug_output notifications. */ 186 public interface Handler { 187 188 /** 189 * This method will be called when an ARB_debug_output message is generated. 190 * 191 * @param source the message source 192 * @param type the message type 193 * @param id the message ID 194 * @param severity the message severity 195 * @param message the string representation of the message. 196 */ handleMessage(int source, int type, int id, int severity, String message)197 void handleMessage(int source, int type, int id, int severity, String message); 198 199 } 200 201 }