am 157fea64: gltrace: add user settings to control data captured.

* commit '157fea642cb4c10e44a61f932c68f7c3a2610a81':
  gltrace: add user settings to control data captured.
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 @@
 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 @@
     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 @@
     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 @@
     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 @@
 
 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 @@
 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 @@
     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 @@
     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 @@
     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::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 @@
 
     // 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 @@
         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 @@
         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;