a73a97728b
Currently, to activate OpenGL tracing, an application has to be start with --opengl-trace option (or have a debug prop set). This CL adds support for tracing an application which may already be running. This is implemented as follows: - DDMS initiates a JDWP message to the VM indicating that opengl traces be enabled. - When that message is received, a flag is set that indicates that tracing should be enabled. - The trace flag is checked during every eglSwap() operation, and if it finds that tracing should be active and it isn't, then it starts the tracing component. Change-Id: I3347fe89fc06c7404d7aa9360f4b21e5bf36ebcb
80 lines
3.9 KiB
Plaintext
80 lines
3.9 KiB
Plaintext
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.
|