blob: 058bea4d6f48ec62b55df2172ebe17fa51e3c7a5 [file] [log] [blame]
David Lie9f619f2011-04-14 11:20:22 -07001/*
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
21namespace
22{
23
24// The fixture for testing class Foo.
25class DbgContextTest : public ::testing::Test
26{
27protected:
28 android::DbgContext dbg;
29 gl_hooks_t hooks;
30
31 DbgContextTest()
32 : dbg(1, &hooks, 32, GL_RGBA, GL_UNSIGNED_BYTE) {
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
59TEST_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
107TEST_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
165TEST_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
230int main(int argc, char **argv)
231{
232 ::testing::InitGoogleTest(&argc, argv);
233 return RUN_ALL_TESTS();
234}