1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980 |
- 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.
-
- 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.
- Enabling tracing while the application is running:
- In order to allow tracing of an already running application, we allow DdmServer to enable
- OpenGL tracing. In such a case, the application already has its GL hooks set up to point to the
- real GL implementation, and we need to switch them to point to the trace implementation.
- This is achieved by checking whether tracing should be enabled at every eglSwap call.
- (Note: We were already checking for tracing at every eglSwap, the only change now is that
- the tracing could actually be ON/OFF at runtime - earlier it was set once and never changed).
- If eglSwap detects that tracing should be enabled now, then it performs the following steps:
- - switch the gl hooks to point to the trace implementation.
- - call trace eglMakeCurrent to indicate that there is now a new context that is current.
- - continue on with tracing the eglSwap call.
- This switches the hooks to point to the trace implementation only for the current context.
- But the other contexts have their gl hooks updated when they perform eglMakeCurrent.
- The GLTrace version of eglMakeCurrent now has to be updated to allow switching to a context
- it may not know of. In such a case, it creates a context matching the version that it is now
- switching to.
- Disabling tracing:
- We disable tracing under two conditions:
- - stop tracing request from DdmServer
- - gltrace transport gets disconnected from the host.
- In either case, both actions simply disable the tracing flag. The current context gets its
- gl hooks restored in the next eglSwap, and the other traced contexts get their gl hooks
- restored when they perform a eglMakeCurrent.
- 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.
|