1 /* 2 ** Copyright 2011, The Android Open Source Project 3 ** 4 ** Licensed under the Apache License, Version 2.0 (the "License"); 5 ** you may not use this file except in compliance with the License. 6 ** You may obtain a copy of the License at 7 ** 8 ** http://www.apache.org/licenses/LICENSE-2.0 9 ** 10 ** Unless required by applicable law or agreed to in writing, software 11 ** distributed under the License is distributed on an "AS IS" BASIS, 12 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 ** See the License for the specific language governing permissions and 14 ** limitations under the License. 15 */ 16 17 #include "header.h" 18 #include "gtest/gtest.h" 19 #include "hooks.h" 20 21 namespace android 22 { 23 extern FILE * file; 24 extern unsigned int MAX_FILE_SIZE; 25 }; 26 27 // tmpfile fails, so need to manually make a writable file first 28 static const char * filePath = "/data/local/tmp/dump.gles2dbg"; 29 30 class ServerFileTest : public ::testing::Test 31 { 32 protected: 33 ServerFileTest() { } 34 35 virtual ~ServerFileTest() { } 36 37 virtual void SetUp() { 38 MAX_FILE_SIZE = 8 << 20; 39 ASSERT_EQ((FILE *)NULL, file); 40 file = fopen("/data/local/tmp/dump.gles2dbg", "wb+"); 41 ASSERT_NE((FILE *)NULL, file) << "make sure file is writable: " 42 << filePath; 43 } 44 45 virtual void TearDown() { 46 ASSERT_NE((FILE *)NULL, file); 47 fclose(file); 48 file = NULL; 49 } 50 51 void Read(glesv2debugger::Message & msg) const { 52 msg.Clear(); 53 uint32_t len = 0; 54 ASSERT_EQ(sizeof(len), fread(&len, 1, sizeof(len), file)); 55 ASSERT_GT(len, 0u); 56 char * buffer = new char [len]; 57 ASSERT_EQ(len, fread(buffer, 1, len, file)); 58 msg.ParseFromArray(buffer, len); 59 delete buffer; 60 } 61 62 void CheckNoAvailable() { 63 const long pos = ftell(file); 64 fseek(file, 0, SEEK_END); 65 EXPECT_EQ(pos, ftell(file)) << "check no available"; 66 } 67 }; 68 69 TEST_F(ServerFileTest, Send) 70 { 71 glesv2debugger::Message msg, cmd, read; 72 msg.set_context_id(1); 73 msg.set_function(msg.glFinish); 74 msg.set_expect_response(false); 75 msg.set_type(msg.BeforeCall); 76 rewind(file); 77 android::Send(msg, cmd); 78 rewind(file); 79 Read(read); 80 EXPECT_EQ(msg.context_id(), read.context_id()); 81 EXPECT_EQ(msg.function(), read.function()); 82 EXPECT_EQ(msg.expect_response(), read.expect_response()); 83 EXPECT_EQ(msg.type(), read.type()); 84 } 85 86 TEST_F(ServerFileTest, CreateDbgContext) 87 { 88 gl_hooks_t hooks; 89 struct Constant { 90 GLenum pname; 91 GLint param; 92 }; 93 static const Constant constants [] = { 94 {GL_MAX_VERTEX_ATTRIBS, 16}, 95 {GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, 32}, 96 {GL_IMPLEMENTATION_COLOR_READ_FORMAT, GL_RGBA}, 97 {GL_IMPLEMENTATION_COLOR_READ_TYPE, GL_UNSIGNED_BYTE}, 98 }; 99 struct HookMock { 100 static void GetIntegerv(GLenum pname, GLint* params) { 101 ASSERT_TRUE(params != NULL); 102 for (unsigned int i = 0; i < sizeof(constants) / sizeof(*constants); i++) 103 if (pname == constants[i].pname) { 104 *params = constants[i].param; 105 return; 106 } 107 FAIL() << "GetIntegerv unknown pname: " << pname; 108 } 109 static GLenum GetError() { 110 return GL_NO_ERROR; 111 } 112 }; 113 hooks.gl.glGetError = HookMock::GetError; 114 hooks.gl.glGetIntegerv = HookMock::GetIntegerv; 115 DbgContext * const dbg = CreateDbgContext(1, &hooks); 116 ASSERT_TRUE(dbg != NULL); 117 EXPECT_TRUE(dbg->vertexAttribs != NULL); 118 119 rewind(file); 120 glesv2debugger::Message read; 121 for (unsigned int i = 0; i < 2; i++) { 122 Read(read); 123 EXPECT_EQ(reinterpret_cast<int>(dbg), read.context_id()); 124 EXPECT_FALSE(read.expect_response()); 125 EXPECT_EQ(read.Response, read.type()); 126 EXPECT_EQ(read.SETPROP, read.function()); 127 EXPECT_EQ(read.GLConstant, read.prop()); 128 GLint expectedConstant = 0; 129 HookMock::GetIntegerv(read.arg0(), &expectedConstant); 130 EXPECT_EQ(expectedConstant, read.arg1()); 131 } 132 CheckNoAvailable(); 133 dbgReleaseThread(); 134 } 135 136 void * glNoop() 137 { 138 return 0; 139 } 140 141 class ServerFileContextTest : public ServerFileTest 142 { 143 protected: 144 DbgContext* dbg; 145 gl_hooks_t hooks; 146 147 ServerFileContextTest() { } 148 149 virtual ~ServerFileContextTest() { } 150 151 virtual void SetUp() { 152 ServerFileTest::SetUp(); 153 154 dbg = new DbgContext(1, &hooks, 32); 155 ASSERT_NE((void *)NULL, dbg); 156 for (unsigned int i = 0; i < sizeof(hooks) / sizeof(void *); i++) 157 ((void **)&hooks)[i] = reinterpret_cast<void *>(glNoop); 158 } 159 160 virtual void TearDown() { 161 ServerFileTest::TearDown(); 162 } 163 }; 164 165 TEST_F(ServerFileContextTest, MessageLoop) 166 { 167 static const int arg0 = 45; 168 static const float arg7 = -87.2331f; 169 static const int arg8 = -3; 170 static const int * ret = reinterpret_cast<int *>(870); 171 172 struct Caller : public FunctionCall { 173 const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) { 174 msg.set_arg0(arg0); 175 msg.set_arg7((int &)arg7); 176 msg.set_arg8(arg8); 177 return ret; 178 } 179 } caller; 180 const int contextId = reinterpret_cast<int>(dbg); 181 glesv2debugger::Message msg, read; 182 183 EXPECT_EQ(ret, MessageLoop(caller, msg, msg.glFinish)); 184 185 rewind(file); 186 Read(read); 187 EXPECT_EQ(contextId, read.context_id()); 188 EXPECT_EQ(read.glFinish, read.function()); 189 EXPECT_EQ(false, read.expect_response()); 190 EXPECT_EQ(read.BeforeCall, read.type()); 191 192 Read(read); 193 EXPECT_EQ(contextId, read.context_id()); 194 EXPECT_EQ(read.glFinish, read.function()); 195 EXPECT_EQ(false, read.expect_response()); 196 EXPECT_EQ(read.AfterCall, read.type()); 197 EXPECT_TRUE(read.has_time()); 198 EXPECT_EQ(arg0, read.arg0()); 199 const int readArg7 = read.arg7(); 200 EXPECT_EQ(arg7, (float &)readArg7); 201 EXPECT_EQ(arg8, read.arg8()); 202 203 const long pos = ftell(file); 204 fseek(file, 0, SEEK_END); 205 EXPECT_EQ(pos, ftell(file)) 206 << "should only write the BeforeCall and AfterCall messages"; 207 } 208 209 TEST_F(ServerFileContextTest, DisableEnableVertexAttribArray) 210 { 211 Debug_glEnableVertexAttribArray(dbg->MAX_VERTEX_ATTRIBS + 2); // should just ignore invalid index 212 213 glesv2debugger::Message read; 214 rewind(file); 215 Read(read); 216 EXPECT_EQ(read.glEnableVertexAttribArray, read.function()); 217 EXPECT_EQ(dbg->MAX_VERTEX_ATTRIBS + 2, read.arg0()); 218 Read(read); 219 220 rewind(file); 221 Debug_glDisableVertexAttribArray(dbg->MAX_VERTEX_ATTRIBS + 4); // should just ignore invalid index 222 rewind(file); 223 Read(read); 224 Read(read); 225 226 for (unsigned int i = 0; i < dbg->MAX_VERTEX_ATTRIBS; i += 5) { 227 rewind(file); 228 Debug_glEnableVertexAttribArray(i); 229 EXPECT_TRUE(dbg->vertexAttribs[i].enabled); 230 rewind(file); 231 Read(read); 232 EXPECT_EQ(read.glEnableVertexAttribArray, read.function()); 233 EXPECT_EQ(i, read.arg0()); 234 Read(read); 235 236 rewind(file); 237 Debug_glDisableVertexAttribArray(i); 238 EXPECT_FALSE(dbg->vertexAttribs[i].enabled); 239 rewind(file); 240 Read(read); 241 EXPECT_EQ(read.glDisableVertexAttribArray, read.function()); 242 EXPECT_EQ(i, read.arg0()); 243 Read(read); 244 } 245 } 246