diff options
Diffstat (limited to 'opengl/libs/GLES2_dbg/src/server.cpp')
-rw-r--r-- | opengl/libs/GLES2_dbg/src/server.cpp | 109 |
1 files changed, 82 insertions, 27 deletions
diff --git a/opengl/libs/GLES2_dbg/src/server.cpp b/opengl/libs/GLES2_dbg/src/server.cpp index 7039c84..0c711bf 100644 --- a/opengl/libs/GLES2_dbg/src/server.cpp +++ b/opengl/libs/GLES2_dbg/src/server.cpp @@ -28,7 +28,8 @@ namespace android { int serverSock = -1, clientSock = -1; - +FILE * file = NULL; +unsigned int MAX_FILE_SIZE = 0; int timeMode = SYSTEM_TIME_THREAD; static void Die(const char * msg) @@ -38,18 +39,25 @@ static void Die(const char * msg) exit(1); } -void StartDebugServer(unsigned short port) +void StartDebugServer(const unsigned short port, const bool forceUseFile, + const unsigned int maxFileSize, const char * const filePath) { + MAX_FILE_SIZE = maxFileSize; + LOGD("GLESv2_dbg: StartDebugServer"); - if (serverSock >= 0) + if (serverSock >= 0 || file) return; LOGD("GLESv2_dbg: StartDebugServer create socket"); struct sockaddr_in server = {}, client = {}; /* Create the TCP socket */ - if ((serverSock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) { - Die("Failed to create socket"); + if (forceUseFile || (serverSock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) { + file = fopen(filePath, "wb"); + if (!file) + Die("Failed to create socket and file"); + else + return; } /* Construct the server sockaddr_in structure */ server.sin_family = AF_INET; /* Internet/IP */ @@ -92,13 +100,17 @@ void StopDebugServer() close(serverSock); serverSock = -1; } - + if (file) { + fclose(file); + file = NULL; + } } void Receive(glesv2debugger::Message & cmd) { + if (clientSock < 0) + return; unsigned len = 0; - int received = recv(clientSock, &len, 4, MSG_WAITALL); if (received < 0) Die("Failed to receive response length"); @@ -106,7 +118,6 @@ void Receive(glesv2debugger::Message & cmd) LOGD("received %dB: %.8X", received, len); Die("Received length mismatch, expected 4"); } - len = ntohl(len); static void * buffer = NULL; static unsigned bufferSize = 0; if (bufferSize < len) { @@ -125,6 +136,8 @@ void Receive(glesv2debugger::Message & cmd) bool TryReceive(glesv2debugger::Message & cmd) { + if (clientSock < 0) + return false; fd_set readSet; FD_ZERO(&readSet); FD_SET(clientSock, &readSet); @@ -146,14 +159,34 @@ bool TryReceive(glesv2debugger::Message & cmd) float Send(const glesv2debugger::Message & msg, glesv2debugger::Message & cmd) { + // TODO: use per DbgContext send/receive buffer and async socket + // instead of mutex and blocking io; watch out for large messages static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; - pthread_mutex_lock(&mutex); // TODO: this is just temporary + struct Autolock { + Autolock() { + pthread_mutex_lock(&mutex); + } + ~Autolock() { + pthread_mutex_unlock(&mutex); + } + } autolock; if (msg.function() != glesv2debugger::Message_Function_ACK) assert(msg.has_context_id() && msg.context_id() != 0); static std::string str; msg.SerializeToString(&str); - uint32_t len = htonl(str.length()); + const uint32_t len = str.length(); + if (clientSock < 0) { + if (file) { + fwrite(&len, sizeof(len), 1, file); + fwrite(str.data(), len, 1, file); + if (ftell(file) >= MAX_FILE_SIZE) { + fclose(file); + Die("MAX_FILE_SIZE reached"); + } + } + return 0; + } int sent = -1; sent = send(clientSock, &len, sizeof(len), 0); if (sent != sizeof(len)) { @@ -161,36 +194,37 @@ float Send(const glesv2debugger::Message & msg, glesv2debugger::Message & cmd) Die("Failed to send message length"); } nsecs_t c0 = systemTime(timeMode); - sent = send(clientSock, str.c_str(), str.length(), 0); + sent = send(clientSock, str.data(), str.length(), 0); float t = (float)ns2ms(systemTime(timeMode) - c0); if (sent != str.length()) { LOGD("actual sent=%d expected=%d clientSock=%d", sent, str.length(), clientSock); Die("Failed to send message"); } - + // TODO: factor Receive & TryReceive out and into MessageLoop, or add control argument. + // mean while, if server is sending a SETPROP then don't try to receive, + // because server will not be processing received command + if (msg.function() == msg.SETPROP) + return t; // try to receive commands even though not expecting response, - // since client can send SETPROP commands anytime + // since client can send SETPROP and other commands anytime if (!msg.expect_response()) { if (TryReceive(cmd)) { - LOGD("Send: TryReceived"); if (glesv2debugger::Message_Function_SETPROP == cmd.function()) - LOGD("Send: received SETPROP"); + LOGD("Send: TryReceived SETPROP"); else - LOGD("Send: received something else"); + LOGD("Send: TryReceived %u", cmd.function()); } } else Receive(cmd); - - pthread_mutex_unlock(&mutex); return t; } void SetProp(DbgContext * const dbg, const glesv2debugger::Message & cmd) { switch (cmd.prop()) { - case glesv2debugger::Message_Prop_Capture: - LOGD("SetProp Message_Prop_Capture %d", cmd.arg0()); - capture = cmd.arg0(); + case glesv2debugger::Message_Prop_CaptureDraw: + LOGD("SetProp Message_Prop_CaptureDraw %d", cmd.arg0()); + dbg->captureDraw = cmd.arg0(); break; case glesv2debugger::Message_Prop_TimeMode: LOGD("SetProp Message_Prop_TimeMode %d", cmd.arg0()); @@ -200,6 +234,10 @@ void SetProp(DbgContext * const dbg, const glesv2debugger::Message & cmd) LOGD("SetProp Message_Prop_ExpectResponse %d=%d", cmd.arg0(), cmd.arg1()); dbg->expectResponse.Bit((glesv2debugger::Message_Function)cmd.arg0(), cmd.arg1()); break; + case glesv2debugger::Message_Prop_CaptureSwap: + LOGD("SetProp CaptureSwap %d", cmd.arg0()); + dbg->captureSwap = cmd.arg0(); + break; default: assert(0); } @@ -213,12 +251,17 @@ int * MessageLoop(FunctionCall & functionCall, glesv2debugger::Message & msg, glesv2debugger::Message cmd; msg.set_context_id(reinterpret_cast<int>(dbg)); msg.set_type(glesv2debugger::Message_Type_BeforeCall); - const bool expectResponse = dbg->expectResponse.Bit(function); + bool expectResponse = dbg->expectResponse.Bit(function); msg.set_expect_response(expectResponse); msg.set_function(function); - if (!expectResponse) - cmd.set_function(glesv2debugger::Message_Function_CONTINUE); + + // when not exectResponse, set cmd to CONTINUE then SKIP + // cmd will be overwritten by received command + cmd.set_function(glesv2debugger::Message_Function_CONTINUE); + cmd.set_expect_response(expectResponse); + glesv2debugger::Message_Function oldCmd = cmd.function(); Send(msg, cmd); + expectResponse = cmd.expect_response(); while (true) { msg.Clear(); nsecs_t c0 = systemTime(timeMode); @@ -233,22 +276,34 @@ int * MessageLoop(FunctionCall & functionCall, glesv2debugger::Message & msg, msg.set_function(function); msg.set_type(glesv2debugger::Message_Type_AfterCall); msg.set_expect_response(expectResponse); - if (!expectResponse) + if (!expectResponse) { cmd.set_function(glesv2debugger::Message_Function_SKIP); + cmd.set_expect_response(false); + } + oldCmd = cmd.function(); Send(msg, cmd); + expectResponse = cmd.expect_response(); break; case glesv2debugger::Message_Function_SKIP: return const_cast<int *>(ret); case glesv2debugger::Message_Function_SETPROP: SetProp(dbg, cmd); - Receive(cmd); + expectResponse = cmd.expect_response(); + if (!expectResponse) // SETPROP is "out of band" + cmd.set_function(oldCmd); + else + Receive(cmd); break; default: ret = GenerateCall(dbg, cmd, msg, ret); msg.set_expect_response(expectResponse); - if (!expectResponse) + if (!expectResponse) { cmd.set_function(cmd.SKIP); + cmd.set_expect_response(expectResponse); + } + oldCmd = cmd.function(); Send(msg, cmd); + expectResponse = cmd.expect_response(); break; } } |