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