| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 // Tests for the Command Buffer Helper. | 5 // Tests for the Command Buffer Helper. |
| 6 | 6 |
| 7 #include "gpu/command_buffer/client/gles2_implementation.h" | 7 #include "gpu/command_buffer/client/gles2_implementation.h" |
| 8 | 8 |
| 9 #include <GLES2/gl2ext.h> | 9 #include <GLES2/gl2ext.h> |
| 10 #include "gpu/command_buffer/common/command_buffer.h" | 10 #include "gpu/command_buffer/common/command_buffer.h" |
| (...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 124 MOCK_METHOD1(OnFlush, void(void* result)); | 124 MOCK_METHOD1(OnFlush, void(void* result)); |
| 125 }; | 125 }; |
| 126 | 126 |
| 127 // GCC requires these declarations, but MSVC requires they not be present | 127 // GCC requires these declarations, but MSVC requires they not be present |
| 128 #ifndef _MSC_VER | 128 #ifndef _MSC_VER |
| 129 const int32 GLES2MockCommandBufferHelper::kTransferBufferId; | 129 const int32 GLES2MockCommandBufferHelper::kTransferBufferId; |
| 130 #endif | 130 #endif |
| 131 | 131 |
| 132 namespace gles2 { | 132 namespace gles2 { |
| 133 | 133 |
| 134 using testing::Return; |
| 135 using testing::Mock; |
| 136 using testing::Truly; |
| 137 using testing::Sequence; |
| 138 using testing::DoAll; |
| 139 using testing::Invoke; |
| 134 using testing::_; | 140 using testing::_; |
| 135 using testing::DoAll; | |
| 136 using testing::InSequence; | |
| 137 using testing::Invoke; | |
| 138 using testing::Mock; | |
| 139 using testing::Sequence; | |
| 140 using testing::Truly; | |
| 141 using testing::Return; | |
| 142 | 141 |
| 143 ACTION_P(SetMemory, obj) { | 142 ACTION_P(SetMemory, obj) { |
| 144 memcpy(arg0, &obj, sizeof(obj)); | 143 memcpy(arg0, &obj, sizeof(obj)); |
| 145 } | 144 } |
| 146 | 145 |
| 147 ACTION_P2(SetMemoryAtOffset, offset, obj) { | 146 ACTION_P2(SetMemoryAtOffset, offset, obj) { |
| 148 memcpy(static_cast<char*>(arg0) + offset, &obj, sizeof(obj)); | 147 memcpy(static_cast<char*>(arg0) + offset, &obj, sizeof(obj)); |
| 149 } | 148 } |
| 150 | 149 |
| 151 ACTION_P3(SetMemoryAtOffsetFromArray, offset, array, size) { | 150 ACTION_P3(SetMemoryAtOffsetFromArray, offset, array, size) { |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 203 static const GLint kMaxFragmentUniformVectors = 16; | 202 static const GLint kMaxFragmentUniformVectors = 16; |
| 204 static const GLint kMaxRenderbufferSize = 64; | 203 static const GLint kMaxRenderbufferSize = 64; |
| 205 static const GLint kMaxTextureImageUnits = 8; | 204 static const GLint kMaxTextureImageUnits = 8; |
| 206 static const GLint kMaxTextureSize = 128; | 205 static const GLint kMaxTextureSize = 128; |
| 207 static const GLint kMaxVaryingVectors = 8; | 206 static const GLint kMaxVaryingVectors = 8; |
| 208 static const GLint kMaxVertexAttribs = 8; | 207 static const GLint kMaxVertexAttribs = 8; |
| 209 static const GLint kMaxVertexTextureImageUnits = 0; | 208 static const GLint kMaxVertexTextureImageUnits = 0; |
| 210 static const GLint kMaxVertexUniformVectors = 128; | 209 static const GLint kMaxVertexUniformVectors = 128; |
| 211 static const GLint kNumCompressedTextureFormats = 0; | 210 static const GLint kNumCompressedTextureFormats = 0; |
| 212 static const GLint kNumShaderBinaryFormats = 0; | 211 static const GLint kNumShaderBinaryFormats = 0; |
| 213 static const GLuint kStartId = 1024; | |
| 214 | 212 |
| 215 GLES2ImplementationTest() | 213 GLES2ImplementationTest() |
| 216 : commands_(NULL), | 214 : commands_(NULL), |
| 217 token_(0), | 215 token_(0), |
| 218 offset_(0) { | 216 offset_(0) { |
| 219 } | 217 } |
| 220 | 218 |
| 221 virtual void SetUp() { | 219 virtual void SetUp() { |
| 222 Initialize(false, true); | |
| 223 } | |
| 224 | |
| 225 virtual void TearDown() { | |
| 226 } | |
| 227 | |
| 228 void Initialize(bool shared_resources, bool bind_generates_resource) { | |
| 229 offset_ = GLES2Implementation::kStartingOffset; | 220 offset_ = GLES2Implementation::kStartingOffset; |
| 230 | 221 |
| 231 command_buffer_.reset(new MockGLES2CommandBuffer()); | 222 command_buffer_.reset(new MockGLES2CommandBuffer()); |
| 232 command_buffer_->Initialize(kCommandBufferSizeBytes); | 223 command_buffer_->Initialize(kCommandBufferSizeBytes); |
| 233 | 224 |
| 234 EXPECT_EQ(kTransferBufferId, | 225 EXPECT_EQ(kTransferBufferId, |
| 235 command_buffer_->CreateTransferBuffer(kTransferBufferSize, -1)); | 226 command_buffer_->CreateTransferBuffer(kTransferBufferSize, -1)); |
| 236 transfer_buffer_ = command_buffer_->GetTransferBuffer(kTransferBufferId); | 227 transfer_buffer_ = command_buffer_->GetTransferBuffer(kTransferBufferId); |
| 237 ClearTransferBuffer(); | 228 ClearTransferBuffer(); |
| 238 | 229 |
| (...skipping 13 matching lines...) Expand all Loading... |
| 252 state.max_vertex_uniform_vectors = kMaxVertexUniformVectors; | 243 state.max_vertex_uniform_vectors = kMaxVertexUniformVectors; |
| 253 state.num_compressed_texture_formats = kNumCompressedTextureFormats; | 244 state.num_compressed_texture_formats = kNumCompressedTextureFormats; |
| 254 state.num_shader_binary_formats = kNumShaderBinaryFormats; | 245 state.num_shader_binary_formats = kNumShaderBinaryFormats; |
| 255 | 246 |
| 256 // This just happens to work for now because GLState has 1 GLint per | 247 // This just happens to work for now because GLState has 1 GLint per |
| 257 // state. If GLState gets more complicated this code will need to get | 248 // state. If GLState gets more complicated this code will need to get |
| 258 // more complicated. | 249 // more complicated. |
| 259 AllocateTransferBuffer(sizeof(state)); // in | 250 AllocateTransferBuffer(sizeof(state)); // in |
| 260 uint32 offset = AllocateTransferBuffer(sizeof(state)); // out | 251 uint32 offset = AllocateTransferBuffer(sizeof(state)); // out |
| 261 | 252 |
| 262 { | 253 EXPECT_CALL(*command_buffer_, OnFlush(_)) |
| 263 InSequence sequence; | 254 .WillOnce(SetMemoryAtOffset(offset, state)) |
| 255 .RetiresOnSaturation(); |
| 256 GetNextToken(); // eat the token that starting up will use. |
| 264 | 257 |
| 265 EXPECT_CALL(*command_buffer_, OnFlush(_)) | 258 gl_.reset(new GLES2Implementation( |
| 266 .WillOnce(SetMemoryAtOffset(offset, state)) | 259 helper_.get(), |
| 267 .RetiresOnSaturation(); | 260 kTransferBufferSize, |
| 268 GetNextToken(); // eat the token that starting up will use. | 261 transfer_buffer_.ptr, |
| 269 | 262 kTransferBufferId, |
| 270 // Must match StrictSharedIdHandler::kNumIdsToGet. | 263 false)); |
| 271 GLuint num_ids = 2048; | |
| 272 scoped_array<GLuint> all_ids(new GLuint[num_ids]); | |
| 273 if (shared_resources) { | |
| 274 if (!bind_generates_resource) { | |
| 275 GLuint start = kStartId; | |
| 276 GLuint max_num_per = MaxTransferBufferSize() / sizeof(GLuint); | |
| 277 GLuint* ids = all_ids.get(); | |
| 278 for (GLuint ii = 0; ii < num_ids; ++ii) { | |
| 279 ids[ii] = start + ii; | |
| 280 } | |
| 281 while (num_ids) { | |
| 282 GLuint num = std::min(num_ids, max_num_per); | |
| 283 size_t size = num * sizeof(ids[0]); | |
| 284 uint32 offset = AllocateTransferBuffer(size); | |
| 285 EXPECT_CALL(*command_buffer_, OnFlush(_)) | |
| 286 .WillOnce(SetMemoryAtOffsetFromArray(offset, ids, size)) | |
| 287 .RetiresOnSaturation(); | |
| 288 GetNextToken(); | |
| 289 start += num; | |
| 290 ids += num; | |
| 291 num_ids -= num; | |
| 292 } | |
| 293 } | |
| 294 } | |
| 295 | |
| 296 gl_.reset(new GLES2Implementation( | |
| 297 helper_.get(), | |
| 298 kTransferBufferSize, | |
| 299 transfer_buffer_.ptr, | |
| 300 kTransferBufferId, | |
| 301 shared_resources, | |
| 302 bind_generates_resource)); | |
| 303 } | |
| 304 | 264 |
| 305 EXPECT_CALL(*command_buffer_, OnFlush(_)) | 265 EXPECT_CALL(*command_buffer_, OnFlush(_)) |
| 306 .Times(1) | 266 .Times(1) |
| 307 .RetiresOnSaturation(); | 267 .RetiresOnSaturation(); |
| 308 helper_->CommandBufferHelper::Finish(); | 268 helper_->CommandBufferHelper::Finish(); |
| 309 Buffer ring_buffer = command_buffer_->GetRingBuffer(); | 269 Buffer ring_buffer = command_buffer_->GetRingBuffer(); |
| 310 commands_ = static_cast<CommandBufferEntry*>(ring_buffer.ptr) + | 270 commands_ = static_cast<CommandBufferEntry*>(ring_buffer.ptr) + |
| 311 command_buffer_->GetState().put_offset; | 271 command_buffer_->GetState().put_offset; |
| 312 ClearCommands(); | 272 ClearCommands(); |
| 313 } | 273 } |
| 314 | 274 |
| 275 virtual void TearDown() { |
| 276 } |
| 277 |
| 315 const void* GetPut() { | 278 const void* GetPut() { |
| 316 return helper_->GetSpace(0); | 279 return helper_->GetSpace(0); |
| 317 } | 280 } |
| 318 | 281 |
| 319 size_t MaxTransferBufferSize() { | 282 size_t MaxTransferBufferSize() { |
| 320 return kTransferBufferSize - GLES2Implementation::kStartingOffset; | 283 return kTransferBufferSize - GLES2Implementation::kStartingOffset; |
| 321 } | 284 } |
| 322 | 285 |
| 323 void ClearCommands() { | 286 void ClearCommands() { |
| 324 Buffer ring_buffer = command_buffer_->GetRingBuffer(); | 287 Buffer ring_buffer = command_buffer_->GetRingBuffer(); |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 365 Buffer transfer_buffer_; | 328 Buffer transfer_buffer_; |
| 366 CommandBufferEntry* commands_; | 329 CommandBufferEntry* commands_; |
| 367 scoped_ptr<MockGLES2CommandBuffer> command_buffer_; | 330 scoped_ptr<MockGLES2CommandBuffer> command_buffer_; |
| 368 scoped_ptr<GLES2CmdHelper> helper_; | 331 scoped_ptr<GLES2CmdHelper> helper_; |
| 369 Sequence sequence_; | 332 Sequence sequence_; |
| 370 scoped_ptr<GLES2Implementation> gl_; | 333 scoped_ptr<GLES2Implementation> gl_; |
| 371 int token_; | 334 int token_; |
| 372 uint32 offset_; | 335 uint32 offset_; |
| 373 }; | 336 }; |
| 374 | 337 |
| 375 class GLES2ImplementationStrictSharedTest : public GLES2ImplementationTest { | |
| 376 protected: | |
| 377 virtual void SetUp() { | |
| 378 Initialize(true, false); | |
| 379 } | |
| 380 }; | |
| 381 | |
| 382 // GCC requires these declarations, but MSVC requires they not be present | 338 // GCC requires these declarations, but MSVC requires they not be present |
| 383 #ifndef _MSC_VER | 339 #ifndef _MSC_VER |
| 384 const int32 GLES2ImplementationTest::kTransferBufferId; | 340 const int32 GLES2ImplementationTest::kTransferBufferId; |
| 385 #endif | 341 #endif |
| 386 | 342 |
| 387 | 343 |
| 388 TEST_F(GLES2ImplementationTest, ShaderSource) { | 344 TEST_F(GLES2ImplementationTest, ShaderSource) { |
| 389 const uint32 kBucketId = 1; // This id is hardcoded into GLES2Implemenation | 345 const uint32 kBucketId = 1; // This id is hardcoded into GLES2Implemenation |
| 390 const GLuint kShaderId = 456; | 346 const GLuint kShaderId = 456; |
| 391 const char* kString1 = "foobar"; | 347 const char* kString1 = "foobar"; |
| (...skipping 1332 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1724 gl_->TexImage2D( | 1680 gl_->TexImage2D( |
| 1725 kTarget, kLevel, kFormat, kWidth, kHeight, kBorder, kFormat, kType, | 1681 kTarget, kLevel, kFormat, kWidth, kHeight, kBorder, kFormat, kType, |
| 1726 pixels.get()); | 1682 pixels.get()); |
| 1727 EXPECT_EQ(0, memcmp(&expected, commands2, sizeof(expected))); | 1683 EXPECT_EQ(0, memcmp(&expected, commands2, sizeof(expected))); |
| 1728 EXPECT_TRUE(CheckRect( | 1684 EXPECT_TRUE(CheckRect( |
| 1729 kWidth / 2, 1, kFormat, kType, kPixelStoreUnpackAlignment, false, | 1685 kWidth / 2, 1, kFormat, kType, kPixelStoreUnpackAlignment, false, |
| 1730 pixels.get() + padded_row_size + part_size, | 1686 pixels.get() + padded_row_size + part_size, |
| 1731 GetTransferAddressFromOffsetAs<uint8>(offset4, part_size))); | 1687 GetTransferAddressFromOffsetAs<uint8>(offset4, part_size))); |
| 1732 } | 1688 } |
| 1733 | 1689 |
| 1734 // Test that GenBuffer does not call GenSharedIds. | |
| 1735 // This is because with client side arrays on we know the StrictSharedIdHandler | |
| 1736 // for buffers has already gotten a set of ids | |
| 1737 TEST_F(GLES2ImplementationStrictSharedTest, GenBuffer) { | |
| 1738 // Starts at + 2 because client side arrays take first 2 ids. | |
| 1739 GLuint ids[3] = { kStartId + 2, kStartId + 3, kStartId + 4 }; | |
| 1740 struct Cmds { | |
| 1741 GenBuffersImmediate gen; | |
| 1742 GLuint data[3]; | |
| 1743 }; | |
| 1744 Cmds expected; | |
| 1745 expected.gen.Init(arraysize(ids), &ids[0]); | |
| 1746 gl_->GenBuffers(arraysize(ids), &ids[0]); | |
| 1747 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); | |
| 1748 EXPECT_NE(0u, ids[0]); | |
| 1749 EXPECT_NE(0u, ids[1]); | |
| 1750 EXPECT_NE(0u, ids[2]); | |
| 1751 } | |
| 1752 | |
| 1753 // Binds can not be cached with bind_generates_resource = false because | |
| 1754 // our id might not be valid. | |
| 1755 TEST_F(GLES2ImplementationStrictSharedTest, BindsNotCached) { | |
| 1756 struct PNameValue { | |
| 1757 GLenum pname; | |
| 1758 GLint expected; | |
| 1759 }; | |
| 1760 const PNameValue pairs[] = { | |
| 1761 { GL_TEXTURE_BINDING_2D, 1, }, | |
| 1762 { GL_TEXTURE_BINDING_CUBE_MAP, 2, }, | |
| 1763 { GL_FRAMEBUFFER_BINDING, 3, }, | |
| 1764 { GL_RENDERBUFFER_BINDING, 4, }, | |
| 1765 { GL_ARRAY_BUFFER_BINDING, 5, }, | |
| 1766 { GL_ELEMENT_ARRAY_BUFFER_BINDING, 6, }, | |
| 1767 }; | |
| 1768 size_t num_pairs = sizeof(pairs) / sizeof(pairs[0]); | |
| 1769 for (size_t ii = 0; ii < num_pairs; ++ii) { | |
| 1770 const PNameValue& pv = pairs[ii]; | |
| 1771 GLint v = -1; | |
| 1772 EXPECT_CALL(*command_buffer_, OnFlush(_)) | |
| 1773 .WillOnce(SetMemory(SizedResultHelper<GLuint>(pv.expected))) | |
| 1774 .RetiresOnSaturation(); | |
| 1775 gl_->GetIntegerv(pv.pname, &v); | |
| 1776 EXPECT_EQ(pv.expected, v); | |
| 1777 } | |
| 1778 } | |
| 1779 | |
| 1780 TEST_F(GLES2ImplementationStrictSharedTest, CanNotDeleteIdsWeDidNotCreate) { | |
| 1781 GLuint id = 0x12345678; | |
| 1782 | |
| 1783 EXPECT_CALL(*command_buffer_, OnFlush(_)) | |
| 1784 .WillOnce(SetMemory(GLuint(GL_NO_ERROR))) | |
| 1785 .WillOnce(SetMemory(GLuint(GL_NO_ERROR))) | |
| 1786 .WillOnce(SetMemory(GLuint(GL_NO_ERROR))) | |
| 1787 .WillOnce(SetMemory(GLuint(GL_NO_ERROR))) | |
| 1788 .WillOnce(SetMemory(GLuint(GL_NO_ERROR))) | |
| 1789 .WillOnce(SetMemory(GLuint(GL_NO_ERROR))) | |
| 1790 .RetiresOnSaturation(); | |
| 1791 | |
| 1792 gl_->DeleteBuffers(1, &id); | |
| 1793 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE), gl_->GetError()); | |
| 1794 gl_->DeleteFramebuffers(1, &id); | |
| 1795 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE), gl_->GetError()); | |
| 1796 gl_->DeleteRenderbuffers(1, &id); | |
| 1797 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE), gl_->GetError()); | |
| 1798 gl_->DeleteTextures(1, &id); | |
| 1799 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE), gl_->GetError()); | |
| 1800 gl_->DeleteProgram(id); | |
| 1801 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE), gl_->GetError()); | |
| 1802 gl_->DeleteShader(id); | |
| 1803 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE), gl_->GetError()); | |
| 1804 } | |
| 1805 | |
| 1806 } // namespace gles2 | 1690 } // namespace gles2 |
| 1807 } // namespace gpu | 1691 } // namespace gpu |
| 1808 | 1692 |
| 1809 | 1693 |
| OLD | NEW |