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