Home | History | Annotate | Download | only in test
      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