Home | History | Annotate | Download | only in client
      1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "gpu/command_buffer/client/vertex_array_object_manager.h"
      6 
      7 #include <GLES2/gl2ext.h>
      8 #include "testing/gtest/include/gtest/gtest.h"
      9 
     10 namespace gpu {
     11 namespace gles2 {
     12 
     13 class VertexArrayObjectManagerTest : public testing::Test {
     14  protected:
     15   static const GLuint kMaxAttribs = 4;
     16   static const GLuint kClientSideArrayBuffer = 0x1234;
     17   static const GLuint kClientSideElementArrayBuffer = 0x1235;
     18 
     19   virtual void SetUp() {
     20     manager_.reset(new VertexArrayObjectManager(
     21         kMaxAttribs,
     22         kClientSideArrayBuffer,
     23         kClientSideElementArrayBuffer));
     24   }
     25   virtual void TearDown() {
     26   }
     27 
     28   scoped_ptr<VertexArrayObjectManager> manager_;
     29 };
     30 
     31 // GCC requires these declarations, but MSVC requires they not be present
     32 #ifndef _MSC_VER
     33 const GLuint VertexArrayObjectManagerTest::kMaxAttribs;
     34 const GLuint VertexArrayObjectManagerTest::kClientSideArrayBuffer;
     35 const GLuint VertexArrayObjectManagerTest::kClientSideElementArrayBuffer;
     36 #endif
     37 
     38 TEST_F(VertexArrayObjectManagerTest, Basic) {
     39   EXPECT_FALSE(manager_->HaveEnabledClientSideBuffers());
     40   // Check out of bounds access.
     41   uint32 param;
     42   void* ptr;
     43   EXPECT_FALSE(manager_->GetVertexAttrib(
     44       kMaxAttribs, GL_VERTEX_ATTRIB_ARRAY_ENABLED, &param));
     45   EXPECT_FALSE(manager_->GetAttribPointer(
     46       kMaxAttribs, GL_VERTEX_ATTRIB_ARRAY_POINTER, &ptr));
     47   // Check defaults.
     48   for (GLuint ii = 0; ii < kMaxAttribs; ++ii) {
     49     EXPECT_TRUE(manager_->GetVertexAttrib(
     50         ii, GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING, &param));
     51     EXPECT_EQ(0u, param);
     52     EXPECT_TRUE(manager_->GetVertexAttrib(
     53         ii, GL_VERTEX_ATTRIB_ARRAY_ENABLED, &param));
     54     EXPECT_EQ(0u, param);
     55     EXPECT_TRUE(manager_->GetVertexAttrib(
     56         ii, GL_VERTEX_ATTRIB_ARRAY_SIZE, &param));
     57     EXPECT_EQ(4u, param);
     58     EXPECT_TRUE(manager_->GetVertexAttrib(
     59         ii, GL_VERTEX_ATTRIB_ARRAY_TYPE, &param));
     60     EXPECT_EQ(static_cast<uint32>(GL_FLOAT), param);
     61     EXPECT_TRUE(manager_->GetVertexAttrib(
     62         ii, GL_VERTEX_ATTRIB_ARRAY_NORMALIZED, &param));
     63     EXPECT_EQ(0u, param);
     64     EXPECT_TRUE(manager_->GetAttribPointer(
     65         ii, GL_VERTEX_ATTRIB_ARRAY_POINTER, &ptr));
     66     EXPECT_TRUE(NULL == ptr);
     67   }
     68 }
     69 
     70 TEST_F(VertexArrayObjectManagerTest, UnbindBuffer) {
     71   const GLuint kBufferToUnbind = 123;
     72   const GLuint kBufferToRemain = 456;
     73   const GLuint kElementArray = 789;
     74   bool changed = false;
     75   GLuint ids[2] = { 1, 3, };
     76   manager_->GenVertexArrays(arraysize(ids), ids);
     77   // Bind buffers to attribs on 2 vaos.
     78   for (size_t ii = 0; ii < arraysize(ids); ++ii) {
     79     EXPECT_TRUE(manager_->BindVertexArray(ids[ii], &changed));
     80     EXPECT_TRUE(manager_->SetAttribPointer(
     81         kBufferToUnbind, 0, 4, GL_FLOAT, false, 0, 0));
     82     EXPECT_TRUE(manager_->SetAttribPointer(
     83         kBufferToRemain, 1, 4, GL_FLOAT, false, 0, 0));
     84     EXPECT_TRUE(manager_->SetAttribPointer(
     85         kBufferToUnbind, 2, 4, GL_FLOAT, false, 0, 0));
     86     EXPECT_TRUE(manager_->SetAttribPointer(
     87         kBufferToRemain, 3, 4, GL_FLOAT, false, 0, 0));
     88     for (size_t jj = 0; jj < 4u; ++jj) {
     89       manager_->SetAttribEnable(jj, true);
     90     }
     91     manager_->BindElementArray(kElementArray);
     92   }
     93   EXPECT_FALSE(manager_->HaveEnabledClientSideBuffers());
     94   EXPECT_TRUE(manager_->BindVertexArray(ids[0], &changed));
     95   // Unbind the buffer.
     96   manager_->UnbindBuffer(kBufferToUnbind);
     97   manager_->UnbindBuffer(kElementArray);
     98   // The attribs are still enabled but their buffer is 0.
     99   EXPECT_TRUE(manager_->HaveEnabledClientSideBuffers());
    100   // Check the status of the bindings.
    101   static const uint32 expected[][4] = {
    102     { 0, kBufferToRemain, 0, kBufferToRemain, },
    103     { kBufferToUnbind, kBufferToRemain, kBufferToUnbind, kBufferToRemain, },
    104   };
    105   static const GLuint expected_element_array[] = {
    106     0, kElementArray,
    107   };
    108   for (size_t ii = 0; ii < arraysize(ids); ++ii) {
    109     EXPECT_TRUE(manager_->BindVertexArray(ids[ii], &changed));
    110     for (size_t jj = 0; jj < 4; ++jj) {
    111       uint32 param = 1;
    112       EXPECT_TRUE(manager_->GetVertexAttrib(
    113           jj, GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING, &param));
    114       EXPECT_EQ(expected[ii][jj], param)
    115           << "id: " << ids[ii] << ", attrib: " << jj;
    116     }
    117     EXPECT_EQ(expected_element_array[ii],
    118               manager_->bound_element_array_buffer());
    119   }
    120 
    121   // The vao that was not bound still has all service side bufferws.
    122   EXPECT_FALSE(manager_->HaveEnabledClientSideBuffers());
    123 
    124   // Make sure unbinding 0 does not effect count incorrectly.
    125   EXPECT_TRUE(manager_->BindVertexArray(0, &changed));
    126   EXPECT_FALSE(manager_->HaveEnabledClientSideBuffers());
    127   manager_->SetAttribEnable(2, true);
    128   manager_->UnbindBuffer(0);
    129   manager_->SetAttribEnable(2, false);
    130   EXPECT_FALSE(manager_->HaveEnabledClientSideBuffers());
    131 }
    132 
    133 TEST_F(VertexArrayObjectManagerTest, GetSet) {
    134   const char* dummy = "dummy";
    135   const void* p = reinterpret_cast<const void*>(dummy);
    136   manager_->SetAttribEnable(1, true);
    137   manager_->SetAttribPointer(123, 1, 3, GL_BYTE, true, 3, p);
    138   uint32 param;
    139   void* ptr;
    140   EXPECT_TRUE(manager_->GetVertexAttrib(
    141       1, GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING, &param));
    142   EXPECT_EQ(123u, param);
    143   EXPECT_TRUE(manager_->GetVertexAttrib(
    144       1, GL_VERTEX_ATTRIB_ARRAY_ENABLED, &param));
    145   EXPECT_NE(0u, param);
    146   EXPECT_TRUE(manager_->GetVertexAttrib(
    147       1, GL_VERTEX_ATTRIB_ARRAY_SIZE, &param));
    148   EXPECT_EQ(3u, param);
    149   EXPECT_TRUE(manager_->GetVertexAttrib(
    150       1, GL_VERTEX_ATTRIB_ARRAY_TYPE, &param));
    151   EXPECT_EQ(static_cast<uint32>(GL_BYTE), param);
    152   EXPECT_TRUE(manager_->GetVertexAttrib(
    153       1, GL_VERTEX_ATTRIB_ARRAY_NORMALIZED, &param));
    154   EXPECT_NE(0u, param);
    155   EXPECT_TRUE(manager_->GetAttribPointer(
    156       1, GL_VERTEX_ATTRIB_ARRAY_POINTER, &ptr));
    157   EXPECT_EQ(p, ptr);
    158 
    159   // Check that getting the divisor is passed to the service.
    160   // This is because the divisor is an optional feature which
    161   // only the service can validate.
    162   EXPECT_FALSE(manager_->GetVertexAttrib(
    163       0, GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE, &param));
    164 }
    165 
    166 TEST_F(VertexArrayObjectManagerTest, HaveEnabledClientSideArrays) {
    167   // Check turning on an array.
    168   manager_->SetAttribEnable(1, true);
    169   EXPECT_TRUE(manager_->HaveEnabledClientSideBuffers());
    170   // Check turning off an array.
    171   manager_->SetAttribEnable(1, false);
    172   EXPECT_FALSE(manager_->HaveEnabledClientSideBuffers());
    173   // Check turning on an array and assigning a buffer.
    174   manager_->SetAttribEnable(1, true);
    175   manager_->SetAttribPointer(123, 1, 3, GL_BYTE, true, 3, NULL);
    176   EXPECT_FALSE(manager_->HaveEnabledClientSideBuffers());
    177   // Check unassigning a buffer.
    178   manager_->SetAttribPointer(0, 1, 3, GL_BYTE, true, 3, NULL);
    179   EXPECT_TRUE(manager_->HaveEnabledClientSideBuffers());
    180   // Check disabling the array.
    181   manager_->SetAttribEnable(1, false);
    182   EXPECT_FALSE(manager_->HaveEnabledClientSideBuffers());
    183 }
    184 
    185 TEST_F(VertexArrayObjectManagerTest, BindElementArray) {
    186   bool changed = false;
    187   GLuint ids[2] = { 1, 3, };
    188   manager_->GenVertexArrays(arraysize(ids), ids);
    189 
    190   // Check the default element array is 0.
    191   EXPECT_EQ(0u, manager_->bound_element_array_buffer());
    192   // Check binding the same array does not need a service call.
    193   EXPECT_FALSE(manager_->BindElementArray(0u));
    194   // Check binding a new element array requires a service call.
    195   EXPECT_TRUE(manager_->BindElementArray(55u));
    196   // Check the element array was bound.
    197   EXPECT_EQ(55u, manager_->bound_element_array_buffer());
    198   // Check binding the same array does not need a service call.
    199   EXPECT_FALSE(manager_->BindElementArray(55u));
    200 
    201   // Check with a new vao.
    202   EXPECT_TRUE(manager_->BindVertexArray(1, &changed));
    203   // Check the default element array is 0.
    204   EXPECT_EQ(0u, manager_->bound_element_array_buffer());
    205   // Check binding a new element array requires a service call.
    206   EXPECT_TRUE(manager_->BindElementArray(11u));
    207   // Check the element array was bound.
    208   EXPECT_EQ(11u, manager_->bound_element_array_buffer());
    209   // Check binding the same array does not need a service call.
    210   EXPECT_FALSE(manager_->BindElementArray(11u));
    211 
    212   // check switching vao bindings returns the correct element array.
    213   EXPECT_TRUE(manager_->BindVertexArray(3, &changed));
    214   EXPECT_EQ(0u, manager_->bound_element_array_buffer());
    215   EXPECT_TRUE(manager_->BindVertexArray(0, &changed));
    216   EXPECT_EQ(55u, manager_->bound_element_array_buffer());
    217   EXPECT_TRUE(manager_->BindVertexArray(1, &changed));
    218   EXPECT_EQ(11u, manager_->bound_element_array_buffer());
    219 }
    220 
    221 TEST_F(VertexArrayObjectManagerTest, GenBindDelete) {
    222   // Check unknown array fails.
    223   bool changed = false;
    224   EXPECT_FALSE(manager_->BindVertexArray(123, &changed));
    225   EXPECT_FALSE(changed);
    226 
    227   GLuint ids[2] = { 1, 3, };
    228   manager_->GenVertexArrays(arraysize(ids), ids);
    229   // Check Genned arrays succeed.
    230   EXPECT_TRUE(manager_->BindVertexArray(1, &changed));
    231   EXPECT_TRUE(changed);
    232   EXPECT_TRUE(manager_->BindVertexArray(3, &changed));
    233   EXPECT_TRUE(changed);
    234 
    235   // Check binding the same array returns changed as false.
    236   EXPECT_TRUE(manager_->BindVertexArray(3, &changed));
    237   EXPECT_FALSE(changed);
    238 
    239   // Check deleted ararys fail to bind
    240   manager_->DeleteVertexArrays(2, ids);
    241   EXPECT_FALSE(manager_->BindVertexArray(1, &changed));
    242   EXPECT_FALSE(changed);
    243   EXPECT_FALSE(manager_->BindVertexArray(3, &changed));
    244   EXPECT_FALSE(changed);
    245 
    246   // Check binding 0 returns changed as false since it's
    247   // already bound.
    248   EXPECT_TRUE(manager_->BindVertexArray(0, &changed));
    249   EXPECT_FALSE(changed);
    250 }
    251 
    252 TEST_F(VertexArrayObjectManagerTest, IsReservedId) {
    253   EXPECT_TRUE(manager_->IsReservedId(kClientSideArrayBuffer));
    254   EXPECT_TRUE(manager_->IsReservedId(kClientSideElementArrayBuffer));
    255   EXPECT_FALSE(manager_->IsReservedId(0));
    256   EXPECT_FALSE(manager_->IsReservedId(1));
    257   EXPECT_FALSE(manager_->IsReservedId(2));
    258 }
    259 
    260 }  // namespace gles2
    261 }  // namespace gpu
    262 
    263