/** * Creates a tracer implementation that wraps OpenGL 2+. * * @param glInterface OGL object to wrap * @param glInterfaceClasses The interface(s) to implement * @return A tracer that implements the given interface */ public static Object createDesktopGlTracer(Object glInterface, Class<?> ... glInterfaceClasses) { IntMap<String> constMap = generateConstantMap(GL2.class, GL3.class, GL4.class, GLFbo.class, GLExt.class); return Proxy.newProxyInstance(glInterface.getClass().getClassLoader(), glInterfaceClasses, new GLTracer(glInterface, constMap)); }
private void printArgs(String methodName, Object[] args, Class<?>[] paramTypes) { if (methodName.equals("glClear")) { printArgsClear((Integer)args[0]); return; } else if (methodName.equals("glTexParameteri")) { printArgsTexParameter(args); return; } else if (methodName.equals("glGetInteger")) { printArgsGetInteger(args); return; print("()"); return; print("("); for (int i = 0; i < args.length; i++) { if (paramTypes[i] == int.class) { int val = (Integer)args[i]; printIntOrEnum(methodName, val, i); } else if (paramTypes[i] == boolean.class) { printBoolean((Boolean)args[i]); } else if (paramTypes[i] == String.class) { printString((String)args[i]); } else if (paramTypes[i] == String[].class) { String[] arr = (String[]) args[i]; if (arr.length == 1) { printString(arr[0]); } else { print("string[" + arr.length + "]");
@Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { String methodName = method.getName(); printMethodName(methodName); if (methodName.startsWith("gl")) { try { // Try to evaluate result first, so we can see output values. Object result = method.invoke(obj, args); printArgs(methodName, args, method.getParameterTypes()); printResult(methodName, result, method.getReturnType()); printNewLine(); return result; } catch (Throwable ex) { // Execution failed, print args anyway // but output values will be incorrect. printArgs(methodName, args, method.getParameterTypes()); printNewLine(); System.out.println("\tException occurred!"); System.out.println(ex.toString()); throw ex; } } else { printNewLine(); return method.invoke(obj, args); } } }
private void printArgsTexParameter(Object[] args) { print("("); int target = (Integer) args[0]; int param = (Integer) args[1]; int value = (Integer) args[2]; printEnum(target); print(", "); printEnum(param); print(", "); if (param == GL2.GL_TEXTURE_BASE_LEVEL || param == GL2.GL_TEXTURE_MAX_LEVEL) { printInt(value); } else { printEnum(value); } print(")"); }
private void printResult(String methodName, Object result, Class<?> returnType) { if (returnType != void.class) { print(" = "); if (result instanceof String) { printString((String) result); } else if (returnType == int.class) { int val = (Integer) result; printIntOrEnum(methodName, val, -1); } else if (returnType == boolean.class) { printBoolean((Boolean)result); } else { print(" = ???"); } } }
private void printArgsGetInteger(Object[] args) { print("("); int param = (Integer)args[0]; IntBuffer ib = (IntBuffer) args[1]; printEnum(param); print(", "); printOut(); if (param == GL2.GL_DRAW_BUFFER || param == GL2.GL_READ_BUFFER) { printEnum(ib.get(0)); } else { printInt(ib.get(0)); } print(")"); }
gl = (GL) GLTracer.createDesktopGlTracer(gl, GL.class, GL2.class, GL3.class, GL4.class); glext = (GLExt) GLTracer.createDesktopGlTracer(glext, GLExt.class); glfbo = (GLFbo) GLTracer.createDesktopGlTracer(glfbo, GLFbo.class);
private void printArgsClear(int mask) { boolean needAPipe = false; print("("); if ((mask & GL.GL_COLOR_BUFFER_BIT) != 0) { printStyle(ANSI_GREEN, "COLOR_BUFFER_BIT"); needAPipe = true; } if ((mask & GL.GL_DEPTH_BUFFER_BIT) != 0) { if (needAPipe) { print(" | "); } printStyle(ANSI_GREEN, "DEPTH_BUFFER_BIT"); } if ((mask & GL.GL_STENCIL_BUFFER_BIT) != 0) { if (needAPipe) { print(" | "); } printStyle(ANSI_GREEN, "STENCIL_BUFFER_BIT"); } print(")"); }
private void printInt(int value) { print(Integer.toString(value)); }
gl = (GL) GLTracer.createDesktopGlTracer(gl, GL.class, GL2.class, GL3.class, GL4.class); glext = (GLExt) GLTracer.createDesktopGlTracer(glext, GLExt.class); glfbo = (GLFbo) GLTracer.createDesktopGlTracer(glfbo, GLFbo.class);
private void printArgsGetInteger(Object[] args) { print("("); int param = (Integer)args[0]; IntBuffer ib = (IntBuffer) args[1]; printEnum(param); print(", "); printOut(); if (param == GL2.GL_DRAW_BUFFER || param == GL2.GL_READ_BUFFER) { printEnum(ib.get(0)); } else { printInt(ib.get(0)); } print(")"); }
private void printResult(String methodName, Object result, Class<?> returnType) { if (returnType != void.class) { print(" = "); if (result instanceof String) { printString((String) result); } else if (returnType == int.class) { int val = (Integer) result; printIntOrEnum(methodName, val, -1); } else if (returnType == boolean.class) { printBoolean((Boolean)result); } else { print(" = ???"); } } }
private void printArgsTexParameter(Object[] args) { print("("); int target = (Integer) args[0]; int param = (Integer) args[1]; int value = (Integer) args[2]; printEnum(target); print(", "); printEnum(param); print(", "); if (param == GL2.GL_TEXTURE_BASE_LEVEL || param == GL2.GL_TEXTURE_MAX_LEVEL) { printInt(value); } else { printEnum(value); } print(")"); }
private void printMethodName(String methodName) { if (methodName.startsWith("gl")) { // GL calls which actually draw (as opposed to change state) // will be printed in darker color methodName = methodName.substring(2); if (methodName.equals("Clear") || methodName.equals("DrawRangeElements") || methodName.equals("DrawElementsInstancedARB")) { print(methodName); } else { if (methodName.endsWith("EXT")) { methodName = methodName.substring(0, methodName.length() - 3); } printStyle(ANSI_BRIGHT, methodName); } } else if (methodName.equals("resetStats")) { printStyle(ANSI_RED, "-- frame boundary --"); } }
private void printString(String value) { if (value.length() > 150) { value = value.substring(0, 150) + "..."; } StringBuilder sb = new StringBuilder(); sb.append(ANSI_YELLOW); sb.append("\""); sb.append(ANSI_RESET); for (String line : value.split("\n")) { sb.append(ANSI_YELLOW); sb.append(line.replaceAll("\0", "\\\\0")); sb.append(ANSI_RESET); sb.append("\n"); } if (sb.length() > 1 && sb.charAt(sb.length() - 1) == '\n') { sb.setLength(sb.length() - 1); } sb.append(ANSI_YELLOW); sb.append("\""); sb.append(ANSI_RESET); print(sb.toString()); }
private void printArgs(String methodName, Object[] args, Class<?>[] paramTypes) { if (methodName.equals("glClear")) { printArgsClear((Integer)args[0]); return; } else if (methodName.equals("glTexParameteri")) { printArgsTexParameter(args); return; } else if (methodName.equals("glGetInteger")) { printArgsGetInteger(args); return; print("()"); return; print("("); for (int i = 0; i < args.length; i++) { if (paramTypes[i] == int.class) { int val = (Integer)args[i]; printIntOrEnum(methodName, val, i); } else if (paramTypes[i] == boolean.class) { printBoolean((Boolean)args[i]); } else if (paramTypes[i] == String.class) { printString((String)args[i]); } else if (paramTypes[i] == String[].class) { String[] arr = (String[]) args[i]; if (arr.length == 1) { printString(arr[0]); } else { print("string[" + arr.length + "]");
gl = (GL) GLTracer.createDesktopGlTracer(gl, GL.class, GL2.class, GL3.class, GL4.class); glext = (GLExt) GLTracer.createDesktopGlTracer(glext, GLExt.class); glfbo = (GLFbo) GLTracer.createDesktopGlTracer(glfbo, GLFbo.class);
@Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { String methodName = method.getName(); printMethodName(methodName); if (methodName.startsWith("gl")) { try { // Try to evaluate result first, so we can see output values. Object result = method.invoke(obj, args); printArgs(methodName, args, method.getParameterTypes()); printResult(methodName, result, method.getReturnType()); printNewLine(); return result; } catch (Throwable ex) { // Execution failed, print args anyway // but output values will be incorrect. printArgs(methodName, args, method.getParameterTypes()); printNewLine(); System.out.println("\tException occurred!"); System.out.println(ex.toString()); throw ex; } } else { printNewLine(); return method.invoke(obj, args); } } }
/** * Creates a tracer implementation that wraps OpenGL ES 2. * * @param glInterface OGL object to wrap * @param glInterfaceClasses The interface(s) to implement * @return A tracer that implements the given interface */ public static Object createGlesTracer(Object glInterface, Class<?>... glInterfaceClasses) { IntMap<String> constMap = generateConstantMap(GL.class, GL2.class, GL3.class, GLFbo.class, GLExt.class); return Proxy.newProxyInstance( glInterface.getClass().getClassLoader(), glInterfaceClasses, new GLTracer(glInterface, constMap)); }
private void printArgsClear(int mask) { boolean needAPipe = false; print("("); if ((mask & GL.GL_COLOR_BUFFER_BIT) != 0) { printStyle(ANSI_GREEN, "COLOR_BUFFER_BIT"); needAPipe = true; } if ((mask & GL.GL_DEPTH_BUFFER_BIT) != 0) { if (needAPipe) { print(" | "); } printStyle(ANSI_GREEN, "DEPTH_BUFFER_BIT"); } if ((mask & GL.GL_STENCIL_BUFFER_BIT) != 0) { if (needAPipe) { print(" | "); } printStyle(ANSI_GREEN, "STENCIL_BUFFER_BIT"); } print(")"); }