GLES2Dbg: send some GL implementation constants to client

Change-Id: Ic6c51c09b1c3d2e1e1a28c6ed552714c3243827c
Signed-off-by: David Li <davidxli@google.com>
This commit is contained in:
David Li 2011-04-15 15:35:10 -07:00
parent 7b271eba88
commit 620676eec7
7 changed files with 107 additions and 21 deletions

View File

@ -142,6 +142,7 @@ message Message
TimeMode = 1; // arg0 = SYSTEM_TIME_* in utils/Timers.h
ExpectResponse = 2; // arg0 = enum Function, arg1 = true/false
CaptureSwap = 3; // arg0 = number of eglSwapBuffers to glReadPixels
GLConstant = 4; // arg0 = GLenum, arg1 = constant; send GL impl. constants
};
optional Prop prop = 21; // used with SETPROP, value in arg0
optional float clock = 22; // wall clock in seconds

View File

@ -71,7 +71,24 @@ DbgContext * CreateDbgContext(const pthread_key_t EGLThreadLocalStorageKey,
GLint readFormat, readType;
hooks->gl.glGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_FORMAT, &readFormat);
hooks->gl.glGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_TYPE, &readType);
return new DbgContext(version, hooks, MAX_VERTEX_ATTRIBS, readFormat, readType);
DbgContext * const dbg = new DbgContext(version, hooks, MAX_VERTEX_ATTRIBS, readFormat, readType);
glesv2debugger::Message msg, cmd;
msg.set_context_id(reinterpret_cast<int>(dbg));
msg.set_expect_response(false);
msg.set_type(msg.Response);
msg.set_function(msg.SETPROP);
msg.set_prop(msg.GLConstant);
msg.set_arg0(GL_MAX_VERTEX_ATTRIBS);
msg.set_arg1(MAX_VERTEX_ATTRIBS);
Send(msg, cmd);
GLint MAX_COMBINED_TEXTURE_IMAGE_UNITS = 0;
hooks->gl.glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &MAX_COMBINED_TEXTURE_IMAGE_UNITS);
msg.set_arg0(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS);
msg.set_arg1(MAX_COMBINED_TEXTURE_IMAGE_UNITS);
Send(msg, cmd);
return dbg;
}
void DestroyDbgContext(DbgContext * const dbg)

View File

@ -477,6 +477,7 @@ bool Message_Prop_IsValid(int value) {
case 1:
case 2:
case 3:
case 4:
return true;
default:
return false;
@ -488,6 +489,7 @@ const Message_Prop Message::CaptureDraw;
const Message_Prop Message::TimeMode;
const Message_Prop Message::ExpectResponse;
const Message_Prop Message::CaptureSwap;
const Message_Prop Message::GLConstant;
const Message_Prop Message::Prop_MIN;
const Message_Prop Message::Prop_MAX;
const int Message::Prop_ARRAYSIZE;

View File

@ -258,11 +258,12 @@ enum Message_Prop {
Message_Prop_CaptureDraw = 0,
Message_Prop_TimeMode = 1,
Message_Prop_ExpectResponse = 2,
Message_Prop_CaptureSwap = 3
Message_Prop_CaptureSwap = 3,
Message_Prop_GLConstant = 4
};
bool Message_Prop_IsValid(int value);
const Message_Prop Message_Prop_Prop_MIN = Message_Prop_CaptureDraw;
const Message_Prop Message_Prop_Prop_MAX = Message_Prop_CaptureSwap;
const Message_Prop Message_Prop_Prop_MAX = Message_Prop_GLConstant;
const int Message_Prop_Prop_ARRAYSIZE = Message_Prop_Prop_MAX + 1;
// ===================================================================
@ -544,6 +545,7 @@ class Message : public ::google::protobuf::MessageLite {
static const Prop TimeMode = Message_Prop_TimeMode;
static const Prop ExpectResponse = Message_Prop_ExpectResponse;
static const Prop CaptureSwap = Message_Prop_CaptureSwap;
static const Prop GLConstant = Message_Prop_GLConstant;
static inline bool Prop_IsValid(int value) {
return Message_Prop_IsValid(value);
}

View File

@ -159,8 +159,17 @@ 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);
@ -176,7 +185,6 @@ float Send(const glesv2debugger::Message & msg, glesv2debugger::Message & cmd)
Die("MAX_FILE_SIZE reached");
}
}
pthread_mutex_unlock(&mutex);
return 0;
}
int sent = -1;
@ -192,7 +200,11 @@ float Send(const glesv2debugger::Message & msg, glesv2debugger::Message & cmd)
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 and other commands anytime
if (!msg.expect_response()) {
@ -204,8 +216,6 @@ float Send(const glesv2debugger::Message & msg, glesv2debugger::Message & cmd)
}
} else
Receive(cmd);
pthread_mutex_unlock(&mutex);
return t;
}

View File

@ -60,10 +60,14 @@ protected:
msg.ParseFromArray(buffer, len);
delete buffer;
}
void CheckNoAvailable() {
const long pos = ftell(file);
fseek(file, 0, SEEK_END);
EXPECT_EQ(pos, ftell(file)) << "check no available";
}
};
TEST_F(ServerFileTest, Send)
{
glesv2debugger::Message msg, cmd, read;
@ -81,6 +85,56 @@ TEST_F(ServerFileTest, Send)
EXPECT_EQ(msg.type(), read.type());
}
TEST_F(ServerFileTest, CreateDbgContext)
{
gl_hooks_t hooks;
struct Constant {
GLenum pname;
GLint param;
};
static const Constant constants [] = {
{GL_MAX_VERTEX_ATTRIBS, 16},
{GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, 32},
{GL_IMPLEMENTATION_COLOR_READ_FORMAT, GL_RGBA},
{GL_IMPLEMENTATION_COLOR_READ_TYPE, GL_UNSIGNED_BYTE},
};
struct HookMock {
static void GetIntegerv(GLenum pname, GLint* params) {
ASSERT_TRUE(params != NULL);
for (unsigned int i = 0; i < sizeof(constants) / sizeof(*constants); i++)
if (pname == constants[i].pname) {
*params = constants[i].param;
return;
}
FAIL() << "GetIntegerv unknown pname: " << pname;
}
static GLenum GetError() {
return GL_NO_ERROR;
}
};
hooks.gl.glGetError = HookMock::GetError;
hooks.gl.glGetIntegerv = HookMock::GetIntegerv;
DbgContext * const dbg = CreateDbgContext(-1, 1, &hooks);
ASSERT_TRUE(dbg != NULL);
EXPECT_TRUE(dbg->vertexAttribs != NULL);
rewind(file);
glesv2debugger::Message read;
for (unsigned int i = 0; i < 2; i++) {
Read(read);
EXPECT_EQ(reinterpret_cast<int>(dbg), read.context_id());
EXPECT_FALSE(read.expect_response());
EXPECT_EQ(read.Response, read.type());
EXPECT_EQ(read.SETPROP, read.function());
EXPECT_EQ(read.GLConstant, read.prop());
GLint expectedConstant = 0;
HookMock::GetIntegerv(read.arg0(), &expectedConstant);
EXPECT_EQ(expectedConstant, read.arg1());
}
CheckNoAvailable();
DestroyDbgContext(dbg);
}
void * glNoop()
{
return 0;

View File

@ -50,7 +50,7 @@ protected:
pthread_key_create(&dbgEGLThreadLocalStorageKey, NULL);
ASSERT_NE(-1, dbgEGLThreadLocalStorageKey);
tls.dbg = new DbgContext(1, &hooks, 32, GL_RGBA, GL_UNSIGNED_BYTE);
ASSERT_NE((void *)NULL, tls.dbg);
ASSERT_TRUE(tls.dbg != NULL);
pthread_setspecific(dbgEGLThreadLocalStorageKey, &tls);
for (unsigned int i = 0; i < sizeof(hooks) / sizeof(void *); i++)
((void **)&hooks)[i] = (void *)glNoop;
@ -95,7 +95,7 @@ protected:
if (len > bufferSize) {
bufferSize = len;
buffer = new char[bufferSize];
ASSERT_NE((char *)NULL, buffer);
ASSERT_TRUE(buffer != NULL);
}
ASSERT_EQ(len, recv(sock, buffer, len, 0));
msg.Clear();
@ -427,7 +427,7 @@ TEST_F(SocketContextTest, CopyTexImage2D)
EXPECT_EQ(_height, height);
EXPECT_EQ(GL_RGBA, format);
EXPECT_EQ(GL_UNSIGNED_BYTE, type);
ASSERT_NE((void *)NULL, pixels);
ASSERT_TRUE(pixels != NULL);
memcpy(pixels, _pixels, sizeof(_pixels));
readPixels++;
}