There is a better approach to this called AOP (Aspect Oriented Programming). I had some experience working with it in C # in the past (about 7 years ago) with SpringFramework and PostSharp. This approach makes extensive use of code injection techniques.
So, when I ran into this problem (tracking GL errors), it arose as a classic problem for AOP. Since injecting the code introduces some performance penalties, I assume that this change (enabling GL logging) is temporary and will contain it in the git patch for cases where I want to use it.
1) First change the gradle build scripts: In the top-level build script add this:
buildscript { dependencies { classpath 'com.uphyca.gradle:gradle-android-aspectj-plugin:0.9.14'
In the app-level script add this:
apply plugin: 'com.uphyca.android-aspectj'
This will enable the aspectj plugin in gradle. This project (located here: https://github.com/uPhyca/gradle-android-aspectj-plugin ) seems deprecated, but it works. You can see the newer version here: https://github.com/HujiangTechnology/gradle_plugin_android_aspectjx . For my needs (basic coding of java code) the old version worked well. Rebuild to find out if you have any problems.
2) Add our annotation, which we will use later, to mark the methods to which we want to apply our aspect:
package com.example.neutrino.maze; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Retention(RetentionPolicy.CLASS) @Target({ ElementType.CONSTRUCTOR, ElementType.METHOD }) public @interface GlTrace { }
3) Add our aspect:
package com.example.neutrino.maze; import android.opengl.GLES20; import android.opengl.GLU; import android.util.Log; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.Signature; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Pointcut; import org.aspectj.lang.reflect.MethodSignature; @Aspect public class GlTraceAspect { private static final String POINTCUT_METHOD = "execution(@com.example.neutrino.maze.GlTrace * *(..))"; private static final String POINTCUT_CONSTRUCTOR = "execution(@com.example.neutrino.maze.GlTrace *.new(..))"; @Pointcut(POINTCUT_METHOD) public void methodAnnotatedWithGlTrace() {} @Pointcut(POINTCUT_CONSTRUCTOR) public void constructorAnnotatedWithGlTrace() {} @Around("methodAnnotatedWithGlTrace() || constructorAnnotatedWithGlTrace()") public Object weaveJoinPoint(ProceedingJoinPoint joinPoint) throws Throwable { Signature signature = joinPoint.getSignature(); String className = signature.getDeclaringType().getSimpleName(); String methodName = signature.getName();
4) Note the methods or constructors that execute GL code with the @GlTrace annotation:
... @GlTrace public GlEngine(int quadsNum) { ... @GlTrace public void draw(float[] mvpMatrix) { ...
Now, after all this, just run the project in AndroidStudio. You will have the following output:
07-18 12:34:37.715 19167-19187/com.example.neutrino.maze D/GlEngine: GlState[<init>]: no error 07-18 12:34:37.715 19167-19187/com.example.neutrino.maze D/GlEngine: GlState[draw]: no error 07-18 12:34:37.733 19167-19187/com.example.neutrino.maze D/GlEngine: GlState[<init>]: no error 07-18 12:34:37.735 19167-19187/com.example.neutrino.maze D/GlEngine: GlState[draw]: no error 07-18 12:34:37.751 19167-19187/com.example.neutrino.maze D/GlEngine: GlState[<init>]: no error 07-18 12:34:37.751 19167-19187/com.example.neutrino.maze D/GlEngine: GlState[draw]: no error 07-18 12:34:37.771 19167-19187/com.example.neutrino.maze D/GlEngine: GlState[<init>]: no error 07-18 12:34:37.771 19167-19187/com.example.neutrino.maze D/GlEngine: GlState[draw]: no error
In my project, I have only two methods with GL calls: the draw method and the constructor of the GlEngine class.
After you play around a bit with this and get these annoying error-free messages, you can make some improvements: 0) Only print errors 1) control all methods that match gl * (all OpenGl methods).
Enjoy it!