GLES2Debugger: Make command exchange async to improve performance.
In message loop, use select to check for available commands from client, rather than always expecting commands in eglSwapBuffers. Change-Id: Ifc34dd77c2528c8b9c71f594e3eda4f93400cd2b Signed-off-by: David Li <davidxli@google.com>
This commit is contained in:
@@ -340,7 +340,10 @@ static void initEglTraceLevel() {
|
||||
}
|
||||
|
||||
if (gEGLDebugLevel > 0)
|
||||
StartDebugServer();
|
||||
{
|
||||
property_get("debug.egl.debug_port", value, "5039");
|
||||
StartDebugServer(atoi(value));
|
||||
}
|
||||
}
|
||||
|
||||
static void setGLHooksThreadSpecific(gl_hooks_t const *value) {
|
||||
@@ -350,7 +353,6 @@ static void setGLHooksThreadSpecific(gl_hooks_t const *value) {
|
||||
} else if (gEGLDebugLevel > 0 && value != &gHooksNoContext) {
|
||||
setGlTraceThreadSpecific(value);
|
||||
setGlThreadSpecific(&gHooksDebug);
|
||||
LOGD("\n* setGLHooksThreadSpecific gHooksDebug");
|
||||
} else {
|
||||
setGlThreadSpecific(value);
|
||||
}
|
||||
|
||||
@@ -98,9 +98,6 @@ message Message
|
||||
output.write(" SETPROP = %d;\n" % (i))
|
||||
i += 1
|
||||
|
||||
output.write(" CAPTURE = %d;\n" % (i))
|
||||
i += 1
|
||||
|
||||
output.write(""" }
|
||||
required Function function = 2 [default = NEG]; // type/function of message
|
||||
enum Type
|
||||
|
||||
@@ -65,8 +65,9 @@ void DbgContext::Fetch(const unsigned index, std::string * const data) const
|
||||
|
||||
void DbgContext::glUseProgram(GLuint program)
|
||||
{
|
||||
assert(GL_NO_ERROR == hooks->gl.glGetError());
|
||||
|
||||
while (GLenum error = hooks->gl.glGetError())
|
||||
LOGD("DbgContext::glUseProgram: before glGetError() = 0x%.4X", error);
|
||||
|
||||
this->program = program;
|
||||
|
||||
GLint activeAttributes = 0;
|
||||
@@ -106,6 +107,9 @@ void DbgContext::glUseProgram(GLuint program)
|
||||
maxAttrib = slot;
|
||||
}
|
||||
delete name;
|
||||
|
||||
while (GLenum error = hooks->gl.glGetError())
|
||||
LOGD("DbgContext::glUseProgram: after glGetError() = 0x%.4X", error);
|
||||
}
|
||||
|
||||
static bool HasNonVBOAttribs(const DbgContext * const ctx)
|
||||
|
||||
@@ -229,7 +229,6 @@ bool Message_Function_IsValid(int value) {
|
||||
case 188:
|
||||
case 189:
|
||||
case 190:
|
||||
case 191:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
@@ -428,7 +427,6 @@ const Message_Function Message::NEG;
|
||||
const Message_Function Message::CONTINUE;
|
||||
const Message_Function Message::SKIP;
|
||||
const Message_Function Message::SETPROP;
|
||||
const Message_Function Message::CAPTURE;
|
||||
const Message_Function Message::Function_MIN;
|
||||
const Message_Function Message::Function_MAX;
|
||||
const int Message::Function_ARRAYSIZE;
|
||||
|
||||
@@ -226,12 +226,11 @@ enum Message_Function {
|
||||
Message_Function_NEG = 187,
|
||||
Message_Function_CONTINUE = 188,
|
||||
Message_Function_SKIP = 189,
|
||||
Message_Function_SETPROP = 190,
|
||||
Message_Function_CAPTURE = 191
|
||||
Message_Function_SETPROP = 190
|
||||
};
|
||||
bool Message_Function_IsValid(int value);
|
||||
const Message_Function Message_Function_Function_MIN = Message_Function_glActiveTexture;
|
||||
const Message_Function Message_Function_Function_MAX = Message_Function_CAPTURE;
|
||||
const Message_Function Message_Function_Function_MAX = Message_Function_SETPROP;
|
||||
const int Message_Function_Function_ARRAYSIZE = Message_Function_Function_MAX + 1;
|
||||
|
||||
enum Message_Type {
|
||||
@@ -488,7 +487,6 @@ class Message : public ::google::protobuf::MessageLite {
|
||||
static const Function CONTINUE = Message_Function_CONTINUE;
|
||||
static const Function SKIP = Message_Function_SKIP;
|
||||
static const Function SETPROP = Message_Function_SETPROP;
|
||||
static const Function CAPTURE = Message_Function_CAPTURE;
|
||||
static inline bool Function_IsValid(int value) {
|
||||
return Message_Function_IsValid(value);
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
EGLBoolean Debug_eglSwapBuffers(EGLDisplay dpy, EGLSurface draw)
|
||||
{
|
||||
glesv2debugger::Message msg;
|
||||
const bool expectResponse = true;
|
||||
const bool expectResponse = false;
|
||||
struct : public FunctionCall {
|
||||
EGLDisplay dpy;
|
||||
EGLSurface draw;
|
||||
|
||||
@@ -113,7 +113,7 @@ struct FunctionCall {
|
||||
virtual ~FunctionCall() {}
|
||||
};
|
||||
|
||||
// move these into DbgContext
|
||||
// move these into DbgContext as static
|
||||
extern bool capture;
|
||||
extern int timeMode; // SYSTEM_TIME_
|
||||
|
||||
@@ -121,8 +121,10 @@ extern int clientSock, serverSock;
|
||||
|
||||
unsigned GetBytesPerPixel(const GLenum format, const GLenum type);
|
||||
|
||||
// every Debug_gl* function calls this to send message to client and possibly receive commands
|
||||
int * MessageLoop(FunctionCall & functionCall, glesv2debugger::Message & msg,
|
||||
const bool expectResponse, const glesv2debugger::Message_Function function);
|
||||
|
||||
void Receive(glesv2debugger::Message & cmd);
|
||||
float Send(const glesv2debugger::Message & msg, glesv2debugger::Message & cmd);
|
||||
void SetProp(const glesv2debugger::Message & cmd);
|
||||
|
||||
@@ -38,7 +38,7 @@ static void Die(const char * msg)
|
||||
exit(1);
|
||||
}
|
||||
|
||||
void StartDebugServer()
|
||||
void StartDebugServer(unsigned short port)
|
||||
{
|
||||
LOGD("GLESv2_dbg: StartDebugServer");
|
||||
if (serverSock >= 0)
|
||||
@@ -53,8 +53,8 @@ void StartDebugServer()
|
||||
}
|
||||
/* Construct the server sockaddr_in structure */
|
||||
server.sin_family = AF_INET; /* Internet/IP */
|
||||
server.sin_addr.s_addr = htonl(INADDR_ANY); /* Incoming addr */
|
||||
server.sin_port = htons(5039); /* server port */
|
||||
server.sin_addr.s_addr = htonl(INADDR_LOOPBACK); /* Incoming addr */
|
||||
server.sin_port = htons(port); /* server port */
|
||||
|
||||
/* Bind the server socket */
|
||||
socklen_t sizeofSockaddr_in = sizeof(sockaddr_in);
|
||||
@@ -79,13 +79,6 @@ void StartDebugServer()
|
||||
|
||||
LOGD("Client connected: %s\n", inet_ntoa(client.sin_addr));
|
||||
// fcntl(clientSock, F_SETFL, O_NONBLOCK);
|
||||
|
||||
glesv2debugger::Message msg, cmd;
|
||||
msg.set_context_id(0);
|
||||
msg.set_function(glesv2debugger::Message_Function_ACK);
|
||||
msg.set_type(glesv2debugger::Message_Type_Response);
|
||||
msg.set_expect_response(false);
|
||||
Send(msg, cmd);
|
||||
}
|
||||
|
||||
void StopDebugServer()
|
||||
@@ -130,6 +123,27 @@ void Receive(glesv2debugger::Message & cmd)
|
||||
cmd.ParseFromArray(buffer, len);
|
||||
}
|
||||
|
||||
bool TryReceive(glesv2debugger::Message & cmd)
|
||||
{
|
||||
fd_set readSet;
|
||||
FD_ZERO(&readSet);
|
||||
FD_SET(clientSock, &readSet);
|
||||
timeval timeout;
|
||||
timeout.tv_sec = timeout.tv_usec = 0;
|
||||
|
||||
int rc = select(clientSock + 1, &readSet, NULL, NULL, &timeout);
|
||||
if (rc < 0)
|
||||
Die("failed to select clientSock");
|
||||
|
||||
bool received = false;
|
||||
if (FD_ISSET(clientSock, &readSet)) {
|
||||
LOGD("TryReceive: avaiable for read");
|
||||
Receive(cmd);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
float Send(const glesv2debugger::Message & msg, glesv2debugger::Message & cmd)
|
||||
{
|
||||
static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
@@ -155,12 +169,18 @@ float Send(const glesv2debugger::Message & msg, glesv2debugger::Message & cmd)
|
||||
Die("Failed to send message");
|
||||
}
|
||||
|
||||
// try to receive commands even though not expecting response,
|
||||
// since client can send SETPROP commands anytime
|
||||
if (!msg.expect_response()) {
|
||||
pthread_mutex_unlock(&mutex);
|
||||
return t;
|
||||
}
|
||||
|
||||
Receive(cmd);
|
||||
if (TryReceive(cmd)) {
|
||||
LOGD("Send: TryReceived");
|
||||
if (glesv2debugger::Message_Function_SETPROP == cmd.function())
|
||||
LOGD("Send: received SETPROP");
|
||||
else
|
||||
LOGD("Send: received something else");
|
||||
}
|
||||
} else
|
||||
Receive(cmd);
|
||||
|
||||
//LOGD("Message sent tid=%lu len=%d", pthread_self(), str.length());
|
||||
pthread_mutex_unlock(&mutex);
|
||||
@@ -193,24 +213,26 @@ int * MessageLoop(FunctionCall & functionCall, glesv2debugger::Message & msg,
|
||||
msg.set_type(glesv2debugger::Message_Type_BeforeCall);
|
||||
msg.set_expect_response(expectResponse);
|
||||
msg.set_function(function);
|
||||
Send(msg, cmd);
|
||||
if (!expectResponse)
|
||||
cmd.set_function(glesv2debugger::Message_Function_CONTINUE);
|
||||
Send(msg, cmd);
|
||||
while (true) {
|
||||
msg.Clear();
|
||||
nsecs_t c0 = systemTime(timeMode);
|
||||
switch (cmd.function()) {
|
||||
case glesv2debugger::Message_Function_CONTINUE:
|
||||
ret = functionCall(&dbg->hooks->gl, msg);
|
||||
while (GLenum error = dbg->hooks->gl.glGetError())
|
||||
LOGD("Function=%u glGetError() = 0x%.4X", function, error);
|
||||
if (!msg.has_time()) // some has output data copy, so time inside call
|
||||
msg.set_time((systemTime(timeMode) - c0) * 1e-6f);
|
||||
msg.set_context_id(reinterpret_cast<int>(dbg));
|
||||
msg.set_function(function);
|
||||
msg.set_type(glesv2debugger::Message_Type_AfterCall);
|
||||
msg.set_expect_response(expectResponse);
|
||||
Send(msg, cmd);
|
||||
if (!expectResponse)
|
||||
cmd.set_function(glesv2debugger::Message_Function_SKIP);
|
||||
Send(msg, cmd);
|
||||
break;
|
||||
case glesv2debugger::Message_Function_SKIP:
|
||||
return const_cast<int *>(ret);
|
||||
|
||||
@@ -41,10 +41,10 @@ void Debug_glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum
|
||||
msg.set_arg6(reinterpret_cast<int>(pixels));
|
||||
//void * data = NULL;
|
||||
//unsigned encodedSize = 0;
|
||||
Send(msg, cmd);
|
||||
float t = 0;
|
||||
if (!expectResponse)
|
||||
cmd.set_function(glesv2debugger::Message_Function_CONTINUE);
|
||||
Send(msg, cmd);
|
||||
float t = 0;
|
||||
while (true) {
|
||||
msg.Clear();
|
||||
nsecs_t c0 = systemTime(timeMode);
|
||||
@@ -61,6 +61,8 @@ void Debug_glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum
|
||||
//msg.set_data(data, encodedSize);
|
||||
//free(data);
|
||||
c0 = systemTime(timeMode);
|
||||
if (!expectResponse)
|
||||
cmd.set_function(glesv2debugger::Message_Function_SKIP);
|
||||
t = Send(msg, cmd);
|
||||
msg.set_time((systemTime(timeMode) - c0) * 1e-6f);
|
||||
msg.set_clock(t);
|
||||
@@ -69,11 +71,13 @@ void Debug_glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum
|
||||
msg.set_expect_response(false);
|
||||
msg.set_type(glesv2debugger::Message_Type_AfterCall);
|
||||
//Send(msg, cmd);
|
||||
if (!expectResponse)
|
||||
cmd.set_function(glesv2debugger::Message_Function_SKIP);
|
||||
break;
|
||||
case glesv2debugger::Message_Function_SKIP:
|
||||
return;
|
||||
case glesv2debugger::Message_Function_SETPROP:
|
||||
SetProp(cmd);
|
||||
Receive(cmd);
|
||||
break;
|
||||
default:
|
||||
assert(0); //GenerateCall(msg, cmd);
|
||||
break;
|
||||
@@ -104,9 +108,9 @@ void Debug_glDrawArrays(GLenum mode, GLint first, GLsizei count)
|
||||
void * pixels = NULL;
|
||||
GLint readFormat = 0, readType = 0;
|
||||
int viewport[4] = {};
|
||||
Send(msg, cmd);
|
||||
if (!expectResponse)
|
||||
cmd.set_function(glesv2debugger::Message_Function_CONTINUE);
|
||||
Send(msg, cmd);
|
||||
while (true) {
|
||||
msg.Clear();
|
||||
nsecs_t c0 = systemTime(timeMode);
|
||||
@@ -118,25 +122,26 @@ void Debug_glDrawArrays(GLenum mode, GLint first, GLsizei count)
|
||||
msg.set_function(glesv2debugger::Message_Function_glDrawArrays);
|
||||
msg.set_type(glesv2debugger::Message_Type_AfterCall);
|
||||
msg.set_expect_response(expectResponse);
|
||||
Send(msg, cmd);
|
||||
if (capture)
|
||||
cmd.set_function(glesv2debugger::Message_Function_CAPTURE);
|
||||
else if (!expectResponse)
|
||||
if (!expectResponse)
|
||||
cmd.set_function(glesv2debugger::Message_Function_SKIP);
|
||||
Send(msg, cmd);
|
||||
if (capture) {
|
||||
dbg->hooks->gl.glGetIntegerv(GL_VIEWPORT, viewport);
|
||||
dbg->hooks->gl.glGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_FORMAT, &readFormat);
|
||||
dbg->hooks->gl.glGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_TYPE, &readType);
|
||||
LOGD("glDrawArrays CAPTURE: x=%d y=%d width=%d height=%d format=0x%.4X type=0x%.4X",
|
||||
viewport[0], viewport[1], viewport[2], viewport[3], readFormat, readType);
|
||||
pixels = malloc(viewport[2] * viewport[3] * 4);
|
||||
Debug_glReadPixels(viewport[0], viewport[1], viewport[2], viewport[3],
|
||||
readFormat, readType, pixels);
|
||||
free(pixels);
|
||||
}
|
||||
break;
|
||||
case glesv2debugger::Message_Function_SKIP:
|
||||
return;
|
||||
case glesv2debugger::Message_Function_CAPTURE:
|
||||
dbg->hooks->gl.glGetIntegerv(GL_VIEWPORT, viewport);
|
||||
dbg->hooks->gl.glGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_FORMAT, &readFormat);
|
||||
dbg->hooks->gl.glGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_TYPE, &readType);
|
||||
LOGD("glDrawArrays CAPTURE: x=%d y=%d width=%d height=%d format=0x%.4X type=0x%.4X",
|
||||
viewport[0], viewport[1], viewport[2], viewport[3], readFormat, readType);
|
||||
pixels = malloc(viewport[2] * viewport[3] * 4);
|
||||
Debug_glReadPixels(viewport[0], viewport[1], viewport[2], viewport[3],
|
||||
readFormat, readType, pixels);
|
||||
free(pixels);
|
||||
cmd.set_function(glesv2debugger::Message_Function_SKIP);
|
||||
case glesv2debugger::Message_Function_SETPROP:
|
||||
SetProp(cmd);
|
||||
Receive(cmd);
|
||||
break;
|
||||
default:
|
||||
assert(0); //GenerateCall(msg, cmd);
|
||||
@@ -189,9 +194,9 @@ void Debug_glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid*
|
||||
void * pixels = NULL;
|
||||
GLint readFormat = 0, readType = 0;
|
||||
int viewport[4] = {};
|
||||
Send(msg, cmd);
|
||||
if (!expectResponse)
|
||||
cmd.set_function(glesv2debugger::Message_Function_CONTINUE);
|
||||
Send(msg, cmd);
|
||||
while (true) {
|
||||
msg.Clear();
|
||||
nsecs_t c0 = systemTime(timeMode);
|
||||
@@ -203,25 +208,26 @@ void Debug_glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid*
|
||||
msg.set_function(glesv2debugger::Message_Function_glDrawElements);
|
||||
msg.set_type(glesv2debugger::Message_Type_AfterCall);
|
||||
msg.set_expect_response(expectResponse);
|
||||
Send(msg, cmd);
|
||||
if (capture)
|
||||
cmd.set_function(glesv2debugger::Message_Function_CAPTURE);
|
||||
else if (!expectResponse)
|
||||
if (!expectResponse)
|
||||
cmd.set_function(glesv2debugger::Message_Function_SKIP);
|
||||
Send(msg, cmd);
|
||||
if (capture) {
|
||||
dbg->hooks->gl.glGetIntegerv(GL_VIEWPORT, viewport);
|
||||
dbg->hooks->gl.glGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_FORMAT, &readFormat);
|
||||
dbg->hooks->gl.glGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_TYPE, &readType);
|
||||
LOGD("glDrawArrays CAPTURE: x=%d y=%d width=%d height=%d format=0x%.4X type=0x%.4X",
|
||||
viewport[0], viewport[1], viewport[2], viewport[3], readFormat, readType);
|
||||
pixels = malloc(viewport[2] * viewport[3] * 4);
|
||||
Debug_glReadPixels(viewport[0], viewport[1], viewport[2], viewport[3],
|
||||
readFormat, readType, pixels);
|
||||
free(pixels);
|
||||
}
|
||||
break;
|
||||
case glesv2debugger::Message_Function_SKIP:
|
||||
return;
|
||||
case glesv2debugger::Message_Function_CAPTURE:
|
||||
dbg->hooks->gl.glGetIntegerv(GL_VIEWPORT, viewport);
|
||||
dbg->hooks->gl.glGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_FORMAT, &readFormat);
|
||||
dbg->hooks->gl.glGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_TYPE, &readType);
|
||||
LOGD("glDrawArrays CAPTURE: x=%d y=%d width=%d height=%d format=0x%.4X type=0x%.4X",
|
||||
viewport[0], viewport[1], viewport[2], viewport[3], readFormat, readType);
|
||||
pixels = malloc(viewport[2] * viewport[3] * 4);
|
||||
Debug_glReadPixels(viewport[0], viewport[1], viewport[2], viewport[3],
|
||||
readFormat, readType, pixels);
|
||||
free(pixels);
|
||||
cmd.set_function(glesv2debugger::Message_Function_SKIP);
|
||||
case glesv2debugger::Message_Function_SETPROP:
|
||||
SetProp(cmd);
|
||||
Receive(cmd);
|
||||
break;
|
||||
default:
|
||||
assert(0); //GenerateCall(msg, cmd);
|
||||
|
||||
@@ -24,7 +24,7 @@ namespace android
|
||||
DbgContext * CreateDbgContext(const unsigned version, const gl_hooks_t * const hooks);
|
||||
void DestroyDbgContext(DbgContext * const dbg);
|
||||
|
||||
void StartDebugServer(); // create and bind socket if haven't already
|
||||
void StartDebugServer(unsigned short port); // create and bind socket if haven't already
|
||||
void StopDebugServer(); // close socket if open
|
||||
|
||||
}; // namespace android
|
||||
|
||||
Reference in New Issue
Block a user