From 2fdcc81ddfdbdfbbde63bd64e9ac9272b5417553 Mon Sep 17 00:00:00 2001 From: Siva Velusamy Date: Wed, 16 May 2012 11:38:03 -0700 Subject: [PATCH] gltrace: Allow receiving commands of length > 4 Currently, gltrace offers very few trace collection options. As a result, these options are encoded in a single integer. The trace control task simply receives integers and interprets them as commands. This patch changes the control protocol to first receive the command length followed by the actual command itself. This allows for future flexibility to provide enable other commands. Change-Id: Id5f56c80a025bbbe7613ab4457e092732e7d9dc9 --- opengl/libs/GLES_trace/src/gltrace_eglapi.cpp | 41 ++++++++++++++++--- .../libs/GLES_trace/src/gltrace_transport.cpp | 14 ++++++- .../libs/GLES_trace/src/gltrace_transport.h | 7 +++- 3 files changed, 53 insertions(+), 9 deletions(-) diff --git a/opengl/libs/GLES_trace/src/gltrace_eglapi.cpp b/opengl/libs/GLES_trace/src/gltrace_eglapi.cpp index c44215379..9698bf90c 100644 --- a/opengl/libs/GLES_trace/src/gltrace_eglapi.cpp +++ b/opengl/libs/GLES_trace/src/gltrace_eglapi.cpp @@ -44,9 +44,14 @@ 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; + // The control stream always receives an integer size of the + // command buffer, followed by the actual command buffer. + uint32_t cmdSize; + + // Command Buffer + void *cmdBuf = NULL; + uint32_t cmdBufSize = 0; + enum TraceSettingsMasks { READ_FB_ON_EGLSWAP_MASK = 1 << 0, READ_FB_ON_GLDRAW_MASK = 1 << 1, @@ -54,12 +59,33 @@ static void *commandReceiveTask(void *arg) { }; while (true) { - int n = stream->receive(&cmd, 4); - if (n != 4) { + // read command size + if (stream->receive(&cmdSize, sizeof(uint32_t)) < 0) { + break; + } + cmdSize = ntohl(cmdSize); + + // ensure command buffer is of required size + if (cmdBufSize < cmdSize) { + free(cmdBuf); + cmdBufSize = cmdSize; + cmdBuf = malloc(cmdSize); + if (cmdBuf == NULL) + break; + } + + // receive the command + if (stream->receive(cmdBuf, cmdSize) < 0) { break; } - cmd = ntohl(cmd); + if (cmdSize != sizeof(uint32_t)) { + // Currently, we only support commands that are a single integer, + // so we skip all other commands + continue; + } + + uint32_t cmd = ntohl(*(uint32_t*)cmdBuf); bool collectFbOnEglSwap = (cmd & READ_FB_ON_EGLSWAP_MASK) != 0; bool collectFbOnGlDraw = (cmd & READ_FB_ON_GLDRAW_MASK) != 0; @@ -73,6 +99,9 @@ static void *commandReceiveTask(void *arg) { collectFbOnEglSwap, collectFbOnGlDraw, collectTextureData); } + ALOGE("Stopping OpenGL Trace Command Receiver\n"); + + free(cmdBuf); return NULL; } diff --git a/opengl/libs/GLES_trace/src/gltrace_transport.cpp b/opengl/libs/GLES_trace/src/gltrace_transport.cpp index 157bd24a6..2996d32c8 100644 --- a/opengl/libs/GLES_trace/src/gltrace_transport.cpp +++ b/opengl/libs/GLES_trace/src/gltrace_transport.cpp @@ -14,6 +14,7 @@ * limitations under the License. */ +#include #include #include @@ -123,7 +124,18 @@ int TCPStream::receive(void *data, size_t len) { return -1; } - return read(mSocket, data, len); + size_t totalRead = 0; + while (totalRead < len) { + int n = read(mSocket, (uint8_t*)data + totalRead, len - totalRead); + if (n < 0) { + ALOGE("Error receiving data from stream: %d", errno); + return -1; + } + + totalRead += n; + } + + return 0; } BufferedOutputStream::BufferedOutputStream(TCPStream *stream, size_t bufferSize) { diff --git a/opengl/libs/GLES_trace/src/gltrace_transport.h b/opengl/libs/GLES_trace/src/gltrace_transport.h index 36650355a..9cf5b4528 100644 --- a/opengl/libs/GLES_trace/src/gltrace_transport.h +++ b/opengl/libs/GLES_trace/src/gltrace_transport.h @@ -42,8 +42,11 @@ public: /** Send @data of size @len to host. . Returns -1 on error, 0 on success. */ int send(void *data, size_t len); - /** Receive data into @buf from the remote end. This is a blocking call. */ - int receive(void *buf, size_t size); + /** + * Receive @len bytes of data into @buf from the remote end. This is a blocking call. + * Returns -1 on failure, 0 on success. + */ + int receive(void *buf, size_t len); }; /**