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 AMD_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 AMDDebugOutputCallback extends PointerWrapperAbstract { 45 46 /** Severity levels. */ 47 private static final int GL_DEBUG_SEVERITY_HIGH_AMD = 0x9146, 48 GL_DEBUG_SEVERITY_MEDIUM_AMD = 0x9147, 49 GL_DEBUG_SEVERITY_LOW_AMD = 0x9148; 50 51 /** Categories */ 52 private static final int GL_DEBUG_CATEGORY_API_ERROR_AMD = 0x9149, 53 GL_DEBUG_CATEGORY_WINDOW_SYSTEM_AMD = 0x914A, 54 GL_DEBUG_CATEGORY_DEPRECATION_AMD = 0x914B, 55 GL_DEBUG_CATEGORY_UNDEFINED_BEHAVIOR_AMD = 0x914C, 56 GL_DEBUG_CATEGORY_PERFORMANCE_AMD = 0x914D, 57 GL_DEBUG_CATEGORY_SHADER_COMPILER_AMD = 0x914E, 58 GL_DEBUG_CATEGORY_APPLICATION_AMD = 0x914F, 59 GL_DEBUG_CATEGORY_OTHER_AMD = 0x9150; 60 61 private static final long CALLBACK_POINTER; 62 63 static { 64 long pointer = 0; 65 try { 66 // Call reflectively so that we can compile this class for the Generator. 67 pointer = (Long)Class.forName("org.lwjgl.opengl.CallbackUtil").getDeclaredMethod("getDebugOutputCallbackAMD").invoke(null); 68 } catch (Exception e) { 69 // ignore 70 } 71 CALLBACK_POINTER = pointer; 72 } 73 74 private final Handler handler; 75 76 /** 77 * Creates an AMDDebugOutputCallback with a default callback handler. 78 * The default handler will simply print the message on System.err. 79 */ AMDDebugOutputCallback()80 public AMDDebugOutputCallback() { 81 this(new Handler() { 82 public void handleMessage(final int id, final int category, final int severity, final String message) { 83 System.err.println("[LWJGL] AMD_debug_output message"); 84 System.err.println("\tID: " + id); 85 86 String description; 87 switch ( category ) { 88 case GL_DEBUG_CATEGORY_API_ERROR_AMD: 89 description = "API ERROR"; 90 break; 91 case GL_DEBUG_CATEGORY_WINDOW_SYSTEM_AMD: 92 description = "WINDOW SYSTEM"; 93 break; 94 case GL_DEBUG_CATEGORY_DEPRECATION_AMD: 95 description = "DEPRECATION"; 96 break; 97 case GL_DEBUG_CATEGORY_UNDEFINED_BEHAVIOR_AMD: 98 description = "UNDEFINED BEHAVIOR"; 99 break; 100 case GL_DEBUG_CATEGORY_PERFORMANCE_AMD: 101 description = "PERFORMANCE"; 102 break; 103 case GL_DEBUG_CATEGORY_SHADER_COMPILER_AMD: 104 description = "SHADER COMPILER"; 105 break; 106 case GL_DEBUG_CATEGORY_APPLICATION_AMD: 107 description = "APPLICATION"; 108 break; 109 case GL_DEBUG_CATEGORY_OTHER_AMD: 110 description = "OTHER"; 111 break; 112 default: 113 description = printUnknownToken(category); 114 } 115 System.err.println("\tCategory: " + description); 116 117 switch ( severity ) { 118 case GL_DEBUG_SEVERITY_HIGH_AMD: 119 description = "HIGH"; 120 break; 121 case GL_DEBUG_SEVERITY_MEDIUM_AMD: 122 description = "MEDIUM"; 123 break; 124 case GL_DEBUG_SEVERITY_LOW_AMD: 125 description = "LOW"; 126 break; 127 default: 128 description = printUnknownToken(severity); 129 } 130 System.err.println("\tSeverity: " + description); 131 132 System.err.println("\tMessage: " + message); 133 } 134 135 private String printUnknownToken(final int token) { 136 return "Unknown (0x" + Integer.toHexString(token).toUpperCase() + ")"; 137 } 138 }); 139 } 140 141 /** 142 * Creates an AMDDebugOutputCallback with the specified callback handler. 143 * The handler's {@code handleMessage} method will be called whenever 144 * debug output is generated by the GL. 145 * 146 * @param handler the callback handler 147 */ AMDDebugOutputCallback(final Handler handler)148 public AMDDebugOutputCallback(final Handler handler) { 149 super(CALLBACK_POINTER); 150 151 this.handler = handler; 152 } 153 getHandler()154 Handler getHandler() { 155 return handler; 156 } 157 158 /** Implementations of this interface can be used to receive AMD_debug_output notifications. */ 159 public interface Handler { 160 161 /** 162 * This method will be called when an AMD_debug_output message is generated. 163 * 164 * @param id the message ID 165 * @param category the message category 166 * @param severity the message severity 167 * @param message the string representation of the message. 168 */ handleMessage(int id, int category, int severity, String message)169 void handleMessage(int id, int category, int severity, String message); 170 171 } 172 173 } 174