Siva Velusamy | 0469dd6 | 2011-11-30 15:05:37 -0800 | [diff] [blame] | 1 | Design of the GLES Tracing Library |
| 2 | |
| 3 | Code Runtime Behavior: |
| 4 | |
| 5 | Initialization: |
| 6 | |
| 7 | egl_display_t::initialize() calls initEglTraceLevel() to figure out whether tracing should be |
| 8 | enabled. Currently, the shell properties "debug.egl.trace" and "debug.egl.debug_proc" together |
| 9 | control whether tracing should be enabled for a certain process. If tracing is enabled, this |
| 10 | calls GLTrace_start() to start the trace server. |
| 11 | |
Siva Velusamy | 0469dd6 | 2011-11-30 15:05:37 -0800 | [diff] [blame] | 12 | egl_display_t::initialize() then calls setGLHooksThreadSpecific() where we set the thread |
| 13 | specific gl_hooks structure to point to the trace implementation. From this point on, every |
| 14 | GLES call is redirected to the trace implementation. |
| 15 | |
| 16 | Application runtime: |
| 17 | |
| 18 | While the application is running, all its GLES calls are directly routed to their corresponding |
| 19 | trace implementation. |
| 20 | |
| 21 | For EGL calls, the trace library provides a bunch of functions that must be explicitly called |
| 22 | from the EGL library. These functions are declared in glestrace.h |
| 23 | |
| 24 | Application shutdown: |
| 25 | |
| 26 | Currently, the application is killed when the user stops tracing from the frontend GUI. We need |
| 27 | to explore if a more graceful method of stopping the application, or detaching tracing from the |
| 28 | application is required. |
| 29 | |
Siva Velusamy | a73a977 | 2012-12-18 14:56:55 -0800 | [diff] [blame] | 30 | |
| 31 | Enabling tracing while the application is running: |
| 32 | |
| 33 | In order to allow tracing of an already running application, we allow DdmServer to enable |
| 34 | OpenGL tracing. In such a case, the application already has its GL hooks set up to point to the |
| 35 | real GL implementation, and we need to switch them to point to the trace implementation. |
| 36 | |
| 37 | This is achieved by checking whether tracing should be enabled at every eglSwap call. |
| 38 | (Note: We were already checking for tracing at every eglSwap, the only change now is that |
| 39 | the tracing could actually be ON/OFF at runtime - earlier it was set once and never changed). |
| 40 | |
| 41 | If eglSwap detects that tracing should be enabled now, then it performs the following steps: |
| 42 | - switch the gl hooks to point to the trace implementation. |
| 43 | - call trace eglMakeCurrent to indicate that there is now a new context that is current. |
| 44 | - continue on with tracing the eglSwap call. |
| 45 | This switches the hooks to point to the trace implementation only for the current context. |
| 46 | But the other contexts have their gl hooks updated when they perform eglMakeCurrent. |
| 47 | |
| 48 | The GLTrace version of eglMakeCurrent now has to be updated to allow switching to a context |
| 49 | it may not know of. In such a case, it creates a context matching the version that it is now |
| 50 | switching to. |
| 51 | |
| 52 | Disabling tracing: |
| 53 | |
| 54 | We disable tracing under two conditions: |
| 55 | - stop tracing request from DdmServer |
| 56 | - gltrace transport gets disconnected from the host. |
| 57 | In either case, both actions simply disable the tracing flag. The current context gets its |
| 58 | gl hooks restored in the next eglSwap, and the other traced contexts get their gl hooks |
| 59 | restored when they perform a eglMakeCurrent. |
| 60 | |
Siva Velusamy | 0469dd6 | 2011-11-30 15:05:37 -0800 | [diff] [blame] | 61 | Code Structure: |
| 62 | |
| 63 | glestrace.h declares all the hooks exposed by libglestrace. These are used by EGL/egl.cpp and |
| 64 | EGL/eglApi.cpp to initialize the trace library, and to inform the library of EGL calls. |
| 65 | |
| 66 | All GL calls are present in GLES_Trace/src/gltrace_api.cpp. This file is generated by the |
| 67 | GLES_Trace/src/genapi.py script. The structure of all the functions looks like this: |
| 68 | |
| 69 | void GLTrace_glFunction(args) { |
| 70 | // declare a protobuf |
| 71 | // copy arguments into the protobuf |
| 72 | // call the original GLES function |
| 73 | // if there is a return value, save it into the protobuf |
| 74 | // fixup the protobuf if necessary |
| 75 | // transport the protobuf to the host |
| 76 | } |
| 77 | |
| 78 | The fixupGLMessage() call does any custom processing of the protobuf based on the GLES call. |
| 79 | This typically amounts to copying the data corresponding to input or output pointers. |