diff options
author | Siva Velusamy <vsiva@google.com> | 2012-01-03 14:39:31 -0800 |
---|---|---|
committer | Siva Velusamy <vsiva@google.com> | 2012-01-04 12:50:13 -0800 |
commit | 157fea642cb4c10e44a61f932c68f7c3a2610a81 (patch) | |
tree | 58badbc40683dde6329be8f8560259afc6180e66 /opengl | |
parent | 193b45970e512e99b4557fe4bbb30b2dca30320f (diff) | |
download | frameworks_base-157fea642cb4c10e44a61f932c68f7c3a2610a81.zip frameworks_base-157fea642cb4c10e44a61f932c68f7c3a2610a81.tar.gz frameworks_base-157fea642cb4c10e44a61f932c68f7c3a2610a81.tar.bz2 |
gltrace: add user settings to control data captured.
Currently users do not have control over the amount of data
captured during tracing. This patch adds 3 settings that users
can enable/disable at runtime:
- capture framebuffer on eglSwap() calls
- capture framebuffer on glDraw*() calls
- capture texture data passed to glTexImage*() calls
Disabling these options when not needed signficantly decreases
the size of the trace file, and reduces performance overhead for
the running application.
These settings are stored in the per process GLTraceState.
A separate thread listens for commands from the host, and updates
the state based on the user commands.
Change-Id: Ic4518b94e8bcbc5330ac7138153721caa98b365d
Diffstat (limited to 'opengl')
-rw-r--r-- | opengl/libs/GLES_trace/src/gltrace_context.cpp | 51 | ||||
-rw-r--r-- | opengl/libs/GLES_trace/src/gltrace_context.h | 28 | ||||
-rw-r--r-- | opengl/libs/GLES_trace/src/gltrace_egl.cpp | 6 | ||||
-rw-r--r-- | opengl/libs/GLES_trace/src/gltrace_eglapi.cpp | 44 | ||||
-rw-r--r-- | opengl/libs/GLES_trace/src/gltrace_fixup.cpp | 14 |
5 files changed, 135 insertions, 8 deletions
diff --git a/opengl/libs/GLES_trace/src/gltrace_context.cpp b/opengl/libs/GLES_trace/src/gltrace_context.cpp index 81d2f1a..65b7662 100644 --- a/opengl/libs/GLES_trace/src/gltrace_context.cpp +++ b/opengl/libs/GLES_trace/src/gltrace_context.cpp @@ -59,6 +59,11 @@ void releaseContext() { GLTraceState::GLTraceState(TCPStream *stream) { mTraceContextIds = 0; mStream = stream; + + mCollectFbOnEglSwap = false; + mCollectFbOnGlDraw = false; + mCollectTextureDataOnGlTexImage = false; + pthread_rwlock_init(&mTraceOptionsRwLock, NULL); } GLTraceState::~GLTraceState() { @@ -72,12 +77,49 @@ TCPStream *GLTraceState::getStream() { return mStream; } +void GLTraceState::safeSetValue(bool *ptr, bool value, pthread_rwlock_t *lock) { + pthread_rwlock_wrlock(lock); + *ptr = value; + pthread_rwlock_unlock(lock); +} + +bool GLTraceState::safeGetValue(bool *ptr, pthread_rwlock_t *lock) { + pthread_rwlock_rdlock(lock); + bool value = *ptr; + pthread_rwlock_unlock(lock); + return value; +} + +void GLTraceState::setCollectFbOnEglSwap(bool en) { + safeSetValue(&mCollectFbOnEglSwap, en, &mTraceOptionsRwLock); +} + +void GLTraceState::setCollectFbOnGlDraw(bool en) { + safeSetValue(&mCollectFbOnGlDraw, en, &mTraceOptionsRwLock); +} + +void GLTraceState::setCollectTextureDataOnGlTexImage(bool en) { + safeSetValue(&mCollectTextureDataOnGlTexImage, en, &mTraceOptionsRwLock); +} + +bool GLTraceState::shouldCollectFbOnEglSwap() { + return safeGetValue(&mCollectFbOnEglSwap, &mTraceOptionsRwLock); +} + +bool GLTraceState::shouldCollectFbOnGlDraw() { + return safeGetValue(&mCollectFbOnGlDraw, &mTraceOptionsRwLock); +} + +bool GLTraceState::shouldCollectTextureDataOnGlTexImage() { + return safeGetValue(&mCollectTextureDataOnGlTexImage, &mTraceOptionsRwLock); +} + GLTraceContext *GLTraceState::createTraceContext(int version, EGLContext eglContext) { int id = __sync_fetch_and_add(&mTraceContextIds, 1); const size_t DEFAULT_BUFFER_SIZE = 8192; BufferedOutputStream *stream = new BufferedOutputStream(mStream, DEFAULT_BUFFER_SIZE); - GLTraceContext *traceContext = new GLTraceContext(id, stream); + GLTraceContext *traceContext = new GLTraceContext(id, this, stream); mPerContextState[eglContext] = traceContext; return traceContext; @@ -87,8 +129,9 @@ GLTraceContext *GLTraceState::getTraceContext(EGLContext c) { return mPerContextState[c]; } -GLTraceContext::GLTraceContext(int id, BufferedOutputStream *stream) { +GLTraceContext::GLTraceContext(int id, GLTraceState *state, BufferedOutputStream *stream) { mId = id; + mState = state; fbcontents = fbcompressed = NULL; fbcontentsSize = 0; @@ -99,6 +142,10 @@ int GLTraceContext::getId() { return mId; } +GLTraceState *GLTraceContext::getGlobalTraceState() { + return mState; +} + void GLTraceContext::resizeFBMemory(unsigned minSize) { if (fbcontentsSize >= minSize) { return; diff --git a/opengl/libs/GLES_trace/src/gltrace_context.h b/opengl/libs/GLES_trace/src/gltrace_context.h index 0680a9b..129116a 100644 --- a/opengl/libs/GLES_trace/src/gltrace_context.h +++ b/opengl/libs/GLES_trace/src/gltrace_context.h @@ -18,6 +18,7 @@ #define __GLTRACE_CONTEXT_H_ #include <map> +#include <pthread.h> #include "hooks.h" #include "gltrace_transport.h" @@ -29,9 +30,12 @@ using ::android::gl_hooks_t; enum FBBinding {CURRENTLY_BOUND_FB, FB0}; +class GLTraceState; + /** GL Trace Context info associated with each EGLContext */ class GLTraceContext { int mId; /* unique context id */ + GLTraceState *mState; /* parent GL Trace state (for per process GL Trace State Info) */ void *fbcontents; /* memory area to read framebuffer contents */ void *fbcompressed; /* destination for lzf compressed framebuffer */ @@ -43,8 +47,9 @@ class GLTraceContext { public: gl_hooks_t *hooks; - GLTraceContext(int id, BufferedOutputStream *stream); + GLTraceContext(int id, GLTraceState *state, BufferedOutputStream *stream); int getId(); + GLTraceState *getGlobalTraceState(); void getCompressedFB(void **fb, unsigned *fbsize, unsigned *fbwidth, unsigned *fbheight, FBBinding fbToRead); @@ -56,6 +61,17 @@ class GLTraceState { int mTraceContextIds; TCPStream *mStream; std::map<EGLContext, GLTraceContext*> mPerContextState; + + /* Options controlling additional data to be collected on + certain trace calls. */ + bool mCollectFbOnEglSwap; + bool mCollectFbOnGlDraw; + bool mCollectTextureDataOnGlTexImage; + pthread_rwlock_t mTraceOptionsRwLock; + + /* helper methods to get/set values using provided lock for mutual exclusion. */ + void safeSetValue(bool *ptr, bool value, pthread_rwlock_t *lock); + bool safeGetValue(bool *ptr, pthread_rwlock_t *lock); public: GLTraceState(TCPStream *stream); ~GLTraceState(); @@ -64,6 +80,16 @@ public: GLTraceContext *getTraceContext(EGLContext c); TCPStream *getStream(); + + /* Methods to set trace options. */ + void setCollectFbOnEglSwap(bool en); + void setCollectFbOnGlDraw(bool en); + void setCollectTextureDataOnGlTexImage(bool en); + + /* Methods to retrieve trace options. */ + bool shouldCollectFbOnEglSwap(); + bool shouldCollectFbOnGlDraw(); + bool shouldCollectTextureDataOnGlTexImage(); }; void setupTraceContextThreadSpecific(GLTraceContext *context); diff --git a/opengl/libs/GLES_trace/src/gltrace_egl.cpp b/opengl/libs/GLES_trace/src/gltrace_egl.cpp index 50743ff..9d1682a 100644 --- a/opengl/libs/GLES_trace/src/gltrace_egl.cpp +++ b/opengl/libs/GLES_trace/src/gltrace_egl.cpp @@ -78,8 +78,10 @@ void GLTrace_eglSwapBuffers(void *dpy, void *draw) { glmessage.set_context_id(glContext->getId()); glmessage.set_function(GLMessage::eglSwapBuffers); - // read FB0 since that is what is displayed on the screen - fixup_addFBContents(glContext, &glmessage, FB0); + if (glContext->getGlobalTraceState()->shouldCollectFbOnEglSwap()) { + // read FB0 since that is what is displayed on the screen + fixup_addFBContents(glContext, &glmessage, FB0); + } // set start time and duration glmessage.set_start_time(systemTime()); diff --git a/opengl/libs/GLES_trace/src/gltrace_eglapi.cpp b/opengl/libs/GLES_trace/src/gltrace_eglapi.cpp index e04e6d4..0fe97ce 100644 --- a/opengl/libs/GLES_trace/src/gltrace_eglapi.cpp +++ b/opengl/libs/GLES_trace/src/gltrace_eglapi.cpp @@ -14,6 +14,7 @@ * limitations under the License. */ +#include <arpa/inet.h> #include <stdlib.h> #include <cutils/log.h> #include <cutils/properties.h> @@ -33,6 +34,47 @@ using gltrace::GLTraceContext; using gltrace::TCPStream; static GLTraceState *sGLTraceState; +static pthread_t sReceiveThreadId; + +/** + * Task that monitors the control stream from the host and updates + * the trace status according to commands received from the host. + */ +static void *commandReceiveTask(void *arg) { + GLTraceState *state = (GLTraceState *)arg; + TCPStream *stream = state->getStream(); + + // Currently, there are very few user configurable settings. + // As a result, they can be encoded in a single integer. + int cmd; + enum TraceSettingsMasks { + READ_FB_ON_EGLSWAP_MASK = 1 << 0, + READ_FB_ON_GLDRAW_MASK = 1 << 1, + READ_TEXTURE_DATA_ON_GLTEXIMAGE_MASK = 1 << 2, + }; + + while (true) { + int n = stream->receive(&cmd, 4); + if (n != 4) { + break; + } + + cmd = ntohl(cmd); + + bool collectFbOnEglSwap = (cmd & READ_FB_ON_EGLSWAP_MASK) != 0; + bool collectFbOnGlDraw = (cmd & READ_FB_ON_GLDRAW_MASK) != 0; + bool collectTextureData = (cmd & READ_TEXTURE_DATA_ON_GLTEXIMAGE_MASK) != 0; + + state->setCollectFbOnEglSwap(collectFbOnEglSwap); + state->setCollectFbOnGlDraw(collectFbOnGlDraw); + state->setCollectTextureDataOnGlTexImage(collectTextureData); + + ALOGD("trace options: eglswap: %d, gldraw: %d, texImage: %d", + collectFbOnEglSwap, collectFbOnGlDraw, collectTextureData); + } + + return NULL; +} void GLTrace_start() { char value[PROPERTY_VALUE_MAX]; @@ -51,6 +93,8 @@ void GLTrace_start() { // initialize tracing state sGLTraceState = new GLTraceState(stream); + + pthread_create(&sReceiveThreadId, NULL, commandReceiveTask, sGLTraceState); } void GLTrace_stop() { diff --git a/opengl/libs/GLES_trace/src/gltrace_fixup.cpp b/opengl/libs/GLES_trace/src/gltrace_fixup.cpp index 7fbae1de..5a439e3 100644 --- a/opengl/libs/GLES_trace/src/gltrace_fixup.cpp +++ b/opengl/libs/GLES_trace/src/gltrace_fixup.cpp @@ -283,7 +283,9 @@ void fixupGLMessage(GLTraceContext *context, nsecs_t start, nsecs_t end, GLMessa fixup_glGetString(glmsg); break; case GLMessage::glTexImage2D: - fixup_glTexImage2D(glmsg); + if (context->getGlobalTraceState()->shouldCollectTextureDataOnGlTexImage()) { + fixup_glTexImage2D(glmsg); + } break; case GLMessage::glShaderSource: fixup_glShaderSource(glmsg); @@ -304,10 +306,16 @@ void fixupGLMessage(GLTraceContext *context, nsecs_t start, nsecs_t end, GLMessa fixup_glUniformMatrixGeneric(4, glmsg); break; case GLMessage::glDrawArrays: - case GLMessage::glDrawElements: /* void glDrawArrays(GLenum mode, GLint first, GLsizei count) */ + if (context->getGlobalTraceState()->shouldCollectFbOnGlDraw()) { + fixup_addFBContents(context, glmsg, CURRENTLY_BOUND_FB); + } + break; + case GLMessage::glDrawElements: /* void glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices) */ - fixup_addFBContents(context, glmsg, CURRENTLY_BOUND_FB); + if (context->getGlobalTraceState()->shouldCollectFbOnGlDraw()) { + fixup_addFBContents(context, glmsg, CURRENTLY_BOUND_FB); + } break; default: break; |