C'è un approccio migliore a questo chiamato AOP (Aspect Oriented Programming). Ho avuto qualche esperienza in C# in passato (circa 7 anni fa) con SpringFramework e PostSharp. Questo approccio usa ampiamente tecniche di iniezione di codice.
Così, quando ho affrontato questo problema (tracciando gli errori GL) è apparso come un classico problema per AOP.Dal momento che l'introduzione di codice introduce alcune penalità prestazionali, presumo che questa modifica (abilitazione della registrazione GL) sia temporanea e la terrò in una patch git per i casi in cui voglio usarla.
1) In primo luogo, modificare le script di build Gradle: In script di build di livello superiore aggiungere questo:
buildscript {
dependencies {
classpath 'com.uphyca.gradle:gradle-android-aspectj-plugin:0.9.14'
In script a livello di app aggiungere questo:
apply plugin: 'com.uphyca.android-aspectj'
Ciò consentirà aspectj plugin in gradle. Questo progetto (ospitato qui: https://github.com/uPhyca/gradle-android-aspectj-plugin) sembra ora deprecato, ma funziona. Puoi guardare ad una versione più recente qui: https://github.com/HujiangTechnology/gradle_plugin_android_aspectjx. Per le mie esigenze (tessitura di base del codice java) la vecchia versione funzionava bene. Ricostruisci per trovare se hai qualche problema.
2) Aggiungere la nostra annotazione, che useremo in seguito per contrassegnare i metodi vogliamo che il nostro aspetto da applicare:
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;
/**
* Created by Greg Stein on 7/18/2016.
*/
@Retention(RetentionPolicy.CLASS)
@Target({ ElementType.CONSTRUCTOR, ElementType.METHOD })
public @interface GlTrace {
}
3) Aggiungi il nostro aspetto:
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;
/**
* Created by Greg Stein on 7/18/2016.
*/
@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();
// Before method execution
// -- nothing --
Object result = joinPoint.proceed();
// After method execution
Log.d(className, buildLogMessage(methodName));
return result;
}
/**
* Create a log message.
*
* @param methodName A string with the method name.
* @return A string representing message.
*/
private static String buildLogMessage(String methodName) {
StringBuilder message = new StringBuilder();
int errorCode = GLES20.glGetError();
message.append("GlState[");
message.append(methodName);
message.append("]: ");
if (GLES20.GL_NO_ERROR != errorCode) {
message.append("ERROR:");
}
message.append(GLU.gluErrorString(errorCode));
return message.toString();
}
}
4) Mark metodi o costruttori che eseguire codice GL con @GlTrace annotazione:
...
@GlTrace
public GlEngine(int quadsNum) {
...
@GlTrace
public void draw(float[] mvpMatrix) {
...
Ora, dopo tutto questo fatto, basta eseguire nuovamente il progetto in AndroidStudio. Si avrà il seguente 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
Nel mio progetto ho solo due metodi con GL chiama: Metodo di pareggio e il costruttore della classe di GlEngine.
Dopo aver giocato un po 'con questo e ottenere quei fastidiosi messaggi di "errore" non si può fare alcuni miglioramenti: errori 0) stampare solo 1) monitorare tutti i metodi che partita gl * (tutti i metodi OpenGL).
Divertiti!
JIC, "Abilita tracce OpenGL" è entrato in 4.2 ... :) –
Grazie, ho modificato il mio post di conseguenza. – sschuberth
Non riesco a trovare "Abilita tracce OpenGL" su Oreo. Qualche idea sul perché sono andati? – Pavel