Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6b5f29f3 authored by Jack Palevich's avatar Jack Palevich Committed by Android (Google) Code Review
Browse files

Merge "OpenGL tracing."

parents 6f688ae7 d4d0fb96
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -8,6 +8,7 @@ include $(CLEAR_VARS)

LOCAL_SRC_FILES:= 	       \
	EGL/egl.cpp 	       \
	EGL/trace.cpp              \
	EGL/getProcAddress.cpp.arm \
	EGL/hooks.cpp 	       \
	EGL/Loader.cpp 	       \
@@ -33,6 +34,7 @@ endif
LOCAL_CFLAGS += -DLOG_TAG=\"libEGL\"
LOCAL_CFLAGS += -DGL_GLEXT_PROTOTYPES -DEGL_EGLEXT_PROTOTYPES
LOCAL_CFLAGS += -fvisibility=hidden
LOCAL_CFLAGS += -DEGL_TRACE=1

ifeq ($(TARGET_BOARD_PLATFORM),msm7k)
LOCAL_CFLAGS += -DADRENO130=1
+73 −6
Original line number Diff line number Diff line
@@ -285,6 +285,58 @@ EGLAPI gl_hooks_t gHooks[2][IMPL_NUM_IMPLEMENTATIONS];
EGLAPI gl_hooks_t gHooksNoContext;
EGLAPI pthread_key_t gGLWrapperKey = -1;

#if EGL_TRACE

EGLAPI pthread_key_t gGLTraceKey = -1;

// ----------------------------------------------------------------------------

static int gEGLTraceLevel;
static int gEGLApplicationTraceLevel;
extern EGLAPI gl_hooks_t gHooksTrace;

static inline void setGlTraceThreadSpecific(gl_hooks_t const *value) {
    pthread_setspecific(gGLTraceKey, value);
}

gl_hooks_t const* getGLTraceThreadSpecific() {
    return static_cast<gl_hooks_t*>(pthread_getspecific(gGLTraceKey));
}

static void initEglTraceLevel() {
    char value[PROPERTY_VALUE_MAX];
    property_get("debug.egl.trace", value, "0");
    int propertyLevel = atoi(value);
    int applicationLevel = gEGLApplicationTraceLevel;
    gEGLTraceLevel = propertyLevel > applicationLevel ? propertyLevel : applicationLevel;
}

static void setGLHooksThreadSpecific(gl_hooks_t const *value) {
    if (gEGLTraceLevel > 0) {
        setGlTraceThreadSpecific(value);
        setGlThreadSpecific(&gHooksTrace);
    } else {
        setGlThreadSpecific(value);
    }
}

/*
 * Global entry point to allow applications to modify their own trace level.
 * The effective trace level is the max of this level and the value of debug.egl.trace.
 */
extern "C"
void setGLTraceLevel(int level) {
    gEGLApplicationTraceLevel = level;
}

#else

static inline void setGLHooksThreadSpecific(gl_hooks_t const *value) {
    setGlThreadSpecific(value);
}

#endif

// ----------------------------------------------------------------------------

static __attribute__((noinline))
@@ -458,6 +510,10 @@ static void early_egl_init(void)
{
#if !USE_FAST_TLS_KEY
    pthread_key_create(&gGLWrapperKey, NULL);
#endif
#if EGL_TRACE
    pthread_key_create(&gGLTraceKey, NULL);
    initEglTraceLevel();
#endif
    uint32_t addr = (uint32_t)((void*)gl_no_context);
    android_memset32(
@@ -465,7 +521,7 @@ static void early_egl_init(void)
            addr, 
            sizeof(gHooksNoContext));

    setGlThreadSpecific(&gHooksNoContext);
    setGLHooksThreadSpecific(&gHooksNoContext);
}

static pthread_once_t once_control = PTHREAD_ONCE_INIT;
@@ -678,7 +734,15 @@ EGLBoolean eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor)
        return EGL_TRUE;
    }

    setGlThreadSpecific(&gHooksNoContext);
#if EGL_TRACE

    // Called both at early_init time and at this time. (Early_init is pre-zygote, so
    // the information from that call may be stale.)
    initEglTraceLevel();

#endif

    setGLHooksThreadSpecific(&gHooksNoContext);

    // initialize each EGL and
    // build our own extension string first, based on the extension we know
@@ -1238,11 +1302,11 @@ EGLBoolean eglMakeCurrent( EGLDisplay dpy, EGLSurface draw,

        // cur_c has to be valid here (but could be terminated)
        if (ctx != EGL_NO_CONTEXT) {
            setGlThreadSpecific(c->cnx->hooks[c->version]);
            setGLHooksThreadSpecific(c->cnx->hooks[c->version]);
            setContext(ctx);
            _c.acquire();
        } else {
            setGlThreadSpecific(&gHooksNoContext);
            setGLHooksThreadSpecific(&gHooksNoContext);
            setContext(EGL_NO_CONTEXT);
        }
        _cur_c.release();
@@ -1434,6 +1498,9 @@ __eglMustCastToProperFunctionPointerType eglGetProcAddress(const char *procname)
                    // Extensions are independent of the bound context
                    cnx->hooks[GLESv1_INDEX]->ext.extensions[slot] =
                    cnx->hooks[GLESv2_INDEX]->ext.extensions[slot] =
#if EGL_TRACE
                    gHooksTrace.ext.extensions[slot] =
#endif
                            cnx->egl.eglGetProcAddress(procname);
                }
            }
+247 −0
Original line number Diff line number Diff line
/*
 ** Copyright 2010, The Android Open Source Project
 **
 ** Licensed under the Apache License, Version 2.0 (the "License");
 ** you may not use this file except in compliance with the License.
 ** You may obtain a copy of the License at
 **
 **     http://www.apache.org/licenses/LICENSE-2.0
 **
 ** Unless required by applicable law or agreed to in writing, software
 ** distributed under the License is distributed on an "AS IS" BASIS,
 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */

#if EGL_TRACE

#include <stdarg.h>
#include <stdlib.h>

#include <EGL/egl.h>
#include <EGL/eglext.h>
#include <GLES/gl.h>
#include <GLES/glext.h>

#include <cutils/log.h>

#include "hooks.h"

// ----------------------------------------------------------------------------
namespace android {
// ----------------------------------------------------------------------------

struct GLenumString {
    GLenum e;
    const char* s;
};

#undef GL_ENUM
#define GL_ENUM(VAL,NAME) {VAL, #NAME},

static GLenumString g_enumnames[] = {
#include "enums.in"
};
#undef GL_ENUM

static int compareGLEnum(const void* a, const void* b) {
    return ((const GLenumString*) a)->e - ((const GLenumString*) b)->e;
}

static const char* GLEnumToString(GLenum e) {
    GLenumString key = {e, ""};
    const GLenumString* result = (const GLenumString*) bsearch(
        &key, g_enumnames,
        sizeof(g_enumnames) / sizeof(g_enumnames[0]),
        sizeof(g_enumnames[0]), compareGLEnum);
    if (result) {
        return result->s;
    }
    return NULL;
}

static GLenumString g_bitfieldNames[] = {
    {0x00004000, "GL_COLOR_BUFFER_BIT"},
    {0x00000400, "GL_STENCIL_BUFFER_BIT"},
    {0x00000100, "GL_DEPTH_BUFFER_BIT"}
};


static void TraceGLShaderSource(GLuint shader, GLsizei count,
    const GLchar** string, const GLint* length) {
    LOGD("const char* shaderSrc[] = {");
    for (GLsizei i = 0; i < count; i++) {
        const char* comma = i < count-1 ? "," : "";
        const GLchar* s = string[i];
        if (length) {
            GLint len = length[i];
            LOGD("    \"%*s\"%s", len, s, comma);
        } else {
            LOGD("    \"%s\"%s", s, comma);
        }
    }
    LOGD("};");
    if (length) {
        LOGD("const GLint* shaderLength[] = {");
        for (GLsizei i = 0; i < count; i++) {
            const char* comma = i < count-1 ? "," : "";
            GLint len = length[i];
            LOGD("    \"%d\"%s", len, comma);
        }
        LOGD("};");
        LOGD("glShaderSource(%u, %u, shaderSrc, shaderLength);",
            shader, count);
    } else {
        LOGD("glShaderSource(%u, %u, shaderSrc, (const GLint*) 0);",
            shader, count);
    }
}

static void TraceGL(const char* name, int numArgs, ...) {
    va_list argp;
    va_start(argp, numArgs);
    if (strcmp(name, "glShaderSource") == 0) {
        va_arg(argp, const char*);
        GLuint shader = va_arg(argp, GLuint);
        va_arg(argp, const char*);
        GLsizei count = va_arg(argp, GLsizei);
        va_arg(argp, const char*);
        const GLchar** string = (const GLchar**) va_arg(argp, void*);
        va_arg(argp, const char*);
        const GLint* length = (const GLint*) va_arg(argp, void*);
        TraceGLShaderSource(shader, count, string, length);
        va_end(argp);
        return;
    }
    const int lineSize = 500;
    char line[lineSize];
    int line_index = 0;
    #define APPEND(...) \
        line_index += snprintf(line + line_index, lineSize-line_index, __VA_ARGS__);
    APPEND("%s(", name);
    for (int i = 0; i < numArgs; i++) {
        if (i > 0) {
            APPEND(", ");
        }
        const char* type = va_arg(argp, const char*);
        bool isPtr = type[strlen(type)-1] == '*'
            || strcmp(type, "GLeglImageOES") == 0;
        if (isPtr) {
            const void* arg = va_arg(argp, const void*);
            APPEND("(%s) 0x%08x", type, (size_t) arg);
        } else if (strcmp(type, "GLbitfield") == 0) {
            size_t arg = va_arg(argp, size_t);
            bool first = true;
            for (size_t i = 0; i < sizeof(g_bitfieldNames) / sizeof(g_bitfieldNames[0]); i++) {
                const GLenumString* b = &g_bitfieldNames[i];
                if (b->e & arg) {
                    if (first) {
                        first = false;
                    } else {
                        APPEND(" | ");
                    }
                    APPEND("%s", b->s);
                    arg &= ~b->e;
                }
            }
            if (first || arg != 0) {
                if (!first) {
                    APPEND(" | ");
                }
                APPEND("0x%08x", arg);
            }
        } else if (strcmp(type, "GLboolean") == 0) {
            int arg = va_arg(argp, int);
            APPEND("%s", arg ? "GL_TRUE" : "GL_FALSE");
        } else if (strcmp(type, "GLclampf") == 0) {
            double arg = va_arg(argp, double);
            APPEND("%g", arg);
        } else if (strcmp(type, "GLenum") == 0) {
            GLenum arg = va_arg(argp, int);
            const char* s = GLEnumToString(arg);
            if (s) {
                APPEND("%s", s);
            } else {
                APPEND("0x%x", arg);
            }
        } else if (strcmp(type, "GLfixed") == 0) {
            int arg = va_arg(argp, int);
            APPEND("0x%08x", arg);
        } else if (strcmp(type, "GLfloat") == 0) {
            double arg = va_arg(argp, double);
            APPEND("%g", arg);
        } else if (strcmp(type, "GLint") == 0) {
            int arg = va_arg(argp, int);
            const char* s = NULL;
            if (strcmp(name, "glTexParameteri") == 0) {
                s = GLEnumToString(arg);
            }
            if (s) {
                APPEND("%s", s);
            } else {
                APPEND("%d", arg);
            }
        } else if (strcmp(type, "GLintptr") == 0) {
            int arg = va_arg(argp, unsigned int);
            APPEND("%u", arg);
        } else if (strcmp(type, "GLsizei") == 0) {
            int arg = va_arg(argp, size_t);
            APPEND("%u", arg);
        } else if (strcmp(type, "GLsizeiptr") == 0) {
            int arg = va_arg(argp, size_t);
            APPEND("%u", arg);
        } else if (strcmp(type, "GLuint") == 0) {
            int arg = va_arg(argp, unsigned int);
            APPEND("%u", arg);
        } else {
            APPEND("/* ??? %s */", type);
            break;
        }
    }
    APPEND(");");
    line[lineSize-1] = '\0';
    LOGD("%s", line);
    va_end(argp);
}

#undef TRACE_GL_VOID
#undef TRACE_GL

#define TRACE_GL_VOID(_api, _args, _argList, ...)                         \
static void Tracing_ ## _api _args {                                      \
    TraceGL(#_api, __VA_ARGS__);                                          \
    gl_hooks_t::gl_t const * const _c = &getGLTraceThreadSpecific()->gl;  \
    _c->_api _argList;                                                    \
}

#define TRACE_GL(_type, _api, _args, _argList, ...)                       \
static _type Tracing_ ## _api _args {                                     \
    TraceGL(#_api, __VA_ARGS__);                                          \
    gl_hooks_t::gl_t const * const _c = &getGLTraceThreadSpecific()->gl;  \
    return _c->_api _argList;                                             \
}

extern "C" {
#include "../trace.in"
}
#undef TRACE_GL_VOID
#undef TRACE_GL

#define GL_ENTRY(_r, _api, ...) Tracing_ ## _api,

EGLAPI gl_hooks_t gHooksTrace = {
    {
        #include "entries.in"
    },
    {
        {0}
    }
};
#undef GL_ENTRY

// ----------------------------------------------------------------------------
}; // namespace android
// ----------------------------------------------------------------------------

#endif // EGL_TRACE

opengl/libs/enums.in

0 → 100644
+594 −0

File added.

Preview size limit exceeded, changes collapsed.

+5 −0
Original line number Diff line number Diff line
@@ -141,6 +141,11 @@ static gl_hooks_t const* getGlThreadSpecific() {

#endif

#if EGL_TRACE

extern gl_hooks_t const* getGLTraceThreadSpecific();

#endif

// ----------------------------------------------------------------------------
}; // namespace android
Loading