gles2_implementation_unittest.cc revision 5821806d5e7f356e8fa4b058a389a808ea183019
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// Tests for GLES2Implementation. 6 7#include "gpu/command_buffer/client/gles2_implementation.h" 8 9#include <GLES2/gl2ext.h> 10#include "gpu/command_buffer/client/client_test_helper.h" 11#include "gpu/command_buffer/client/program_info_manager.h" 12#include "gpu/command_buffer/client/transfer_buffer.h" 13#include "gpu/command_buffer/common/command_buffer.h" 14#include "gpu/command_buffer/common/compiler_specific.h" 15#include "testing/gtest/include/gtest/gtest.h" 16#include "testing/gmock/include/gmock/gmock.h" 17 18#if !defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS) 19#define GLES2_SUPPORT_CLIENT_SIDE_ARRAYS 20#endif 21 22using testing::_; 23using testing::AnyNumber; 24using testing::DoAll; 25using testing::InSequence; 26using testing::Invoke; 27using testing::Mock; 28using testing::Sequence; 29using testing::StrictMock; 30using testing::Truly; 31using testing::Return; 32 33namespace gpu { 34namespace gles2 { 35 36ACTION_P2(SetMemory, dst, obj) { 37 memcpy(dst, &obj, sizeof(obj)); 38} 39 40ACTION_P3(SetMemoryFromArray, dst, array, size) { 41 memcpy(dst, array, size); 42} 43 44// Used to help set the transfer buffer result to SizedResult of a single value. 45template <typename T> 46class SizedResultHelper { 47 public: 48 explicit SizedResultHelper(T result) 49 : size_(sizeof(result)), 50 result_(result) { 51 } 52 53 private: 54 uint32 size_; 55 T result_; 56}; 57 58// Struct to make it easy to pass a vec4 worth of floats. 59struct FourFloats { 60 FourFloats(float _x, float _y, float _z, float _w) 61 : x(_x), 62 y(_y), 63 z(_z), 64 w(_w) { 65 } 66 67 float x; 68 float y; 69 float z; 70 float w; 71}; 72 73#pragma pack(push, 1) 74// Struct that holds 7 characters. 75struct Str7 { 76 char str[7]; 77}; 78#pragma pack(pop) 79 80class MockTransferBuffer : public TransferBufferInterface { 81 public: 82 struct ExpectedMemoryInfo { 83 uint32 offset; 84 int32 id; 85 uint8* ptr; 86 }; 87 88 MockTransferBuffer( 89 CommandBuffer* command_buffer, 90 unsigned int size, 91 unsigned int result_size, 92 unsigned int alignment) 93 : command_buffer_(command_buffer), 94 size_(size), 95 result_size_(result_size), 96 alignment_(alignment), 97 actual_buffer_index_(0), 98 expected_buffer_index_(0), 99 last_alloc_(NULL), 100 expected_offset_(result_size), 101 actual_offset_(result_size) { 102 // We have to allocate the buffers here because 103 // we need to know their address before GLES2Implementation::Initialize 104 // is called. 105 for (int ii = 0; ii < kNumBuffers; ++ii) { 106 buffer_ids_[ii] = command_buffer_->CreateTransferBuffer( 107 size_ + ii * alignment_, -1); 108 EXPECT_NE(-1, buffer_ids_[ii]); 109 buffers_[ii] = command_buffer_->GetTransferBuffer(buffer_ids_[ii]); 110 } 111 } 112 113 virtual ~MockTransferBuffer() { } 114 115 bool Initialize( 116 unsigned int starting_buffer_size, 117 unsigned int result_size, 118 unsigned int /* min_buffer_size */, 119 unsigned int /* max_buffer_size */, 120 unsigned int alignment, 121 unsigned int size_to_flush) OVERRIDE; 122 virtual int GetShmId() OVERRIDE; 123 virtual void* GetResultBuffer() OVERRIDE; 124 virtual int GetResultOffset() OVERRIDE; 125 virtual void Free() OVERRIDE; 126 virtual bool HaveBuffer() const OVERRIDE; 127 virtual void* AllocUpTo( 128 unsigned int size, unsigned int* size_allocated) OVERRIDE; 129 virtual void* Alloc(unsigned int size) OVERRIDE; 130 virtual RingBuffer::Offset GetOffset(void* pointer) const OVERRIDE; 131 virtual void FreePendingToken(void* p, unsigned int /* token */) OVERRIDE; 132 133 size_t MaxTransferBufferSize() { 134 return size_ - result_size_; 135 } 136 137 unsigned int RoundToAlignment(unsigned int size) { 138 return (size + alignment_ - 1) & ~(alignment_ - 1); 139 } 140 141 bool InSync() { 142 return expected_buffer_index_ == actual_buffer_index_; 143 } 144 145 ExpectedMemoryInfo GetExpectedMemory(size_t size) { 146 ExpectedMemoryInfo mem; 147 mem.offset = AllocateExpectedTransferBuffer(size); 148 mem.id = GetExpectedTransferBufferId(); 149 mem.ptr = static_cast<uint8*>( 150 GetExpectedTransferAddressFromOffset(mem.offset, size)); 151 return mem; 152 } 153 154 ExpectedMemoryInfo GetExpectedResultMemory(size_t size) { 155 ExpectedMemoryInfo mem; 156 mem.offset = GetExpectedResultBufferOffset(); 157 mem.id = GetExpectedResultBufferId(); 158 mem.ptr = static_cast<uint8*>( 159 GetExpectedTransferAddressFromOffset(mem.offset, size)); 160 return mem; 161 } 162 163 private: 164 static const int kNumBuffers = 2; 165 166 uint8* actual_buffer() const { 167 return static_cast<uint8*>(buffers_[actual_buffer_index_].ptr); 168 } 169 170 uint8* expected_buffer() const { 171 return static_cast<uint8*>(buffers_[expected_buffer_index_].ptr); 172 } 173 174 uint32 AllocateExpectedTransferBuffer(size_t size) { 175 EXPECT_LE(size, MaxTransferBufferSize()); 176 177 // Toggle which buffer we get each time to simulate the buffer being 178 // reallocated. 179 expected_buffer_index_ = (expected_buffer_index_ + 1) % kNumBuffers; 180 181 if (expected_offset_ + size > size_) { 182 expected_offset_ = result_size_; 183 } 184 uint32 offset = expected_offset_; 185 expected_offset_ += RoundToAlignment(size); 186 187 // Make sure each buffer has a different offset. 188 return offset + expected_buffer_index_ * alignment_; 189 } 190 191 void* GetExpectedTransferAddressFromOffset(uint32 offset, size_t size) { 192 EXPECT_GE(offset, expected_buffer_index_ * alignment_); 193 EXPECT_LE(offset + size, size_ + expected_buffer_index_ * alignment_); 194 return expected_buffer() + offset; 195 } 196 197 int GetExpectedResultBufferId() { 198 return buffer_ids_[expected_buffer_index_]; 199 } 200 201 uint32 GetExpectedResultBufferOffset() { 202 return expected_buffer_index_ * alignment_; 203 } 204 205 int GetExpectedTransferBufferId() { 206 return buffer_ids_[expected_buffer_index_]; 207 } 208 209 CommandBuffer* command_buffer_; 210 size_t size_; 211 size_t result_size_; 212 uint32 alignment_; 213 int buffer_ids_[kNumBuffers]; 214 gpu::Buffer buffers_[kNumBuffers]; 215 int actual_buffer_index_; 216 int expected_buffer_index_; 217 void* last_alloc_; 218 uint32 expected_offset_; 219 uint32 actual_offset_; 220 221 DISALLOW_COPY_AND_ASSIGN(MockTransferBuffer); 222}; 223 224bool MockTransferBuffer::Initialize( 225 unsigned int starting_buffer_size, 226 unsigned int result_size, 227 unsigned int /* min_buffer_size */, 228 unsigned int /* max_buffer_size */, 229 unsigned int alignment, 230 unsigned int /* size_to_flush */) { 231 // Just check they match. 232 return size_ == starting_buffer_size && 233 result_size_ == result_size && 234 alignment_ == alignment; 235}; 236 237int MockTransferBuffer::GetShmId() { 238 return buffer_ids_[actual_buffer_index_]; 239} 240 241void* MockTransferBuffer::GetResultBuffer() { 242 return actual_buffer() + actual_buffer_index_ * alignment_; 243} 244 245int MockTransferBuffer::GetResultOffset() { 246 return actual_buffer_index_ * alignment_; 247} 248 249void MockTransferBuffer::Free() { 250 GPU_NOTREACHED(); 251} 252 253bool MockTransferBuffer::HaveBuffer() const { 254 return true; 255} 256 257void* MockTransferBuffer::AllocUpTo( 258 unsigned int size, unsigned int* size_allocated) { 259 EXPECT_TRUE(size_allocated != NULL); 260 EXPECT_TRUE(last_alloc_ == NULL); 261 262 // Toggle which buffer we get each time to simulate the buffer being 263 // reallocated. 264 actual_buffer_index_ = (actual_buffer_index_ + 1) % kNumBuffers; 265 266 size = std::min(static_cast<size_t>(size), MaxTransferBufferSize()); 267 if (actual_offset_ + size > size_) { 268 actual_offset_ = result_size_; 269 } 270 uint32 offset = actual_offset_; 271 actual_offset_ += RoundToAlignment(size); 272 *size_allocated = size; 273 274 // Make sure each buffer has a different offset. 275 last_alloc_ = actual_buffer() + offset + actual_buffer_index_ * alignment_; 276 return last_alloc_; 277} 278 279void* MockTransferBuffer::Alloc(unsigned int size) { 280 EXPECT_LE(size, MaxTransferBufferSize()); 281 unsigned int temp = 0; 282 void* p = AllocUpTo(size, &temp); 283 EXPECT_EQ(temp, size); 284 return p; 285} 286 287RingBuffer::Offset MockTransferBuffer::GetOffset(void* pointer) const { 288 // Make sure each buffer has a different offset. 289 return static_cast<uint8*>(pointer) - actual_buffer(); 290} 291 292void MockTransferBuffer::FreePendingToken(void* p, unsigned int /* token */) { 293 EXPECT_EQ(last_alloc_, p); 294 last_alloc_ = NULL; 295} 296 297class GLES2ImplementationTest : public testing::Test { 298 protected: 299 static const uint8 kInitialValue = 0xBD; 300 static const int32 kNumCommandEntries = 500; 301 static const int32 kCommandBufferSizeBytes = 302 kNumCommandEntries * sizeof(CommandBufferEntry); 303 static const size_t kTransferBufferSize = 256; 304 305 static const GLint kMaxCombinedTextureImageUnits = 8; 306 static const GLint kMaxCubeMapTextureSize = 64; 307 static const GLint kMaxFragmentUniformVectors = 16; 308 static const GLint kMaxRenderbufferSize = 64; 309 static const GLint kMaxTextureImageUnits = 8; 310 static const GLint kMaxTextureSize = 128; 311 static const GLint kMaxVaryingVectors = 8; 312 static const GLint kMaxVertexAttribs = 8; 313 static const GLint kMaxVertexTextureImageUnits = 0; 314 static const GLint kMaxVertexUniformVectors = 128; 315 static const GLint kNumCompressedTextureFormats = 0; 316 static const GLint kNumShaderBinaryFormats = 0; 317 static const GLuint kStartId = 1024; 318 static const GLuint kBuffersStartId = 319 GLES2Implementation::kClientSideArrayId + 2; 320 static const GLuint kFramebuffersStartId = 1; 321 static const GLuint kProgramsAndShadersStartId = 1; 322 static const GLuint kRenderbuffersStartId = 1; 323 static const GLuint kTexturesStartId = 1; 324 static const GLuint kQueriesStartId = 1; 325 static const GLuint kVertexArraysStartId = 1; 326 327 typedef MockTransferBuffer::ExpectedMemoryInfo ExpectedMemoryInfo; 328 329 GLES2ImplementationTest() 330 : commands_(NULL), 331 token_(0) { 332 } 333 334 virtual void SetUp() OVERRIDE; 335 virtual void TearDown() OVERRIDE; 336 337 bool NoCommandsWritten() { 338 Buffer ring_buffer = helper_->get_ring_buffer(); 339 const uint8* cmds = reinterpret_cast<const uint8*>(ring_buffer.ptr); 340 const uint8* end = cmds + ring_buffer.size; 341 for (; cmds < end; ++cmds) { 342 if (*cmds != kInitialValue) { 343 return false; 344 } 345 } 346 return true; 347 } 348 349 QueryTracker::Query* GetQuery(GLuint id) { 350 return gl_->query_tracker_->GetQuery(id); 351 } 352 353 void Initialize(bool shared_resources, bool bind_generates_resource) { 354 command_buffer_.reset(new StrictMock<MockClientCommandBuffer>()); 355 ASSERT_TRUE(command_buffer_->Initialize()); 356 357 transfer_buffer_.reset(new MockTransferBuffer( 358 command_buffer(), 359 kTransferBufferSize, 360 GLES2Implementation::kStartingOffset, 361 GLES2Implementation::kAlignment)); 362 363 helper_.reset(new GLES2CmdHelper(command_buffer())); 364 helper_->Initialize(kCommandBufferSizeBytes); 365 366 GLES2Implementation::GLCachedState state; 367 GLES2Implementation::GLCachedState::IntState& int_state = state.int_state; 368 int_state.max_combined_texture_image_units = kMaxCombinedTextureImageUnits; 369 int_state.max_cube_map_texture_size = kMaxCubeMapTextureSize; 370 int_state.max_fragment_uniform_vectors = kMaxFragmentUniformVectors; 371 int_state.max_renderbuffer_size = kMaxRenderbufferSize; 372 int_state.max_texture_image_units = kMaxTextureImageUnits; 373 int_state.max_texture_size = kMaxTextureSize; 374 int_state.max_varying_vectors = kMaxVaryingVectors; 375 int_state.max_vertex_attribs = kMaxVertexAttribs; 376 int_state.max_vertex_texture_image_units = kMaxVertexTextureImageUnits; 377 int_state.max_vertex_uniform_vectors = kMaxVertexUniformVectors; 378 int_state.num_compressed_texture_formats = kNumCompressedTextureFormats; 379 int_state.num_shader_binary_formats = kNumShaderBinaryFormats; 380 381 // This just happens to work for now because IntState has 1 GLint per state. 382 // If IntState gets more complicated this code will need to get more 383 // complicated. 384 ExpectedMemoryInfo mem1 = GetExpectedMemory(sizeof(int_state) * 2); 385 386 { 387 InSequence sequence; 388 389 EXPECT_CALL(*command_buffer(), OnFlush()) 390 .WillOnce(SetMemory(mem1.ptr + sizeof(int_state), int_state)) 391 .RetiresOnSaturation(); 392 GetNextToken(); // eat the token that starting up will use. 393 394 gl_.reset(new GLES2Implementation( 395 helper_.get(), 396 NULL, 397 transfer_buffer_.get(), 398 shared_resources, 399 bind_generates_resource)); 400 ASSERT_TRUE(gl_->Initialize( 401 kTransferBufferSize, 402 kTransferBufferSize, 403 kTransferBufferSize)); 404 } 405 406 EXPECT_CALL(*command_buffer(), OnFlush()) 407 .Times(1) 408 .RetiresOnSaturation(); 409 helper_->CommandBufferHelper::Finish(); 410 ::testing::Mock::VerifyAndClearExpectations(gl_.get()); 411 412 Buffer ring_buffer = helper_->get_ring_buffer(); 413 commands_ = static_cast<CommandBufferEntry*>(ring_buffer.ptr) + 414 command_buffer()->GetState().put_offset; 415 ClearCommands(); 416 EXPECT_TRUE(transfer_buffer_->InSync()); 417 418 ::testing::Mock::VerifyAndClearExpectations(command_buffer()); 419 } 420 421 MockClientCommandBuffer* command_buffer() const { 422 return command_buffer_.get(); 423 } 424 425 int GetNextToken() { 426 return ++token_; 427 } 428 429 const void* GetPut() { 430 return helper_->GetSpace(0); 431 } 432 433 void ClearCommands() { 434 Buffer ring_buffer = helper_->get_ring_buffer(); 435 memset(ring_buffer.ptr, kInitialValue, ring_buffer.size); 436 } 437 438 size_t MaxTransferBufferSize() { 439 return transfer_buffer_->MaxTransferBufferSize(); 440 } 441 442 ExpectedMemoryInfo GetExpectedMemory(size_t size) { 443 return transfer_buffer_->GetExpectedMemory(size); 444 } 445 446 ExpectedMemoryInfo GetExpectedResultMemory(size_t size) { 447 return transfer_buffer_->GetExpectedResultMemory(size); 448 } 449 450 // Sets the ProgramInfoManager. The manager will be owned 451 // by the ShareGroup. 452 void SetProgramInfoManager(ProgramInfoManager* manager) { 453 gl_->share_group()->set_program_info_manager(manager); 454 } 455 456 int CheckError() { 457 ExpectedMemoryInfo result = 458 GetExpectedResultMemory(sizeof(GetError::Result)); 459 EXPECT_CALL(*command_buffer(), OnFlush()) 460 .WillOnce(SetMemory(result.ptr, GLuint(GL_NO_ERROR))) 461 .RetiresOnSaturation(); 462 return gl_->GetError(); 463 } 464 465 bool GetBucketContents(uint32 bucket_id, std::vector<int8>* data) { 466 return gl_->GetBucketContents(bucket_id, data); 467 } 468 469 Sequence sequence_; 470 scoped_ptr<MockClientCommandBuffer> command_buffer_; 471 scoped_ptr<GLES2CmdHelper> helper_; 472 scoped_ptr<MockTransferBuffer> transfer_buffer_; 473 scoped_ptr<GLES2Implementation> gl_; 474 CommandBufferEntry* commands_; 475 int token_; 476}; 477 478void GLES2ImplementationTest::SetUp() { 479 Initialize(false, true); 480} 481 482void GLES2ImplementationTest::TearDown() { 483 Mock::VerifyAndClear(gl_.get()); 484 EXPECT_CALL(*command_buffer(), OnFlush()).Times(AnyNumber()); 485 // For command buffer. 486 EXPECT_CALL(*command_buffer(), DestroyTransferBuffer(_)) 487 .Times(1) 488 .RetiresOnSaturation(); 489 gl_.reset(); 490} 491 492class GLES2ImplementationStrictSharedTest : public GLES2ImplementationTest { 493 protected: 494 virtual void SetUp() OVERRIDE; 495}; 496 497void GLES2ImplementationStrictSharedTest::SetUp() { 498 Initialize(true, false); 499} 500 501// GCC requires these declarations, but MSVC requires they not be present 502#ifndef _MSC_VER 503const uint8 GLES2ImplementationTest::kInitialValue; 504const int32 GLES2ImplementationTest::kNumCommandEntries; 505const int32 GLES2ImplementationTest::kCommandBufferSizeBytes; 506const size_t GLES2ImplementationTest::kTransferBufferSize; 507const GLint GLES2ImplementationTest::kMaxCombinedTextureImageUnits; 508const GLint GLES2ImplementationTest::kMaxCubeMapTextureSize; 509const GLint GLES2ImplementationTest::kMaxFragmentUniformVectors; 510const GLint GLES2ImplementationTest::kMaxRenderbufferSize; 511const GLint GLES2ImplementationTest::kMaxTextureImageUnits; 512const GLint GLES2ImplementationTest::kMaxTextureSize; 513const GLint GLES2ImplementationTest::kMaxVaryingVectors; 514const GLint GLES2ImplementationTest::kMaxVertexAttribs; 515const GLint GLES2ImplementationTest::kMaxVertexTextureImageUnits; 516const GLint GLES2ImplementationTest::kMaxVertexUniformVectors; 517const GLint GLES2ImplementationTest::kNumCompressedTextureFormats; 518const GLint GLES2ImplementationTest::kNumShaderBinaryFormats; 519const GLuint GLES2ImplementationTest::kStartId; 520const GLuint GLES2ImplementationTest::kBuffersStartId; 521const GLuint GLES2ImplementationTest::kFramebuffersStartId; 522const GLuint GLES2ImplementationTest::kProgramsAndShadersStartId; 523const GLuint GLES2ImplementationTest::kRenderbuffersStartId; 524const GLuint GLES2ImplementationTest::kTexturesStartId; 525const GLuint GLES2ImplementationTest::kQueriesStartId; 526const GLuint GLES2ImplementationTest::kVertexArraysStartId; 527#endif 528 529TEST_F(GLES2ImplementationTest, Basic) { 530 EXPECT_TRUE(gl_->share_group() != NULL); 531} 532 533TEST_F(GLES2ImplementationTest, GetBucketContents) { 534 const uint32 kBucketId = GLES2Implementation::kResultBucketId; 535 const uint32 kTestSize = MaxTransferBufferSize() + 32; 536 537 scoped_array<uint8> buf(new uint8 [kTestSize]); 538 uint8* expected_data = buf.get(); 539 for (uint32 ii = 0; ii < kTestSize; ++ii) { 540 expected_data[ii] = ii * 3; 541 } 542 543 struct Cmds { 544 cmd::GetBucketStart get_bucket_start; 545 cmd::SetToken set_token1; 546 cmd::GetBucketData get_bucket_data; 547 cmd::SetToken set_token2; 548 cmd::SetBucketSize set_bucket_size2; 549 }; 550 551 ExpectedMemoryInfo mem1 = GetExpectedMemory(MaxTransferBufferSize()); 552 ExpectedMemoryInfo result1 = GetExpectedResultMemory(sizeof(uint32)); 553 ExpectedMemoryInfo mem2 = GetExpectedMemory( 554 kTestSize - MaxTransferBufferSize()); 555 556 Cmds expected; 557 expected.get_bucket_start.Init( 558 kBucketId, result1.id, result1.offset, 559 MaxTransferBufferSize(), mem1.id, mem1.offset); 560 expected.set_token1.Init(GetNextToken()); 561 expected.get_bucket_data.Init( 562 kBucketId, MaxTransferBufferSize(), 563 kTestSize - MaxTransferBufferSize(), mem2.id, mem2.offset); 564 expected.set_bucket_size2.Init(kBucketId, 0); 565 expected.set_token2.Init(GetNextToken()); 566 567 EXPECT_CALL(*command_buffer(), OnFlush()) 568 .WillOnce(DoAll( 569 SetMemory(result1.ptr, kTestSize), 570 SetMemoryFromArray( 571 mem1.ptr, expected_data, MaxTransferBufferSize()))) 572 .WillOnce(SetMemoryFromArray( 573 mem2.ptr, expected_data + MaxTransferBufferSize(), 574 kTestSize - MaxTransferBufferSize())) 575 .RetiresOnSaturation(); 576 577 std::vector<int8> data; 578 GetBucketContents(kBucketId, &data); 579 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); 580 ASSERT_EQ(kTestSize, data.size()); 581 EXPECT_EQ(0, memcmp(expected_data, &data[0], data.size())); 582} 583 584TEST_F(GLES2ImplementationTest, ShaderSource) { 585 const uint32 kBucketId = GLES2Implementation::kResultBucketId; 586 const GLuint kShaderId = 456; 587 const char* kString1 = "foobar"; 588 const char* kString2 = "barfoo"; 589 const size_t kString1Size = strlen(kString1); 590 const size_t kString2Size = strlen(kString2); 591 const size_t kString3Size = 1; // Want the NULL; 592 const size_t kSourceSize = kString1Size + kString2Size + kString3Size; 593 const size_t kPaddedString1Size = 594 transfer_buffer_->RoundToAlignment(kString1Size); 595 const size_t kPaddedString2Size = 596 transfer_buffer_->RoundToAlignment(kString2Size); 597 const size_t kPaddedString3Size = 598 transfer_buffer_->RoundToAlignment(kString3Size); 599 struct Cmds { 600 cmd::SetBucketSize set_bucket_size; 601 cmd::SetBucketData set_bucket_data1; 602 cmd::SetToken set_token1; 603 cmd::SetBucketData set_bucket_data2; 604 cmd::SetToken set_token2; 605 cmd::SetBucketData set_bucket_data3; 606 cmd::SetToken set_token3; 607 ShaderSourceBucket shader_source_bucket; 608 cmd::SetBucketSize clear_bucket_size; 609 }; 610 611 ExpectedMemoryInfo mem1 = GetExpectedMemory(kPaddedString1Size); 612 ExpectedMemoryInfo mem2 = GetExpectedMemory(kPaddedString2Size); 613 ExpectedMemoryInfo mem3 = GetExpectedMemory(kPaddedString3Size); 614 615 Cmds expected; 616 expected.set_bucket_size.Init(kBucketId, kSourceSize); 617 expected.set_bucket_data1.Init( 618 kBucketId, 0, kString1Size, mem1.id, mem1.offset); 619 expected.set_token1.Init(GetNextToken()); 620 expected.set_bucket_data2.Init( 621 kBucketId, kString1Size, kString2Size, mem2.id, mem2.offset); 622 expected.set_token2.Init(GetNextToken()); 623 expected.set_bucket_data3.Init( 624 kBucketId, kString1Size + kString2Size, 625 kString3Size, mem3.id, mem3.offset); 626 expected.set_token3.Init(GetNextToken()); 627 expected.shader_source_bucket.Init(kShaderId, kBucketId); 628 expected.clear_bucket_size.Init(kBucketId, 0); 629 const char* strings[] = { 630 kString1, 631 kString2, 632 }; 633 gl_->ShaderSource(kShaderId, 2, strings, NULL); 634 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); 635} 636 637TEST_F(GLES2ImplementationTest, GetShaderSource) { 638 const uint32 kBucketId = GLES2Implementation::kResultBucketId; 639 const GLuint kShaderId = 456; 640 const Str7 kString = {"foobar"}; 641 const char kBad = 0x12; 642 struct Cmds { 643 cmd::SetBucketSize set_bucket_size1; 644 GetShaderSource get_shader_source; 645 cmd::GetBucketStart get_bucket_start; 646 cmd::SetToken set_token1; 647 cmd::SetBucketSize set_bucket_size2; 648 }; 649 650 ExpectedMemoryInfo mem1 = GetExpectedMemory(MaxTransferBufferSize()); 651 ExpectedMemoryInfo result1 = GetExpectedResultMemory(sizeof(uint32)); 652 653 Cmds expected; 654 expected.set_bucket_size1.Init(kBucketId, 0); 655 expected.get_shader_source.Init(kShaderId, kBucketId); 656 expected.get_bucket_start.Init( 657 kBucketId, result1.id, result1.offset, 658 MaxTransferBufferSize(), mem1.id, mem1.offset); 659 expected.set_token1.Init(GetNextToken()); 660 expected.set_bucket_size2.Init(kBucketId, 0); 661 char buf[sizeof(kString) + 1]; 662 memset(buf, kBad, sizeof(buf)); 663 664 EXPECT_CALL(*command_buffer(), OnFlush()) 665 .WillOnce(DoAll(SetMemory(result1.ptr, uint32(sizeof(kString))), 666 SetMemory(mem1.ptr, kString))) 667 .RetiresOnSaturation(); 668 669 GLsizei length = 0; 670 gl_->GetShaderSource(kShaderId, sizeof(buf), &length, buf); 671 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); 672 EXPECT_EQ(sizeof(kString) - 1, static_cast<size_t>(length)); 673 EXPECT_STREQ(kString.str, buf); 674 EXPECT_EQ(buf[sizeof(kString)], kBad); 675} 676 677#if defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS) 678 679TEST_F(GLES2ImplementationTest, DrawArraysClientSideBuffers) { 680 static const float verts[][4] = { 681 { 12.0f, 23.0f, 34.0f, 45.0f, }, 682 { 56.0f, 67.0f, 78.0f, 89.0f, }, 683 { 13.0f, 24.0f, 35.0f, 46.0f, }, 684 }; 685 struct Cmds { 686 EnableVertexAttribArray enable1; 687 EnableVertexAttribArray enable2; 688 BindBuffer bind_to_emu; 689 BufferData set_size; 690 BufferSubData copy_data1; 691 cmd::SetToken set_token1; 692 VertexAttribPointer set_pointer1; 693 BufferSubData copy_data2; 694 cmd::SetToken set_token2; 695 VertexAttribPointer set_pointer2; 696 DrawArrays draw; 697 BindBuffer restore; 698 }; 699 const GLuint kEmuBufferId = GLES2Implementation::kClientSideArrayId; 700 const GLuint kAttribIndex1 = 1; 701 const GLuint kAttribIndex2 = 3; 702 const GLint kNumComponents1 = 3; 703 const GLint kNumComponents2 = 2; 704 const GLsizei kClientStride = sizeof(verts[0]); 705 const GLint kFirst = 1; 706 const GLsizei kCount = 2; 707 const GLsizei kSize1 = 708 arraysize(verts) * kNumComponents1 * sizeof(verts[0][0]); 709 const GLsizei kSize2 = 710 arraysize(verts) * kNumComponents2 * sizeof(verts[0][0]); 711 const GLsizei kEmuOffset1 = 0; 712 const GLsizei kEmuOffset2 = kSize1; 713 const GLsizei kTotalSize = kSize1 + kSize2; 714 715 ExpectedMemoryInfo mem1 = GetExpectedMemory(kSize1); 716 ExpectedMemoryInfo mem2 = GetExpectedMemory(kSize2); 717 718 Cmds expected; 719 expected.enable1.Init(kAttribIndex1); 720 expected.enable2.Init(kAttribIndex2); 721 expected.bind_to_emu.Init(GL_ARRAY_BUFFER, kEmuBufferId); 722 expected.set_size.Init(GL_ARRAY_BUFFER, kTotalSize, 0, 0, GL_DYNAMIC_DRAW); 723 expected.copy_data1.Init( 724 GL_ARRAY_BUFFER, kEmuOffset1, kSize1, mem1.id, mem1.offset); 725 expected.set_token1.Init(GetNextToken()); 726 expected.set_pointer1.Init( 727 kAttribIndex1, kNumComponents1, GL_FLOAT, GL_FALSE, 0, kEmuOffset1); 728 expected.copy_data2.Init( 729 GL_ARRAY_BUFFER, kEmuOffset2, kSize2, mem2.id, mem2.offset); 730 expected.set_token2.Init(GetNextToken()); 731 expected.set_pointer2.Init( 732 kAttribIndex2, kNumComponents2, GL_FLOAT, GL_FALSE, 0, kEmuOffset2); 733 expected.draw.Init(GL_POINTS, kFirst, kCount); 734 expected.restore.Init(GL_ARRAY_BUFFER, 0); 735 gl_->EnableVertexAttribArray(kAttribIndex1); 736 gl_->EnableVertexAttribArray(kAttribIndex2); 737 gl_->VertexAttribPointer( 738 kAttribIndex1, kNumComponents1, GL_FLOAT, GL_FALSE, kClientStride, verts); 739 gl_->VertexAttribPointer( 740 kAttribIndex2, kNumComponents2, GL_FLOAT, GL_FALSE, kClientStride, verts); 741 gl_->DrawArrays(GL_POINTS, kFirst, kCount); 742 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); 743} 744 745TEST_F(GLES2ImplementationTest, DrawArraysInstancedANGLEClientSideBuffers) { 746 static const float verts[][4] = { 747 { 12.0f, 23.0f, 34.0f, 45.0f, }, 748 { 56.0f, 67.0f, 78.0f, 89.0f, }, 749 { 13.0f, 24.0f, 35.0f, 46.0f, }, 750 }; 751 struct Cmds { 752 EnableVertexAttribArray enable1; 753 EnableVertexAttribArray enable2; 754 VertexAttribDivisorANGLE divisor; 755 BindBuffer bind_to_emu; 756 BufferData set_size; 757 BufferSubData copy_data1; 758 cmd::SetToken set_token1; 759 VertexAttribPointer set_pointer1; 760 BufferSubData copy_data2; 761 cmd::SetToken set_token2; 762 VertexAttribPointer set_pointer2; 763 DrawArraysInstancedANGLE draw; 764 BindBuffer restore; 765 }; 766 const GLuint kEmuBufferId = GLES2Implementation::kClientSideArrayId; 767 const GLuint kAttribIndex1 = 1; 768 const GLuint kAttribIndex2 = 3; 769 const GLint kNumComponents1 = 3; 770 const GLint kNumComponents2 = 2; 771 const GLsizei kClientStride = sizeof(verts[0]); 772 const GLint kFirst = 1; 773 const GLsizei kCount = 2; 774 const GLuint kDivisor = 1; 775 const GLsizei kSize1 = 776 arraysize(verts) * kNumComponents1 * sizeof(verts[0][0]); 777 const GLsizei kSize2 = 778 1 * kNumComponents2 * sizeof(verts[0][0]); 779 const GLsizei kEmuOffset1 = 0; 780 const GLsizei kEmuOffset2 = kSize1; 781 const GLsizei kTotalSize = kSize1 + kSize2; 782 783 ExpectedMemoryInfo mem1 = GetExpectedMemory(kSize1); 784 ExpectedMemoryInfo mem2 = GetExpectedMemory(kSize2); 785 786 Cmds expected; 787 expected.enable1.Init(kAttribIndex1); 788 expected.enable2.Init(kAttribIndex2); 789 expected.divisor.Init(kAttribIndex2, kDivisor); 790 expected.bind_to_emu.Init(GL_ARRAY_BUFFER, kEmuBufferId); 791 expected.set_size.Init(GL_ARRAY_BUFFER, kTotalSize, 0, 0, GL_DYNAMIC_DRAW); 792 expected.copy_data1.Init( 793 GL_ARRAY_BUFFER, kEmuOffset1, kSize1, mem1.id, mem1.offset); 794 expected.set_token1.Init(GetNextToken()); 795 expected.set_pointer1.Init( 796 kAttribIndex1, kNumComponents1, GL_FLOAT, GL_FALSE, 0, kEmuOffset1); 797 expected.copy_data2.Init( 798 GL_ARRAY_BUFFER, kEmuOffset2, kSize2, mem2.id, mem2.offset); 799 expected.set_token2.Init(GetNextToken()); 800 expected.set_pointer2.Init( 801 kAttribIndex2, kNumComponents2, GL_FLOAT, GL_FALSE, 0, kEmuOffset2); 802 expected.draw.Init(GL_POINTS, kFirst, kCount, 1); 803 expected.restore.Init(GL_ARRAY_BUFFER, 0); 804 gl_->EnableVertexAttribArray(kAttribIndex1); 805 gl_->EnableVertexAttribArray(kAttribIndex2); 806 gl_->VertexAttribPointer( 807 kAttribIndex1, kNumComponents1, GL_FLOAT, GL_FALSE, kClientStride, verts); 808 gl_->VertexAttribPointer( 809 kAttribIndex2, kNumComponents2, GL_FLOAT, GL_FALSE, kClientStride, verts); 810 gl_->VertexAttribDivisorANGLE(kAttribIndex2, kDivisor); 811 gl_->DrawArraysInstancedANGLE(GL_POINTS, kFirst, kCount, 1); 812 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); 813} 814 815TEST_F(GLES2ImplementationTest, DrawElementsClientSideBuffers) { 816 static const float verts[][4] = { 817 { 12.0f, 23.0f, 34.0f, 45.0f, }, 818 { 56.0f, 67.0f, 78.0f, 89.0f, }, 819 { 13.0f, 24.0f, 35.0f, 46.0f, }, 820 }; 821 static const uint16 indices[] = { 822 1, 2, 823 }; 824 struct Cmds { 825 EnableVertexAttribArray enable1; 826 EnableVertexAttribArray enable2; 827 BindBuffer bind_to_index_emu; 828 BufferData set_index_size; 829 BufferSubData copy_data0; 830 cmd::SetToken set_token0; 831 BindBuffer bind_to_emu; 832 BufferData set_size; 833 BufferSubData copy_data1; 834 cmd::SetToken set_token1; 835 VertexAttribPointer set_pointer1; 836 BufferSubData copy_data2; 837 cmd::SetToken set_token2; 838 VertexAttribPointer set_pointer2; 839 DrawElements draw; 840 BindBuffer restore; 841 BindBuffer restore_element; 842 }; 843 const GLsizei kIndexSize = sizeof(indices); 844 const GLuint kEmuBufferId = GLES2Implementation::kClientSideArrayId; 845 const GLuint kEmuIndexBufferId = 846 GLES2Implementation::kClientSideElementArrayId; 847 const GLuint kAttribIndex1 = 1; 848 const GLuint kAttribIndex2 = 3; 849 const GLint kNumComponents1 = 3; 850 const GLint kNumComponents2 = 2; 851 const GLsizei kClientStride = sizeof(verts[0]); 852 const GLsizei kCount = 2; 853 const GLsizei kSize1 = 854 arraysize(verts) * kNumComponents1 * sizeof(verts[0][0]); 855 const GLsizei kSize2 = 856 arraysize(verts) * kNumComponents2 * sizeof(verts[0][0]); 857 const GLsizei kEmuOffset1 = 0; 858 const GLsizei kEmuOffset2 = kSize1; 859 const GLsizei kTotalSize = kSize1 + kSize2; 860 861 ExpectedMemoryInfo mem1 = GetExpectedMemory(kIndexSize); 862 ExpectedMemoryInfo mem2 = GetExpectedMemory(kSize1); 863 ExpectedMemoryInfo mem3 = GetExpectedMemory(kSize2); 864 865 Cmds expected; 866 expected.enable1.Init(kAttribIndex1); 867 expected.enable2.Init(kAttribIndex2); 868 expected.bind_to_index_emu.Init(GL_ELEMENT_ARRAY_BUFFER, kEmuIndexBufferId); 869 expected.set_index_size.Init( 870 GL_ELEMENT_ARRAY_BUFFER, kIndexSize, 0, 0, GL_DYNAMIC_DRAW); 871 expected.copy_data0.Init( 872 GL_ELEMENT_ARRAY_BUFFER, 0, kIndexSize, mem1.id, mem1.offset); 873 expected.set_token0.Init(GetNextToken()); 874 expected.bind_to_emu.Init(GL_ARRAY_BUFFER, kEmuBufferId); 875 expected.set_size.Init(GL_ARRAY_BUFFER, kTotalSize, 0, 0, GL_DYNAMIC_DRAW); 876 expected.copy_data1.Init( 877 GL_ARRAY_BUFFER, kEmuOffset1, kSize1, mem2.id, mem2.offset); 878 expected.set_token1.Init(GetNextToken()); 879 expected.set_pointer1.Init( 880 kAttribIndex1, kNumComponents1, GL_FLOAT, GL_FALSE, 0, kEmuOffset1); 881 expected.copy_data2.Init( 882 GL_ARRAY_BUFFER, kEmuOffset2, kSize2, mem3.id, mem3.offset); 883 expected.set_token2.Init(GetNextToken()); 884 expected.set_pointer2.Init(kAttribIndex2, kNumComponents2, 885 GL_FLOAT, GL_FALSE, 0, kEmuOffset2); 886 expected.draw.Init(GL_POINTS, kCount, GL_UNSIGNED_SHORT, 0); 887 expected.restore.Init(GL_ARRAY_BUFFER, 0); 888 expected.restore_element.Init(GL_ELEMENT_ARRAY_BUFFER, 0); 889 gl_->EnableVertexAttribArray(kAttribIndex1); 890 gl_->EnableVertexAttribArray(kAttribIndex2); 891 gl_->VertexAttribPointer(kAttribIndex1, kNumComponents1, 892 GL_FLOAT, GL_FALSE, kClientStride, verts); 893 gl_->VertexAttribPointer(kAttribIndex2, kNumComponents2, 894 GL_FLOAT, GL_FALSE, kClientStride, verts); 895 gl_->DrawElements(GL_POINTS, kCount, GL_UNSIGNED_SHORT, indices); 896 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); 897} 898 899TEST_F(GLES2ImplementationTest, DrawElementsClientSideBuffersIndexUint) { 900 static const float verts[][4] = { 901 { 12.0f, 23.0f, 34.0f, 45.0f, }, 902 { 56.0f, 67.0f, 78.0f, 89.0f, }, 903 { 13.0f, 24.0f, 35.0f, 46.0f, }, 904 }; 905 static const uint32 indices[] = { 906 1, 2, 907 }; 908 struct Cmds { 909 EnableVertexAttribArray enable1; 910 EnableVertexAttribArray enable2; 911 BindBuffer bind_to_index_emu; 912 BufferData set_index_size; 913 BufferSubData copy_data0; 914 cmd::SetToken set_token0; 915 BindBuffer bind_to_emu; 916 BufferData set_size; 917 BufferSubData copy_data1; 918 cmd::SetToken set_token1; 919 VertexAttribPointer set_pointer1; 920 BufferSubData copy_data2; 921 cmd::SetToken set_token2; 922 VertexAttribPointer set_pointer2; 923 DrawElements draw; 924 BindBuffer restore; 925 BindBuffer restore_element; 926 }; 927 const GLsizei kIndexSize = sizeof(indices); 928 const GLuint kEmuBufferId = GLES2Implementation::kClientSideArrayId; 929 const GLuint kEmuIndexBufferId = 930 GLES2Implementation::kClientSideElementArrayId; 931 const GLuint kAttribIndex1 = 1; 932 const GLuint kAttribIndex2 = 3; 933 const GLint kNumComponents1 = 3; 934 const GLint kNumComponents2 = 2; 935 const GLsizei kClientStride = sizeof(verts[0]); 936 const GLsizei kCount = 2; 937 const GLsizei kSize1 = 938 arraysize(verts) * kNumComponents1 * sizeof(verts[0][0]); 939 const GLsizei kSize2 = 940 arraysize(verts) * kNumComponents2 * sizeof(verts[0][0]); 941 const GLsizei kEmuOffset1 = 0; 942 const GLsizei kEmuOffset2 = kSize1; 943 const GLsizei kTotalSize = kSize1 + kSize2; 944 945 ExpectedMemoryInfo mem1 = GetExpectedMemory(kIndexSize); 946 ExpectedMemoryInfo mem2 = GetExpectedMemory(kSize1); 947 ExpectedMemoryInfo mem3 = GetExpectedMemory(kSize2); 948 949 Cmds expected; 950 expected.enable1.Init(kAttribIndex1); 951 expected.enable2.Init(kAttribIndex2); 952 expected.bind_to_index_emu.Init(GL_ELEMENT_ARRAY_BUFFER, kEmuIndexBufferId); 953 expected.set_index_size.Init( 954 GL_ELEMENT_ARRAY_BUFFER, kIndexSize, 0, 0, GL_DYNAMIC_DRAW); 955 expected.copy_data0.Init( 956 GL_ELEMENT_ARRAY_BUFFER, 0, kIndexSize, mem1.id, mem1.offset); 957 expected.set_token0.Init(GetNextToken()); 958 expected.bind_to_emu.Init(GL_ARRAY_BUFFER, kEmuBufferId); 959 expected.set_size.Init(GL_ARRAY_BUFFER, kTotalSize, 0, 0, GL_DYNAMIC_DRAW); 960 expected.copy_data1.Init( 961 GL_ARRAY_BUFFER, kEmuOffset1, kSize1, mem2.id, mem2.offset); 962 expected.set_token1.Init(GetNextToken()); 963 expected.set_pointer1.Init( 964 kAttribIndex1, kNumComponents1, GL_FLOAT, GL_FALSE, 0, kEmuOffset1); 965 expected.copy_data2.Init( 966 GL_ARRAY_BUFFER, kEmuOffset2, kSize2, mem3.id, mem3.offset); 967 expected.set_token2.Init(GetNextToken()); 968 expected.set_pointer2.Init(kAttribIndex2, kNumComponents2, 969 GL_FLOAT, GL_FALSE, 0, kEmuOffset2); 970 expected.draw.Init(GL_POINTS, kCount, GL_UNSIGNED_INT, 0); 971 expected.restore.Init(GL_ARRAY_BUFFER, 0); 972 expected.restore_element.Init(GL_ELEMENT_ARRAY_BUFFER, 0); 973 gl_->EnableVertexAttribArray(kAttribIndex1); 974 gl_->EnableVertexAttribArray(kAttribIndex2); 975 gl_->VertexAttribPointer(kAttribIndex1, kNumComponents1, 976 GL_FLOAT, GL_FALSE, kClientStride, verts); 977 gl_->VertexAttribPointer(kAttribIndex2, kNumComponents2, 978 GL_FLOAT, GL_FALSE, kClientStride, verts); 979 gl_->DrawElements(GL_POINTS, kCount, GL_UNSIGNED_INT, indices); 980 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); 981} 982 983TEST_F(GLES2ImplementationTest, DrawElementsClientSideBuffersInvalidIndexUint) { 984 static const float verts[][4] = { 985 { 12.0f, 23.0f, 34.0f, 45.0f, }, 986 { 56.0f, 67.0f, 78.0f, 89.0f, }, 987 { 13.0f, 24.0f, 35.0f, 46.0f, }, 988 }; 989 static const uint32 indices[] = { 990 1, 0x90000000 991 }; 992 993 const GLuint kAttribIndex1 = 1; 994 const GLuint kAttribIndex2 = 3; 995 const GLint kNumComponents1 = 3; 996 const GLint kNumComponents2 = 2; 997 const GLsizei kClientStride = sizeof(verts[0]); 998 const GLsizei kCount = 2; 999 1000 EXPECT_CALL(*command_buffer(), OnFlush()) 1001 .Times(1) 1002 .RetiresOnSaturation(); 1003 1004 gl_->EnableVertexAttribArray(kAttribIndex1); 1005 gl_->EnableVertexAttribArray(kAttribIndex2); 1006 gl_->VertexAttribPointer(kAttribIndex1, kNumComponents1, 1007 GL_FLOAT, GL_FALSE, kClientStride, verts); 1008 gl_->VertexAttribPointer(kAttribIndex2, kNumComponents2, 1009 GL_FLOAT, GL_FALSE, kClientStride, verts); 1010 gl_->DrawElements(GL_POINTS, kCount, GL_UNSIGNED_INT, indices); 1011 1012 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_OPERATION), gl_->GetError()); 1013} 1014 1015TEST_F(GLES2ImplementationTest, 1016 DrawElementsClientSideBuffersServiceSideIndices) { 1017 static const float verts[][4] = { 1018 { 12.0f, 23.0f, 34.0f, 45.0f, }, 1019 { 56.0f, 67.0f, 78.0f, 89.0f, }, 1020 { 13.0f, 24.0f, 35.0f, 46.0f, }, 1021 }; 1022 struct Cmds { 1023 EnableVertexAttribArray enable1; 1024 EnableVertexAttribArray enable2; 1025 BindBuffer bind_to_index; 1026 GetMaxValueInBufferCHROMIUM get_max; 1027 BindBuffer bind_to_emu; 1028 BufferData set_size; 1029 BufferSubData copy_data1; 1030 cmd::SetToken set_token1; 1031 VertexAttribPointer set_pointer1; 1032 BufferSubData copy_data2; 1033 cmd::SetToken set_token2; 1034 VertexAttribPointer set_pointer2; 1035 DrawElements draw; 1036 BindBuffer restore; 1037 }; 1038 const GLuint kEmuBufferId = GLES2Implementation::kClientSideArrayId; 1039 const GLuint kClientIndexBufferId = 0x789; 1040 const GLuint kIndexOffset = 0x40; 1041 const GLuint kMaxIndex = 2; 1042 const GLuint kAttribIndex1 = 1; 1043 const GLuint kAttribIndex2 = 3; 1044 const GLint kNumComponents1 = 3; 1045 const GLint kNumComponents2 = 2; 1046 const GLsizei kClientStride = sizeof(verts[0]); 1047 const GLsizei kCount = 2; 1048 const GLsizei kSize1 = 1049 arraysize(verts) * kNumComponents1 * sizeof(verts[0][0]); 1050 const GLsizei kSize2 = 1051 arraysize(verts) * kNumComponents2 * sizeof(verts[0][0]); 1052 const GLsizei kEmuOffset1 = 0; 1053 const GLsizei kEmuOffset2 = kSize1; 1054 const GLsizei kTotalSize = kSize1 + kSize2; 1055 1056 ExpectedMemoryInfo mem1 = GetExpectedResultMemory(sizeof(uint32)); 1057 ExpectedMemoryInfo mem2 = GetExpectedMemory(kSize1); 1058 ExpectedMemoryInfo mem3 = GetExpectedMemory(kSize2); 1059 1060 1061 Cmds expected; 1062 expected.enable1.Init(kAttribIndex1); 1063 expected.enable2.Init(kAttribIndex2); 1064 expected.bind_to_index.Init(GL_ELEMENT_ARRAY_BUFFER, kClientIndexBufferId); 1065 expected.get_max.Init(kClientIndexBufferId, kCount, GL_UNSIGNED_SHORT, 1066 kIndexOffset, mem1.id, mem1.offset); 1067 expected.bind_to_emu.Init(GL_ARRAY_BUFFER, kEmuBufferId); 1068 expected.set_size.Init(GL_ARRAY_BUFFER, kTotalSize, 0, 0, GL_DYNAMIC_DRAW); 1069 expected.copy_data1.Init( 1070 GL_ARRAY_BUFFER, kEmuOffset1, kSize1, mem2.id, mem2.offset); 1071 expected.set_token1.Init(GetNextToken()); 1072 expected.set_pointer1.Init(kAttribIndex1, kNumComponents1, 1073 GL_FLOAT, GL_FALSE, 0, kEmuOffset1); 1074 expected.copy_data2.Init( 1075 GL_ARRAY_BUFFER, kEmuOffset2, kSize2, mem3.id, mem3.offset); 1076 expected.set_token2.Init(GetNextToken()); 1077 expected.set_pointer2.Init(kAttribIndex2, kNumComponents2, 1078 GL_FLOAT, GL_FALSE, 0, kEmuOffset2); 1079 expected.draw.Init(GL_POINTS, kCount, GL_UNSIGNED_SHORT, kIndexOffset); 1080 expected.restore.Init(GL_ARRAY_BUFFER, 0); 1081 1082 EXPECT_CALL(*command_buffer(), OnFlush()) 1083 .WillOnce(SetMemory(mem1.ptr,kMaxIndex)) 1084 .RetiresOnSaturation(); 1085 1086 gl_->EnableVertexAttribArray(kAttribIndex1); 1087 gl_->EnableVertexAttribArray(kAttribIndex2); 1088 gl_->BindBuffer(GL_ELEMENT_ARRAY_BUFFER, kClientIndexBufferId); 1089 gl_->VertexAttribPointer(kAttribIndex1, kNumComponents1, 1090 GL_FLOAT, GL_FALSE, kClientStride, verts); 1091 gl_->VertexAttribPointer(kAttribIndex2, kNumComponents2, 1092 GL_FLOAT, GL_FALSE, kClientStride, verts); 1093 gl_->DrawElements(GL_POINTS, kCount, GL_UNSIGNED_SHORT, 1094 reinterpret_cast<const void*>(kIndexOffset)); 1095 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); 1096} 1097 1098TEST_F(GLES2ImplementationTest, DrawElementsInstancedANGLEClientSideBuffers) { 1099 static const float verts[][4] = { 1100 { 12.0f, 23.0f, 34.0f, 45.0f, }, 1101 { 56.0f, 67.0f, 78.0f, 89.0f, }, 1102 { 13.0f, 24.0f, 35.0f, 46.0f, }, 1103 }; 1104 static const uint16 indices[] = { 1105 1, 2, 1106 }; 1107 struct Cmds { 1108 EnableVertexAttribArray enable1; 1109 EnableVertexAttribArray enable2; 1110 VertexAttribDivisorANGLE divisor; 1111 BindBuffer bind_to_index_emu; 1112 BufferData set_index_size; 1113 BufferSubData copy_data0; 1114 cmd::SetToken set_token0; 1115 BindBuffer bind_to_emu; 1116 BufferData set_size; 1117 BufferSubData copy_data1; 1118 cmd::SetToken set_token1; 1119 VertexAttribPointer set_pointer1; 1120 BufferSubData copy_data2; 1121 cmd::SetToken set_token2; 1122 VertexAttribPointer set_pointer2; 1123 DrawElementsInstancedANGLE draw; 1124 BindBuffer restore; 1125 BindBuffer restore_element; 1126 }; 1127 const GLsizei kIndexSize = sizeof(indices); 1128 const GLuint kEmuBufferId = GLES2Implementation::kClientSideArrayId; 1129 const GLuint kEmuIndexBufferId = 1130 GLES2Implementation::kClientSideElementArrayId; 1131 const GLuint kAttribIndex1 = 1; 1132 const GLuint kAttribIndex2 = 3; 1133 const GLint kNumComponents1 = 3; 1134 const GLint kNumComponents2 = 2; 1135 const GLsizei kClientStride = sizeof(verts[0]); 1136 const GLsizei kCount = 2; 1137 const GLsizei kSize1 = 1138 arraysize(verts) * kNumComponents1 * sizeof(verts[0][0]); 1139 const GLsizei kSize2 = 1140 1 * kNumComponents2 * sizeof(verts[0][0]); 1141 const GLuint kDivisor = 1; 1142 const GLsizei kEmuOffset1 = 0; 1143 const GLsizei kEmuOffset2 = kSize1; 1144 const GLsizei kTotalSize = kSize1 + kSize2; 1145 1146 ExpectedMemoryInfo mem1 = GetExpectedMemory(kIndexSize); 1147 ExpectedMemoryInfo mem2 = GetExpectedMemory(kSize1); 1148 ExpectedMemoryInfo mem3 = GetExpectedMemory(kSize2); 1149 1150 Cmds expected; 1151 expected.enable1.Init(kAttribIndex1); 1152 expected.enable2.Init(kAttribIndex2); 1153 expected.divisor.Init(kAttribIndex2, kDivisor); 1154 expected.bind_to_index_emu.Init(GL_ELEMENT_ARRAY_BUFFER, kEmuIndexBufferId); 1155 expected.set_index_size.Init( 1156 GL_ELEMENT_ARRAY_BUFFER, kIndexSize, 0, 0, GL_DYNAMIC_DRAW); 1157 expected.copy_data0.Init( 1158 GL_ELEMENT_ARRAY_BUFFER, 0, kIndexSize, mem1.id, mem1.offset); 1159 expected.set_token0.Init(GetNextToken()); 1160 expected.bind_to_emu.Init(GL_ARRAY_BUFFER, kEmuBufferId); 1161 expected.set_size.Init(GL_ARRAY_BUFFER, kTotalSize, 0, 0, GL_DYNAMIC_DRAW); 1162 expected.copy_data1.Init( 1163 GL_ARRAY_BUFFER, kEmuOffset1, kSize1, mem2.id, mem2.offset); 1164 expected.set_token1.Init(GetNextToken()); 1165 expected.set_pointer1.Init( 1166 kAttribIndex1, kNumComponents1, GL_FLOAT, GL_FALSE, 0, kEmuOffset1); 1167 expected.copy_data2.Init( 1168 GL_ARRAY_BUFFER, kEmuOffset2, kSize2, mem3.id, mem3.offset); 1169 expected.set_token2.Init(GetNextToken()); 1170 expected.set_pointer2.Init(kAttribIndex2, kNumComponents2, 1171 GL_FLOAT, GL_FALSE, 0, kEmuOffset2); 1172 expected.draw.Init(GL_POINTS, kCount, GL_UNSIGNED_SHORT, 0, 1); 1173 expected.restore.Init(GL_ARRAY_BUFFER, 0); 1174 expected.restore_element.Init(GL_ELEMENT_ARRAY_BUFFER, 0); 1175 gl_->EnableVertexAttribArray(kAttribIndex1); 1176 gl_->EnableVertexAttribArray(kAttribIndex2); 1177 gl_->VertexAttribPointer(kAttribIndex1, kNumComponents1, 1178 GL_FLOAT, GL_FALSE, kClientStride, verts); 1179 gl_->VertexAttribPointer(kAttribIndex2, kNumComponents2, 1180 GL_FLOAT, GL_FALSE, kClientStride, verts); 1181 gl_->VertexAttribDivisorANGLE(kAttribIndex2, kDivisor); 1182 gl_->DrawElementsInstancedANGLE( 1183 GL_POINTS, kCount, GL_UNSIGNED_SHORT, indices, 1); 1184 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); 1185} 1186 1187TEST_F(GLES2ImplementationTest, GetVertexBufferPointerv) { 1188 static const float verts[1] = { 0.0f, }; 1189 const GLuint kAttribIndex1 = 1; 1190 const GLuint kAttribIndex2 = 3; 1191 const GLint kNumComponents1 = 3; 1192 const GLint kNumComponents2 = 2; 1193 const GLsizei kStride1 = 12; 1194 const GLsizei kStride2 = 0; 1195 const GLuint kBufferId = 0x123; 1196 const GLint kOffset2 = 0x456; 1197 1198 // Only one set and one get because the client side buffer's info is stored 1199 // on the client side. 1200 struct Cmds { 1201 BindBuffer bind; 1202 VertexAttribPointer set_pointer; 1203 GetVertexAttribPointerv get_pointer; 1204 }; 1205 1206 ExpectedMemoryInfo mem1 = GetExpectedResultMemory(16); 1207 1208 Cmds expected; 1209 expected.bind.Init(GL_ARRAY_BUFFER, kBufferId); 1210 expected.set_pointer.Init(kAttribIndex2, kNumComponents2, GL_FLOAT, GL_FALSE, 1211 kStride2, kOffset2); 1212 expected.get_pointer.Init(kAttribIndex2, GL_VERTEX_ATTRIB_ARRAY_POINTER, 1213 mem1.id, mem1.offset); 1214 1215 // One call to flush to way for GetVertexAttribPointerv 1216 EXPECT_CALL(*command_buffer(), OnFlush()) 1217 .WillOnce(SetMemory(mem1.ptr, SizedResultHelper<uint32>(kOffset2))) 1218 .RetiresOnSaturation(); 1219 1220 // Set one client side buffer. 1221 gl_->VertexAttribPointer(kAttribIndex1, kNumComponents1, 1222 GL_FLOAT, GL_FALSE, kStride1, verts); 1223 // Set one VBO 1224 gl_->BindBuffer(GL_ARRAY_BUFFER, kBufferId); 1225 gl_->VertexAttribPointer(kAttribIndex2, kNumComponents2, 1226 GL_FLOAT, GL_FALSE, kStride2, 1227 reinterpret_cast<const void*>(kOffset2)); 1228 // now get them both. 1229 void* ptr1 = NULL; 1230 void* ptr2 = NULL; 1231 1232 gl_->GetVertexAttribPointerv( 1233 kAttribIndex1, GL_VERTEX_ATTRIB_ARRAY_POINTER, &ptr1); 1234 gl_->GetVertexAttribPointerv( 1235 kAttribIndex2, GL_VERTEX_ATTRIB_ARRAY_POINTER, &ptr2); 1236 1237 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); 1238 EXPECT_TRUE(static_cast<const void*>(&verts) == ptr1); 1239 // because the service is not running ptr2 is not read. 1240 EXPECT_TRUE(ptr2 == reinterpret_cast<void*>(kOffset2)); 1241} 1242 1243TEST_F(GLES2ImplementationTest, GetVertexAttrib) { 1244 static const float verts[1] = { 0.0f, }; 1245 const GLuint kAttribIndex1 = 1; 1246 const GLuint kAttribIndex2 = 3; 1247 const GLint kNumComponents1 = 3; 1248 const GLint kNumComponents2 = 2; 1249 const GLsizei kStride1 = 12; 1250 const GLsizei kStride2 = 0; 1251 const GLuint kBufferId = 0x123; 1252 const GLint kOffset2 = 0x456; 1253 1254 // Only one set and one get because the client side buffer's info is stored 1255 // on the client side. 1256 struct Cmds { 1257 EnableVertexAttribArray enable; 1258 BindBuffer bind; 1259 VertexAttribPointer set_pointer; 1260 GetVertexAttribiv get1; // for getting the buffer from attrib2 1261 GetVertexAttribfv get2; // for getting the value from attrib1 1262 }; 1263 1264 ExpectedMemoryInfo mem1 = GetExpectedResultMemory(16); 1265 ExpectedMemoryInfo mem2 = GetExpectedResultMemory(16); 1266 1267 Cmds expected; 1268 expected.enable.Init(kAttribIndex1); 1269 expected.bind.Init(GL_ARRAY_BUFFER, kBufferId); 1270 expected.set_pointer.Init(kAttribIndex2, kNumComponents2, GL_FLOAT, GL_FALSE, 1271 kStride2, kOffset2); 1272 expected.get1.Init(kAttribIndex2, 1273 GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING, 1274 mem1.id, mem1.offset); 1275 expected.get2.Init(kAttribIndex1, 1276 GL_CURRENT_VERTEX_ATTRIB, 1277 mem2.id, mem2.offset); 1278 1279 FourFloats current_attrib(1.2f, 3.4f, 5.6f, 7.8f); 1280 1281 // One call to flush to way for GetVertexAttribiv 1282 EXPECT_CALL(*command_buffer(), OnFlush()) 1283 .WillOnce(SetMemory( 1284 mem1.ptr, SizedResultHelper<GLuint>(kBufferId))) 1285 .WillOnce(SetMemory( 1286 mem2.ptr, SizedResultHelper<FourFloats>(current_attrib))) 1287 .RetiresOnSaturation(); 1288 1289 gl_->EnableVertexAttribArray(kAttribIndex1); 1290 // Set one client side buffer. 1291 gl_->VertexAttribPointer(kAttribIndex1, kNumComponents1, 1292 GL_FLOAT, GL_FALSE, kStride1, verts); 1293 // Set one VBO 1294 gl_->BindBuffer(GL_ARRAY_BUFFER, kBufferId); 1295 gl_->VertexAttribPointer(kAttribIndex2, kNumComponents2, 1296 GL_FLOAT, GL_FALSE, kStride2, 1297 reinterpret_cast<const void*>(kOffset2)); 1298 // first get the service side once to see that we make a command 1299 GLint buffer_id = 0; 1300 GLint enabled = 0; 1301 GLint size = 0; 1302 GLint stride = 0; 1303 GLint type = 0; 1304 GLint normalized = 1; 1305 float current[4] = { 0.0f, }; 1306 1307 gl_->GetVertexAttribiv( 1308 kAttribIndex2, GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING, &buffer_id); 1309 EXPECT_EQ(kBufferId, static_cast<GLuint>(buffer_id)); 1310 gl_->GetVertexAttribiv( 1311 kAttribIndex1, GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING, &buffer_id); 1312 gl_->GetVertexAttribiv( 1313 kAttribIndex1, GL_VERTEX_ATTRIB_ARRAY_ENABLED, &enabled); 1314 gl_->GetVertexAttribiv( 1315 kAttribIndex1, GL_VERTEX_ATTRIB_ARRAY_SIZE, &size); 1316 gl_->GetVertexAttribiv( 1317 kAttribIndex1, GL_VERTEX_ATTRIB_ARRAY_STRIDE, &stride); 1318 gl_->GetVertexAttribiv( 1319 kAttribIndex1, GL_VERTEX_ATTRIB_ARRAY_TYPE, &type); 1320 gl_->GetVertexAttribiv( 1321 kAttribIndex1, GL_VERTEX_ATTRIB_ARRAY_NORMALIZED, &normalized); 1322 gl_->GetVertexAttribfv( 1323 kAttribIndex1, GL_CURRENT_VERTEX_ATTRIB, ¤t[0]); 1324 1325 EXPECT_EQ(0, buffer_id); 1326 EXPECT_EQ(GL_TRUE, enabled); 1327 EXPECT_EQ(kNumComponents1, size); 1328 EXPECT_EQ(kStride1, stride); 1329 EXPECT_EQ(GL_FLOAT, type); 1330 EXPECT_EQ(GL_FALSE, normalized); 1331 EXPECT_EQ(0, memcmp(¤t_attrib, ¤t, sizeof(current_attrib))); 1332 1333 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); 1334} 1335 1336TEST_F(GLES2ImplementationTest, ReservedIds) { 1337 // Only the get error command should be issued. 1338 struct Cmds { 1339 GetError get; 1340 }; 1341 Cmds expected; 1342 1343 ExpectedMemoryInfo mem1 = GetExpectedResultMemory(sizeof(GetError::Result)); 1344 1345 expected.get.Init(mem1.id, mem1.offset); 1346 1347 // One call to flush to wait for GetError 1348 EXPECT_CALL(*command_buffer(), OnFlush()) 1349 .WillOnce(SetMemory(mem1.ptr, GLuint(GL_NO_ERROR))) 1350 .RetiresOnSaturation(); 1351 1352 gl_->BindBuffer( 1353 GL_ARRAY_BUFFER, 1354 GLES2Implementation::kClientSideArrayId); 1355 gl_->BindBuffer( 1356 GL_ARRAY_BUFFER, 1357 GLES2Implementation::kClientSideElementArrayId); 1358 GLenum err = gl_->GetError(); 1359 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_OPERATION), err); 1360 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); 1361} 1362 1363#endif // defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS) 1364 1365TEST_F(GLES2ImplementationTest, ReadPixels2Reads) { 1366 struct Cmds { 1367 ReadPixels read1; 1368 cmd::SetToken set_token1; 1369 ReadPixels read2; 1370 cmd::SetToken set_token2; 1371 }; 1372 const GLint kBytesPerPixel = 4; 1373 const GLint kWidth = 1374 (kTransferBufferSize - GLES2Implementation::kStartingOffset) / 1375 kBytesPerPixel; 1376 const GLint kHeight = 2; 1377 const GLenum kFormat = GL_RGBA; 1378 const GLenum kType = GL_UNSIGNED_BYTE; 1379 1380 ExpectedMemoryInfo mem1 = 1381 GetExpectedMemory(kWidth * kHeight / 2 * kBytesPerPixel); 1382 ExpectedMemoryInfo result1 = 1383 GetExpectedResultMemory(sizeof(ReadPixels::Result)); 1384 ExpectedMemoryInfo mem2 = 1385 GetExpectedMemory(kWidth * kHeight / 2 * kBytesPerPixel); 1386 ExpectedMemoryInfo result2 = 1387 GetExpectedResultMemory(sizeof(ReadPixels::Result)); 1388 1389 Cmds expected; 1390 expected.read1.Init( 1391 0, 0, kWidth, kHeight / 2, kFormat, kType, 1392 mem1.id, mem1.offset, result1.id, result1.offset); 1393 expected.set_token1.Init(GetNextToken()); 1394 expected.read2.Init( 1395 0, kHeight / 2, kWidth, kHeight / 2, kFormat, kType, 1396 mem2.id, mem2.offset, result2.id, result2.offset); 1397 expected.set_token2.Init(GetNextToken()); 1398 scoped_array<int8> buffer(new int8[kWidth * kHeight * kBytesPerPixel]); 1399 1400 EXPECT_CALL(*command_buffer(), OnFlush()) 1401 .WillOnce(SetMemory(result1.ptr, static_cast<uint32>(1))) 1402 .WillOnce(SetMemory(result2.ptr, static_cast<uint32>(1))) 1403 .RetiresOnSaturation(); 1404 1405 gl_->ReadPixels(0, 0, kWidth, kHeight, kFormat, kType, buffer.get()); 1406 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); 1407} 1408 1409TEST_F(GLES2ImplementationTest, ReadPixelsBadFormatType) { 1410 struct Cmds { 1411 ReadPixels read; 1412 cmd::SetToken set_token; 1413 }; 1414 const GLint kBytesPerPixel = 4; 1415 const GLint kWidth = 2; 1416 const GLint kHeight = 2; 1417 const GLenum kFormat = 0; 1418 const GLenum kType = 0; 1419 1420 ExpectedMemoryInfo mem1 = 1421 GetExpectedMemory(kWidth * kHeight * kBytesPerPixel); 1422 ExpectedMemoryInfo result1 = 1423 GetExpectedResultMemory(sizeof(ReadPixels::Result)); 1424 1425 Cmds expected; 1426 expected.read.Init( 1427 0, 0, kWidth, kHeight, kFormat, kType, 1428 mem1.id, mem1.offset, result1.id, result1.offset); 1429 expected.set_token.Init(GetNextToken()); 1430 scoped_array<int8> buffer(new int8[kWidth * kHeight * kBytesPerPixel]); 1431 1432 EXPECT_CALL(*command_buffer(), OnFlush()) 1433 .Times(1) 1434 .RetiresOnSaturation(); 1435 1436 gl_->ReadPixels(0, 0, kWidth, kHeight, kFormat, kType, buffer.get()); 1437} 1438 1439TEST_F(GLES2ImplementationTest, FreeUnusedSharedMemory) { 1440 struct Cmds { 1441 BufferSubData buf; 1442 cmd::SetToken set_token; 1443 }; 1444 const GLenum kTarget = GL_ELEMENT_ARRAY_BUFFER; 1445 const GLintptr kOffset = 15; 1446 const GLsizeiptr kSize = 16; 1447 1448 ExpectedMemoryInfo mem1 = GetExpectedMemory(kSize); 1449 1450 Cmds expected; 1451 expected.buf.Init( 1452 kTarget, kOffset, kSize, mem1.id, mem1.offset); 1453 expected.set_token.Init(GetNextToken()); 1454 1455 void* mem = gl_->MapBufferSubDataCHROMIUM( 1456 kTarget, kOffset, kSize, GL_WRITE_ONLY); 1457 ASSERT_TRUE(mem != NULL); 1458 gl_->UnmapBufferSubDataCHROMIUM(mem); 1459 EXPECT_CALL(*command_buffer(), DestroyTransferBuffer(_)) 1460 .Times(1) 1461 .RetiresOnSaturation(); 1462 gl_->FreeUnusedSharedMemory(); 1463} 1464 1465TEST_F(GLES2ImplementationTest, MapUnmapBufferSubDataCHROMIUM) { 1466 struct Cmds { 1467 BufferSubData buf; 1468 cmd::SetToken set_token; 1469 }; 1470 const GLenum kTarget = GL_ELEMENT_ARRAY_BUFFER; 1471 const GLintptr kOffset = 15; 1472 const GLsizeiptr kSize = 16; 1473 1474 uint32 offset = 0; 1475 Cmds expected; 1476 expected.buf.Init( 1477 kTarget, kOffset, kSize, 1478 command_buffer()->GetNextFreeTransferBufferId(), offset); 1479 expected.set_token.Init(GetNextToken()); 1480 1481 void* mem = gl_->MapBufferSubDataCHROMIUM( 1482 kTarget, kOffset, kSize, GL_WRITE_ONLY); 1483 ASSERT_TRUE(mem != NULL); 1484 gl_->UnmapBufferSubDataCHROMIUM(mem); 1485 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); 1486} 1487 1488TEST_F(GLES2ImplementationTest, MapUnmapBufferSubDataCHROMIUMBadArgs) { 1489 const GLenum kTarget = GL_ELEMENT_ARRAY_BUFFER; 1490 const GLintptr kOffset = 15; 1491 const GLsizeiptr kSize = 16; 1492 1493 ExpectedMemoryInfo result1 = 1494 GetExpectedResultMemory(sizeof(GetError::Result)); 1495 ExpectedMemoryInfo result2 = 1496 GetExpectedResultMemory(sizeof(GetError::Result)); 1497 ExpectedMemoryInfo result3 = 1498 GetExpectedResultMemory(sizeof(GetError::Result)); 1499 ExpectedMemoryInfo result4 = 1500 GetExpectedResultMemory(sizeof(GetError::Result)); 1501 1502 // Calls to flush to wait for GetError 1503 EXPECT_CALL(*command_buffer(), OnFlush()) 1504 .WillOnce(SetMemory(result1.ptr, GLuint(GL_NO_ERROR))) 1505 .WillOnce(SetMemory(result2.ptr, GLuint(GL_NO_ERROR))) 1506 .WillOnce(SetMemory(result3.ptr, GLuint(GL_NO_ERROR))) 1507 .WillOnce(SetMemory(result4.ptr, GLuint(GL_NO_ERROR))) 1508 .RetiresOnSaturation(); 1509 1510 void* mem; 1511 mem = gl_->MapBufferSubDataCHROMIUM(kTarget, -1, kSize, GL_WRITE_ONLY); 1512 ASSERT_TRUE(mem == NULL); 1513 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE), gl_->GetError()); 1514 mem = gl_->MapBufferSubDataCHROMIUM(kTarget, kOffset, -1, GL_WRITE_ONLY); 1515 ASSERT_TRUE(mem == NULL); 1516 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE), gl_->GetError()); 1517 mem = gl_->MapBufferSubDataCHROMIUM(kTarget, kOffset, kSize, GL_READ_ONLY); 1518 ASSERT_TRUE(mem == NULL); 1519 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_ENUM), gl_->GetError()); 1520 const char* kPtr = "something"; 1521 gl_->UnmapBufferSubDataCHROMIUM(kPtr); 1522 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE), gl_->GetError()); 1523} 1524 1525TEST_F(GLES2ImplementationTest, MapUnmapTexSubImage2DCHROMIUM) { 1526 struct Cmds { 1527 TexSubImage2D tex; 1528 cmd::SetToken set_token; 1529 }; 1530 const GLint kLevel = 1; 1531 const GLint kXOffset = 2; 1532 const GLint kYOffset = 3; 1533 const GLint kWidth = 4; 1534 const GLint kHeight = 5; 1535 const GLenum kFormat = GL_RGBA; 1536 const GLenum kType = GL_UNSIGNED_BYTE; 1537 1538 uint32 offset = 0; 1539 Cmds expected; 1540 expected.tex.Init( 1541 GL_TEXTURE_2D, kLevel, kXOffset, kYOffset, kWidth, kHeight, kFormat, 1542 kType, 1543 command_buffer()->GetNextFreeTransferBufferId(), offset, GL_FALSE); 1544 expected.set_token.Init(GetNextToken()); 1545 1546 void* mem = gl_->MapTexSubImage2DCHROMIUM( 1547 GL_TEXTURE_2D, 1548 kLevel, 1549 kXOffset, 1550 kYOffset, 1551 kWidth, 1552 kHeight, 1553 kFormat, 1554 kType, 1555 GL_WRITE_ONLY); 1556 ASSERT_TRUE(mem != NULL); 1557 gl_->UnmapTexSubImage2DCHROMIUM(mem); 1558 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); 1559} 1560 1561TEST_F(GLES2ImplementationTest, MapUnmapTexSubImage2DCHROMIUMBadArgs) { 1562 const GLint kLevel = 1; 1563 const GLint kXOffset = 2; 1564 const GLint kYOffset = 3; 1565 const GLint kWidth = 4; 1566 const GLint kHeight = 5; 1567 const GLenum kFormat = GL_RGBA; 1568 const GLenum kType = GL_UNSIGNED_BYTE; 1569 1570 ExpectedMemoryInfo result1 = 1571 GetExpectedResultMemory(sizeof(GetError::Result)); 1572 ExpectedMemoryInfo result2 = 1573 GetExpectedResultMemory(sizeof(GetError::Result)); 1574 ExpectedMemoryInfo result3 = 1575 GetExpectedResultMemory(sizeof(GetError::Result)); 1576 ExpectedMemoryInfo result4 = 1577 GetExpectedResultMemory(sizeof(GetError::Result)); 1578 ExpectedMemoryInfo result5 = 1579 GetExpectedResultMemory(sizeof(GetError::Result)); 1580 ExpectedMemoryInfo result6 = 1581 GetExpectedResultMemory(sizeof(GetError::Result)); 1582 ExpectedMemoryInfo result7 = 1583 GetExpectedResultMemory(sizeof(GetError::Result)); 1584 1585 // Calls to flush to wait for GetError 1586 EXPECT_CALL(*command_buffer(), OnFlush()) 1587 .WillOnce(SetMemory(result1.ptr, GLuint(GL_NO_ERROR))) 1588 .WillOnce(SetMemory(result2.ptr, GLuint(GL_NO_ERROR))) 1589 .WillOnce(SetMemory(result3.ptr, GLuint(GL_NO_ERROR))) 1590 .WillOnce(SetMemory(result4.ptr, GLuint(GL_NO_ERROR))) 1591 .WillOnce(SetMemory(result5.ptr, GLuint(GL_NO_ERROR))) 1592 .WillOnce(SetMemory(result6.ptr, GLuint(GL_NO_ERROR))) 1593 .WillOnce(SetMemory(result7.ptr, GLuint(GL_NO_ERROR))) 1594 .RetiresOnSaturation(); 1595 1596 void* mem; 1597 mem = gl_->MapTexSubImage2DCHROMIUM( 1598 GL_TEXTURE_2D, 1599 -1, 1600 kXOffset, 1601 kYOffset, 1602 kWidth, 1603 kHeight, 1604 kFormat, 1605 kType, 1606 GL_WRITE_ONLY); 1607 EXPECT_TRUE(mem == NULL); 1608 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE), gl_->GetError()); 1609 mem = gl_->MapTexSubImage2DCHROMIUM( 1610 GL_TEXTURE_2D, 1611 kLevel, 1612 -1, 1613 kYOffset, 1614 kWidth, 1615 kHeight, 1616 kFormat, 1617 kType, 1618 GL_WRITE_ONLY); 1619 EXPECT_TRUE(mem == NULL); 1620 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE), gl_->GetError()); 1621 mem = gl_->MapTexSubImage2DCHROMIUM( 1622 GL_TEXTURE_2D, 1623 kLevel, 1624 kXOffset, 1625 -1, 1626 kWidth, 1627 kHeight, 1628 kFormat, 1629 kType, 1630 GL_WRITE_ONLY); 1631 EXPECT_TRUE(mem == NULL); 1632 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE), gl_->GetError()); 1633 mem = gl_->MapTexSubImage2DCHROMIUM( 1634 GL_TEXTURE_2D, 1635 kLevel, 1636 kXOffset, 1637 kYOffset, 1638 -1, 1639 kHeight, 1640 kFormat, 1641 kType, 1642 GL_WRITE_ONLY); 1643 EXPECT_TRUE(mem == NULL); 1644 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE), gl_->GetError()); 1645 mem = gl_->MapTexSubImage2DCHROMIUM( 1646 GL_TEXTURE_2D, 1647 kLevel, 1648 kXOffset, 1649 kYOffset, 1650 kWidth, 1651 -1, 1652 kFormat, 1653 kType, 1654 GL_WRITE_ONLY); 1655 EXPECT_TRUE(mem == NULL); 1656 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE), gl_->GetError()); 1657 mem = gl_->MapTexSubImage2DCHROMIUM( 1658 GL_TEXTURE_2D, 1659 kLevel, 1660 kXOffset, 1661 kYOffset, 1662 kWidth, 1663 kHeight, 1664 kFormat, 1665 kType, 1666 GL_READ_ONLY); 1667 EXPECT_TRUE(mem == NULL); 1668 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_ENUM), gl_->GetError()); 1669 const char* kPtr = "something"; 1670 gl_->UnmapTexSubImage2DCHROMIUM(kPtr); 1671 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE), gl_->GetError()); 1672} 1673 1674TEST_F(GLES2ImplementationTest, GetMultipleIntegervCHROMIUMValidArgs) { 1675 const GLenum pnames[] = { 1676 GL_DEPTH_WRITEMASK, 1677 GL_COLOR_WRITEMASK, 1678 GL_STENCIL_WRITEMASK, 1679 }; 1680 const GLint num_results = 6; 1681 GLint results[num_results + 1]; 1682 struct Cmds { 1683 GetMultipleIntegervCHROMIUM get_multiple; 1684 cmd::SetToken set_token; 1685 }; 1686 const GLsizei kNumPnames = arraysize(pnames); 1687 const GLsizeiptr kResultsSize = num_results * sizeof(results[0]); 1688 const size_t kPNamesSize = kNumPnames * sizeof(pnames[0]); 1689 1690 ExpectedMemoryInfo mem1 = GetExpectedMemory(kPNamesSize + kResultsSize); 1691 ExpectedMemoryInfo result1 = GetExpectedResultMemory( 1692 sizeof(GetError::Result)); 1693 1694 const uint32 kPnamesOffset = mem1.offset; 1695 const uint32 kResultsOffset = mem1.offset + kPNamesSize; 1696 Cmds expected; 1697 expected.get_multiple.Init( 1698 mem1.id, kPnamesOffset, kNumPnames, 1699 mem1.id, kResultsOffset, kResultsSize); 1700 expected.set_token.Init(GetNextToken()); 1701 1702 const GLint kSentinel = 0x12345678; 1703 memset(results, 0, sizeof(results)); 1704 results[num_results] = kSentinel; 1705 const GLint returned_results[] = { 1706 1, 0, 1, 0, 1, -1, 1707 }; 1708 // One call to flush to wait for results 1709 EXPECT_CALL(*command_buffer(), OnFlush()) 1710 .WillOnce(SetMemoryFromArray(mem1.ptr + kPNamesSize, 1711 returned_results, sizeof(returned_results))) 1712 .WillOnce(SetMemory(result1.ptr, GLuint(GL_NO_ERROR))) 1713 .RetiresOnSaturation(); 1714 1715 gl_->GetMultipleIntegervCHROMIUM( 1716 &pnames[0], kNumPnames, &results[0], kResultsSize); 1717 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); 1718 EXPECT_EQ(0, memcmp(&returned_results, results, sizeof(returned_results))); 1719 EXPECT_EQ(kSentinel, results[num_results]); 1720 EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), gl_->GetError()); 1721} 1722 1723TEST_F(GLES2ImplementationTest, GetMultipleIntegervCHROMIUMBadArgs) { 1724 GLenum pnames[] = { 1725 GL_DEPTH_WRITEMASK, 1726 GL_COLOR_WRITEMASK, 1727 GL_STENCIL_WRITEMASK, 1728 }; 1729 const GLint num_results = 6; 1730 GLint results[num_results + 1]; 1731 const GLsizei kNumPnames = arraysize(pnames); 1732 const GLsizeiptr kResultsSize = num_results * sizeof(results[0]); 1733 1734 ExpectedMemoryInfo result1 = 1735 GetExpectedResultMemory(sizeof(GetError::Result)); 1736 ExpectedMemoryInfo result2 = 1737 GetExpectedResultMemory(sizeof(GetError::Result)); 1738 ExpectedMemoryInfo result3 = 1739 GetExpectedResultMemory(sizeof(GetError::Result)); 1740 ExpectedMemoryInfo result4 = 1741 GetExpectedResultMemory(sizeof(GetError::Result)); 1742 1743 // Calls to flush to wait for GetError 1744 EXPECT_CALL(*command_buffer(), OnFlush()) 1745 .WillOnce(SetMemory(result1.ptr, GLuint(GL_NO_ERROR))) 1746 .WillOnce(SetMemory(result2.ptr, GLuint(GL_NO_ERROR))) 1747 .WillOnce(SetMemory(result3.ptr, GLuint(GL_NO_ERROR))) 1748 .WillOnce(SetMemory(result4.ptr, GLuint(GL_NO_ERROR))) 1749 .RetiresOnSaturation(); 1750 1751 const GLint kSentinel = 0x12345678; 1752 memset(results, 0, sizeof(results)); 1753 results[num_results] = kSentinel; 1754 // try bad size. 1755 gl_->GetMultipleIntegervCHROMIUM( 1756 &pnames[0], kNumPnames, &results[0], kResultsSize + 1); 1757 EXPECT_TRUE(NoCommandsWritten()); 1758 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE), gl_->GetError()); 1759 EXPECT_EQ(0, results[0]); 1760 EXPECT_EQ(kSentinel, results[num_results]); 1761 // try bad size. 1762 ClearCommands(); 1763 gl_->GetMultipleIntegervCHROMIUM( 1764 &pnames[0], kNumPnames, &results[0], kResultsSize - 1); 1765 EXPECT_TRUE(NoCommandsWritten()); 1766 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE), gl_->GetError()); 1767 EXPECT_EQ(0, results[0]); 1768 EXPECT_EQ(kSentinel, results[num_results]); 1769 // try uncleared results. 1770 ClearCommands(); 1771 results[2] = 1; 1772 gl_->GetMultipleIntegervCHROMIUM( 1773 &pnames[0], kNumPnames, &results[0], kResultsSize); 1774 EXPECT_TRUE(NoCommandsWritten()); 1775 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE), gl_->GetError()); 1776 EXPECT_EQ(0, results[0]); 1777 EXPECT_EQ(kSentinel, results[num_results]); 1778 // try bad enum results. 1779 ClearCommands(); 1780 results[2] = 0; 1781 pnames[1] = GL_TRUE; 1782 gl_->GetMultipleIntegervCHROMIUM( 1783 &pnames[0], kNumPnames, &results[0], kResultsSize); 1784 EXPECT_TRUE(NoCommandsWritten()); 1785 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_ENUM), gl_->GetError()); 1786 EXPECT_EQ(0, results[0]); 1787 EXPECT_EQ(kSentinel, results[num_results]); 1788} 1789 1790TEST_F(GLES2ImplementationTest, GetProgramInfoCHROMIUMGoodArgs) { 1791 const uint32 kBucketId = GLES2Implementation::kResultBucketId; 1792 const GLuint kProgramId = 123; 1793 const char kBad = 0x12; 1794 GLsizei size = 0; 1795 const Str7 kString = {"foobar"}; 1796 char buf[20]; 1797 1798 ExpectedMemoryInfo mem1 = 1799 GetExpectedMemory(MaxTransferBufferSize()); 1800 ExpectedMemoryInfo result1 = 1801 GetExpectedResultMemory(sizeof(cmd::GetBucketStart::Result)); 1802 ExpectedMemoryInfo result2 = 1803 GetExpectedResultMemory(sizeof(GetError::Result)); 1804 1805 memset(buf, kBad, sizeof(buf)); 1806 EXPECT_CALL(*command_buffer(), OnFlush()) 1807 .WillOnce(DoAll(SetMemory(result1.ptr, uint32(sizeof(kString))), 1808 SetMemory(mem1.ptr, kString))) 1809 .WillOnce(SetMemory(result2.ptr, GLuint(GL_NO_ERROR))) 1810 .RetiresOnSaturation(); 1811 1812 struct Cmds { 1813 cmd::SetBucketSize set_bucket_size1; 1814 GetProgramInfoCHROMIUM get_program_info; 1815 cmd::GetBucketStart get_bucket_start; 1816 cmd::SetToken set_token1; 1817 cmd::SetBucketSize set_bucket_size2; 1818 }; 1819 Cmds expected; 1820 expected.set_bucket_size1.Init(kBucketId, 0); 1821 expected.get_program_info.Init(kProgramId, kBucketId); 1822 expected.get_bucket_start.Init( 1823 kBucketId, result1.id, result1.offset, 1824 MaxTransferBufferSize(), mem1.id, mem1.offset); 1825 expected.set_token1.Init(GetNextToken()); 1826 expected.set_bucket_size2.Init(kBucketId, 0); 1827 gl_->GetProgramInfoCHROMIUM(kProgramId, sizeof(buf), &size, &buf); 1828 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); 1829 EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), gl_->GetError()); 1830 EXPECT_EQ(sizeof(kString), static_cast<size_t>(size)); 1831 EXPECT_STREQ(kString.str, buf); 1832 EXPECT_EQ(buf[sizeof(kString)], kBad); 1833} 1834 1835TEST_F(GLES2ImplementationTest, GetProgramInfoCHROMIUMBadArgs) { 1836 const uint32 kBucketId = GLES2Implementation::kResultBucketId; 1837 const GLuint kProgramId = 123; 1838 GLsizei size = 0; 1839 const Str7 kString = {"foobar"}; 1840 char buf[20]; 1841 1842 ExpectedMemoryInfo mem1 = GetExpectedMemory(MaxTransferBufferSize()); 1843 ExpectedMemoryInfo result1 = 1844 GetExpectedResultMemory(sizeof(cmd::GetBucketStart::Result)); 1845 ExpectedMemoryInfo result2 = 1846 GetExpectedResultMemory(sizeof(GetError::Result)); 1847 ExpectedMemoryInfo result3 = 1848 GetExpectedResultMemory(sizeof(GetError::Result)); 1849 ExpectedMemoryInfo result4 = 1850 GetExpectedResultMemory(sizeof(GetError::Result)); 1851 1852 EXPECT_CALL(*command_buffer(), OnFlush()) 1853 .WillOnce(DoAll(SetMemory(result1.ptr, uint32(sizeof(kString))), 1854 SetMemory(mem1.ptr, kString))) 1855 .WillOnce(SetMemory(result2.ptr, GLuint(GL_NO_ERROR))) 1856 .WillOnce(SetMemory(result3.ptr, GLuint(GL_NO_ERROR))) 1857 .WillOnce(SetMemory(result4.ptr, GLuint(GL_NO_ERROR))) 1858 .RetiresOnSaturation(); 1859 1860 // try bufsize not big enough. 1861 struct Cmds { 1862 cmd::SetBucketSize set_bucket_size1; 1863 GetProgramInfoCHROMIUM get_program_info; 1864 cmd::GetBucketStart get_bucket_start; 1865 cmd::SetToken set_token1; 1866 cmd::SetBucketSize set_bucket_size2; 1867 }; 1868 Cmds expected; 1869 expected.set_bucket_size1.Init(kBucketId, 0); 1870 expected.get_program_info.Init(kProgramId, kBucketId); 1871 expected.get_bucket_start.Init( 1872 kBucketId, result1.id, result1.offset, 1873 MaxTransferBufferSize(), mem1.id, mem1.offset); 1874 expected.set_token1.Init(GetNextToken()); 1875 expected.set_bucket_size2.Init(kBucketId, 0); 1876 gl_->GetProgramInfoCHROMIUM(kProgramId, 6, &size, &buf); 1877 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); 1878 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_OPERATION), gl_->GetError()); 1879 ClearCommands(); 1880 1881 // try bad bufsize 1882 gl_->GetProgramInfoCHROMIUM(kProgramId, -1, &size, &buf); 1883 EXPECT_TRUE(NoCommandsWritten()); 1884 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE), gl_->GetError()); 1885 ClearCommands(); 1886 // try no size ptr. 1887 gl_->GetProgramInfoCHROMIUM(kProgramId, sizeof(buf), NULL, &buf); 1888 EXPECT_TRUE(NoCommandsWritten()); 1889 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE), gl_->GetError()); 1890} 1891 1892// Test that things are cached 1893TEST_F(GLES2ImplementationTest, GetIntegerCacheRead) { 1894 struct PNameValue { 1895 GLenum pname; 1896 GLint expected; 1897 }; 1898 const PNameValue pairs[] = { 1899 { GL_ACTIVE_TEXTURE, GL_TEXTURE0, }, 1900 { GL_TEXTURE_BINDING_2D, 0, }, 1901 { GL_TEXTURE_BINDING_CUBE_MAP, 0, }, 1902 { GL_FRAMEBUFFER_BINDING, 0, }, 1903 { GL_RENDERBUFFER_BINDING, 0, }, 1904 { GL_ARRAY_BUFFER_BINDING, 0, }, 1905 { GL_ELEMENT_ARRAY_BUFFER_BINDING, 0, }, 1906 { GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, kMaxCombinedTextureImageUnits, }, 1907 { GL_MAX_CUBE_MAP_TEXTURE_SIZE, kMaxCubeMapTextureSize, }, 1908 { GL_MAX_FRAGMENT_UNIFORM_VECTORS, kMaxFragmentUniformVectors, }, 1909 { GL_MAX_RENDERBUFFER_SIZE, kMaxRenderbufferSize, }, 1910 { GL_MAX_TEXTURE_IMAGE_UNITS, kMaxTextureImageUnits, }, 1911 { GL_MAX_TEXTURE_SIZE, kMaxTextureSize, }, 1912 { GL_MAX_VARYING_VECTORS, kMaxVaryingVectors, }, 1913 { GL_MAX_VERTEX_ATTRIBS, kMaxVertexAttribs, }, 1914 { GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, kMaxVertexTextureImageUnits, }, 1915 { GL_MAX_VERTEX_UNIFORM_VECTORS, kMaxVertexUniformVectors, }, 1916 { GL_NUM_COMPRESSED_TEXTURE_FORMATS, kNumCompressedTextureFormats, }, 1917 { GL_NUM_SHADER_BINARY_FORMATS, kNumShaderBinaryFormats, }, 1918 }; 1919 size_t num_pairs = sizeof(pairs) / sizeof(pairs[0]); 1920 for (size_t ii = 0; ii < num_pairs; ++ii) { 1921 const PNameValue& pv = pairs[ii]; 1922 GLint v = -1; 1923 gl_->GetIntegerv(pv.pname, &v); 1924 EXPECT_TRUE(NoCommandsWritten()); 1925 EXPECT_EQ(pv.expected, v); 1926 } 1927 1928 ExpectedMemoryInfo result1 = 1929 GetExpectedResultMemory(sizeof(GetError::Result)); 1930 1931 EXPECT_CALL(*command_buffer(), OnFlush()) 1932 .WillOnce(SetMemory(result1.ptr, GLuint(GL_NO_ERROR))) 1933 .RetiresOnSaturation(); 1934 EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), gl_->GetError()); 1935} 1936 1937TEST_F(GLES2ImplementationTest, GetIntegerCacheWrite) { 1938 struct PNameValue { 1939 GLenum pname; 1940 GLint expected; 1941 }; 1942 gl_->ActiveTexture(GL_TEXTURE4); 1943 gl_->BindBuffer(GL_ARRAY_BUFFER, 2); 1944 gl_->BindBuffer(GL_ELEMENT_ARRAY_BUFFER, 3); 1945 gl_->BindFramebuffer(GL_FRAMEBUFFER, 4); 1946 gl_->BindRenderbuffer(GL_RENDERBUFFER, 5); 1947 gl_->BindTexture(GL_TEXTURE_2D, 6); 1948 gl_->BindTexture(GL_TEXTURE_CUBE_MAP, 7); 1949 1950 const PNameValue pairs[] = { 1951 { GL_ACTIVE_TEXTURE, GL_TEXTURE4, }, 1952 { GL_ARRAY_BUFFER_BINDING, 2, }, 1953 { GL_ELEMENT_ARRAY_BUFFER_BINDING, 3, }, 1954 { GL_FRAMEBUFFER_BINDING, 4, }, 1955 { GL_RENDERBUFFER_BINDING, 5, }, 1956 { GL_TEXTURE_BINDING_2D, 6, }, 1957 { GL_TEXTURE_BINDING_CUBE_MAP, 7, }, 1958 }; 1959 size_t num_pairs = sizeof(pairs) / sizeof(pairs[0]); 1960 for (size_t ii = 0; ii < num_pairs; ++ii) { 1961 const PNameValue& pv = pairs[ii]; 1962 GLint v = -1; 1963 gl_->GetIntegerv(pv.pname, &v); 1964 EXPECT_EQ(pv.expected, v); 1965 } 1966 1967 ExpectedMemoryInfo result1 = 1968 GetExpectedResultMemory(sizeof(GetError::Result)); 1969 1970 EXPECT_CALL(*command_buffer(), OnFlush()) 1971 .WillOnce(SetMemory(result1.ptr, GLuint(GL_NO_ERROR))) 1972 .RetiresOnSaturation(); 1973 EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), gl_->GetError()); 1974} 1975 1976static bool CheckRect( 1977 int width, int height, GLenum format, GLenum type, int alignment, 1978 bool flip_y, const uint8* r1, const uint8* r2) { 1979 uint32 size = 0; 1980 uint32 unpadded_row_size = 0; 1981 uint32 padded_row_size = 0; 1982 if (!GLES2Util::ComputeImageDataSizes( 1983 width, height, format, type, alignment, &size, &unpadded_row_size, 1984 &padded_row_size)) { 1985 return false; 1986 } 1987 1988 int r2_stride = flip_y ? 1989 -static_cast<int>(padded_row_size) : 1990 static_cast<int>(padded_row_size); 1991 r2 = flip_y ? (r2 + (height - 1) * padded_row_size) : r2; 1992 1993 for (int y = 0; y < height; ++y) { 1994 if (memcmp(r1, r2, unpadded_row_size) != 0) { 1995 return false; 1996 } 1997 r1 += padded_row_size; 1998 r2 += r2_stride; 1999 } 2000 return true; 2001} 2002 2003ACTION_P8(CheckRectAction, width, height, format, type, alignment, flip_y, 2004 r1, r2) { 2005 EXPECT_TRUE(CheckRect( 2006 width, height, format, type, alignment, flip_y, r1, r2)); 2007} 2008 2009// Test TexImage2D with and without flip_y 2010TEST_F(GLES2ImplementationTest, TexImage2D) { 2011 struct Cmds { 2012 TexImage2D tex_image_2d; 2013 cmd::SetToken set_token; 2014 }; 2015 struct Cmds2 { 2016 TexImage2D tex_image_2d; 2017 cmd::SetToken set_token; 2018 }; 2019 const GLenum kTarget = GL_TEXTURE_2D; 2020 const GLint kLevel = 0; 2021 const GLenum kFormat = GL_RGB; 2022 const GLsizei kWidth = 3; 2023 const GLsizei kHeight = 4; 2024 const GLint kBorder = 0; 2025 const GLenum kType = GL_UNSIGNED_BYTE; 2026 const GLint kPixelStoreUnpackAlignment = 4; 2027 static uint8 pixels[] = { 2028 11, 12, 13, 13, 14, 15, 15, 16, 17, 101, 102, 103, 2029 21, 22, 23, 23, 24, 25, 25, 26, 27, 201, 202, 203, 2030 31, 32, 33, 33, 34, 35, 35, 36, 37, 123, 124, 125, 2031 41, 42, 43, 43, 44, 45, 45, 46, 47, 2032 }; 2033 2034 ExpectedMemoryInfo mem1 = GetExpectedMemory(sizeof(pixels)); 2035 2036 Cmds expected; 2037 expected.tex_image_2d.Init( 2038 kTarget, kLevel, kFormat, kWidth, kHeight, kBorder, kFormat, kType, 2039 mem1.id, mem1.offset); 2040 expected.set_token.Init(GetNextToken()); 2041 gl_->TexImage2D( 2042 kTarget, kLevel, kFormat, kWidth, kHeight, kBorder, kFormat, kType, 2043 pixels); 2044 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); 2045 EXPECT_TRUE(CheckRect( 2046 kWidth, kHeight, kFormat, kType, kPixelStoreUnpackAlignment, false, 2047 pixels, mem1.ptr)); 2048 2049 ClearCommands(); 2050 gl_->PixelStorei(GL_UNPACK_FLIP_Y_CHROMIUM, GL_TRUE); 2051 2052 ExpectedMemoryInfo mem2 = GetExpectedMemory(sizeof(pixels)); 2053 Cmds2 expected2; 2054 expected2.tex_image_2d.Init( 2055 kTarget, kLevel, kFormat, kWidth, kHeight, kBorder, kFormat, kType, 2056 mem2.id, mem2.offset); 2057 expected2.set_token.Init(GetNextToken()); 2058 const void* commands2 = GetPut(); 2059 gl_->TexImage2D( 2060 kTarget, kLevel, kFormat, kWidth, kHeight, kBorder, kFormat, kType, 2061 pixels); 2062 EXPECT_EQ(0, memcmp(&expected2, commands2, sizeof(expected2))); 2063 EXPECT_TRUE(CheckRect( 2064 kWidth, kHeight, kFormat, kType, kPixelStoreUnpackAlignment, true, 2065 pixels, mem2.ptr)); 2066} 2067 2068// Test TexImage2D with 2 writes 2069TEST_F(GLES2ImplementationTest, TexImage2D2Writes) { 2070 struct Cmds { 2071 TexImage2D tex_image_2d; 2072 TexSubImage2D tex_sub_image_2d1; 2073 cmd::SetToken set_token1; 2074 TexSubImage2D tex_sub_image_2d2; 2075 cmd::SetToken set_token2; 2076 }; 2077 const GLenum kTarget = GL_TEXTURE_2D; 2078 const GLint kLevel = 0; 2079 const GLenum kFormat = GL_RGB; 2080 const GLint kBorder = 0; 2081 const GLenum kType = GL_UNSIGNED_BYTE; 2082 const GLint kPixelStoreUnpackAlignment = 4; 2083 const GLsizei kWidth = 3; 2084 2085 uint32 size = 0; 2086 uint32 unpadded_row_size = 0; 2087 uint32 padded_row_size = 0; 2088 ASSERT_TRUE(GLES2Util::ComputeImageDataSizes( 2089 kWidth, 2, kFormat, kType, kPixelStoreUnpackAlignment, 2090 &size, &unpadded_row_size, &padded_row_size)); 2091 const GLsizei kHeight = (MaxTransferBufferSize() / padded_row_size) * 2; 2092 ASSERT_TRUE(GLES2Util::ComputeImageDataSizes( 2093 kWidth, kHeight, kFormat, kType, kPixelStoreUnpackAlignment, 2094 &size, NULL, NULL)); 2095 uint32 half_size = 0; 2096 ASSERT_TRUE(GLES2Util::ComputeImageDataSizes( 2097 kWidth, kHeight / 2, kFormat, kType, kPixelStoreUnpackAlignment, 2098 &half_size, NULL, NULL)); 2099 2100 scoped_array<uint8> pixels(new uint8[size]); 2101 for (uint32 ii = 0; ii < size; ++ii) { 2102 pixels[ii] = static_cast<uint8>(ii); 2103 } 2104 2105 ExpectedMemoryInfo mem1 = GetExpectedMemory(half_size); 2106 ExpectedMemoryInfo mem2 = GetExpectedMemory(half_size); 2107 2108 Cmds expected; 2109 expected.tex_image_2d.Init( 2110 kTarget, kLevel, kFormat, kWidth, kHeight, kBorder, kFormat, kType, 2111 0, 0); 2112 expected.tex_sub_image_2d1.Init( 2113 kTarget, kLevel, 0, 0, kWidth, kHeight / 2, kFormat, kType, 2114 mem1.id, mem1.offset, true); 2115 expected.set_token1.Init(GetNextToken()); 2116 expected.tex_sub_image_2d2.Init( 2117 kTarget, kLevel, 0, kHeight / 2, kWidth, kHeight / 2, kFormat, kType, 2118 mem2.id, mem2.offset, true); 2119 expected.set_token2.Init(GetNextToken()); 2120 2121 // TODO(gman): Make it possible to run this test 2122 // EXPECT_CALL(*command_buffer(), OnFlush()) 2123 // .WillOnce(CheckRectAction( 2124 // kWidth, kHeight / 2, kFormat, kType, kPixelStoreUnpackAlignment, 2125 // false, pixels.get(), 2126 // GetExpectedTransferAddressFromOffsetAs<uint8>(offset1, half_size))) 2127 // .RetiresOnSaturation(); 2128 2129 gl_->TexImage2D( 2130 kTarget, kLevel, kFormat, kWidth, kHeight, kBorder, kFormat, kType, 2131 pixels.get()); 2132 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); 2133 EXPECT_TRUE(CheckRect( 2134 kWidth, kHeight / 2, kFormat, kType, kPixelStoreUnpackAlignment, false, 2135 pixels.get() + kHeight / 2 * padded_row_size, mem2.ptr)); 2136 2137 ClearCommands(); 2138 gl_->PixelStorei(GL_UNPACK_FLIP_Y_CHROMIUM, GL_TRUE); 2139 const void* commands2 = GetPut(); 2140 ExpectedMemoryInfo mem3 = GetExpectedMemory(half_size); 2141 ExpectedMemoryInfo mem4 = GetExpectedMemory(half_size); 2142 expected.tex_image_2d.Init( 2143 kTarget, kLevel, kFormat, kWidth, kHeight, kBorder, kFormat, kType, 2144 0, 0); 2145 expected.tex_sub_image_2d1.Init( 2146 kTarget, kLevel, 0, kHeight / 2, kWidth, kHeight / 2, kFormat, kType, 2147 mem3.id, mem3.offset, true); 2148 expected.set_token1.Init(GetNextToken()); 2149 expected.tex_sub_image_2d2.Init( 2150 kTarget, kLevel, 0, 0, kWidth, kHeight / 2, kFormat, kType, 2151 mem4.id, mem4.offset, true); 2152 expected.set_token2.Init(GetNextToken()); 2153 2154 // TODO(gman): Make it possible to run this test 2155 // EXPECT_CALL(*command_buffer(), OnFlush()) 2156 // .WillOnce(CheckRectAction( 2157 // kWidth, kHeight / 2, kFormat, kType, kPixelStoreUnpackAlignment, 2158 // true, pixels.get(), 2159 // GetExpectedTransferAddressFromOffsetAs<uint8>(offset3, half_size))) 2160 // .RetiresOnSaturation(); 2161 2162 gl_->TexImage2D( 2163 kTarget, kLevel, kFormat, kWidth, kHeight, kBorder, kFormat, kType, 2164 pixels.get()); 2165 EXPECT_EQ(0, memcmp(&expected, commands2, sizeof(expected))); 2166 EXPECT_TRUE(CheckRect( 2167 kWidth, kHeight / 2, kFormat, kType, kPixelStoreUnpackAlignment, true, 2168 pixels.get() + kHeight / 2 * padded_row_size, mem4.ptr)); 2169} 2170 2171// Test TexSubImage2D with GL_PACK_FLIP_Y set and partial multirow transfers 2172TEST_F(GLES2ImplementationTest, TexSubImage2DFlipY) { 2173 const GLsizei kTextureWidth = MaxTransferBufferSize() / 4; 2174 const GLsizei kTextureHeight = 7; 2175 const GLsizei kSubImageWidth = MaxTransferBufferSize() / 8; 2176 const GLsizei kSubImageHeight = 4; 2177 const GLint kSubImageXOffset = 1; 2178 const GLint kSubImageYOffset = 2; 2179 const GLenum kFormat = GL_RGBA; 2180 const GLenum kType = GL_UNSIGNED_BYTE; 2181 const GLenum kTarget = GL_TEXTURE_2D; 2182 const GLint kLevel = 0; 2183 const GLint kBorder = 0; 2184 const GLint kPixelStoreUnpackAlignment = 4; 2185 2186 struct Cmds { 2187 PixelStorei pixel_store_i1; 2188 TexImage2D tex_image_2d; 2189 PixelStorei pixel_store_i2; 2190 TexSubImage2D tex_sub_image_2d1; 2191 cmd::SetToken set_token1; 2192 TexSubImage2D tex_sub_image_2d2; 2193 cmd::SetToken set_token2; 2194 }; 2195 2196 uint32 sub_2_high_size = 0; 2197 ASSERT_TRUE(GLES2Util::ComputeImageDataSizes( 2198 kSubImageWidth, 2, kFormat, kType, kPixelStoreUnpackAlignment, 2199 &sub_2_high_size, NULL, NULL)); 2200 2201 ExpectedMemoryInfo mem1 = GetExpectedMemory(sub_2_high_size); 2202 ExpectedMemoryInfo mem2 = GetExpectedMemory(sub_2_high_size); 2203 2204 Cmds expected; 2205 expected.pixel_store_i1.Init(GL_UNPACK_ALIGNMENT, kPixelStoreUnpackAlignment); 2206 expected.tex_image_2d.Init( 2207 kTarget, kLevel, kFormat, kTextureWidth, kTextureHeight, kBorder, kFormat, 2208 kType, 0, 0); 2209 expected.pixel_store_i2.Init(GL_UNPACK_FLIP_Y_CHROMIUM, GL_TRUE); 2210 expected.tex_sub_image_2d1.Init(kTarget, kLevel, kSubImageXOffset, 2211 kSubImageYOffset + 2, kSubImageWidth, 2, kFormat, kType, 2212 mem1.id, mem1.offset, false); 2213 expected.set_token1.Init(GetNextToken()); 2214 expected.tex_sub_image_2d2.Init(kTarget, kLevel, kSubImageXOffset, 2215 kSubImageYOffset, kSubImageWidth , 2, kFormat, kType, 2216 mem2.id, mem2.offset, false); 2217 expected.set_token2.Init(GetNextToken()); 2218 2219 gl_->PixelStorei(GL_UNPACK_ALIGNMENT, kPixelStoreUnpackAlignment); 2220 gl_->TexImage2D( 2221 kTarget, kLevel, kFormat, kTextureWidth, kTextureHeight, kBorder, kFormat, 2222 kType, NULL); 2223 gl_->PixelStorei(GL_UNPACK_FLIP_Y_CHROMIUM, GL_TRUE); 2224 scoped_array<uint32> pixels(new uint32[kSubImageWidth * kSubImageHeight]); 2225 for (int y = 0; y < kSubImageHeight; ++y) { 2226 for (int x = 0; x < kSubImageWidth; ++x) { 2227 pixels.get()[kSubImageWidth * y + x] = x | (y << 16); 2228 } 2229 } 2230 gl_->TexSubImage2D( 2231 GL_TEXTURE_2D, 0, kSubImageXOffset, kSubImageYOffset, kSubImageWidth, 2232 kSubImageHeight, GL_RGBA, GL_UNSIGNED_BYTE, pixels.get()); 2233 2234 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); 2235 EXPECT_TRUE(CheckRect( 2236 kSubImageWidth, 2, kFormat, kType, kPixelStoreUnpackAlignment, true, 2237 reinterpret_cast<uint8*>(pixels.get() + 2 * kSubImageWidth), 2238 mem2.ptr)); 2239} 2240 2241TEST_F(GLES2ImplementationTest, SubImageUnpack) { 2242 static const GLint unpack_alignments[] = { 1, 2, 4, 8 }; 2243 2244 static const GLenum kFormat = GL_RGB; 2245 static const GLenum kType = GL_UNSIGNED_BYTE; 2246 static const GLint kLevel = 0; 2247 static const GLint kBorder = 0; 2248 // We're testing using the unpack params to pull a subimage out of a larger 2249 // source of pixels. Here we specify the subimage by its border rows / 2250 // columns. 2251 static const GLint kSrcWidth = 33; 2252 static const GLint kSrcSubImageX0 = 11; 2253 static const GLint kSrcSubImageX1 = 20; 2254 static const GLint kSrcSubImageY0 = 18; 2255 static const GLint kSrcSubImageY1 = 23; 2256 static const GLint kSrcSubImageWidth = kSrcSubImageX1 - kSrcSubImageX0; 2257 static const GLint kSrcSubImageHeight = kSrcSubImageY1 - kSrcSubImageY0; 2258 2259 // these are only used in the texsubimage tests 2260 static const GLint kTexWidth = 1023; 2261 static const GLint kTexHeight = 511; 2262 static const GLint kTexSubXOffset = 419; 2263 static const GLint kTexSubYOffset = 103; 2264 2265 struct { 2266 PixelStorei pixel_store_i; 2267 PixelStorei pixel_store_i2; 2268 TexImage2D tex_image_2d; 2269 } texImageExpected; 2270 2271 struct { 2272 PixelStorei pixel_store_i; 2273 PixelStorei pixel_store_i2; 2274 TexImage2D tex_image_2d; 2275 TexSubImage2D tex_sub_image_2d; 2276 } texSubImageExpected; 2277 2278 uint32 src_size; 2279 ASSERT_TRUE(GLES2Util::ComputeImageDataSizes( 2280 kSrcWidth, kSrcSubImageY1, kFormat, kType, 8, &src_size, NULL, NULL)); 2281 scoped_array<uint8> src_pixels; 2282 src_pixels.reset(new uint8[src_size]); 2283 for (size_t i = 0; i < src_size; ++i) { 2284 src_pixels[i] = static_cast<int8>(i); 2285 } 2286 2287 for (int sub = 0; sub < 2; ++sub) { 2288 for (int flip_y = 0; flip_y < 2; ++flip_y) { 2289 for (size_t a = 0; a < arraysize(unpack_alignments); ++a) { 2290 GLint alignment = unpack_alignments[a]; 2291 uint32 size; 2292 uint32 unpadded_row_size; 2293 uint32 padded_row_size; 2294 ASSERT_TRUE(GLES2Util::ComputeImageDataSizes( 2295 kSrcSubImageWidth, kSrcSubImageHeight, kFormat, kType, alignment, 2296 &size, &unpadded_row_size, &padded_row_size)); 2297 ASSERT_TRUE(size <= MaxTransferBufferSize()); 2298 ExpectedMemoryInfo mem = GetExpectedMemory(size); 2299 2300 const void* commands = GetPut(); 2301 gl_->PixelStorei(GL_UNPACK_ALIGNMENT, alignment); 2302 gl_->PixelStorei(GL_UNPACK_ROW_LENGTH, kSrcWidth); 2303 gl_->PixelStorei(GL_UNPACK_SKIP_PIXELS, kSrcSubImageX0); 2304 gl_->PixelStorei(GL_UNPACK_SKIP_ROWS, kSrcSubImageY0); 2305 gl_->PixelStorei(GL_UNPACK_FLIP_Y_CHROMIUM, flip_y); 2306 if (sub) { 2307 gl_->TexImage2D( 2308 GL_TEXTURE_2D, kLevel, kFormat, kTexWidth, kTexHeight, kBorder, 2309 kFormat, kType, NULL); 2310 gl_->TexSubImage2D( 2311 GL_TEXTURE_2D, kLevel, kTexSubXOffset, kTexSubYOffset, 2312 kSrcSubImageWidth, kSrcSubImageHeight, kFormat, kType, 2313 src_pixels.get()); 2314 texSubImageExpected.pixel_store_i.Init( 2315 GL_UNPACK_ALIGNMENT, alignment); 2316 texSubImageExpected.pixel_store_i2.Init( 2317 GL_UNPACK_FLIP_Y_CHROMIUM, flip_y); 2318 texSubImageExpected.tex_image_2d.Init( 2319 GL_TEXTURE_2D, kLevel, kFormat, kTexWidth, kTexHeight, kBorder, 2320 kFormat, kType, 0, 0); 2321 texSubImageExpected.tex_sub_image_2d.Init( 2322 GL_TEXTURE_2D, kLevel, kTexSubXOffset, kTexSubYOffset, 2323 kSrcSubImageWidth, kSrcSubImageHeight, kFormat, kType, mem.id, 2324 mem.offset, GL_FALSE); 2325 EXPECT_EQ(0, memcmp( 2326 &texSubImageExpected, commands, sizeof(texSubImageExpected))); 2327 } else { 2328 gl_->TexImage2D( 2329 GL_TEXTURE_2D, kLevel, kFormat, 2330 kSrcSubImageWidth, kSrcSubImageHeight, kBorder, kFormat, kType, 2331 src_pixels.get()); 2332 texImageExpected.pixel_store_i.Init(GL_UNPACK_ALIGNMENT, alignment); 2333 texImageExpected.pixel_store_i2.Init( 2334 GL_UNPACK_FLIP_Y_CHROMIUM, flip_y); 2335 texImageExpected.tex_image_2d.Init( 2336 GL_TEXTURE_2D, kLevel, kFormat, kSrcSubImageWidth, 2337 kSrcSubImageHeight, kBorder, kFormat, kType, mem.id, mem.offset); 2338 EXPECT_EQ(0, memcmp( 2339 &texImageExpected, commands, sizeof(texImageExpected))); 2340 } 2341 uint32 src_padded_row_size; 2342 ASSERT_TRUE(GLES2Util::ComputeImagePaddedRowSize( 2343 kSrcWidth, kFormat, kType, alignment, &src_padded_row_size)); 2344 uint32 bytes_per_group = GLES2Util::ComputeImageGroupSize( 2345 kFormat, kType); 2346 for (int y = 0; y < kSrcSubImageHeight; ++y) { 2347 GLint src_sub_y = flip_y ? kSrcSubImageHeight - y - 1 : y; 2348 const uint8* src_row = src_pixels.get() + 2349 (kSrcSubImageY0 + src_sub_y) * src_padded_row_size + 2350 bytes_per_group * kSrcSubImageX0; 2351 const uint8* dst_row = mem.ptr + y * padded_row_size; 2352 EXPECT_EQ(0, memcmp(src_row, dst_row, unpadded_row_size)); 2353 } 2354 ClearCommands(); 2355 } 2356 } 2357 } 2358} 2359 2360// Binds can not be cached with bind_generates_resource = false because 2361// our id might not be valid. More specifically if you bind on contextA then 2362// delete on contextB the resource is still bound on contextA but GetInterger 2363// won't return an id. 2364TEST_F(GLES2ImplementationStrictSharedTest, BindsNotCached) { 2365 struct PNameValue { 2366 GLenum pname; 2367 GLint expected; 2368 }; 2369 const PNameValue pairs[] = { 2370 { GL_TEXTURE_BINDING_2D, 1, }, 2371 { GL_TEXTURE_BINDING_CUBE_MAP, 2, }, 2372 { GL_FRAMEBUFFER_BINDING, 3, }, 2373 { GL_RENDERBUFFER_BINDING, 4, }, 2374 { GL_ARRAY_BUFFER_BINDING, 5, }, 2375 { GL_ELEMENT_ARRAY_BUFFER_BINDING, 6, }, 2376 }; 2377 size_t num_pairs = sizeof(pairs) / sizeof(pairs[0]); 2378 for (size_t ii = 0; ii < num_pairs; ++ii) { 2379 const PNameValue& pv = pairs[ii]; 2380 GLint v = -1; 2381 ExpectedMemoryInfo result1 = 2382 GetExpectedResultMemory(sizeof(GetIntegerv::Result)); 2383 EXPECT_CALL(*command_buffer(), OnFlush()) 2384 .WillOnce(SetMemory(result1.ptr, 2385 SizedResultHelper<GLuint>(pv.expected))) 2386 .RetiresOnSaturation(); 2387 gl_->GetIntegerv(pv.pname, &v); 2388 EXPECT_EQ(pv.expected, v); 2389 } 2390} 2391 2392TEST_F(GLES2ImplementationTest, CreateStreamTextureCHROMIUM) { 2393 const GLuint kTextureId = 123; 2394 const GLuint kResult = 456; 2395 2396 struct Cmds { 2397 CreateStreamTextureCHROMIUM create_stream; 2398 }; 2399 2400 ExpectedMemoryInfo result1 = 2401 GetExpectedResultMemory(sizeof(CreateStreamTextureCHROMIUM::Result)); 2402 ExpectedMemoryInfo result2 = 2403 GetExpectedResultMemory(sizeof(GetError::Result)); 2404 2405 Cmds expected; 2406 expected.create_stream.Init(kTextureId, result1.id, result1.offset); 2407 2408 EXPECT_CALL(*command_buffer(), OnFlush()) 2409 .WillOnce(SetMemory(result1.ptr, kResult)) 2410 .WillOnce(SetMemory(result2.ptr, GLuint(GL_NO_ERROR))) 2411 .RetiresOnSaturation(); 2412 2413 GLuint handle = gl_->CreateStreamTextureCHROMIUM(kTextureId); 2414 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); 2415 EXPECT_EQ(handle, kResult); 2416 EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), gl_->GetError()); 2417} 2418 2419TEST_F(GLES2ImplementationTest, GetString) { 2420 const uint32 kBucketId = GLES2Implementation::kResultBucketId; 2421 const Str7 kString = {"foobar"}; 2422 // GL_CHROMIUM_map_sub GL_CHROMIUM_flipy are hard coded into 2423 // GLES2Implementation. 2424 const char* expected_str = 2425 "foobar " 2426 "GL_CHROMIUM_flipy " 2427 "GL_CHROMIUM_map_sub " 2428 "GL_CHROMIUM_shallow_flush " 2429 "GL_EXT_unpack_subimage"; 2430 const char kBad = 0x12; 2431 struct Cmds { 2432 cmd::SetBucketSize set_bucket_size1; 2433 GetString get_string; 2434 cmd::GetBucketStart get_bucket_start; 2435 cmd::SetToken set_token1; 2436 cmd::SetBucketSize set_bucket_size2; 2437 }; 2438 ExpectedMemoryInfo mem1 = GetExpectedMemory(MaxTransferBufferSize()); 2439 ExpectedMemoryInfo result1 = 2440 GetExpectedResultMemory(sizeof(cmd::GetBucketStart::Result)); 2441 Cmds expected; 2442 expected.set_bucket_size1.Init(kBucketId, 0); 2443 expected.get_string.Init(GL_EXTENSIONS, kBucketId); 2444 expected.get_bucket_start.Init( 2445 kBucketId, result1.id, result1.offset, 2446 MaxTransferBufferSize(), mem1.id, mem1.offset); 2447 expected.set_token1.Init(GetNextToken()); 2448 expected.set_bucket_size2.Init(kBucketId, 0); 2449 char buf[sizeof(kString) + 1]; 2450 memset(buf, kBad, sizeof(buf)); 2451 2452 EXPECT_CALL(*command_buffer(), OnFlush()) 2453 .WillOnce(DoAll(SetMemory(result1.ptr, uint32(sizeof(kString))), 2454 SetMemory(mem1.ptr, kString))) 2455 .RetiresOnSaturation(); 2456 2457 const GLubyte* result = gl_->GetString(GL_EXTENSIONS); 2458 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); 2459 EXPECT_STREQ(expected_str, reinterpret_cast<const char*>(result)); 2460} 2461 2462TEST_F(GLES2ImplementationTest, PixelStoreiGLPackReverseRowOrderANGLE) { 2463 const uint32 kBucketId = GLES2Implementation::kResultBucketId; 2464 const Str7 kString = {"foobar"}; 2465 struct Cmds { 2466 cmd::SetBucketSize set_bucket_size1; 2467 GetString get_string; 2468 cmd::GetBucketStart get_bucket_start; 2469 cmd::SetToken set_token1; 2470 cmd::SetBucketSize set_bucket_size2; 2471 PixelStorei pixel_store; 2472 }; 2473 2474 ExpectedMemoryInfo mem1 = GetExpectedMemory(MaxTransferBufferSize()); 2475 ExpectedMemoryInfo result1 = 2476 GetExpectedResultMemory(sizeof(cmd::GetBucketStart::Result)); 2477 2478 Cmds expected; 2479 expected.set_bucket_size1.Init(kBucketId, 0); 2480 expected.get_string.Init(GL_EXTENSIONS, kBucketId); 2481 expected.get_bucket_start.Init( 2482 kBucketId, result1.id, result1.offset, 2483 MaxTransferBufferSize(), mem1.id, mem1.offset); 2484 expected.set_token1.Init(GetNextToken()); 2485 expected.set_bucket_size2.Init(kBucketId, 0); 2486 expected.pixel_store.Init(GL_PACK_REVERSE_ROW_ORDER_ANGLE, 1); 2487 2488 EXPECT_CALL(*command_buffer(), OnFlush()) 2489 .WillOnce(DoAll(SetMemory(result1.ptr, uint32(sizeof(kString))), 2490 SetMemory(mem1.ptr, kString))) 2491 .RetiresOnSaturation(); 2492 2493 gl_->PixelStorei(GL_PACK_REVERSE_ROW_ORDER_ANGLE, 1); 2494 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); 2495} 2496 2497TEST_F(GLES2ImplementationTest, CreateProgram) { 2498 struct Cmds { 2499 CreateProgram cmd; 2500 }; 2501 2502 Cmds expected; 2503 expected.cmd.Init(kProgramsAndShadersStartId); 2504 GLuint id = gl_->CreateProgram(); 2505 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); 2506 EXPECT_EQ(kProgramsAndShadersStartId, id); 2507} 2508 2509TEST_F(GLES2ImplementationTest, BufferDataLargerThanTransferBuffer) { 2510 struct Cmds { 2511 BufferData set_size; 2512 BufferSubData copy_data1; 2513 cmd::SetToken set_token1; 2514 BufferSubData copy_data2; 2515 cmd::SetToken set_token2; 2516 }; 2517 const unsigned kUsableSize = 2518 kTransferBufferSize - GLES2Implementation::kStartingOffset; 2519 uint8 buf[kUsableSize * 2] = { 0, }; 2520 2521 ExpectedMemoryInfo mem1 = GetExpectedMemory(kUsableSize); 2522 ExpectedMemoryInfo mem2 = GetExpectedMemory(kUsableSize); 2523 2524 Cmds expected; 2525 expected.set_size.Init( 2526 GL_ARRAY_BUFFER, arraysize(buf), 0, 0, GL_DYNAMIC_DRAW); 2527 expected.copy_data1.Init( 2528 GL_ARRAY_BUFFER, 0, kUsableSize, mem1.id, mem1.offset); 2529 expected.set_token1.Init(GetNextToken()); 2530 expected.copy_data2.Init( 2531 GL_ARRAY_BUFFER, kUsableSize, kUsableSize, mem2.id, mem2.offset); 2532 expected.set_token2.Init(GetNextToken()); 2533 gl_->BufferData(GL_ARRAY_BUFFER, arraysize(buf), buf, GL_DYNAMIC_DRAW); 2534 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); 2535} 2536 2537TEST_F(GLES2ImplementationTest, CapabilitiesAreCached) { 2538 static const GLenum kStates[] = { 2539 GL_DITHER, 2540 GL_BLEND, 2541 GL_CULL_FACE, 2542 GL_DEPTH_TEST, 2543 GL_POLYGON_OFFSET_FILL, 2544 GL_SAMPLE_ALPHA_TO_COVERAGE, 2545 GL_SAMPLE_COVERAGE, 2546 GL_SCISSOR_TEST, 2547 GL_STENCIL_TEST, 2548 }; 2549 struct Cmds { 2550 Enable enable_cmd; 2551 }; 2552 Cmds expected; 2553 2554 for (size_t ii = 0; ii < arraysize(kStates); ++ii) { 2555 GLenum state = kStates[ii]; 2556 expected.enable_cmd.Init(state); 2557 GLboolean result = gl_->IsEnabled(state); 2558 EXPECT_FALSE(result); 2559 EXPECT_TRUE(NoCommandsWritten()); 2560 const void* commands = GetPut(); 2561 gl_->Enable(state); 2562 EXPECT_EQ(0, memcmp(&expected, commands, sizeof(expected))); 2563 ClearCommands(); 2564 result = gl_->IsEnabled(state); 2565 EXPECT_TRUE(result); 2566 EXPECT_TRUE(NoCommandsWritten()); 2567 } 2568} 2569 2570TEST_F(GLES2ImplementationTest, BeginEndQueryEXT) { 2571 // Test GetQueryivEXT returns 0 if no current query. 2572 GLint param = -1; 2573 gl_->GetQueryivEXT(GL_ANY_SAMPLES_PASSED_EXT, GL_CURRENT_QUERY_EXT, ¶m); 2574 EXPECT_EQ(0, param); 2575 2576 GLuint expected_ids[2] = { 1, 2 }; // These must match what's actually genned. 2577 struct GenCmds { 2578 GenQueriesEXTImmediate gen; 2579 GLuint data[2]; 2580 }; 2581 GenCmds expected_gen_cmds; 2582 expected_gen_cmds.gen.Init(arraysize(expected_ids), &expected_ids[0]); 2583 GLuint ids[arraysize(expected_ids)] = { 0, }; 2584 gl_->GenQueriesEXT(arraysize(expected_ids), &ids[0]); 2585 EXPECT_EQ(0, memcmp( 2586 &expected_gen_cmds, commands_, sizeof(expected_gen_cmds))); 2587 GLuint id1 = ids[0]; 2588 GLuint id2 = ids[1]; 2589 ClearCommands(); 2590 2591 // Test BeginQueryEXT fails if id = 0. 2592 gl_->BeginQueryEXT(GL_ANY_SAMPLES_PASSED_EXT, 0); 2593 EXPECT_TRUE(NoCommandsWritten()); 2594 EXPECT_EQ(GL_INVALID_OPERATION, CheckError()); 2595 2596 // Test BeginQueryEXT fails if id not GENed. 2597 // TODO(gman): 2598 2599 // Test BeginQueryEXT inserts command. 2600 struct BeginCmds { 2601 BeginQueryEXT begin_query; 2602 }; 2603 BeginCmds expected_begin_cmds; 2604 const void* commands = GetPut(); 2605 gl_->BeginQueryEXT(GL_ANY_SAMPLES_PASSED_EXT, id1); 2606 QueryTracker::Query* query = GetQuery(id1); 2607 ASSERT_TRUE(query != NULL); 2608 expected_begin_cmds.begin_query.Init( 2609 GL_ANY_SAMPLES_PASSED_EXT, id1, query->shm_id(), query->shm_offset()); 2610 EXPECT_EQ(0, memcmp( 2611 &expected_begin_cmds, commands, sizeof(expected_begin_cmds))); 2612 ClearCommands(); 2613 2614 // Test GetQueryivEXT returns id. 2615 param = -1; 2616 gl_->GetQueryivEXT(GL_ANY_SAMPLES_PASSED_EXT, GL_CURRENT_QUERY_EXT, ¶m); 2617 EXPECT_EQ(id1, static_cast<GLuint>(param)); 2618 gl_->GetQueryivEXT( 2619 GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT, GL_CURRENT_QUERY_EXT, ¶m); 2620 EXPECT_EQ(0, param); 2621 2622 // Test BeginQueryEXT fails if between Begin/End. 2623 gl_->BeginQueryEXT(GL_ANY_SAMPLES_PASSED_EXT, id2); 2624 EXPECT_TRUE(NoCommandsWritten()); 2625 EXPECT_EQ(GL_INVALID_OPERATION, CheckError()); 2626 2627 // Test EndQueryEXT fails if target not same as current query. 2628 ClearCommands(); 2629 gl_->EndQueryEXT(GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT); 2630 EXPECT_TRUE(NoCommandsWritten()); 2631 EXPECT_EQ(GL_INVALID_OPERATION, CheckError()); 2632 2633 // Test EndQueryEXT sends command 2634 struct EndCmds { 2635 EndQueryEXT end_query; 2636 }; 2637 EndCmds expected_end_cmds; 2638 expected_end_cmds.end_query.Init( 2639 GL_ANY_SAMPLES_PASSED_EXT, query->submit_count()); 2640 commands = GetPut(); 2641 gl_->EndQueryEXT(GL_ANY_SAMPLES_PASSED_EXT); 2642 EXPECT_EQ(0, memcmp( 2643 &expected_end_cmds, commands, sizeof(expected_end_cmds))); 2644 2645 // Test EndQueryEXT fails if no current query. 2646 ClearCommands(); 2647 gl_->EndQueryEXT(GL_ANY_SAMPLES_PASSED_EXT); 2648 EXPECT_TRUE(NoCommandsWritten()); 2649 EXPECT_EQ(GL_INVALID_OPERATION, CheckError()); 2650 2651 // Test 2nd Begin/End increments count. 2652 uint32 old_submit_count = query->submit_count(); 2653 gl_->BeginQueryEXT(GL_ANY_SAMPLES_PASSED_EXT, id1); 2654 EXPECT_NE(old_submit_count, query->submit_count()); 2655 expected_end_cmds.end_query.Init( 2656 GL_ANY_SAMPLES_PASSED_EXT, query->submit_count()); 2657 commands = GetPut(); 2658 gl_->EndQueryEXT(GL_ANY_SAMPLES_PASSED_EXT); 2659 EXPECT_EQ(0, memcmp( 2660 &expected_end_cmds, commands, sizeof(expected_end_cmds))); 2661 2662 // Test BeginQueryEXT fails if target changed. 2663 ClearCommands(); 2664 gl_->BeginQueryEXT(GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT, id1); 2665 EXPECT_TRUE(NoCommandsWritten()); 2666 EXPECT_EQ(GL_INVALID_OPERATION, CheckError()); 2667 2668 // Test GetQueryObjectuivEXT fails if unused id 2669 GLuint available = 0xBDu; 2670 ClearCommands(); 2671 gl_->GetQueryObjectuivEXT(id2, GL_QUERY_RESULT_AVAILABLE_EXT, &available); 2672 EXPECT_TRUE(NoCommandsWritten()); 2673 EXPECT_EQ(0xBDu, available); 2674 EXPECT_EQ(GL_INVALID_OPERATION, CheckError()); 2675 2676 // Test GetQueryObjectuivEXT fails if bad id 2677 ClearCommands(); 2678 gl_->GetQueryObjectuivEXT(4567, GL_QUERY_RESULT_AVAILABLE_EXT, &available); 2679 EXPECT_TRUE(NoCommandsWritten()); 2680 EXPECT_EQ(0xBDu, available); 2681 EXPECT_EQ(GL_INVALID_OPERATION, CheckError()); 2682 2683 // Test GetQueryObjectuivEXT CheckResultsAvailable 2684 ClearCommands(); 2685 gl_->GetQueryObjectuivEXT(id1, GL_QUERY_RESULT_AVAILABLE_EXT, &available); 2686 EXPECT_TRUE(NoCommandsWritten()); 2687 EXPECT_EQ(0u, available); 2688} 2689 2690TEST_F(GLES2ImplementationTest, ErrorQuery) { 2691 GLuint id = 0; 2692 gl_->GenQueriesEXT(1, &id); 2693 ClearCommands(); 2694 2695 // Test BeginQueryEXT does NOT insert commands. 2696 gl_->BeginQueryEXT(GL_GET_ERROR_QUERY_CHROMIUM, id); 2697 EXPECT_TRUE(NoCommandsWritten()); 2698 QueryTracker::Query* query = GetQuery(id); 2699 ASSERT_TRUE(query != NULL); 2700 2701 // Test EndQueryEXT sends both begin and end command 2702 struct EndCmds { 2703 BeginQueryEXT begin_query; 2704 EndQueryEXT end_query; 2705 }; 2706 EndCmds expected_end_cmds; 2707 expected_end_cmds.begin_query.Init( 2708 GL_GET_ERROR_QUERY_CHROMIUM, id, query->shm_id(), query->shm_offset()); 2709 expected_end_cmds.end_query.Init( 2710 GL_GET_ERROR_QUERY_CHROMIUM, query->submit_count()); 2711 const void* commands = GetPut(); 2712 gl_->EndQueryEXT(GL_GET_ERROR_QUERY_CHROMIUM); 2713 EXPECT_EQ(0, memcmp( 2714 &expected_end_cmds, commands, sizeof(expected_end_cmds))); 2715 ClearCommands(); 2716 2717 // Check result is not yet available. 2718 GLuint available = 0xBDu; 2719 gl_->GetQueryObjectuivEXT(id, GL_QUERY_RESULT_AVAILABLE_EXT, &available); 2720 EXPECT_TRUE(NoCommandsWritten()); 2721 EXPECT_EQ(0u, available); 2722 2723 // Test no commands are sent if there is a client side error. 2724 2725 // Generate a client side error 2726 gl_->ActiveTexture(GL_TEXTURE0 - 1); 2727 2728 gl_->BeginQueryEXT(GL_GET_ERROR_QUERY_CHROMIUM, id); 2729 gl_->EndQueryEXT(GL_GET_ERROR_QUERY_CHROMIUM); 2730 EXPECT_TRUE(NoCommandsWritten()); 2731 2732 // Check result is available. 2733 gl_->GetQueryObjectuivEXT(id, GL_QUERY_RESULT_AVAILABLE_EXT, &available); 2734 EXPECT_TRUE(NoCommandsWritten()); 2735 EXPECT_NE(0u, available); 2736 2737 // Check result. 2738 GLuint result = 0xBDu; 2739 gl_->GetQueryObjectuivEXT(id, GL_QUERY_RESULT_EXT, &result); 2740 EXPECT_TRUE(NoCommandsWritten()); 2741 EXPECT_EQ(static_cast<GLuint>(GL_INVALID_ENUM), result); 2742} 2743 2744#if !defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS) 2745TEST_F(GLES2ImplementationTest, VertexArrays) { 2746 const GLuint kAttribIndex1 = 1; 2747 const GLint kNumComponents1 = 3; 2748 const GLsizei kClientStride = 12; 2749 2750 GLuint id = 0; 2751 gl_->GenVertexArraysOES(1, &id); 2752 ClearCommands(); 2753 2754 gl_->BindVertexArrayOES(id); 2755 2756 // Test that VertexAttribPointer cannot be called with a bound buffer of 0 2757 // unless the offset is NULL 2758 gl_->BindBuffer(GL_ARRAY_BUFFER, 0); 2759 2760 gl_->VertexAttribPointer( 2761 kAttribIndex1, kNumComponents1, GL_FLOAT, GL_FALSE, kClientStride, 2762 reinterpret_cast<const void*>(4)); 2763 EXPECT_EQ(GL_INVALID_OPERATION, CheckError()); 2764 2765 gl_->VertexAttribPointer( 2766 kAttribIndex1, kNumComponents1, GL_FLOAT, GL_FALSE, kClientStride, NULL); 2767 EXPECT_EQ(GL_NO_ERROR, CheckError()); 2768} 2769#endif 2770 2771#include "gpu/command_buffer/client/gles2_implementation_unittest_autogen.h" 2772 2773} // namespace gles2 2774} // namespace gpu 2775 2776