Design of the GLES Tracing Library

Code Runtime Behavior:

    Initialization:
    
    egl_display_t::initialize() calls initEglTraceLevel() to figure out whether tracing should be
    enabled. Currently, the shell properties "debug.egl.trace" and "debug.egl.debug_proc" together
    control whether tracing should be enabled for a certain process. If tracing is enabled, this
    calls GLTrace_start() to start the trace server.
    
    Note that initEglTraceLevel() is also called from early_egl_init(), but that happens in the
    context of the zygote, so that invocation has no effect.
    
    egl_display_t::initialize() then calls setGLHooksThreadSpecific() where we set the thread
    specific gl_hooks structure to point to the trace implementation. From this point on, every
    GLES call is redirected to the trace implementation.
    
    Application runtime:

    While the application is running, all its GLES calls are directly routed to their corresponding
    trace implementation.

    For EGL calls, the trace library provides a bunch of functions that must be explicitly called
    from the EGL library. These functions are declared in glestrace.h

    Application shutdown:

    Currently, the application is killed when the user stops tracing from the frontend GUI. We need
    to explore if a more graceful method of stopping the application, or detaching tracing from the
    application is required.

Code Structure:

    glestrace.h declares all the hooks exposed by libglestrace. These are used by EGL/egl.cpp and
    EGL/eglApi.cpp to initialize the trace library, and to inform the library of EGL calls.

    All GL calls are present in GLES_Trace/src/gltrace_api.cpp. This file is generated by the
    GLES_Trace/src/genapi.py script. The structure of all the functions looks like this:

            void GLTrace_glFunction(args) {
                // declare a protobuf
                // copy arguments into the protobuf
                // call the original GLES function
                // if there is a return value, save it into the protobuf
                // fixup the protobuf if necessary
                // transport the protobuf to the host
            }

    The fixupGLMessage() call does any custom processing of the protobuf based on the GLES call.
    This typically amounts to copying the data corresponding to input or output pointers.
