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 170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
181 float w; | 181 float w; |
182 }; | 182 }; |
183 | 183 |
184 #pragma pack(push, 1) | 184 #pragma pack(push, 1) |
185 // Struct that holds 7 characters. | 185 // Struct that holds 7 characters. |
186 struct Str7 { | 186 struct Str7 { |
187 char str[7]; | 187 char str[7]; |
188 }; | 188 }; |
189 #pragma pack(pop) | 189 #pragma pack(pop) |
190 | 190 |
191 // Test fixture for CommandBufferHelper test. | 191 class GLES2CommandBufferTestBase : public testing::Test { |
192 class GLES2ImplementationTest : public testing::Test { | |
193 protected: | 192 protected: |
194 static const int32 kNumCommandEntries = 400; | 193 static const int32 kNumCommandEntries = 400; |
195 static const int32 kCommandBufferSizeBytes = | 194 static const int32 kCommandBufferSizeBytes = |
196 kNumCommandEntries * sizeof(CommandBufferEntry); | 195 kNumCommandEntries * sizeof(CommandBufferEntry); |
197 static const size_t kTransferBufferSize = 256; | 196 static const size_t kTransferBufferSize = 256; |
198 static const int32 kTransferBufferId = | 197 static const int32 kTransferBufferId = |
199 GLES2MockCommandBufferHelper::kTransferBufferId; | 198 GLES2MockCommandBufferHelper::kTransferBufferId; |
200 static const uint8 kInitialValue = 0xBD; | 199 static const uint8 kInitialValue = 0xBD; |
| 200 |
| 201 GLES2CommandBufferTestBase() |
| 202 : commands_(NULL), |
| 203 token_(0), |
| 204 offset_(0), |
| 205 initial_offset_(0), |
| 206 alignment_(0) { |
| 207 } |
| 208 |
| 209 void SetupCommandBuffer(unsigned int offset, unsigned alignment) { |
| 210 initial_offset_ = offset; |
| 211 offset_ = offset; |
| 212 alignment_ = alignment; |
| 213 |
| 214 command_buffer_.reset(new MockGLES2CommandBuffer()); |
| 215 command_buffer_->Initialize(kCommandBufferSizeBytes); |
| 216 |
| 217 EXPECT_EQ(kTransferBufferId, |
| 218 command_buffer_->CreateTransferBuffer(kTransferBufferSize, -1)); |
| 219 transfer_buffer_ = command_buffer_->GetTransferBuffer(kTransferBufferId); |
| 220 ClearTransferBuffer(); |
| 221 |
| 222 helper_.reset(new GLES2CmdHelper(command_buffer_.get())); |
| 223 helper_->Initialize(kCommandBufferSizeBytes); |
| 224 } |
| 225 |
| 226 const void* GetPut() { |
| 227 return helper_->GetSpace(0); |
| 228 } |
| 229 |
| 230 size_t MaxTransferBufferSize() { |
| 231 return kTransferBufferSize - initial_offset_; |
| 232 } |
| 233 |
| 234 void ClearCommands() { |
| 235 Buffer ring_buffer = command_buffer_->GetRingBuffer(); |
| 236 memset(ring_buffer.ptr, kInitialValue, ring_buffer.size); |
| 237 } |
| 238 |
| 239 bool NoCommandsWritten() { |
| 240 return static_cast<const uint8*>(static_cast<const void*>(commands_))[0] == |
| 241 kInitialValue; |
| 242 } |
| 243 |
| 244 void ClearTransferBuffer() { |
| 245 memset(transfer_buffer_.ptr, kInitialValue, kTransferBufferSize); |
| 246 } |
| 247 |
| 248 unsigned int RoundToAlignment(unsigned int size) { |
| 249 return (size + alignment_ - 1) & ~(alignment_ - 1); |
| 250 } |
| 251 |
| 252 int GetNextToken() { |
| 253 return ++token_; |
| 254 } |
| 255 |
| 256 uint32 AllocateTransferBuffer(size_t size) { |
| 257 if (offset_ + size > kTransferBufferSize) { |
| 258 offset_ = initial_offset_; |
| 259 } |
| 260 uint32 offset = offset_; |
| 261 offset_ += RoundToAlignment(size); |
| 262 return offset; |
| 263 } |
| 264 |
| 265 void* GetTransferAddressFromOffset(uint32 offset, size_t size) { |
| 266 EXPECT_LE(offset + size, transfer_buffer_.size); |
| 267 return static_cast<int8*>(transfer_buffer_.ptr) + offset; |
| 268 } |
| 269 |
| 270 template <typename T> |
| 271 T* GetTransferAddressFromOffsetAs(uint32 offset, size_t size) { |
| 272 return static_cast<T*>(GetTransferAddressFromOffset(offset, size)); |
| 273 } |
| 274 |
| 275 Buffer transfer_buffer_; |
| 276 CommandBufferEntry* commands_; |
| 277 scoped_ptr<MockGLES2CommandBuffer> command_buffer_; |
| 278 scoped_ptr<GLES2CmdHelper> helper_; |
| 279 int token_; |
| 280 uint32 offset_; |
| 281 uint32 initial_offset_; |
| 282 uint32 alignment_; |
| 283 }; |
| 284 |
| 285 // GCC requires these declarations, but MSVC requires they not be present |
| 286 #ifndef _MSC_VER |
| 287 const int32 GLES2CommandBufferTestBase::kNumCommandEntries; |
| 288 const int32 GLES2CommandBufferTestBase::kCommandBufferSizeBytes; |
| 289 const size_t GLES2CommandBufferTestBase::kTransferBufferSize; |
| 290 const int32 GLES2CommandBufferTestBase::kTransferBufferId; |
| 291 const uint8 GLES2CommandBufferTestBase::kInitialValue; |
| 292 #endif |
| 293 |
| 294 class TransferBufferTest : public GLES2CommandBufferTestBase { |
| 295 protected: |
| 296 static const unsigned int kStartingOffset = 64; |
| 297 static const unsigned int kAlignment = 4; |
| 298 |
| 299 TransferBufferTest() { } |
| 300 |
| 301 virtual void SetUp() { |
| 302 SetupCommandBuffer( |
| 303 GLES2Implementation::kStartingOffset, |
| 304 GLES2Implementation::kAlignment); |
| 305 |
| 306 transfer_buffer_.reset(new TransferBuffer( |
| 307 helper_.get(), |
| 308 kTransferBufferId, |
| 309 GetTransferAddressFromOffset(0, 0), |
| 310 kTransferBufferSize, |
| 311 kStartingOffset, |
| 312 kAlignment)); |
| 313 } |
| 314 |
| 315 virtual void TearDown() { |
| 316 transfer_buffer_.reset(); |
| 317 } |
| 318 |
| 319 scoped_ptr<TransferBuffer> transfer_buffer_; |
| 320 }; |
| 321 |
| 322 // GCC requires these declarations, but MSVC requires they not be present |
| 323 #ifndef _MSC_VER |
| 324 const unsigned int TransferBufferTest::kStartingOffset; |
| 325 const unsigned int TransferBufferTest::kAlignment; |
| 326 #endif |
| 327 |
| 328 TEST_F(TransferBufferTest, Basic) { |
| 329 EXPECT_TRUE(transfer_buffer_->HaveBuffer()); |
| 330 EXPECT_EQ(kTransferBufferId, transfer_buffer_->GetShmId()); |
| 331 } |
| 332 |
| 333 TEST_F(TransferBufferTest, Free) { |
| 334 EXPECT_TRUE(transfer_buffer_->HaveBuffer()); |
| 335 |
| 336 // Free buffer. |
| 337 EXPECT_CALL(*command_buffer_, DestroyTransferBuffer(_)) |
| 338 .Times(1) |
| 339 .RetiresOnSaturation(); |
| 340 transfer_buffer_->Free(); |
| 341 // See it's freed. |
| 342 EXPECT_FALSE(transfer_buffer_->HaveBuffer()); |
| 343 // See that it gets reallocated. |
| 344 EXPECT_EQ(kTransferBufferId, transfer_buffer_->GetShmId()); |
| 345 EXPECT_TRUE(transfer_buffer_->HaveBuffer()); |
| 346 |
| 347 // Free buffer. |
| 348 EXPECT_CALL(*command_buffer_, DestroyTransferBuffer(_)) |
| 349 .Times(1) |
| 350 .RetiresOnSaturation(); |
| 351 transfer_buffer_->Free(); |
| 352 // See it's freed. |
| 353 EXPECT_FALSE(transfer_buffer_->HaveBuffer()); |
| 354 // See that it gets reallocated. |
| 355 EXPECT_TRUE(transfer_buffer_->GetResultBuffer() != NULL); |
| 356 EXPECT_TRUE(transfer_buffer_->HaveBuffer()); |
| 357 |
| 358 // Free buffer. |
| 359 EXPECT_CALL(*command_buffer_, DestroyTransferBuffer(_)) |
| 360 .Times(1) |
| 361 .RetiresOnSaturation(); |
| 362 transfer_buffer_->Free(); |
| 363 // See it's freed. |
| 364 EXPECT_FALSE(transfer_buffer_->HaveBuffer()); |
| 365 // See that it gets reallocated. |
| 366 EXPECT_TRUE(transfer_buffer_->GetBuffer() != NULL); |
| 367 EXPECT_TRUE(transfer_buffer_->HaveBuffer()); |
| 368 |
| 369 // Free buffer. |
| 370 EXPECT_CALL(*command_buffer_, DestroyTransferBuffer(_)) |
| 371 .Times(1) |
| 372 .RetiresOnSaturation(); |
| 373 transfer_buffer_->Free(); |
| 374 // See it's freed. |
| 375 EXPECT_FALSE(transfer_buffer_->HaveBuffer()); |
| 376 // See that it gets reallocated. |
| 377 transfer_buffer_->GetResultOffset(); |
| 378 EXPECT_TRUE(transfer_buffer_->HaveBuffer()); |
| 379 |
| 380 // Test freeing twice. |
| 381 EXPECT_CALL(*command_buffer_, DestroyTransferBuffer(_)) |
| 382 .Times(1) |
| 383 .RetiresOnSaturation(); |
| 384 transfer_buffer_->Free(); |
| 385 transfer_buffer_->Free(); |
| 386 } |
| 387 |
| 388 class GLES2ImplementationTest : public GLES2CommandBufferTestBase { |
| 389 protected: |
201 static const GLint kMaxCombinedTextureImageUnits = 8; | 390 static const GLint kMaxCombinedTextureImageUnits = 8; |
202 static const GLint kMaxCubeMapTextureSize = 64; | 391 static const GLint kMaxCubeMapTextureSize = 64; |
203 static const GLint kMaxFragmentUniformVectors = 16; | 392 static const GLint kMaxFragmentUniformVectors = 16; |
204 static const GLint kMaxRenderbufferSize = 64; | 393 static const GLint kMaxRenderbufferSize = 64; |
205 static const GLint kMaxTextureImageUnits = 8; | 394 static const GLint kMaxTextureImageUnits = 8; |
206 static const GLint kMaxTextureSize = 128; | 395 static const GLint kMaxTextureSize = 128; |
207 static const GLint kMaxVaryingVectors = 8; | 396 static const GLint kMaxVaryingVectors = 8; |
208 static const GLint kMaxVertexAttribs = 8; | 397 static const GLint kMaxVertexAttribs = 8; |
209 static const GLint kMaxVertexTextureImageUnits = 0; | 398 static const GLint kMaxVertexTextureImageUnits = 0; |
210 static const GLint kMaxVertexUniformVectors = 128; | 399 static const GLint kMaxVertexUniformVectors = 128; |
211 static const GLint kNumCompressedTextureFormats = 0; | 400 static const GLint kNumCompressedTextureFormats = 0; |
212 static const GLint kNumShaderBinaryFormats = 0; | 401 static const GLint kNumShaderBinaryFormats = 0; |
213 static const GLuint kStartId = 1024; | 402 static const GLuint kStartId = 1024; |
214 | 403 |
215 GLES2ImplementationTest() | 404 GLES2ImplementationTest() { } |
216 : commands_(NULL), | |
217 token_(0), | |
218 offset_(0) { | |
219 } | |
220 | 405 |
221 virtual void SetUp() { | 406 virtual void SetUp() { |
222 Initialize(false, true); | 407 Initialize(false, true); |
223 } | 408 } |
224 | 409 |
225 virtual void TearDown() { | 410 virtual void TearDown() { |
226 } | 411 } |
227 | 412 |
228 void Initialize(bool shared_resources, bool bind_generates_resource) { | 413 void Initialize(bool shared_resources, bool bind_generates_resource) { |
229 offset_ = GLES2Implementation::kStartingOffset; | 414 SetupCommandBuffer( |
230 | 415 GLES2Implementation::kStartingOffset, |
231 command_buffer_.reset(new MockGLES2CommandBuffer()); | 416 GLES2Implementation::kAlignment); |
232 command_buffer_->Initialize(kCommandBufferSizeBytes); | |
233 | |
234 EXPECT_EQ(kTransferBufferId, | |
235 command_buffer_->CreateTransferBuffer(kTransferBufferSize, -1)); | |
236 transfer_buffer_ = command_buffer_->GetTransferBuffer(kTransferBufferId); | |
237 ClearTransferBuffer(); | |
238 | |
239 helper_.reset(new GLES2CmdHelper(command_buffer_.get())); | |
240 helper_->Initialize(kCommandBufferSizeBytes); | |
241 | 417 |
242 GLES2Implementation::GLState state; | 418 GLES2Implementation::GLState state; |
243 state.max_combined_texture_image_units = kMaxCombinedTextureImageUnits; | 419 state.max_combined_texture_image_units = kMaxCombinedTextureImageUnits; |
244 state.max_cube_map_texture_size = kMaxCubeMapTextureSize; | 420 state.max_cube_map_texture_size = kMaxCubeMapTextureSize; |
245 state.max_fragment_uniform_vectors = kMaxFragmentUniformVectors; | 421 state.max_fragment_uniform_vectors = kMaxFragmentUniformVectors; |
246 state.max_renderbuffer_size = kMaxRenderbufferSize; | 422 state.max_renderbuffer_size = kMaxRenderbufferSize; |
247 state.max_texture_image_units = kMaxTextureImageUnits; | 423 state.max_texture_image_units = kMaxTextureImageUnits; |
248 state.max_texture_size = kMaxTextureSize; | 424 state.max_texture_size = kMaxTextureSize; |
249 state.max_varying_vectors = kMaxVaryingVectors; | 425 state.max_varying_vectors = kMaxVaryingVectors; |
250 state.max_vertex_attribs = kMaxVertexAttribs; | 426 state.max_vertex_attribs = kMaxVertexAttribs; |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
305 EXPECT_CALL(*command_buffer_, OnFlush(_)) | 481 EXPECT_CALL(*command_buffer_, OnFlush(_)) |
306 .Times(1) | 482 .Times(1) |
307 .RetiresOnSaturation(); | 483 .RetiresOnSaturation(); |
308 helper_->CommandBufferHelper::Finish(); | 484 helper_->CommandBufferHelper::Finish(); |
309 Buffer ring_buffer = command_buffer_->GetRingBuffer(); | 485 Buffer ring_buffer = command_buffer_->GetRingBuffer(); |
310 commands_ = static_cast<CommandBufferEntry*>(ring_buffer.ptr) + | 486 commands_ = static_cast<CommandBufferEntry*>(ring_buffer.ptr) + |
311 command_buffer_->GetState().put_offset; | 487 command_buffer_->GetState().put_offset; |
312 ClearCommands(); | 488 ClearCommands(); |
313 } | 489 } |
314 | 490 |
315 const void* GetPut() { | |
316 return helper_->GetSpace(0); | |
317 } | |
318 | |
319 size_t MaxTransferBufferSize() { | |
320 return kTransferBufferSize - GLES2Implementation::kStartingOffset; | |
321 } | |
322 | |
323 void ClearCommands() { | |
324 Buffer ring_buffer = command_buffer_->GetRingBuffer(); | |
325 memset(ring_buffer.ptr, kInitialValue, ring_buffer.size); | |
326 } | |
327 | |
328 bool NoCommandsWritten() { | |
329 return static_cast<const uint8*>(static_cast<const void*>(commands_))[0] == | |
330 kInitialValue; | |
331 } | |
332 | |
333 void ClearTransferBuffer() { | |
334 memset(transfer_buffer_.ptr, kInitialValue, kTransferBufferSize); | |
335 } | |
336 | |
337 static unsigned int RoundToAlignment(unsigned int size) { | |
338 return (size + GLES2Implementation::kAlignment - 1) & | |
339 ~(GLES2Implementation::kAlignment - 1); | |
340 } | |
341 | |
342 int GetNextToken() { | |
343 return ++token_; | |
344 } | |
345 | |
346 uint32 AllocateTransferBuffer(size_t size) { | |
347 if (offset_ + size > kTransferBufferSize) { | |
348 offset_ = GLES2Implementation::kStartingOffset; | |
349 } | |
350 uint32 offset = offset_; | |
351 offset_ += RoundToAlignment(size); | |
352 return offset; | |
353 } | |
354 | |
355 void* GetTransferAddressFromOffset(uint32 offset, size_t size) { | |
356 EXPECT_LE(offset + size, transfer_buffer_.size); | |
357 return static_cast<int8*>(transfer_buffer_.ptr) + offset; | |
358 } | |
359 | |
360 template <typename T> | |
361 T* GetTransferAddressFromOffsetAs(uint32 offset, size_t size) { | |
362 return static_cast<T*>(GetTransferAddressFromOffset(offset, size)); | |
363 } | |
364 | |
365 Buffer transfer_buffer_; | |
366 CommandBufferEntry* commands_; | |
367 scoped_ptr<MockGLES2CommandBuffer> command_buffer_; | |
368 scoped_ptr<GLES2CmdHelper> helper_; | |
369 Sequence sequence_; | 491 Sequence sequence_; |
370 scoped_ptr<GLES2Implementation> gl_; | 492 scoped_ptr<GLES2Implementation> gl_; |
371 int token_; | |
372 uint32 offset_; | |
373 }; | 493 }; |
374 | 494 |
375 class GLES2ImplementationStrictSharedTest : public GLES2ImplementationTest { | 495 class GLES2ImplementationStrictSharedTest : public GLES2ImplementationTest { |
376 protected: | 496 protected: |
377 virtual void SetUp() { | 497 virtual void SetUp() { |
378 Initialize(true, false); | 498 Initialize(true, false); |
379 } | 499 } |
380 }; | 500 }; |
381 | 501 |
382 // GCC requires these declarations, but MSVC requires they not be present | |
383 #ifndef _MSC_VER | |
384 const int32 GLES2ImplementationTest::kTransferBufferId; | |
385 #endif | |
386 | |
387 TEST_F(GLES2ImplementationTest, ShaderSource) { | 502 TEST_F(GLES2ImplementationTest, ShaderSource) { |
388 const uint32 kBucketId = 1; // This id is hardcoded into GLES2Implemenation | 503 const uint32 kBucketId = 1; // This id is hardcoded into GLES2Implemenation |
389 const GLuint kShaderId = 456; | 504 const GLuint kShaderId = 456; |
390 const char* kString1 = "foobar"; | 505 const char* kString1 = "foobar"; |
391 const char* kString2 = "barfoo"; | 506 const char* kString2 = "barfoo"; |
392 const size_t kString1Size = strlen(kString1); | 507 const size_t kString1Size = strlen(kString1); |
393 const size_t kString2Size = strlen(kString2); | 508 const size_t kString2Size = strlen(kString2); |
394 const size_t kString3Size = 1; // Want the NULL; | 509 const size_t kString3Size = 1; // Want the NULL; |
395 const size_t kSourceSize = kString1Size + kString2Size + kString3Size; | 510 const size_t kSourceSize = kString1Size + kString2Size + kString3Size; |
396 const size_t kPaddedString1Size = RoundToAlignment(kString1Size); | 511 const size_t kPaddedString1Size = RoundToAlignment(kString1Size); |
(...skipping 546 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
943 uint32 offset = 0; | 1058 uint32 offset = 0; |
944 Cmds expected; | 1059 Cmds expected; |
945 expected.buf.Init( | 1060 expected.buf.Init( |
946 kTarget, kOffset, kSize, kTransferBufferId, offset); | 1061 kTarget, kOffset, kSize, kTransferBufferId, offset); |
947 expected.set_token.Init(GetNextToken()); | 1062 expected.set_token.Init(GetNextToken()); |
948 | 1063 |
949 void* mem = gl_->MapBufferSubDataCHROMIUM( | 1064 void* mem = gl_->MapBufferSubDataCHROMIUM( |
950 kTarget, kOffset, kSize, GL_WRITE_ONLY); | 1065 kTarget, kOffset, kSize, GL_WRITE_ONLY); |
951 ASSERT_TRUE(mem != NULL); | 1066 ASSERT_TRUE(mem != NULL); |
952 gl_->UnmapBufferSubDataCHROMIUM(mem); | 1067 gl_->UnmapBufferSubDataCHROMIUM(mem); |
953 EXPECT_CALL(*command_buffer_, DestroyTransferBuffer(_))\ | 1068 EXPECT_CALL(*command_buffer_, DestroyTransferBuffer(_)) |
954 .Times(1) | 1069 .Times(1) |
955 .RetiresOnSaturation(); | 1070 .RetiresOnSaturation(); |
956 gl_->FreeUnusedSharedMemory(); | 1071 gl_->FreeUnusedSharedMemory(); |
957 } | 1072 } |
958 | 1073 |
959 TEST_F(GLES2ImplementationTest, MapUnmapBufferSubDataCHROMIUM) { | 1074 TEST_F(GLES2ImplementationTest, MapUnmapBufferSubDataCHROMIUM) { |
960 struct Cmds { | 1075 struct Cmds { |
961 BufferSubData buf; | 1076 BufferSubData buf; |
962 cmd::SetToken set_token; | 1077 cmd::SetToken set_token; |
963 }; | 1078 }; |
(...skipping 965 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1929 expected.destroy_stream.Init(kTextureHandle); | 2044 expected.destroy_stream.Init(kTextureHandle); |
1930 | 2045 |
1931 gl_->DestroyStreamTextureCHROMIUM(kTextureHandle); | 2046 gl_->DestroyStreamTextureCHROMIUM(kTextureHandle); |
1932 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); | 2047 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); |
1933 } | 2048 } |
1934 | 2049 |
1935 } // namespace gles2 | 2050 } // namespace gles2 |
1936 } // namespace gpu | 2051 } // namespace gpu |
1937 | 2052 |
1938 | 2053 |
OLD | NEW |