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 22 { 23 24 // The fixture for testing class Foo. 25 class DbgContextTest : public ::testing::Test 26 { 27 protected: 28 android::DbgContext dbg; 29 gl_hooks_t hooks; 30 31 DbgContextTest() 32 : dbg(1, &hooks, 32) { 33 // You can do set-up work for each test here. 34 hooks.gl.glGetError = GetError; 35 } 36 37 static GLenum GetError() { 38 return GL_NO_ERROR; 39 } 40 41 virtual ~DbgContextTest() { 42 // You can do clean-up work that doesn't throw exceptions here. 43 } 44 45 // If the constructor and destructor are not enough for setting up 46 // and cleaning up each test, you can define the following methods: 47 48 virtual void SetUp() { 49 // Code here will be called immediately after the constructor (right 50 // before each test). 51 } 52 53 virtual void TearDown() { 54 // Code here will be called immediately after each test (right 55 // before the destructor). 56 } 57 }; 58 59 TEST_F(DbgContextTest, GetReadPixelBuffer) 60 { 61 const unsigned int bufferSize = 512; 62 // test that it's allocating two buffers and swapping them 63 void * const buffer0 = dbg.GetReadPixelsBuffer(bufferSize); 64 ASSERT_NE((void *)NULL, buffer0); 65 for (unsigned int i = 0; i < bufferSize / sizeof(unsigned int); i++) { 66 EXPECT_EQ(0, ((unsigned int *)buffer0)[i]) 67 << "GetReadPixelsBuffer should allocate and zero"; 68 ((unsigned int *)buffer0)[i] = i * 13; 69 } 70 71 void * const buffer1 = dbg.GetReadPixelsBuffer(bufferSize); 72 ASSERT_NE((void *)NULL, buffer1); 73 EXPECT_NE(buffer0, buffer1); 74 for (unsigned int i = 0; i < bufferSize / sizeof(unsigned int); i++) { 75 EXPECT_EQ(0, ((unsigned int *)buffer1)[i]) 76 << "GetReadPixelsBuffer should allocate and zero"; 77 ((unsigned int *)buffer1)[i] = i * 17; 78 } 79 80 void * const buffer2 = dbg.GetReadPixelsBuffer(bufferSize); 81 EXPECT_EQ(buffer2, buffer0); 82 for (unsigned int i = 0; i < bufferSize / sizeof(unsigned int); i++) 83 EXPECT_EQ(i * 13, ((unsigned int *)buffer2)[i]) 84 << "GetReadPixelsBuffer should swap buffers"; 85 86 void * const buffer3 = dbg.GetReadPixelsBuffer(bufferSize); 87 EXPECT_EQ(buffer3, buffer1); 88 for (unsigned int i = 0; i < bufferSize / sizeof(unsigned int); i++) 89 EXPECT_EQ(i * 17, ((unsigned int *)buffer3)[i]) 90 << "GetReadPixelsBuffer should swap buffers"; 91 92 void * const buffer4 = dbg.GetReadPixelsBuffer(bufferSize); 93 EXPECT_NE(buffer3, buffer4); 94 EXPECT_EQ(buffer0, buffer2); 95 EXPECT_EQ(buffer1, buffer3); 96 EXPECT_EQ(buffer2, buffer4); 97 98 // it reallocs as necessary; 0 size may result in NULL 99 for (unsigned int i = 0; i < 42; i++) { 100 void * const buffer = dbg.GetReadPixelsBuffer(((i & 7)) << 20); 101 EXPECT_NE((void *)NULL, buffer) 102 << "should be able to get a variety of reasonable sizes"; 103 EXPECT_TRUE(dbg.IsReadPixelBuffer(buffer)); 104 } 105 } 106 107 TEST_F(DbgContextTest, CompressReadPixelBuffer) 108 { 109 const unsigned int bufferSize = dbg.LZF_CHUNK_SIZE * 4 + 33; 110 std::string out; 111 unsigned char * buffer = (unsigned char *)dbg.GetReadPixelsBuffer(bufferSize); 112 for (unsigned int i = 0; i < bufferSize; i++) 113 buffer[i] = i * 13; 114 dbg.CompressReadPixelBuffer(&out); 115 uint32_t decompSize = 0; 116 ASSERT_LT(12, out.length()); // at least written chunk header 117 ASSERT_EQ(bufferSize, *(uint32_t *)out.data()) 118 << "total decompressed size should be as requested in GetReadPixelsBuffer"; 119 for (unsigned int i = 4; i < out.length();) { 120 const uint32_t outSize = *(uint32_t *)(out.data() + i); 121 i += 4; 122 const uint32_t inSize = *(uint32_t *)(out.data() + i); 123 i += 4; 124 if (inSize == 0) 125 i += outSize; // chunk not compressed 126 else 127 i += inSize; // skip the actual compressed chunk 128 decompSize += outSize; 129 } 130 ASSERT_EQ(bufferSize, decompSize); 131 decompSize = 0; 132 133 unsigned char * decomp = dbg.Decompress(out.data(), out.length(), &decompSize); 134 ASSERT_EQ(decompSize, bufferSize); 135 for (unsigned int i = 0; i < bufferSize; i++) 136 EXPECT_EQ((unsigned char)(i * 13), decomp[i]) << "xor with 0 ref is identity"; 137 free(decomp); 138 139 buffer = (unsigned char *)dbg.GetReadPixelsBuffer(bufferSize); 140 for (unsigned int i = 0; i < bufferSize; i++) 141 buffer[i] = i * 13; 142 out.clear(); 143 dbg.CompressReadPixelBuffer(&out); 144 decompSize = 0; 145 decomp = dbg.Decompress(out.data(), out.length(), &decompSize); 146 ASSERT_EQ(decompSize, bufferSize); 147 for (unsigned int i = 0; i < bufferSize; i++) 148 EXPECT_EQ(0, decomp[i]) << "xor with same ref is 0"; 149 free(decomp); 150 151 buffer = (unsigned char *)dbg.GetReadPixelsBuffer(bufferSize); 152 for (unsigned int i = 0; i < bufferSize; i++) 153 buffer[i] = i * 19; 154 out.clear(); 155 dbg.CompressReadPixelBuffer(&out); 156 decompSize = 0; 157 decomp = dbg.Decompress(out.data(), out.length(), &decompSize); 158 ASSERT_EQ(decompSize, bufferSize); 159 for (unsigned int i = 0; i < bufferSize; i++) 160 EXPECT_EQ((unsigned char)(i * 13) ^ (unsigned char)(i * 19), decomp[i]) 161 << "xor ref"; 162 free(decomp); 163 } 164 165 TEST_F(DbgContextTest, UseProgram) 166 { 167 static const GLuint _program = 74568; 168 static const struct Attribute { 169 const char * name; 170 GLint location; 171 GLint size; 172 GLenum type; 173 } _attributes [] = { 174 {"aaa", 2, 2, GL_FLOAT_VEC2}, 175 {"bb", 6, 2, GL_FLOAT_MAT2}, 176 {"c", 1, 1, GL_FLOAT}, 177 }; 178 static const unsigned int _attributeCount = sizeof(_attributes) / sizeof(*_attributes); 179 struct GL { 180 static void GetProgramiv(GLuint program, GLenum pname, GLint* params) { 181 EXPECT_EQ(_program, program); 182 ASSERT_NE((GLint *)NULL, params); 183 switch (pname) { 184 case GL_ACTIVE_ATTRIBUTES: 185 *params = _attributeCount; 186 return; 187 case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH: 188 *params = 4; // includes NULL terminator 189 return; 190 default: 191 ADD_FAILURE() << "not handled pname: " << pname; 192 } 193 } 194 195 static GLint GetAttribLocation(GLuint program, const GLchar* name) { 196 EXPECT_EQ(_program, program); 197 for (unsigned int i = 0; i < _attributeCount; i++) 198 if (!strcmp(name, _attributes[i].name)) 199 return _attributes[i].location; 200 ADD_FAILURE() << "unknown attribute name: " << name; 201 return -1; 202 } 203 204 static void GetActiveAttrib(GLuint program, GLuint index, GLsizei bufsize, 205 GLsizei* length, GLint* size, GLenum* type, GLchar* name) { 206 EXPECT_EQ(_program, program); 207 ASSERT_LT(index, _attributeCount); 208 const Attribute & att = _attributes[index]; 209 ASSERT_GE(bufsize, strlen(att.name) + 1); 210 ASSERT_NE((GLint *)NULL, size); 211 ASSERT_NE((GLenum *)NULL, type); 212 ASSERT_NE((GLchar *)NULL, name); 213 strcpy(name, att.name); 214 if (length) 215 *length = strlen(name) + 1; 216 *size = att.size; 217 *type = att.type; 218 } 219 }; 220 hooks.gl.glGetProgramiv = GL::GetProgramiv; 221 hooks.gl.glGetAttribLocation = GL::GetAttribLocation; 222 hooks.gl.glGetActiveAttrib = GL::GetActiveAttrib; 223 dbg.glUseProgram(_program); 224 EXPECT_EQ(10, dbg.maxAttrib); 225 dbg.glUseProgram(0); 226 EXPECT_EQ(0, dbg.maxAttrib); 227 } 228 } // namespace 229 230 int main(int argc, char **argv) 231 { 232 ::testing::InitGoogleTest(&argc, argv); 233 return RUN_ALL_TESTS(); 234 } 235