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 10namespace gpu { 11namespace gles2 { 12 13class 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 33const GLuint VertexArrayObjectManagerTest::kMaxAttribs; 34const GLuint VertexArrayObjectManagerTest::kClientSideArrayBuffer; 35const GLuint VertexArrayObjectManagerTest::kClientSideElementArrayBuffer; 36#endif 37 38TEST_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, ¶m)); 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, ¶m)); 51 EXPECT_EQ(0u, param); 52 EXPECT_TRUE(manager_->GetVertexAttrib( 53 ii, GL_VERTEX_ATTRIB_ARRAY_ENABLED, ¶m)); 54 EXPECT_EQ(0u, param); 55 EXPECT_TRUE(manager_->GetVertexAttrib( 56 ii, GL_VERTEX_ATTRIB_ARRAY_SIZE, ¶m)); 57 EXPECT_EQ(4u, param); 58 EXPECT_TRUE(manager_->GetVertexAttrib( 59 ii, GL_VERTEX_ATTRIB_ARRAY_TYPE, ¶m)); 60 EXPECT_EQ(static_cast<uint32>(GL_FLOAT), param); 61 EXPECT_TRUE(manager_->GetVertexAttrib( 62 ii, GL_VERTEX_ATTRIB_ARRAY_NORMALIZED, ¶m)); 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 70TEST_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, ¶m)); 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 133TEST_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, ¶m)); 142 EXPECT_EQ(123u, param); 143 EXPECT_TRUE(manager_->GetVertexAttrib( 144 1, GL_VERTEX_ATTRIB_ARRAY_ENABLED, ¶m)); 145 EXPECT_NE(0u, param); 146 EXPECT_TRUE(manager_->GetVertexAttrib( 147 1, GL_VERTEX_ATTRIB_ARRAY_SIZE, ¶m)); 148 EXPECT_EQ(3u, param); 149 EXPECT_TRUE(manager_->GetVertexAttrib( 150 1, GL_VERTEX_ATTRIB_ARRAY_TYPE, ¶m)); 151 EXPECT_EQ(static_cast<uint32>(GL_BYTE), param); 152 EXPECT_TRUE(manager_->GetVertexAttrib( 153 1, GL_VERTEX_ATTRIB_ARRAY_NORMALIZED, ¶m)); 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, ¶m)); 164} 165 166TEST_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 185TEST_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 221TEST_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 252TEST_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