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