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.
5 // Tests for GLES2Implementation.
7 #include "gpu/command_buffer/client/gles2_implementation.h"
9 #include <GLES2/gl2ext.h>
10 #include <GLES2/gl2extchromium.h>
11 #include "base/compiler_specific.h"
12 #include "gpu/command_buffer/client/client_test_helper.h"
13 #include "gpu/command_buffer/client/program_info_manager.h"
14 #include "gpu/command_buffer/client/transfer_buffer.h"
15 #include "gpu/command_buffer/common/command_buffer.h"
16 #include "testing/gtest/include/gtest/gtest.h"
17 #include "testing/gmock/include/gmock/gmock.h"
19 #if !defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS)
20 #define GLES2_SUPPORT_CLIENT_SIDE_ARRAYS
24 using testing::AtLeast;
25 using testing::AnyNumber;
27 using testing::InSequence;
28 using testing::Invoke;
30 using testing::Sequence;
31 using testing::StrictMock;
33 using testing::Return;
38 ACTION_P2(SetMemory, dst, obj) {
39 memcpy(dst, &obj, sizeof(obj));
42 ACTION_P3(SetMemoryFromArray, dst, array, size) {
43 memcpy(dst, array, size);
46 // Used to help set the transfer buffer result to SizedResult of a single value.
48 class SizedResultHelper {
50 explicit SizedResultHelper(T result)
51 : size_(sizeof(result)),
60 // Struct to make it easy to pass a vec4 worth of floats.
62 FourFloats(float _x, float _y, float _z, float _w)
76 // Struct that holds 7 characters.
82 class MockTransferBuffer : public TransferBufferInterface {
84 struct ExpectedMemoryInfo {
91 CommandBuffer* command_buffer,
93 unsigned int result_size,
94 unsigned int alignment)
95 : command_buffer_(command_buffer),
97 result_size_(result_size),
98 alignment_(alignment),
99 actual_buffer_index_(0),
100 expected_buffer_index_(0),
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
107 for (int ii = 0; ii < kNumBuffers; ++ii) {
108 buffers_[ii] = command_buffer_->CreateTransferBuffer(
109 size_ + ii * alignment_,
111 EXPECT_NE(-1, buffer_ids_[ii]);
115 virtual ~MockTransferBuffer() { }
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;
135 size_t MaxTransferBufferSize() {
136 return size_ - result_size_;
139 unsigned int RoundToAlignment(unsigned int size) {
140 return (size + alignment_ - 1) & ~(alignment_ - 1);
144 return expected_buffer_index_ == actual_buffer_index_ &&
145 expected_offset_ == actual_offset_;
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));
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));
167 static const int kNumBuffers = 2;
169 uint8* actual_buffer() const {
170 return static_cast<uint8*>(buffers_[actual_buffer_index_].ptr);
173 uint8* expected_buffer() const {
174 return static_cast<uint8*>(buffers_[expected_buffer_index_].ptr);
177 uint32 AllocateExpectedTransferBuffer(size_t size) {
178 EXPECT_LE(size, MaxTransferBufferSize());
180 // Toggle which buffer we get each time to simulate the buffer being
182 expected_buffer_index_ = (expected_buffer_index_ + 1) % kNumBuffers;
184 if (expected_offset_ + size > size_) {
185 expected_offset_ = result_size_;
187 uint32 offset = expected_offset_;
188 expected_offset_ += RoundToAlignment(size);
190 // Make sure each buffer has a different offset.
191 return offset + expected_buffer_index_ * alignment_;
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;
200 int GetExpectedResultBufferId() {
201 return buffer_ids_[expected_buffer_index_];
204 uint32 GetExpectedResultBufferOffset() {
205 return expected_buffer_index_ * alignment_;
208 int GetExpectedTransferBufferId() {
209 return buffer_ids_[expected_buffer_index_];
212 CommandBuffer* command_buffer_;
216 int buffer_ids_[kNumBuffers];
217 gpu::Buffer buffers_[kNumBuffers];
218 int actual_buffer_index_;
219 int expected_buffer_index_;
221 uint32 expected_offset_;
222 uint32 actual_offset_;
224 DISALLOW_COPY_AND_ASSIGN(MockTransferBuffer);
227 bool 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;
240 int MockTransferBuffer::GetShmId() {
241 return buffer_ids_[actual_buffer_index_];
244 void* MockTransferBuffer::GetResultBuffer() {
245 return actual_buffer() + actual_buffer_index_ * alignment_;
248 int MockTransferBuffer::GetResultOffset() {
249 return actual_buffer_index_ * alignment_;
252 void MockTransferBuffer::Free() {
256 bool MockTransferBuffer::HaveBuffer() const {
260 void* MockTransferBuffer::AllocUpTo(
261 unsigned int size, unsigned int* size_allocated) {
262 EXPECT_TRUE(size_allocated != NULL);
263 EXPECT_TRUE(last_alloc_ == NULL);
265 // Toggle which buffer we get each time to simulate the buffer being
267 actual_buffer_index_ = (actual_buffer_index_ + 1) % kNumBuffers;
269 size = std::min(static_cast<size_t>(size), MaxTransferBufferSize());
270 if (actual_offset_ + size > size_) {
271 actual_offset_ = result_size_;
273 uint32 offset = actual_offset_;
274 actual_offset_ += RoundToAlignment(size);
275 *size_allocated = size;
277 // Make sure each buffer has a different offset.
278 last_alloc_ = actual_buffer() + offset + actual_buffer_index_ * alignment_;
282 void* 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);
290 RingBuffer::Offset MockTransferBuffer::GetOffset(void* pointer) const {
291 // Make sure each buffer has a different offset.
292 return static_cast<uint8*>(pointer) - actual_buffer();
295 void MockTransferBuffer::FreePendingToken(void* p, unsigned int /* token */) {
296 EXPECT_EQ(last_alloc_, p);
300 class GLES2ImplementationTest : public testing::Test {
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;
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;
330 typedef MockTransferBuffer::ExpectedMemoryInfo ExpectedMemoryInfo;
332 GLES2ImplementationTest()
337 virtual void SetUp() OVERRIDE;
338 virtual void TearDown() OVERRIDE;
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) {
352 QueryTracker::Query* GetQuery(GLuint id) {
353 return gl_->query_tracker_->GetQuery(id);
356 void Initialize(bool bind_generates_resource) {
357 command_buffer_.reset(new StrictMock<MockClientCommandBuffer>());
358 ASSERT_TRUE(command_buffer_->Initialize());
360 transfer_buffer_.reset(new MockTransferBuffer(
363 GLES2Implementation::kStartingOffset,
364 GLES2Implementation::kAlignment));
366 helper_.reset(new GLES2CmdHelper(command_buffer()));
367 helper_->Initialize(kCommandBufferSizeBytes);
369 gpu_control_.reset(new StrictMock<MockClientGpuControl>());
370 EXPECT_CALL(*gpu_control_, GetCapabilities())
371 .WillOnce(testing::Return(Capabilities()));
373 GLES2Implementation::GLStaticState state;
374 GLES2Implementation::GLStaticState::IntState& int_state = state.int_state;
375 int_state.max_combined_texture_image_units = kMaxCombinedTextureImageUnits;
376 int_state.max_cube_map_texture_size = kMaxCubeMapTextureSize;
377 int_state.max_fragment_uniform_vectors = kMaxFragmentUniformVectors;
378 int_state.max_renderbuffer_size = kMaxRenderbufferSize;
379 int_state.max_texture_image_units = kMaxTextureImageUnits;
380 int_state.max_texture_size = kMaxTextureSize;
381 int_state.max_varying_vectors = kMaxVaryingVectors;
382 int_state.max_vertex_attribs = kMaxVertexAttribs;
383 int_state.max_vertex_texture_image_units = kMaxVertexTextureImageUnits;
384 int_state.max_vertex_uniform_vectors = kMaxVertexUniformVectors;
385 int_state.num_compressed_texture_formats = kNumCompressedTextureFormats;
386 int_state.num_shader_binary_formats = kNumShaderBinaryFormats;
388 // This just happens to work for now because IntState has 1 GLint per state.
389 // If IntState gets more complicated this code will need to get more
391 ExpectedMemoryInfo mem1 = GetExpectedMemory(
392 sizeof(GLES2Implementation::GLStaticState::IntState) * 2 +
393 sizeof(cmds::GetShaderPrecisionFormat::Result) * 12);
398 EXPECT_CALL(*command_buffer(), OnFlush())
399 .WillOnce(SetMemory(mem1.ptr + sizeof(int_state), int_state))
400 .RetiresOnSaturation();
401 GetNextToken(); // eat the token that starting up will use.
403 gl_.reset(new GLES2Implementation(
406 transfer_buffer_.get(),
407 bind_generates_resource,
408 false /* free_everything_when_invisible */,
409 gpu_control_.get()));
410 ASSERT_TRUE(gl_->Initialize(
414 GLES2Implementation::kNoLimit));
417 EXPECT_CALL(*command_buffer(), OnFlush())
419 .RetiresOnSaturation();
420 helper_->CommandBufferHelper::Finish();
421 ::testing::Mock::VerifyAndClearExpectations(gl_.get());
423 Buffer ring_buffer = helper_->get_ring_buffer();
424 commands_ = static_cast<CommandBufferEntry*>(ring_buffer.ptr) +
425 command_buffer()->GetState().put_offset;
427 EXPECT_TRUE(transfer_buffer_->InSync());
429 ::testing::Mock::VerifyAndClearExpectations(command_buffer());
432 MockClientCommandBuffer* command_buffer() const {
433 return command_buffer_.get();
440 const void* GetPut() {
441 return helper_->GetSpace(0);
444 void ClearCommands() {
445 Buffer ring_buffer = helper_->get_ring_buffer();
446 memset(ring_buffer.ptr, kInitialValue, ring_buffer.size);
449 size_t MaxTransferBufferSize() {
450 return transfer_buffer_->MaxTransferBufferSize();
453 ExpectedMemoryInfo GetExpectedMemory(size_t size) {
454 return transfer_buffer_->GetExpectedMemory(size);
457 ExpectedMemoryInfo GetExpectedResultMemory(size_t size) {
458 return transfer_buffer_->GetExpectedResultMemory(size);
461 // Sets the ProgramInfoManager. The manager will be owned
462 // by the ShareGroup.
463 void SetProgramInfoManager(ProgramInfoManager* manager) {
464 gl_->share_group()->set_program_info_manager(manager);
468 ExpectedMemoryInfo result =
469 GetExpectedResultMemory(sizeof(cmds::GetError::Result));
470 EXPECT_CALL(*command_buffer(), OnFlush())
471 .WillOnce(SetMemory(result.ptr, GLuint(GL_NO_ERROR)))
472 .RetiresOnSaturation();
473 return gl_->GetError();
476 bool GetBucketContents(uint32 bucket_id, std::vector<int8>* data) {
477 return gl_->GetBucketContents(bucket_id, data);
481 scoped_ptr<MockClientCommandBuffer> command_buffer_;
482 scoped_ptr<MockClientGpuControl> gpu_control_;
483 scoped_ptr<GLES2CmdHelper> helper_;
484 scoped_ptr<MockTransferBuffer> transfer_buffer_;
485 scoped_ptr<GLES2Implementation> gl_;
486 CommandBufferEntry* commands_;
490 void GLES2ImplementationTest::SetUp() {
494 void GLES2ImplementationTest::TearDown() {
495 Mock::VerifyAndClear(gl_.get());
496 EXPECT_CALL(*command_buffer(), OnFlush()).Times(AnyNumber());
497 // For command buffer.
498 EXPECT_CALL(*command_buffer(), DestroyTransferBuffer(_))
503 class GLES2ImplementationStrictSharedTest : public GLES2ImplementationTest {
505 virtual void SetUp() OVERRIDE;
508 void GLES2ImplementationStrictSharedTest::SetUp() {
512 // GCC requires these declarations, but MSVC requires they not be present
514 const uint8 GLES2ImplementationTest::kInitialValue;
515 const int32 GLES2ImplementationTest::kNumCommandEntries;
516 const int32 GLES2ImplementationTest::kCommandBufferSizeBytes;
517 const size_t GLES2ImplementationTest::kTransferBufferSize;
518 const GLint GLES2ImplementationTest::kMaxCombinedTextureImageUnits;
519 const GLint GLES2ImplementationTest::kMaxCubeMapTextureSize;
520 const GLint GLES2ImplementationTest::kMaxFragmentUniformVectors;
521 const GLint GLES2ImplementationTest::kMaxRenderbufferSize;
522 const GLint GLES2ImplementationTest::kMaxTextureImageUnits;
523 const GLint GLES2ImplementationTest::kMaxTextureSize;
524 const GLint GLES2ImplementationTest::kMaxVaryingVectors;
525 const GLint GLES2ImplementationTest::kMaxVertexAttribs;
526 const GLint GLES2ImplementationTest::kMaxVertexTextureImageUnits;
527 const GLint GLES2ImplementationTest::kMaxVertexUniformVectors;
528 const GLint GLES2ImplementationTest::kNumCompressedTextureFormats;
529 const GLint GLES2ImplementationTest::kNumShaderBinaryFormats;
530 const GLuint GLES2ImplementationTest::kStartId;
531 const GLuint GLES2ImplementationTest::kBuffersStartId;
532 const GLuint GLES2ImplementationTest::kFramebuffersStartId;
533 const GLuint GLES2ImplementationTest::kProgramsAndShadersStartId;
534 const GLuint GLES2ImplementationTest::kRenderbuffersStartId;
535 const GLuint GLES2ImplementationTest::kTexturesStartId;
536 const GLuint GLES2ImplementationTest::kQueriesStartId;
537 const GLuint GLES2ImplementationTest::kVertexArraysStartId;
540 TEST_F(GLES2ImplementationTest, Basic) {
541 EXPECT_TRUE(gl_->share_group() != NULL);
544 TEST_F(GLES2ImplementationTest, GetBucketContents) {
545 const uint32 kBucketId = GLES2Implementation::kResultBucketId;
546 const uint32 kTestSize = MaxTransferBufferSize() + 32;
548 scoped_ptr<uint8[]> buf(new uint8 [kTestSize]);
549 uint8* expected_data = buf.get();
550 for (uint32 ii = 0; ii < kTestSize; ++ii) {
551 expected_data[ii] = ii * 3;
555 cmd::GetBucketStart get_bucket_start;
556 cmd::SetToken set_token1;
557 cmd::GetBucketData get_bucket_data;
558 cmd::SetToken set_token2;
559 cmd::SetBucketSize set_bucket_size2;
562 ExpectedMemoryInfo mem1 = GetExpectedMemory(MaxTransferBufferSize());
563 ExpectedMemoryInfo result1 = GetExpectedResultMemory(sizeof(uint32));
564 ExpectedMemoryInfo mem2 = GetExpectedMemory(
565 kTestSize - MaxTransferBufferSize());
568 expected.get_bucket_start.Init(
569 kBucketId, result1.id, result1.offset,
570 MaxTransferBufferSize(), mem1.id, mem1.offset);
571 expected.set_token1.Init(GetNextToken());
572 expected.get_bucket_data.Init(
573 kBucketId, MaxTransferBufferSize(),
574 kTestSize - MaxTransferBufferSize(), mem2.id, mem2.offset);
575 expected.set_bucket_size2.Init(kBucketId, 0);
576 expected.set_token2.Init(GetNextToken());
578 EXPECT_CALL(*command_buffer(), OnFlush())
580 SetMemory(result1.ptr, kTestSize),
582 mem1.ptr, expected_data, MaxTransferBufferSize())))
583 .WillOnce(SetMemoryFromArray(
584 mem2.ptr, expected_data + MaxTransferBufferSize(),
585 kTestSize - MaxTransferBufferSize()))
586 .RetiresOnSaturation();
588 std::vector<int8> data;
589 GetBucketContents(kBucketId, &data);
590 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
591 ASSERT_EQ(kTestSize, data.size());
592 EXPECT_EQ(0, memcmp(expected_data, &data[0], data.size()));
595 TEST_F(GLES2ImplementationTest, GetShaderPrecisionFormat) {
597 cmds::GetShaderPrecisionFormat cmd;
599 typedef cmds::GetShaderPrecisionFormat::Result Result;
601 // The first call for mediump should trigger a command buffer request.
602 GLint range1[2] = {0, 0};
603 GLint precision1 = 0;
605 ExpectedMemoryInfo client_result1 = GetExpectedResultMemory(4);
606 expected1.cmd.Init(GL_FRAGMENT_SHADER, GL_MEDIUM_FLOAT,
607 client_result1.id, client_result1.offset);
608 Result server_result1 = {true, 14, 14, 10};
609 EXPECT_CALL(*command_buffer(), OnFlush())
610 .WillOnce(SetMemory(client_result1.ptr, server_result1))
611 .RetiresOnSaturation();
612 gl_->GetShaderPrecisionFormat(GL_FRAGMENT_SHADER, GL_MEDIUM_FLOAT,
613 range1, &precision1);
614 const void* commands2 = GetPut();
615 EXPECT_NE(commands_, commands2);
616 EXPECT_EQ(0, memcmp(&expected1, commands_, sizeof(expected1)));
617 EXPECT_EQ(range1[0], 14);
618 EXPECT_EQ(range1[1], 14);
619 EXPECT_EQ(precision1, 10);
621 // The second call for mediump should use the cached value and avoid
622 // triggering a command buffer request, so we do not expect a call to
623 // OnFlush() here. We do expect the results to be correct though.
624 GLint range2[2] = {0, 0};
625 GLint precision2 = 0;
626 gl_->GetShaderPrecisionFormat(GL_FRAGMENT_SHADER, GL_MEDIUM_FLOAT,
627 range2, &precision2);
628 const void* commands3 = GetPut();
629 EXPECT_EQ(commands2, commands3);
630 EXPECT_EQ(range2[0], 14);
631 EXPECT_EQ(range2[1], 14);
632 EXPECT_EQ(precision2, 10);
634 // If we then make a request for highp, we should get another command
635 // buffer request since it hasn't been cached yet.
636 GLint range3[2] = {0, 0};
637 GLint precision3 = 0;
639 ExpectedMemoryInfo result3 = GetExpectedResultMemory(4);
640 expected3.cmd.Init(GL_FRAGMENT_SHADER, GL_HIGH_FLOAT,
641 result3.id, result3.offset);
642 Result result3_source = {true, 62, 62, 16};
643 EXPECT_CALL(*command_buffer(), OnFlush())
644 .WillOnce(SetMemory(result3.ptr, result3_source))
645 .RetiresOnSaturation();
646 gl_->GetShaderPrecisionFormat(GL_FRAGMENT_SHADER, GL_HIGH_FLOAT,
647 range3, &precision3);
648 const void* commands4 = GetPut();
649 EXPECT_NE(commands3, commands4);
650 EXPECT_EQ(0, memcmp(&expected3, commands3, sizeof(expected3)));
651 EXPECT_EQ(range3[0], 62);
652 EXPECT_EQ(range3[1], 62);
653 EXPECT_EQ(precision3, 16);
656 TEST_F(GLES2ImplementationTest, ShaderSource) {
657 const uint32 kBucketId = GLES2Implementation::kResultBucketId;
658 const GLuint kShaderId = 456;
659 const char* kString1 = "foobar";
660 const char* kString2 = "barfoo";
661 const size_t kString1Size = strlen(kString1);
662 const size_t kString2Size = strlen(kString2);
663 const size_t kString3Size = 1; // Want the NULL;
664 const size_t kSourceSize = kString1Size + kString2Size + kString3Size;
665 const size_t kPaddedString1Size =
666 transfer_buffer_->RoundToAlignment(kString1Size);
667 const size_t kPaddedString2Size =
668 transfer_buffer_->RoundToAlignment(kString2Size);
669 const size_t kPaddedString3Size =
670 transfer_buffer_->RoundToAlignment(kString3Size);
672 cmd::SetBucketSize set_bucket_size;
673 cmd::SetBucketData set_bucket_data1;
674 cmd::SetToken set_token1;
675 cmd::SetBucketData set_bucket_data2;
676 cmd::SetToken set_token2;
677 cmd::SetBucketData set_bucket_data3;
678 cmd::SetToken set_token3;
679 cmds::ShaderSourceBucket shader_source_bucket;
680 cmd::SetBucketSize clear_bucket_size;
683 ExpectedMemoryInfo mem1 = GetExpectedMemory(kPaddedString1Size);
684 ExpectedMemoryInfo mem2 = GetExpectedMemory(kPaddedString2Size);
685 ExpectedMemoryInfo mem3 = GetExpectedMemory(kPaddedString3Size);
688 expected.set_bucket_size.Init(kBucketId, kSourceSize);
689 expected.set_bucket_data1.Init(
690 kBucketId, 0, kString1Size, mem1.id, mem1.offset);
691 expected.set_token1.Init(GetNextToken());
692 expected.set_bucket_data2.Init(
693 kBucketId, kString1Size, kString2Size, mem2.id, mem2.offset);
694 expected.set_token2.Init(GetNextToken());
695 expected.set_bucket_data3.Init(
696 kBucketId, kString1Size + kString2Size,
697 kString3Size, mem3.id, mem3.offset);
698 expected.set_token3.Init(GetNextToken());
699 expected.shader_source_bucket.Init(kShaderId, kBucketId);
700 expected.clear_bucket_size.Init(kBucketId, 0);
701 const char* strings[] = {
705 gl_->ShaderSource(kShaderId, 2, strings, NULL);
706 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
709 TEST_F(GLES2ImplementationTest, GetShaderSource) {
710 const uint32 kBucketId = GLES2Implementation::kResultBucketId;
711 const GLuint kShaderId = 456;
712 const Str7 kString = {"foobar"};
713 const char kBad = 0x12;
715 cmd::SetBucketSize set_bucket_size1;
716 cmds::GetShaderSource get_shader_source;
717 cmd::GetBucketStart get_bucket_start;
718 cmd::SetToken set_token1;
719 cmd::SetBucketSize set_bucket_size2;
722 ExpectedMemoryInfo mem1 = GetExpectedMemory(MaxTransferBufferSize());
723 ExpectedMemoryInfo result1 = GetExpectedResultMemory(sizeof(uint32));
726 expected.set_bucket_size1.Init(kBucketId, 0);
727 expected.get_shader_source.Init(kShaderId, kBucketId);
728 expected.get_bucket_start.Init(
729 kBucketId, result1.id, result1.offset,
730 MaxTransferBufferSize(), mem1.id, mem1.offset);
731 expected.set_token1.Init(GetNextToken());
732 expected.set_bucket_size2.Init(kBucketId, 0);
733 char buf[sizeof(kString) + 1];
734 memset(buf, kBad, sizeof(buf));
736 EXPECT_CALL(*command_buffer(), OnFlush())
737 .WillOnce(DoAll(SetMemory(result1.ptr, uint32(sizeof(kString))),
738 SetMemory(mem1.ptr, kString)))
739 .RetiresOnSaturation();
742 gl_->GetShaderSource(kShaderId, sizeof(buf), &length, buf);
743 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
744 EXPECT_EQ(sizeof(kString) - 1, static_cast<size_t>(length));
745 EXPECT_STREQ(kString.str, buf);
746 EXPECT_EQ(buf[sizeof(kString)], kBad);
749 #if defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS)
751 TEST_F(GLES2ImplementationTest, DrawArraysClientSideBuffers) {
752 static const float verts[][4] = {
753 { 12.0f, 23.0f, 34.0f, 45.0f, },
754 { 56.0f, 67.0f, 78.0f, 89.0f, },
755 { 13.0f, 24.0f, 35.0f, 46.0f, },
758 cmds::EnableVertexAttribArray enable1;
759 cmds::EnableVertexAttribArray enable2;
760 cmds::BindBuffer bind_to_emu;
761 cmds::BufferData set_size;
762 cmds::BufferSubData copy_data1;
763 cmd::SetToken set_token1;
764 cmds::VertexAttribPointer set_pointer1;
765 cmds::BufferSubData copy_data2;
766 cmd::SetToken set_token2;
767 cmds::VertexAttribPointer set_pointer2;
768 cmds::DrawArrays draw;
769 cmds::BindBuffer restore;
771 const GLuint kEmuBufferId = GLES2Implementation::kClientSideArrayId;
772 const GLuint kAttribIndex1 = 1;
773 const GLuint kAttribIndex2 = 3;
774 const GLint kNumComponents1 = 3;
775 const GLint kNumComponents2 = 2;
776 const GLsizei kClientStride = sizeof(verts[0]);
777 const GLint kFirst = 1;
778 const GLsizei kCount = 2;
779 const GLsizei kSize1 =
780 arraysize(verts) * kNumComponents1 * sizeof(verts[0][0]);
781 const GLsizei kSize2 =
782 arraysize(verts) * kNumComponents2 * sizeof(verts[0][0]);
783 const GLsizei kEmuOffset1 = 0;
784 const GLsizei kEmuOffset2 = kSize1;
785 const GLsizei kTotalSize = kSize1 + kSize2;
787 ExpectedMemoryInfo mem1 = GetExpectedMemory(kSize1);
788 ExpectedMemoryInfo mem2 = GetExpectedMemory(kSize2);
791 expected.enable1.Init(kAttribIndex1);
792 expected.enable2.Init(kAttribIndex2);
793 expected.bind_to_emu.Init(GL_ARRAY_BUFFER, kEmuBufferId);
794 expected.set_size.Init(GL_ARRAY_BUFFER, kTotalSize, 0, 0, GL_DYNAMIC_DRAW);
795 expected.copy_data1.Init(
796 GL_ARRAY_BUFFER, kEmuOffset1, kSize1, mem1.id, mem1.offset);
797 expected.set_token1.Init(GetNextToken());
798 expected.set_pointer1.Init(
799 kAttribIndex1, kNumComponents1, GL_FLOAT, GL_FALSE, 0, kEmuOffset1);
800 expected.copy_data2.Init(
801 GL_ARRAY_BUFFER, kEmuOffset2, kSize2, mem2.id, mem2.offset);
802 expected.set_token2.Init(GetNextToken());
803 expected.set_pointer2.Init(
804 kAttribIndex2, kNumComponents2, GL_FLOAT, GL_FALSE, 0, kEmuOffset2);
805 expected.draw.Init(GL_POINTS, kFirst, kCount);
806 expected.restore.Init(GL_ARRAY_BUFFER, 0);
807 gl_->EnableVertexAttribArray(kAttribIndex1);
808 gl_->EnableVertexAttribArray(kAttribIndex2);
809 gl_->VertexAttribPointer(
810 kAttribIndex1, kNumComponents1, GL_FLOAT, GL_FALSE, kClientStride, verts);
811 gl_->VertexAttribPointer(
812 kAttribIndex2, kNumComponents2, GL_FLOAT, GL_FALSE, kClientStride, verts);
813 gl_->DrawArrays(GL_POINTS, kFirst, kCount);
814 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
817 TEST_F(GLES2ImplementationTest, DrawArraysInstancedANGLEClientSideBuffers) {
818 static const float verts[][4] = {
819 { 12.0f, 23.0f, 34.0f, 45.0f, },
820 { 56.0f, 67.0f, 78.0f, 89.0f, },
821 { 13.0f, 24.0f, 35.0f, 46.0f, },
824 cmds::EnableVertexAttribArray enable1;
825 cmds::EnableVertexAttribArray enable2;
826 cmds::VertexAttribDivisorANGLE divisor;
827 cmds::BindBuffer bind_to_emu;
828 cmds::BufferData set_size;
829 cmds::BufferSubData copy_data1;
830 cmd::SetToken set_token1;
831 cmds::VertexAttribPointer set_pointer1;
832 cmds::BufferSubData copy_data2;
833 cmd::SetToken set_token2;
834 cmds::VertexAttribPointer set_pointer2;
835 cmds::DrawArraysInstancedANGLE draw;
836 cmds::BindBuffer restore;
838 const GLuint kEmuBufferId = GLES2Implementation::kClientSideArrayId;
839 const GLuint kAttribIndex1 = 1;
840 const GLuint kAttribIndex2 = 3;
841 const GLint kNumComponents1 = 3;
842 const GLint kNumComponents2 = 2;
843 const GLsizei kClientStride = sizeof(verts[0]);
844 const GLint kFirst = 1;
845 const GLsizei kCount = 2;
846 const GLuint kDivisor = 1;
847 const GLsizei kSize1 =
848 arraysize(verts) * kNumComponents1 * sizeof(verts[0][0]);
849 const GLsizei kSize2 =
850 1 * kNumComponents2 * sizeof(verts[0][0]);
851 const GLsizei kEmuOffset1 = 0;
852 const GLsizei kEmuOffset2 = kSize1;
853 const GLsizei kTotalSize = kSize1 + kSize2;
855 ExpectedMemoryInfo mem1 = GetExpectedMemory(kSize1);
856 ExpectedMemoryInfo mem2 = GetExpectedMemory(kSize2);
859 expected.enable1.Init(kAttribIndex1);
860 expected.enable2.Init(kAttribIndex2);
861 expected.divisor.Init(kAttribIndex2, kDivisor);
862 expected.bind_to_emu.Init(GL_ARRAY_BUFFER, kEmuBufferId);
863 expected.set_size.Init(GL_ARRAY_BUFFER, kTotalSize, 0, 0, GL_DYNAMIC_DRAW);
864 expected.copy_data1.Init(
865 GL_ARRAY_BUFFER, kEmuOffset1, kSize1, mem1.id, mem1.offset);
866 expected.set_token1.Init(GetNextToken());
867 expected.set_pointer1.Init(
868 kAttribIndex1, kNumComponents1, GL_FLOAT, GL_FALSE, 0, kEmuOffset1);
869 expected.copy_data2.Init(
870 GL_ARRAY_BUFFER, kEmuOffset2, kSize2, mem2.id, mem2.offset);
871 expected.set_token2.Init(GetNextToken());
872 expected.set_pointer2.Init(
873 kAttribIndex2, kNumComponents2, GL_FLOAT, GL_FALSE, 0, kEmuOffset2);
874 expected.draw.Init(GL_POINTS, kFirst, kCount, 1);
875 expected.restore.Init(GL_ARRAY_BUFFER, 0);
876 gl_->EnableVertexAttribArray(kAttribIndex1);
877 gl_->EnableVertexAttribArray(kAttribIndex2);
878 gl_->VertexAttribPointer(
879 kAttribIndex1, kNumComponents1, GL_FLOAT, GL_FALSE, kClientStride, verts);
880 gl_->VertexAttribPointer(
881 kAttribIndex2, kNumComponents2, GL_FLOAT, GL_FALSE, kClientStride, verts);
882 gl_->VertexAttribDivisorANGLE(kAttribIndex2, kDivisor);
883 gl_->DrawArraysInstancedANGLE(GL_POINTS, kFirst, kCount, 1);
884 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
887 TEST_F(GLES2ImplementationTest, DrawElementsClientSideBuffers) {
888 static const float verts[][4] = {
889 { 12.0f, 23.0f, 34.0f, 45.0f, },
890 { 56.0f, 67.0f, 78.0f, 89.0f, },
891 { 13.0f, 24.0f, 35.0f, 46.0f, },
893 static const uint16 indices[] = {
897 cmds::EnableVertexAttribArray enable1;
898 cmds::EnableVertexAttribArray enable2;
899 cmds::BindBuffer bind_to_index_emu;
900 cmds::BufferData set_index_size;
901 cmds::BufferSubData copy_data0;
902 cmd::SetToken set_token0;
903 cmds::BindBuffer bind_to_emu;
904 cmds::BufferData set_size;
905 cmds::BufferSubData copy_data1;
906 cmd::SetToken set_token1;
907 cmds::VertexAttribPointer set_pointer1;
908 cmds::BufferSubData copy_data2;
909 cmd::SetToken set_token2;
910 cmds::VertexAttribPointer set_pointer2;
911 cmds::DrawElements draw;
912 cmds::BindBuffer restore;
913 cmds::BindBuffer restore_element;
915 const GLsizei kIndexSize = sizeof(indices);
916 const GLuint kEmuBufferId = GLES2Implementation::kClientSideArrayId;
917 const GLuint kEmuIndexBufferId =
918 GLES2Implementation::kClientSideElementArrayId;
919 const GLuint kAttribIndex1 = 1;
920 const GLuint kAttribIndex2 = 3;
921 const GLint kNumComponents1 = 3;
922 const GLint kNumComponents2 = 2;
923 const GLsizei kClientStride = sizeof(verts[0]);
924 const GLsizei kCount = 2;
925 const GLsizei kSize1 =
926 arraysize(verts) * kNumComponents1 * sizeof(verts[0][0]);
927 const GLsizei kSize2 =
928 arraysize(verts) * kNumComponents2 * sizeof(verts[0][0]);
929 const GLsizei kEmuOffset1 = 0;
930 const GLsizei kEmuOffset2 = kSize1;
931 const GLsizei kTotalSize = kSize1 + kSize2;
933 ExpectedMemoryInfo mem1 = GetExpectedMemory(kIndexSize);
934 ExpectedMemoryInfo mem2 = GetExpectedMemory(kSize1);
935 ExpectedMemoryInfo mem3 = GetExpectedMemory(kSize2);
938 expected.enable1.Init(kAttribIndex1);
939 expected.enable2.Init(kAttribIndex2);
940 expected.bind_to_index_emu.Init(GL_ELEMENT_ARRAY_BUFFER, kEmuIndexBufferId);
941 expected.set_index_size.Init(
942 GL_ELEMENT_ARRAY_BUFFER, kIndexSize, 0, 0, GL_DYNAMIC_DRAW);
943 expected.copy_data0.Init(
944 GL_ELEMENT_ARRAY_BUFFER, 0, kIndexSize, mem1.id, mem1.offset);
945 expected.set_token0.Init(GetNextToken());
946 expected.bind_to_emu.Init(GL_ARRAY_BUFFER, kEmuBufferId);
947 expected.set_size.Init(GL_ARRAY_BUFFER, kTotalSize, 0, 0, GL_DYNAMIC_DRAW);
948 expected.copy_data1.Init(
949 GL_ARRAY_BUFFER, kEmuOffset1, kSize1, mem2.id, mem2.offset);
950 expected.set_token1.Init(GetNextToken());
951 expected.set_pointer1.Init(
952 kAttribIndex1, kNumComponents1, GL_FLOAT, GL_FALSE, 0, kEmuOffset1);
953 expected.copy_data2.Init(
954 GL_ARRAY_BUFFER, kEmuOffset2, kSize2, mem3.id, mem3.offset);
955 expected.set_token2.Init(GetNextToken());
956 expected.set_pointer2.Init(kAttribIndex2, kNumComponents2,
957 GL_FLOAT, GL_FALSE, 0, kEmuOffset2);
958 expected.draw.Init(GL_POINTS, kCount, GL_UNSIGNED_SHORT, 0);
959 expected.restore.Init(GL_ARRAY_BUFFER, 0);
960 expected.restore_element.Init(GL_ELEMENT_ARRAY_BUFFER, 0);
961 gl_->EnableVertexAttribArray(kAttribIndex1);
962 gl_->EnableVertexAttribArray(kAttribIndex2);
963 gl_->VertexAttribPointer(kAttribIndex1, kNumComponents1,
964 GL_FLOAT, GL_FALSE, kClientStride, verts);
965 gl_->VertexAttribPointer(kAttribIndex2, kNumComponents2,
966 GL_FLOAT, GL_FALSE, kClientStride, verts);
967 gl_->DrawElements(GL_POINTS, kCount, GL_UNSIGNED_SHORT, indices);
968 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
971 TEST_F(GLES2ImplementationTest, DrawElementsClientSideBuffersIndexUint) {
972 static const float verts[][4] = {
973 { 12.0f, 23.0f, 34.0f, 45.0f, },
974 { 56.0f, 67.0f, 78.0f, 89.0f, },
975 { 13.0f, 24.0f, 35.0f, 46.0f, },
977 static const uint32 indices[] = {
981 cmds::EnableVertexAttribArray enable1;
982 cmds::EnableVertexAttribArray enable2;
983 cmds::BindBuffer bind_to_index_emu;
984 cmds::BufferData set_index_size;
985 cmds::BufferSubData copy_data0;
986 cmd::SetToken set_token0;
987 cmds::BindBuffer bind_to_emu;
988 cmds::BufferData set_size;
989 cmds::BufferSubData copy_data1;
990 cmd::SetToken set_token1;
991 cmds::VertexAttribPointer set_pointer1;
992 cmds::BufferSubData copy_data2;
993 cmd::SetToken set_token2;
994 cmds::VertexAttribPointer set_pointer2;
995 cmds::DrawElements draw;
996 cmds::BindBuffer restore;
997 cmds::BindBuffer restore_element;
999 const GLsizei kIndexSize = sizeof(indices);
1000 const GLuint kEmuBufferId = GLES2Implementation::kClientSideArrayId;
1001 const GLuint kEmuIndexBufferId =
1002 GLES2Implementation::kClientSideElementArrayId;
1003 const GLuint kAttribIndex1 = 1;
1004 const GLuint kAttribIndex2 = 3;
1005 const GLint kNumComponents1 = 3;
1006 const GLint kNumComponents2 = 2;
1007 const GLsizei kClientStride = sizeof(verts[0]);
1008 const GLsizei kCount = 2;
1009 const GLsizei kSize1 =
1010 arraysize(verts) * kNumComponents1 * sizeof(verts[0][0]);
1011 const GLsizei kSize2 =
1012 arraysize(verts) * kNumComponents2 * sizeof(verts[0][0]);
1013 const GLsizei kEmuOffset1 = 0;
1014 const GLsizei kEmuOffset2 = kSize1;
1015 const GLsizei kTotalSize = kSize1 + kSize2;
1017 ExpectedMemoryInfo mem1 = GetExpectedMemory(kIndexSize);
1018 ExpectedMemoryInfo mem2 = GetExpectedMemory(kSize1);
1019 ExpectedMemoryInfo mem3 = GetExpectedMemory(kSize2);
1022 expected.enable1.Init(kAttribIndex1);
1023 expected.enable2.Init(kAttribIndex2);
1024 expected.bind_to_index_emu.Init(GL_ELEMENT_ARRAY_BUFFER, kEmuIndexBufferId);
1025 expected.set_index_size.Init(
1026 GL_ELEMENT_ARRAY_BUFFER, kIndexSize, 0, 0, GL_DYNAMIC_DRAW);
1027 expected.copy_data0.Init(
1028 GL_ELEMENT_ARRAY_BUFFER, 0, kIndexSize, mem1.id, mem1.offset);
1029 expected.set_token0.Init(GetNextToken());
1030 expected.bind_to_emu.Init(GL_ARRAY_BUFFER, kEmuBufferId);
1031 expected.set_size.Init(GL_ARRAY_BUFFER, kTotalSize, 0, 0, GL_DYNAMIC_DRAW);
1032 expected.copy_data1.Init(
1033 GL_ARRAY_BUFFER, kEmuOffset1, kSize1, mem2.id, mem2.offset);
1034 expected.set_token1.Init(GetNextToken());
1035 expected.set_pointer1.Init(
1036 kAttribIndex1, kNumComponents1, GL_FLOAT, GL_FALSE, 0, kEmuOffset1);
1037 expected.copy_data2.Init(
1038 GL_ARRAY_BUFFER, kEmuOffset2, kSize2, mem3.id, mem3.offset);
1039 expected.set_token2.Init(GetNextToken());
1040 expected.set_pointer2.Init(kAttribIndex2, kNumComponents2,
1041 GL_FLOAT, GL_FALSE, 0, kEmuOffset2);
1042 expected.draw.Init(GL_POINTS, kCount, GL_UNSIGNED_INT, 0);
1043 expected.restore.Init(GL_ARRAY_BUFFER, 0);
1044 expected.restore_element.Init(GL_ELEMENT_ARRAY_BUFFER, 0);
1045 gl_->EnableVertexAttribArray(kAttribIndex1);
1046 gl_->EnableVertexAttribArray(kAttribIndex2);
1047 gl_->VertexAttribPointer(kAttribIndex1, kNumComponents1,
1048 GL_FLOAT, GL_FALSE, kClientStride, verts);
1049 gl_->VertexAttribPointer(kAttribIndex2, kNumComponents2,
1050 GL_FLOAT, GL_FALSE, kClientStride, verts);
1051 gl_->DrawElements(GL_POINTS, kCount, GL_UNSIGNED_INT, indices);
1052 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
1055 TEST_F(GLES2ImplementationTest, DrawElementsClientSideBuffersInvalidIndexUint) {
1056 static const float verts[][4] = {
1057 { 12.0f, 23.0f, 34.0f, 45.0f, },
1058 { 56.0f, 67.0f, 78.0f, 89.0f, },
1059 { 13.0f, 24.0f, 35.0f, 46.0f, },
1061 static const uint32 indices[] = {
1065 const GLuint kAttribIndex1 = 1;
1066 const GLuint kAttribIndex2 = 3;
1067 const GLint kNumComponents1 = 3;
1068 const GLint kNumComponents2 = 2;
1069 const GLsizei kClientStride = sizeof(verts[0]);
1070 const GLsizei kCount = 2;
1072 EXPECT_CALL(*command_buffer(), OnFlush())
1074 .RetiresOnSaturation();
1076 gl_->EnableVertexAttribArray(kAttribIndex1);
1077 gl_->EnableVertexAttribArray(kAttribIndex2);
1078 gl_->VertexAttribPointer(kAttribIndex1, kNumComponents1,
1079 GL_FLOAT, GL_FALSE, kClientStride, verts);
1080 gl_->VertexAttribPointer(kAttribIndex2, kNumComponents2,
1081 GL_FLOAT, GL_FALSE, kClientStride, verts);
1082 gl_->DrawElements(GL_POINTS, kCount, GL_UNSIGNED_INT, indices);
1084 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_OPERATION), gl_->GetError());
1087 TEST_F(GLES2ImplementationTest,
1088 DrawElementsClientSideBuffersServiceSideIndices) {
1089 static const float verts[][4] = {
1090 { 12.0f, 23.0f, 34.0f, 45.0f, },
1091 { 56.0f, 67.0f, 78.0f, 89.0f, },
1092 { 13.0f, 24.0f, 35.0f, 46.0f, },
1095 cmds::EnableVertexAttribArray enable1;
1096 cmds::EnableVertexAttribArray enable2;
1097 cmds::BindBuffer bind_to_index;
1098 cmds::GetMaxValueInBufferCHROMIUM get_max;
1099 cmds::BindBuffer bind_to_emu;
1100 cmds::BufferData set_size;
1101 cmds::BufferSubData copy_data1;
1102 cmd::SetToken set_token1;
1103 cmds::VertexAttribPointer set_pointer1;
1104 cmds::BufferSubData copy_data2;
1105 cmd::SetToken set_token2;
1106 cmds::VertexAttribPointer set_pointer2;
1107 cmds::DrawElements draw;
1108 cmds::BindBuffer restore;
1110 const GLuint kEmuBufferId = GLES2Implementation::kClientSideArrayId;
1111 const GLuint kClientIndexBufferId = 0x789;
1112 const GLuint kIndexOffset = 0x40;
1113 const GLuint kMaxIndex = 2;
1114 const GLuint kAttribIndex1 = 1;
1115 const GLuint kAttribIndex2 = 3;
1116 const GLint kNumComponents1 = 3;
1117 const GLint kNumComponents2 = 2;
1118 const GLsizei kClientStride = sizeof(verts[0]);
1119 const GLsizei kCount = 2;
1120 const GLsizei kSize1 =
1121 arraysize(verts) * kNumComponents1 * sizeof(verts[0][0]);
1122 const GLsizei kSize2 =
1123 arraysize(verts) * kNumComponents2 * sizeof(verts[0][0]);
1124 const GLsizei kEmuOffset1 = 0;
1125 const GLsizei kEmuOffset2 = kSize1;
1126 const GLsizei kTotalSize = kSize1 + kSize2;
1128 ExpectedMemoryInfo mem1 = GetExpectedResultMemory(sizeof(uint32));
1129 ExpectedMemoryInfo mem2 = GetExpectedMemory(kSize1);
1130 ExpectedMemoryInfo mem3 = GetExpectedMemory(kSize2);
1134 expected.enable1.Init(kAttribIndex1);
1135 expected.enable2.Init(kAttribIndex2);
1136 expected.bind_to_index.Init(GL_ELEMENT_ARRAY_BUFFER, kClientIndexBufferId);
1137 expected.get_max.Init(kClientIndexBufferId, kCount, GL_UNSIGNED_SHORT,
1138 kIndexOffset, mem1.id, mem1.offset);
1139 expected.bind_to_emu.Init(GL_ARRAY_BUFFER, kEmuBufferId);
1140 expected.set_size.Init(GL_ARRAY_BUFFER, kTotalSize, 0, 0, GL_DYNAMIC_DRAW);
1141 expected.copy_data1.Init(
1142 GL_ARRAY_BUFFER, kEmuOffset1, kSize1, mem2.id, mem2.offset);
1143 expected.set_token1.Init(GetNextToken());
1144 expected.set_pointer1.Init(kAttribIndex1, kNumComponents1,
1145 GL_FLOAT, GL_FALSE, 0, kEmuOffset1);
1146 expected.copy_data2.Init(
1147 GL_ARRAY_BUFFER, kEmuOffset2, kSize2, mem3.id, mem3.offset);
1148 expected.set_token2.Init(GetNextToken());
1149 expected.set_pointer2.Init(kAttribIndex2, kNumComponents2,
1150 GL_FLOAT, GL_FALSE, 0, kEmuOffset2);
1151 expected.draw.Init(GL_POINTS, kCount, GL_UNSIGNED_SHORT, kIndexOffset);
1152 expected.restore.Init(GL_ARRAY_BUFFER, 0);
1154 EXPECT_CALL(*command_buffer(), OnFlush())
1155 .WillOnce(SetMemory(mem1.ptr,kMaxIndex))
1156 .RetiresOnSaturation();
1158 gl_->EnableVertexAttribArray(kAttribIndex1);
1159 gl_->EnableVertexAttribArray(kAttribIndex2);
1160 gl_->BindBuffer(GL_ELEMENT_ARRAY_BUFFER, kClientIndexBufferId);
1161 gl_->VertexAttribPointer(kAttribIndex1, kNumComponents1,
1162 GL_FLOAT, GL_FALSE, kClientStride, verts);
1163 gl_->VertexAttribPointer(kAttribIndex2, kNumComponents2,
1164 GL_FLOAT, GL_FALSE, kClientStride, verts);
1165 gl_->DrawElements(GL_POINTS, kCount, GL_UNSIGNED_SHORT,
1166 reinterpret_cast<const void*>(kIndexOffset));
1167 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
1170 TEST_F(GLES2ImplementationTest, DrawElementsInstancedANGLEClientSideBuffers) {
1171 static const float verts[][4] = {
1172 { 12.0f, 23.0f, 34.0f, 45.0f, },
1173 { 56.0f, 67.0f, 78.0f, 89.0f, },
1174 { 13.0f, 24.0f, 35.0f, 46.0f, },
1176 static const uint16 indices[] = {
1180 cmds::EnableVertexAttribArray enable1;
1181 cmds::EnableVertexAttribArray enable2;
1182 cmds::VertexAttribDivisorANGLE divisor;
1183 cmds::BindBuffer bind_to_index_emu;
1184 cmds::BufferData set_index_size;
1185 cmds::BufferSubData copy_data0;
1186 cmd::SetToken set_token0;
1187 cmds::BindBuffer bind_to_emu;
1188 cmds::BufferData set_size;
1189 cmds::BufferSubData copy_data1;
1190 cmd::SetToken set_token1;
1191 cmds::VertexAttribPointer set_pointer1;
1192 cmds::BufferSubData copy_data2;
1193 cmd::SetToken set_token2;
1194 cmds::VertexAttribPointer set_pointer2;
1195 cmds::DrawElementsInstancedANGLE draw;
1196 cmds::BindBuffer restore;
1197 cmds::BindBuffer restore_element;
1199 const GLsizei kIndexSize = sizeof(indices);
1200 const GLuint kEmuBufferId = GLES2Implementation::kClientSideArrayId;
1201 const GLuint kEmuIndexBufferId =
1202 GLES2Implementation::kClientSideElementArrayId;
1203 const GLuint kAttribIndex1 = 1;
1204 const GLuint kAttribIndex2 = 3;
1205 const GLint kNumComponents1 = 3;
1206 const GLint kNumComponents2 = 2;
1207 const GLsizei kClientStride = sizeof(verts[0]);
1208 const GLsizei kCount = 2;
1209 const GLsizei kSize1 =
1210 arraysize(verts) * kNumComponents1 * sizeof(verts[0][0]);
1211 const GLsizei kSize2 =
1212 1 * kNumComponents2 * sizeof(verts[0][0]);
1213 const GLuint kDivisor = 1;
1214 const GLsizei kEmuOffset1 = 0;
1215 const GLsizei kEmuOffset2 = kSize1;
1216 const GLsizei kTotalSize = kSize1 + kSize2;
1218 ExpectedMemoryInfo mem1 = GetExpectedMemory(kIndexSize);
1219 ExpectedMemoryInfo mem2 = GetExpectedMemory(kSize1);
1220 ExpectedMemoryInfo mem3 = GetExpectedMemory(kSize2);
1223 expected.enable1.Init(kAttribIndex1);
1224 expected.enable2.Init(kAttribIndex2);
1225 expected.divisor.Init(kAttribIndex2, kDivisor);
1226 expected.bind_to_index_emu.Init(GL_ELEMENT_ARRAY_BUFFER, kEmuIndexBufferId);
1227 expected.set_index_size.Init(
1228 GL_ELEMENT_ARRAY_BUFFER, kIndexSize, 0, 0, GL_DYNAMIC_DRAW);
1229 expected.copy_data0.Init(
1230 GL_ELEMENT_ARRAY_BUFFER, 0, kIndexSize, mem1.id, mem1.offset);
1231 expected.set_token0.Init(GetNextToken());
1232 expected.bind_to_emu.Init(GL_ARRAY_BUFFER, kEmuBufferId);
1233 expected.set_size.Init(GL_ARRAY_BUFFER, kTotalSize, 0, 0, GL_DYNAMIC_DRAW);
1234 expected.copy_data1.Init(
1235 GL_ARRAY_BUFFER, kEmuOffset1, kSize1, mem2.id, mem2.offset);
1236 expected.set_token1.Init(GetNextToken());
1237 expected.set_pointer1.Init(
1238 kAttribIndex1, kNumComponents1, GL_FLOAT, GL_FALSE, 0, kEmuOffset1);
1239 expected.copy_data2.Init(
1240 GL_ARRAY_BUFFER, kEmuOffset2, kSize2, mem3.id, mem3.offset);
1241 expected.set_token2.Init(GetNextToken());
1242 expected.set_pointer2.Init(kAttribIndex2, kNumComponents2,
1243 GL_FLOAT, GL_FALSE, 0, kEmuOffset2);
1244 expected.draw.Init(GL_POINTS, kCount, GL_UNSIGNED_SHORT, 0, 1);
1245 expected.restore.Init(GL_ARRAY_BUFFER, 0);
1246 expected.restore_element.Init(GL_ELEMENT_ARRAY_BUFFER, 0);
1247 gl_->EnableVertexAttribArray(kAttribIndex1);
1248 gl_->EnableVertexAttribArray(kAttribIndex2);
1249 gl_->VertexAttribPointer(kAttribIndex1, kNumComponents1,
1250 GL_FLOAT, GL_FALSE, kClientStride, verts);
1251 gl_->VertexAttribPointer(kAttribIndex2, kNumComponents2,
1252 GL_FLOAT, GL_FALSE, kClientStride, verts);
1253 gl_->VertexAttribDivisorANGLE(kAttribIndex2, kDivisor);
1254 gl_->DrawElementsInstancedANGLE(
1255 GL_POINTS, kCount, GL_UNSIGNED_SHORT, indices, 1);
1256 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
1259 TEST_F(GLES2ImplementationTest, GetVertexBufferPointerv) {
1260 static const float verts[1] = { 0.0f, };
1261 const GLuint kAttribIndex1 = 1;
1262 const GLuint kAttribIndex2 = 3;
1263 const GLint kNumComponents1 = 3;
1264 const GLint kNumComponents2 = 2;
1265 const GLsizei kStride1 = 12;
1266 const GLsizei kStride2 = 0;
1267 const GLuint kBufferId = 0x123;
1268 const GLint kOffset2 = 0x456;
1270 // It's all cached on the client side so no get commands are issued.
1272 cmds::BindBuffer bind;
1273 cmds::VertexAttribPointer set_pointer;
1277 expected.bind.Init(GL_ARRAY_BUFFER, kBufferId);
1278 expected.set_pointer.Init(kAttribIndex2, kNumComponents2, GL_FLOAT, GL_FALSE,
1279 kStride2, kOffset2);
1281 // Set one client side buffer.
1282 gl_->VertexAttribPointer(kAttribIndex1, kNumComponents1,
1283 GL_FLOAT, GL_FALSE, kStride1, verts);
1285 gl_->BindBuffer(GL_ARRAY_BUFFER, kBufferId);
1286 gl_->VertexAttribPointer(kAttribIndex2, kNumComponents2,
1287 GL_FLOAT, GL_FALSE, kStride2,
1288 reinterpret_cast<const void*>(kOffset2));
1289 // now get them both.
1293 gl_->GetVertexAttribPointerv(
1294 kAttribIndex1, GL_VERTEX_ATTRIB_ARRAY_POINTER, &ptr1);
1295 gl_->GetVertexAttribPointerv(
1296 kAttribIndex2, GL_VERTEX_ATTRIB_ARRAY_POINTER, &ptr2);
1298 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
1299 EXPECT_TRUE(static_cast<const void*>(&verts) == ptr1);
1300 EXPECT_TRUE(ptr2 == reinterpret_cast<void*>(kOffset2));
1303 TEST_F(GLES2ImplementationTest, GetVertexAttrib) {
1304 static const float verts[1] = { 0.0f, };
1305 const GLuint kAttribIndex1 = 1;
1306 const GLuint kAttribIndex2 = 3;
1307 const GLint kNumComponents1 = 3;
1308 const GLint kNumComponents2 = 2;
1309 const GLsizei kStride1 = 12;
1310 const GLsizei kStride2 = 0;
1311 const GLuint kBufferId = 0x123;
1312 const GLint kOffset2 = 0x456;
1314 // Only one set and one get because the client side buffer's info is stored
1315 // on the client side.
1317 cmds::EnableVertexAttribArray enable;
1318 cmds::BindBuffer bind;
1319 cmds::VertexAttribPointer set_pointer;
1320 cmds::GetVertexAttribfv get2; // for getting the value from attrib1
1323 ExpectedMemoryInfo mem2 = GetExpectedResultMemory(16);
1326 expected.enable.Init(kAttribIndex1);
1327 expected.bind.Init(GL_ARRAY_BUFFER, kBufferId);
1328 expected.set_pointer.Init(kAttribIndex2, kNumComponents2, GL_FLOAT, GL_FALSE,
1329 kStride2, kOffset2);
1330 expected.get2.Init(kAttribIndex1,
1331 GL_CURRENT_VERTEX_ATTRIB,
1332 mem2.id, mem2.offset);
1334 FourFloats current_attrib(1.2f, 3.4f, 5.6f, 7.8f);
1336 // One call to flush to wait for last call to GetVertexAttribiv
1337 // as others are all cached.
1338 EXPECT_CALL(*command_buffer(), OnFlush())
1339 .WillOnce(SetMemory(
1340 mem2.ptr, SizedResultHelper<FourFloats>(current_attrib)))
1341 .RetiresOnSaturation();
1343 gl_->EnableVertexAttribArray(kAttribIndex1);
1344 // Set one client side buffer.
1345 gl_->VertexAttribPointer(kAttribIndex1, kNumComponents1,
1346 GL_FLOAT, GL_FALSE, kStride1, verts);
1348 gl_->BindBuffer(GL_ARRAY_BUFFER, kBufferId);
1349 gl_->VertexAttribPointer(kAttribIndex2, kNumComponents2,
1350 GL_FLOAT, GL_FALSE, kStride2,
1351 reinterpret_cast<const void*>(kOffset2));
1352 // first get the service side once to see that we make a command
1353 GLint buffer_id = 0;
1358 GLint normalized = 1;
1359 float current[4] = { 0.0f, };
1361 gl_->GetVertexAttribiv(
1362 kAttribIndex2, GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING, &buffer_id);
1363 EXPECT_EQ(kBufferId, static_cast<GLuint>(buffer_id));
1364 gl_->GetVertexAttribiv(
1365 kAttribIndex1, GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING, &buffer_id);
1366 gl_->GetVertexAttribiv(
1367 kAttribIndex1, GL_VERTEX_ATTRIB_ARRAY_ENABLED, &enabled);
1368 gl_->GetVertexAttribiv(
1369 kAttribIndex1, GL_VERTEX_ATTRIB_ARRAY_SIZE, &size);
1370 gl_->GetVertexAttribiv(
1371 kAttribIndex1, GL_VERTEX_ATTRIB_ARRAY_STRIDE, &stride);
1372 gl_->GetVertexAttribiv(
1373 kAttribIndex1, GL_VERTEX_ATTRIB_ARRAY_TYPE, &type);
1374 gl_->GetVertexAttribiv(
1375 kAttribIndex1, GL_VERTEX_ATTRIB_ARRAY_NORMALIZED, &normalized);
1376 gl_->GetVertexAttribfv(
1377 kAttribIndex1, GL_CURRENT_VERTEX_ATTRIB, ¤t[0]);
1379 EXPECT_EQ(0, buffer_id);
1380 EXPECT_EQ(GL_TRUE, enabled);
1381 EXPECT_EQ(kNumComponents1, size);
1382 EXPECT_EQ(kStride1, stride);
1383 EXPECT_EQ(GL_FLOAT, type);
1384 EXPECT_EQ(GL_FALSE, normalized);
1385 EXPECT_EQ(0, memcmp(¤t_attrib, ¤t, sizeof(current_attrib)));
1387 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
1390 TEST_F(GLES2ImplementationTest, ReservedIds) {
1391 // Only the get error command should be issued.
1397 ExpectedMemoryInfo mem1 = GetExpectedResultMemory(
1398 sizeof(cmds::GetError::Result));
1400 expected.get.Init(mem1.id, mem1.offset);
1402 // One call to flush to wait for GetError
1403 EXPECT_CALL(*command_buffer(), OnFlush())
1404 .WillOnce(SetMemory(mem1.ptr, GLuint(GL_NO_ERROR)))
1405 .RetiresOnSaturation();
1409 GLES2Implementation::kClientSideArrayId);
1412 GLES2Implementation::kClientSideElementArrayId);
1413 GLenum err = gl_->GetError();
1414 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_OPERATION), err);
1415 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
1418 #endif // defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS)
1420 TEST_F(GLES2ImplementationTest, ReadPixels2Reads) {
1422 cmds::ReadPixels read1;
1423 cmd::SetToken set_token1;
1424 cmds::ReadPixels read2;
1425 cmd::SetToken set_token2;
1427 const GLint kBytesPerPixel = 4;
1428 const GLint kWidth =
1429 (kTransferBufferSize - GLES2Implementation::kStartingOffset) /
1431 const GLint kHeight = 2;
1432 const GLenum kFormat = GL_RGBA;
1433 const GLenum kType = GL_UNSIGNED_BYTE;
1435 ExpectedMemoryInfo mem1 =
1436 GetExpectedMemory(kWidth * kHeight / 2 * kBytesPerPixel);
1437 ExpectedMemoryInfo result1 =
1438 GetExpectedResultMemory(sizeof(cmds::ReadPixels::Result));
1439 ExpectedMemoryInfo mem2 =
1440 GetExpectedMemory(kWidth * kHeight / 2 * kBytesPerPixel);
1441 ExpectedMemoryInfo result2 =
1442 GetExpectedResultMemory(sizeof(cmds::ReadPixels::Result));
1445 expected.read1.Init(
1446 0, 0, kWidth, kHeight / 2, kFormat, kType,
1447 mem1.id, mem1.offset, result1.id, result1.offset,
1449 expected.set_token1.Init(GetNextToken());
1450 expected.read2.Init(
1451 0, kHeight / 2, kWidth, kHeight / 2, kFormat, kType,
1452 mem2.id, mem2.offset, result2.id, result2.offset, false);
1453 expected.set_token2.Init(GetNextToken());
1454 scoped_ptr<int8[]> buffer(new int8[kWidth * kHeight * kBytesPerPixel]);
1456 EXPECT_CALL(*command_buffer(), OnFlush())
1457 .WillOnce(SetMemory(result1.ptr, static_cast<uint32>(1)))
1458 .WillOnce(SetMemory(result2.ptr, static_cast<uint32>(1)))
1459 .RetiresOnSaturation();
1461 gl_->ReadPixels(0, 0, kWidth, kHeight, kFormat, kType, buffer.get());
1462 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
1465 TEST_F(GLES2ImplementationTest, ReadPixelsBadFormatType) {
1467 cmds::ReadPixels read;
1468 cmd::SetToken set_token;
1470 const GLint kBytesPerPixel = 4;
1471 const GLint kWidth = 2;
1472 const GLint kHeight = 2;
1473 const GLenum kFormat = 0;
1474 const GLenum kType = 0;
1476 ExpectedMemoryInfo mem1 =
1477 GetExpectedMemory(kWidth * kHeight * kBytesPerPixel);
1478 ExpectedMemoryInfo result1 =
1479 GetExpectedResultMemory(sizeof(cmds::ReadPixels::Result));
1483 0, 0, kWidth, kHeight, kFormat, kType,
1484 mem1.id, mem1.offset, result1.id, result1.offset, false);
1485 expected.set_token.Init(GetNextToken());
1486 scoped_ptr<int8[]> buffer(new int8[kWidth * kHeight * kBytesPerPixel]);
1488 EXPECT_CALL(*command_buffer(), OnFlush())
1490 .RetiresOnSaturation();
1492 gl_->ReadPixels(0, 0, kWidth, kHeight, kFormat, kType, buffer.get());
1495 TEST_F(GLES2ImplementationTest, FreeUnusedSharedMemory) {
1497 cmds::BufferSubData buf;
1498 cmd::SetToken set_token;
1500 const GLenum kTarget = GL_ELEMENT_ARRAY_BUFFER;
1501 const GLintptr kOffset = 15;
1502 const GLsizeiptr kSize = 16;
1504 ExpectedMemoryInfo mem1 = GetExpectedMemory(kSize);
1508 kTarget, kOffset, kSize, mem1.id, mem1.offset);
1509 expected.set_token.Init(GetNextToken());
1511 void* mem = gl_->MapBufferSubDataCHROMIUM(
1512 kTarget, kOffset, kSize, GL_WRITE_ONLY);
1513 ASSERT_TRUE(mem != NULL);
1514 gl_->UnmapBufferSubDataCHROMIUM(mem);
1515 EXPECT_CALL(*command_buffer(), DestroyTransferBuffer(_))
1517 .RetiresOnSaturation();
1518 gl_->FreeUnusedSharedMemory();
1521 TEST_F(GLES2ImplementationTest, MapUnmapBufferSubDataCHROMIUM) {
1523 cmds::BufferSubData buf;
1524 cmd::SetToken set_token;
1526 const GLenum kTarget = GL_ELEMENT_ARRAY_BUFFER;
1527 const GLintptr kOffset = 15;
1528 const GLsizeiptr kSize = 16;
1533 kTarget, kOffset, kSize,
1534 command_buffer()->GetNextFreeTransferBufferId(), offset);
1535 expected.set_token.Init(GetNextToken());
1537 void* mem = gl_->MapBufferSubDataCHROMIUM(
1538 kTarget, kOffset, kSize, GL_WRITE_ONLY);
1539 ASSERT_TRUE(mem != NULL);
1540 gl_->UnmapBufferSubDataCHROMIUM(mem);
1541 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
1544 TEST_F(GLES2ImplementationTest, MapUnmapBufferSubDataCHROMIUMBadArgs) {
1545 const GLenum kTarget = GL_ELEMENT_ARRAY_BUFFER;
1546 const GLintptr kOffset = 15;
1547 const GLsizeiptr kSize = 16;
1549 ExpectedMemoryInfo result1 =
1550 GetExpectedResultMemory(sizeof(cmds::GetError::Result));
1551 ExpectedMemoryInfo result2 =
1552 GetExpectedResultMemory(sizeof(cmds::GetError::Result));
1553 ExpectedMemoryInfo result3 =
1554 GetExpectedResultMemory(sizeof(cmds::GetError::Result));
1555 ExpectedMemoryInfo result4 =
1556 GetExpectedResultMemory(sizeof(cmds::GetError::Result));
1558 // Calls to flush to wait for GetError
1559 EXPECT_CALL(*command_buffer(), OnFlush())
1560 .WillOnce(SetMemory(result1.ptr, GLuint(GL_NO_ERROR)))
1561 .WillOnce(SetMemory(result2.ptr, GLuint(GL_NO_ERROR)))
1562 .WillOnce(SetMemory(result3.ptr, GLuint(GL_NO_ERROR)))
1563 .WillOnce(SetMemory(result4.ptr, GLuint(GL_NO_ERROR)))
1564 .RetiresOnSaturation();
1567 mem = gl_->MapBufferSubDataCHROMIUM(kTarget, -1, kSize, 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, -1, GL_WRITE_ONLY);
1571 ASSERT_TRUE(mem == NULL);
1572 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE), gl_->GetError());
1573 mem = gl_->MapBufferSubDataCHROMIUM(kTarget, kOffset, kSize, GL_READ_ONLY);
1574 ASSERT_TRUE(mem == NULL);
1575 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_ENUM), gl_->GetError());
1576 const char* kPtr = "something";
1577 gl_->UnmapBufferSubDataCHROMIUM(kPtr);
1578 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE), gl_->GetError());
1581 TEST_F(GLES2ImplementationTest, MapUnmapTexSubImage2DCHROMIUM) {
1583 cmds::TexSubImage2D tex;
1584 cmd::SetToken set_token;
1586 const GLint kLevel = 1;
1587 const GLint kXOffset = 2;
1588 const GLint kYOffset = 3;
1589 const GLint kWidth = 4;
1590 const GLint kHeight = 5;
1591 const GLenum kFormat = GL_RGBA;
1592 const GLenum kType = GL_UNSIGNED_BYTE;
1597 GL_TEXTURE_2D, kLevel, kXOffset, kYOffset, kWidth, kHeight, kFormat,
1599 command_buffer()->GetNextFreeTransferBufferId(), offset, GL_FALSE);
1600 expected.set_token.Init(GetNextToken());
1602 void* mem = gl_->MapTexSubImage2DCHROMIUM(
1612 ASSERT_TRUE(mem != NULL);
1613 gl_->UnmapTexSubImage2DCHROMIUM(mem);
1614 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
1617 TEST_F(GLES2ImplementationTest, MapUnmapTexSubImage2DCHROMIUMBadArgs) {
1618 const GLint kLevel = 1;
1619 const GLint kXOffset = 2;
1620 const GLint kYOffset = 3;
1621 const GLint kWidth = 4;
1622 const GLint kHeight = 5;
1623 const GLenum kFormat = GL_RGBA;
1624 const GLenum kType = GL_UNSIGNED_BYTE;
1626 ExpectedMemoryInfo result1 =
1627 GetExpectedResultMemory(sizeof(cmds::GetError::Result));
1628 ExpectedMemoryInfo result2 =
1629 GetExpectedResultMemory(sizeof(cmds::GetError::Result));
1630 ExpectedMemoryInfo result3 =
1631 GetExpectedResultMemory(sizeof(cmds::GetError::Result));
1632 ExpectedMemoryInfo result4 =
1633 GetExpectedResultMemory(sizeof(cmds::GetError::Result));
1634 ExpectedMemoryInfo result5 =
1635 GetExpectedResultMemory(sizeof(cmds::GetError::Result));
1636 ExpectedMemoryInfo result6 =
1637 GetExpectedResultMemory(sizeof(cmds::GetError::Result));
1638 ExpectedMemoryInfo result7 =
1639 GetExpectedResultMemory(sizeof(cmds::GetError::Result));
1641 // Calls to flush to wait for GetError
1642 EXPECT_CALL(*command_buffer(), OnFlush())
1643 .WillOnce(SetMemory(result1.ptr, GLuint(GL_NO_ERROR)))
1644 .WillOnce(SetMemory(result2.ptr, GLuint(GL_NO_ERROR)))
1645 .WillOnce(SetMemory(result3.ptr, GLuint(GL_NO_ERROR)))
1646 .WillOnce(SetMemory(result4.ptr, GLuint(GL_NO_ERROR)))
1647 .WillOnce(SetMemory(result5.ptr, GLuint(GL_NO_ERROR)))
1648 .WillOnce(SetMemory(result6.ptr, GLuint(GL_NO_ERROR)))
1649 .WillOnce(SetMemory(result7.ptr, GLuint(GL_NO_ERROR)))
1650 .RetiresOnSaturation();
1653 mem = gl_->MapTexSubImage2DCHROMIUM(
1663 EXPECT_TRUE(mem == NULL);
1664 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE), gl_->GetError());
1665 mem = gl_->MapTexSubImage2DCHROMIUM(
1675 EXPECT_TRUE(mem == NULL);
1676 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE), gl_->GetError());
1677 mem = gl_->MapTexSubImage2DCHROMIUM(
1687 EXPECT_TRUE(mem == NULL);
1688 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE), gl_->GetError());
1689 mem = gl_->MapTexSubImage2DCHROMIUM(
1699 EXPECT_TRUE(mem == NULL);
1700 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE), gl_->GetError());
1701 mem = gl_->MapTexSubImage2DCHROMIUM(
1711 EXPECT_TRUE(mem == NULL);
1712 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE), gl_->GetError());
1713 mem = gl_->MapTexSubImage2DCHROMIUM(
1723 EXPECT_TRUE(mem == NULL);
1724 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_ENUM), gl_->GetError());
1725 const char* kPtr = "something";
1726 gl_->UnmapTexSubImage2DCHROMIUM(kPtr);
1727 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE), gl_->GetError());
1730 TEST_F(GLES2ImplementationTest, GetMultipleIntegervCHROMIUMValidArgs) {
1731 const GLenum pnames[] = {
1734 GL_STENCIL_WRITEMASK,
1736 const GLint num_results = 6;
1737 GLint results[num_results + 1];
1739 cmds::GetMultipleIntegervCHROMIUM get_multiple;
1740 cmd::SetToken set_token;
1742 const GLsizei kNumPnames = arraysize(pnames);
1743 const GLsizeiptr kResultsSize = num_results * sizeof(results[0]);
1744 const size_t kPNamesSize = kNumPnames * sizeof(pnames[0]);
1746 ExpectedMemoryInfo mem1 = GetExpectedMemory(kPNamesSize + kResultsSize);
1747 ExpectedMemoryInfo result1 = GetExpectedResultMemory(
1748 sizeof(cmds::GetError::Result));
1750 const uint32 kPnamesOffset = mem1.offset;
1751 const uint32 kResultsOffset = mem1.offset + kPNamesSize;
1753 expected.get_multiple.Init(
1754 mem1.id, kPnamesOffset, kNumPnames,
1755 mem1.id, kResultsOffset, kResultsSize);
1756 expected.set_token.Init(GetNextToken());
1758 const GLint kSentinel = 0x12345678;
1759 memset(results, 0, sizeof(results));
1760 results[num_results] = kSentinel;
1761 const GLint returned_results[] = {
1764 // One call to flush to wait for results
1765 EXPECT_CALL(*command_buffer(), OnFlush())
1766 .WillOnce(SetMemoryFromArray(mem1.ptr + kPNamesSize,
1767 returned_results, sizeof(returned_results)))
1768 .WillOnce(SetMemory(result1.ptr, GLuint(GL_NO_ERROR)))
1769 .RetiresOnSaturation();
1771 gl_->GetMultipleIntegervCHROMIUM(
1772 &pnames[0], kNumPnames, &results[0], kResultsSize);
1773 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
1774 EXPECT_EQ(0, memcmp(&returned_results, results, sizeof(returned_results)));
1775 EXPECT_EQ(kSentinel, results[num_results]);
1776 EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), gl_->GetError());
1779 TEST_F(GLES2ImplementationTest, GetMultipleIntegervCHROMIUMBadArgs) {
1783 GL_STENCIL_WRITEMASK,
1785 const GLint num_results = 6;
1786 GLint results[num_results + 1];
1787 const GLsizei kNumPnames = arraysize(pnames);
1788 const GLsizeiptr kResultsSize = num_results * sizeof(results[0]);
1790 ExpectedMemoryInfo result1 =
1791 GetExpectedResultMemory(sizeof(cmds::GetError::Result));
1792 ExpectedMemoryInfo result2 =
1793 GetExpectedResultMemory(sizeof(cmds::GetError::Result));
1794 ExpectedMemoryInfo result3 =
1795 GetExpectedResultMemory(sizeof(cmds::GetError::Result));
1796 ExpectedMemoryInfo result4 =
1797 GetExpectedResultMemory(sizeof(cmds::GetError::Result));
1799 // Calls to flush to wait for GetError
1800 EXPECT_CALL(*command_buffer(), OnFlush())
1801 .WillOnce(SetMemory(result1.ptr, GLuint(GL_NO_ERROR)))
1802 .WillOnce(SetMemory(result2.ptr, GLuint(GL_NO_ERROR)))
1803 .WillOnce(SetMemory(result3.ptr, GLuint(GL_NO_ERROR)))
1804 .WillOnce(SetMemory(result4.ptr, GLuint(GL_NO_ERROR)))
1805 .RetiresOnSaturation();
1807 const GLint kSentinel = 0x12345678;
1808 memset(results, 0, sizeof(results));
1809 results[num_results] = kSentinel;
1811 gl_->GetMultipleIntegervCHROMIUM(
1812 &pnames[0], kNumPnames, &results[0], kResultsSize + 1);
1813 EXPECT_TRUE(NoCommandsWritten());
1814 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE), gl_->GetError());
1815 EXPECT_EQ(0, results[0]);
1816 EXPECT_EQ(kSentinel, results[num_results]);
1819 gl_->GetMultipleIntegervCHROMIUM(
1820 &pnames[0], kNumPnames, &results[0], kResultsSize - 1);
1821 EXPECT_TRUE(NoCommandsWritten());
1822 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE), gl_->GetError());
1823 EXPECT_EQ(0, results[0]);
1824 EXPECT_EQ(kSentinel, results[num_results]);
1825 // try uncleared results.
1828 gl_->GetMultipleIntegervCHROMIUM(
1829 &pnames[0], kNumPnames, &results[0], kResultsSize);
1830 EXPECT_TRUE(NoCommandsWritten());
1831 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE), gl_->GetError());
1832 EXPECT_EQ(0, results[0]);
1833 EXPECT_EQ(kSentinel, results[num_results]);
1834 // try bad enum results.
1837 pnames[1] = GL_TRUE;
1838 gl_->GetMultipleIntegervCHROMIUM(
1839 &pnames[0], kNumPnames, &results[0], kResultsSize);
1840 EXPECT_TRUE(NoCommandsWritten());
1841 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_ENUM), gl_->GetError());
1842 EXPECT_EQ(0, results[0]);
1843 EXPECT_EQ(kSentinel, results[num_results]);
1846 TEST_F(GLES2ImplementationTest, GetProgramInfoCHROMIUMGoodArgs) {
1847 const uint32 kBucketId = GLES2Implementation::kResultBucketId;
1848 const GLuint kProgramId = 123;
1849 const char kBad = 0x12;
1851 const Str7 kString = {"foobar"};
1854 ExpectedMemoryInfo mem1 =
1855 GetExpectedMemory(MaxTransferBufferSize());
1856 ExpectedMemoryInfo result1 =
1857 GetExpectedResultMemory(sizeof(cmd::GetBucketStart::Result));
1858 ExpectedMemoryInfo result2 =
1859 GetExpectedResultMemory(sizeof(cmds::GetError::Result));
1861 memset(buf, kBad, sizeof(buf));
1862 EXPECT_CALL(*command_buffer(), OnFlush())
1863 .WillOnce(DoAll(SetMemory(result1.ptr, uint32(sizeof(kString))),
1864 SetMemory(mem1.ptr, kString)))
1865 .WillOnce(SetMemory(result2.ptr, GLuint(GL_NO_ERROR)))
1866 .RetiresOnSaturation();
1869 cmd::SetBucketSize set_bucket_size1;
1870 cmds::GetProgramInfoCHROMIUM get_program_info;
1871 cmd::GetBucketStart get_bucket_start;
1872 cmd::SetToken set_token1;
1873 cmd::SetBucketSize set_bucket_size2;
1876 expected.set_bucket_size1.Init(kBucketId, 0);
1877 expected.get_program_info.Init(kProgramId, kBucketId);
1878 expected.get_bucket_start.Init(
1879 kBucketId, result1.id, result1.offset,
1880 MaxTransferBufferSize(), mem1.id, mem1.offset);
1881 expected.set_token1.Init(GetNextToken());
1882 expected.set_bucket_size2.Init(kBucketId, 0);
1883 gl_->GetProgramInfoCHROMIUM(kProgramId, sizeof(buf), &size, &buf);
1884 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
1885 EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), gl_->GetError());
1886 EXPECT_EQ(sizeof(kString), static_cast<size_t>(size));
1887 EXPECT_STREQ(kString.str, buf);
1888 EXPECT_EQ(buf[sizeof(kString)], kBad);
1891 TEST_F(GLES2ImplementationTest, GetProgramInfoCHROMIUMBadArgs) {
1892 const uint32 kBucketId = GLES2Implementation::kResultBucketId;
1893 const GLuint kProgramId = 123;
1895 const Str7 kString = {"foobar"};
1898 ExpectedMemoryInfo mem1 = GetExpectedMemory(MaxTransferBufferSize());
1899 ExpectedMemoryInfo result1 =
1900 GetExpectedResultMemory(sizeof(cmd::GetBucketStart::Result));
1901 ExpectedMemoryInfo result2 =
1902 GetExpectedResultMemory(sizeof(cmds::GetError::Result));
1903 ExpectedMemoryInfo result3 =
1904 GetExpectedResultMemory(sizeof(cmds::GetError::Result));
1905 ExpectedMemoryInfo result4 =
1906 GetExpectedResultMemory(sizeof(cmds::GetError::Result));
1908 EXPECT_CALL(*command_buffer(), OnFlush())
1909 .WillOnce(DoAll(SetMemory(result1.ptr, uint32(sizeof(kString))),
1910 SetMemory(mem1.ptr, kString)))
1911 .WillOnce(SetMemory(result2.ptr, GLuint(GL_NO_ERROR)))
1912 .WillOnce(SetMemory(result3.ptr, GLuint(GL_NO_ERROR)))
1913 .WillOnce(SetMemory(result4.ptr, GLuint(GL_NO_ERROR)))
1914 .RetiresOnSaturation();
1916 // try bufsize not big enough.
1918 cmd::SetBucketSize set_bucket_size1;
1919 cmds::GetProgramInfoCHROMIUM get_program_info;
1920 cmd::GetBucketStart get_bucket_start;
1921 cmd::SetToken set_token1;
1922 cmd::SetBucketSize set_bucket_size2;
1925 expected.set_bucket_size1.Init(kBucketId, 0);
1926 expected.get_program_info.Init(kProgramId, kBucketId);
1927 expected.get_bucket_start.Init(
1928 kBucketId, result1.id, result1.offset,
1929 MaxTransferBufferSize(), mem1.id, mem1.offset);
1930 expected.set_token1.Init(GetNextToken());
1931 expected.set_bucket_size2.Init(kBucketId, 0);
1932 gl_->GetProgramInfoCHROMIUM(kProgramId, 6, &size, &buf);
1933 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
1934 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_OPERATION), gl_->GetError());
1938 gl_->GetProgramInfoCHROMIUM(kProgramId, -1, &size, &buf);
1939 EXPECT_TRUE(NoCommandsWritten());
1940 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE), gl_->GetError());
1943 gl_->GetProgramInfoCHROMIUM(kProgramId, sizeof(buf), NULL, &buf);
1944 EXPECT_TRUE(NoCommandsWritten());
1945 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE), gl_->GetError());
1948 // Test that things are cached
1949 TEST_F(GLES2ImplementationTest, GetIntegerCacheRead) {
1954 const PNameValue pairs[] = {
1955 {GL_ACTIVE_TEXTURE, GL_TEXTURE0, },
1956 {GL_TEXTURE_BINDING_2D, 0, },
1957 {GL_TEXTURE_BINDING_CUBE_MAP, 0, },
1958 {GL_TEXTURE_BINDING_EXTERNAL_OES, 0, },
1959 {GL_FRAMEBUFFER_BINDING, 0, },
1960 {GL_RENDERBUFFER_BINDING, 0, },
1961 {GL_ARRAY_BUFFER_BINDING, 0, },
1962 {GL_ELEMENT_ARRAY_BUFFER_BINDING, 0, },
1963 {GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, kMaxCombinedTextureImageUnits, },
1964 {GL_MAX_CUBE_MAP_TEXTURE_SIZE, kMaxCubeMapTextureSize, },
1965 {GL_MAX_FRAGMENT_UNIFORM_VECTORS, kMaxFragmentUniformVectors, },
1966 {GL_MAX_RENDERBUFFER_SIZE, kMaxRenderbufferSize, },
1967 {GL_MAX_TEXTURE_IMAGE_UNITS, kMaxTextureImageUnits, },
1968 {GL_MAX_TEXTURE_SIZE, kMaxTextureSize, },
1969 {GL_MAX_VARYING_VECTORS, kMaxVaryingVectors, },
1970 {GL_MAX_VERTEX_ATTRIBS, kMaxVertexAttribs, },
1971 {GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, kMaxVertexTextureImageUnits, },
1972 {GL_MAX_VERTEX_UNIFORM_VECTORS, kMaxVertexUniformVectors, },
1973 {GL_NUM_COMPRESSED_TEXTURE_FORMATS, kNumCompressedTextureFormats, },
1974 {GL_NUM_SHADER_BINARY_FORMATS, kNumShaderBinaryFormats, }, };
1975 size_t num_pairs = sizeof(pairs) / sizeof(pairs[0]);
1976 for (size_t ii = 0; ii < num_pairs; ++ii) {
1977 const PNameValue& pv = pairs[ii];
1979 gl_->GetIntegerv(pv.pname, &v);
1980 EXPECT_TRUE(NoCommandsWritten());
1981 EXPECT_EQ(pv.expected, v);
1984 ExpectedMemoryInfo result1 =
1985 GetExpectedResultMemory(sizeof(cmds::GetError::Result));
1987 EXPECT_CALL(*command_buffer(), OnFlush())
1988 .WillOnce(SetMemory(result1.ptr, GLuint(GL_NO_ERROR)))
1989 .RetiresOnSaturation();
1990 EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), gl_->GetError());
1993 TEST_F(GLES2ImplementationTest, GetIntegerCacheWrite) {
1998 gl_->ActiveTexture(GL_TEXTURE4);
1999 gl_->BindBuffer(GL_ARRAY_BUFFER, 2);
2000 gl_->BindBuffer(GL_ELEMENT_ARRAY_BUFFER, 3);
2001 gl_->BindFramebuffer(GL_FRAMEBUFFER, 4);
2002 gl_->BindRenderbuffer(GL_RENDERBUFFER, 5);
2003 gl_->BindTexture(GL_TEXTURE_2D, 6);
2004 gl_->BindTexture(GL_TEXTURE_CUBE_MAP, 7);
2005 gl_->BindTexture(GL_TEXTURE_EXTERNAL_OES, 8);
2007 const PNameValue pairs[] = {{GL_ACTIVE_TEXTURE, GL_TEXTURE4, },
2008 {GL_ARRAY_BUFFER_BINDING, 2, },
2009 {GL_ELEMENT_ARRAY_BUFFER_BINDING, 3, },
2010 {GL_FRAMEBUFFER_BINDING, 4, },
2011 {GL_RENDERBUFFER_BINDING, 5, },
2012 {GL_TEXTURE_BINDING_2D, 6, },
2013 {GL_TEXTURE_BINDING_CUBE_MAP, 7, },
2014 {GL_TEXTURE_BINDING_EXTERNAL_OES, 8, }, };
2015 size_t num_pairs = sizeof(pairs) / sizeof(pairs[0]);
2016 for (size_t ii = 0; ii < num_pairs; ++ii) {
2017 const PNameValue& pv = pairs[ii];
2019 gl_->GetIntegerv(pv.pname, &v);
2020 EXPECT_EQ(pv.expected, v);
2023 ExpectedMemoryInfo result1 =
2024 GetExpectedResultMemory(sizeof(cmds::GetError::Result));
2026 EXPECT_CALL(*command_buffer(), OnFlush())
2027 .WillOnce(SetMemory(result1.ptr, GLuint(GL_NO_ERROR)))
2028 .RetiresOnSaturation();
2029 EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), gl_->GetError());
2032 static bool CheckRect(
2033 int width, int height, GLenum format, GLenum type, int alignment,
2034 bool flip_y, const uint8* r1, const uint8* r2) {
2036 uint32 unpadded_row_size = 0;
2037 uint32 padded_row_size = 0;
2038 if (!GLES2Util::ComputeImageDataSizes(
2039 width, height, format, type, alignment, &size, &unpadded_row_size,
2040 &padded_row_size)) {
2044 int r2_stride = flip_y ?
2045 -static_cast<int>(padded_row_size) :
2046 static_cast<int>(padded_row_size);
2047 r2 = flip_y ? (r2 + (height - 1) * padded_row_size) : r2;
2049 for (int y = 0; y < height; ++y) {
2050 if (memcmp(r1, r2, unpadded_row_size) != 0) {
2053 r1 += padded_row_size;
2059 ACTION_P8(CheckRectAction, width, height, format, type, alignment, flip_y,
2061 EXPECT_TRUE(CheckRect(
2062 width, height, format, type, alignment, flip_y, r1, r2));
2065 // Test TexImage2D with and without flip_y
2066 TEST_F(GLES2ImplementationTest, TexImage2D) {
2068 cmds::TexImage2D tex_image_2d;
2069 cmd::SetToken set_token;
2072 cmds::TexImage2D tex_image_2d;
2073 cmd::SetToken set_token;
2075 const GLenum kTarget = GL_TEXTURE_2D;
2076 const GLint kLevel = 0;
2077 const GLenum kFormat = GL_RGB;
2078 const GLsizei kWidth = 3;
2079 const GLsizei kHeight = 4;
2080 const GLint kBorder = 0;
2081 const GLenum kType = GL_UNSIGNED_BYTE;
2082 const GLint kPixelStoreUnpackAlignment = 4;
2083 static uint8 pixels[] = {
2084 11, 12, 13, 13, 14, 15, 15, 16, 17, 101, 102, 103,
2085 21, 22, 23, 23, 24, 25, 25, 26, 27, 201, 202, 203,
2086 31, 32, 33, 33, 34, 35, 35, 36, 37, 123, 124, 125,
2087 41, 42, 43, 43, 44, 45, 45, 46, 47,
2090 ExpectedMemoryInfo mem1 = GetExpectedMemory(sizeof(pixels));
2093 expected.tex_image_2d.Init(
2094 kTarget, kLevel, kFormat, kWidth, kHeight, kBorder, kFormat, kType,
2095 mem1.id, mem1.offset);
2096 expected.set_token.Init(GetNextToken());
2098 kTarget, kLevel, kFormat, kWidth, kHeight, kBorder, kFormat, kType,
2100 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
2101 EXPECT_TRUE(CheckRect(
2102 kWidth, kHeight, kFormat, kType, kPixelStoreUnpackAlignment, false,
2106 gl_->PixelStorei(GL_UNPACK_FLIP_Y_CHROMIUM, GL_TRUE);
2108 ExpectedMemoryInfo mem2 = GetExpectedMemory(sizeof(pixels));
2110 expected2.tex_image_2d.Init(
2111 kTarget, kLevel, kFormat, kWidth, kHeight, kBorder, kFormat, kType,
2112 mem2.id, mem2.offset);
2113 expected2.set_token.Init(GetNextToken());
2114 const void* commands2 = GetPut();
2116 kTarget, kLevel, kFormat, kWidth, kHeight, kBorder, kFormat, kType,
2118 EXPECT_EQ(0, memcmp(&expected2, commands2, sizeof(expected2)));
2119 EXPECT_TRUE(CheckRect(
2120 kWidth, kHeight, kFormat, kType, kPixelStoreUnpackAlignment, true,
2124 // Test TexImage2D with 2 writes
2125 TEST_F(GLES2ImplementationTest, TexImage2D2Writes) {
2127 cmds::TexImage2D tex_image_2d;
2128 cmds::TexSubImage2D tex_sub_image_2d1;
2129 cmd::SetToken set_token1;
2130 cmds::TexSubImage2D tex_sub_image_2d2;
2131 cmd::SetToken set_token2;
2133 const GLenum kTarget = GL_TEXTURE_2D;
2134 const GLint kLevel = 0;
2135 const GLenum kFormat = GL_RGB;
2136 const GLint kBorder = 0;
2137 const GLenum kType = GL_UNSIGNED_BYTE;
2138 const GLint kPixelStoreUnpackAlignment = 4;
2139 const GLsizei kWidth = 3;
2142 uint32 unpadded_row_size = 0;
2143 uint32 padded_row_size = 0;
2144 ASSERT_TRUE(GLES2Util::ComputeImageDataSizes(
2145 kWidth, 2, kFormat, kType, kPixelStoreUnpackAlignment,
2146 &size, &unpadded_row_size, &padded_row_size));
2147 const GLsizei kHeight = (MaxTransferBufferSize() / padded_row_size) * 2;
2148 ASSERT_TRUE(GLES2Util::ComputeImageDataSizes(
2149 kWidth, kHeight, kFormat, kType, kPixelStoreUnpackAlignment,
2150 &size, NULL, NULL));
2151 uint32 half_size = 0;
2152 ASSERT_TRUE(GLES2Util::ComputeImageDataSizes(
2153 kWidth, kHeight / 2, kFormat, kType, kPixelStoreUnpackAlignment,
2154 &half_size, NULL, NULL));
2156 scoped_ptr<uint8[]> pixels(new uint8[size]);
2157 for (uint32 ii = 0; ii < size; ++ii) {
2158 pixels[ii] = static_cast<uint8>(ii);
2161 ExpectedMemoryInfo mem1 = GetExpectedMemory(half_size);
2162 ExpectedMemoryInfo mem2 = GetExpectedMemory(half_size);
2165 expected.tex_image_2d.Init(
2166 kTarget, kLevel, kFormat, kWidth, kHeight, kBorder, kFormat, kType,
2168 expected.tex_sub_image_2d1.Init(
2169 kTarget, kLevel, 0, 0, kWidth, kHeight / 2, kFormat, kType,
2170 mem1.id, mem1.offset, true);
2171 expected.set_token1.Init(GetNextToken());
2172 expected.tex_sub_image_2d2.Init(
2173 kTarget, kLevel, 0, kHeight / 2, kWidth, kHeight / 2, kFormat, kType,
2174 mem2.id, mem2.offset, true);
2175 expected.set_token2.Init(GetNextToken());
2177 // TODO(gman): Make it possible to run this test
2178 // EXPECT_CALL(*command_buffer(), OnFlush())
2179 // .WillOnce(CheckRectAction(
2180 // kWidth, kHeight / 2, kFormat, kType, kPixelStoreUnpackAlignment,
2181 // false, pixels.get(),
2182 // GetExpectedTransferAddressFromOffsetAs<uint8>(offset1, half_size)))
2183 // .RetiresOnSaturation();
2186 kTarget, kLevel, kFormat, kWidth, kHeight, kBorder, kFormat, kType,
2188 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
2189 EXPECT_TRUE(CheckRect(
2190 kWidth, kHeight / 2, kFormat, kType, kPixelStoreUnpackAlignment, false,
2191 pixels.get() + kHeight / 2 * padded_row_size, mem2.ptr));
2194 gl_->PixelStorei(GL_UNPACK_FLIP_Y_CHROMIUM, GL_TRUE);
2195 const void* commands2 = GetPut();
2196 ExpectedMemoryInfo mem3 = GetExpectedMemory(half_size);
2197 ExpectedMemoryInfo mem4 = GetExpectedMemory(half_size);
2198 expected.tex_image_2d.Init(
2199 kTarget, kLevel, kFormat, kWidth, kHeight, kBorder, kFormat, kType,
2201 expected.tex_sub_image_2d1.Init(
2202 kTarget, kLevel, 0, kHeight / 2, kWidth, kHeight / 2, kFormat, kType,
2203 mem3.id, mem3.offset, true);
2204 expected.set_token1.Init(GetNextToken());
2205 expected.tex_sub_image_2d2.Init(
2206 kTarget, kLevel, 0, 0, kWidth, kHeight / 2, kFormat, kType,
2207 mem4.id, mem4.offset, true);
2208 expected.set_token2.Init(GetNextToken());
2210 // TODO(gman): Make it possible to run this test
2211 // EXPECT_CALL(*command_buffer(), OnFlush())
2212 // .WillOnce(CheckRectAction(
2213 // kWidth, kHeight / 2, kFormat, kType, kPixelStoreUnpackAlignment,
2214 // true, pixels.get(),
2215 // GetExpectedTransferAddressFromOffsetAs<uint8>(offset3, half_size)))
2216 // .RetiresOnSaturation();
2219 kTarget, kLevel, kFormat, kWidth, kHeight, kBorder, kFormat, kType,
2221 EXPECT_EQ(0, memcmp(&expected, commands2, sizeof(expected)));
2222 EXPECT_TRUE(CheckRect(
2223 kWidth, kHeight / 2, kFormat, kType, kPixelStoreUnpackAlignment, true,
2224 pixels.get() + kHeight / 2 * padded_row_size, mem4.ptr));
2227 // Test TexSubImage2D with GL_PACK_FLIP_Y set and partial multirow transfers
2228 TEST_F(GLES2ImplementationTest, TexSubImage2DFlipY) {
2229 const GLsizei kTextureWidth = MaxTransferBufferSize() / 4;
2230 const GLsizei kTextureHeight = 7;
2231 const GLsizei kSubImageWidth = MaxTransferBufferSize() / 8;
2232 const GLsizei kSubImageHeight = 4;
2233 const GLint kSubImageXOffset = 1;
2234 const GLint kSubImageYOffset = 2;
2235 const GLenum kFormat = GL_RGBA;
2236 const GLenum kType = GL_UNSIGNED_BYTE;
2237 const GLenum kTarget = GL_TEXTURE_2D;
2238 const GLint kLevel = 0;
2239 const GLint kBorder = 0;
2240 const GLint kPixelStoreUnpackAlignment = 4;
2243 cmds::PixelStorei pixel_store_i1;
2244 cmds::TexImage2D tex_image_2d;
2245 cmds::PixelStorei pixel_store_i2;
2246 cmds::TexSubImage2D tex_sub_image_2d1;
2247 cmd::SetToken set_token1;
2248 cmds::TexSubImage2D tex_sub_image_2d2;
2249 cmd::SetToken set_token2;
2252 uint32 sub_2_high_size = 0;
2253 ASSERT_TRUE(GLES2Util::ComputeImageDataSizes(
2254 kSubImageWidth, 2, kFormat, kType, kPixelStoreUnpackAlignment,
2255 &sub_2_high_size, NULL, NULL));
2257 ExpectedMemoryInfo mem1 = GetExpectedMemory(sub_2_high_size);
2258 ExpectedMemoryInfo mem2 = GetExpectedMemory(sub_2_high_size);
2261 expected.pixel_store_i1.Init(GL_UNPACK_ALIGNMENT, kPixelStoreUnpackAlignment);
2262 expected.tex_image_2d.Init(
2263 kTarget, kLevel, kFormat, kTextureWidth, kTextureHeight, kBorder, kFormat,
2265 expected.pixel_store_i2.Init(GL_UNPACK_FLIP_Y_CHROMIUM, GL_TRUE);
2266 expected.tex_sub_image_2d1.Init(kTarget, kLevel, kSubImageXOffset,
2267 kSubImageYOffset + 2, kSubImageWidth, 2, kFormat, kType,
2268 mem1.id, mem1.offset, false);
2269 expected.set_token1.Init(GetNextToken());
2270 expected.tex_sub_image_2d2.Init(kTarget, kLevel, kSubImageXOffset,
2271 kSubImageYOffset, kSubImageWidth , 2, kFormat, kType,
2272 mem2.id, mem2.offset, false);
2273 expected.set_token2.Init(GetNextToken());
2275 gl_->PixelStorei(GL_UNPACK_ALIGNMENT, kPixelStoreUnpackAlignment);
2277 kTarget, kLevel, kFormat, kTextureWidth, kTextureHeight, kBorder, kFormat,
2279 gl_->PixelStorei(GL_UNPACK_FLIP_Y_CHROMIUM, GL_TRUE);
2280 scoped_ptr<uint32[]> pixels(new uint32[kSubImageWidth * kSubImageHeight]);
2281 for (int y = 0; y < kSubImageHeight; ++y) {
2282 for (int x = 0; x < kSubImageWidth; ++x) {
2283 pixels.get()[kSubImageWidth * y + x] = x | (y << 16);
2287 GL_TEXTURE_2D, 0, kSubImageXOffset, kSubImageYOffset, kSubImageWidth,
2288 kSubImageHeight, GL_RGBA, GL_UNSIGNED_BYTE, pixels.get());
2290 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
2291 EXPECT_TRUE(CheckRect(
2292 kSubImageWidth, 2, kFormat, kType, kPixelStoreUnpackAlignment, true,
2293 reinterpret_cast<uint8*>(pixels.get() + 2 * kSubImageWidth),
2297 TEST_F(GLES2ImplementationTest, SubImageUnpack) {
2298 static const GLint unpack_alignments[] = { 1, 2, 4, 8 };
2300 static const GLenum kFormat = GL_RGB;
2301 static const GLenum kType = GL_UNSIGNED_BYTE;
2302 static const GLint kLevel = 0;
2303 static const GLint kBorder = 0;
2304 // We're testing using the unpack params to pull a subimage out of a larger
2305 // source of pixels. Here we specify the subimage by its border rows /
2307 static const GLint kSrcWidth = 33;
2308 static const GLint kSrcSubImageX0 = 11;
2309 static const GLint kSrcSubImageX1 = 20;
2310 static const GLint kSrcSubImageY0 = 18;
2311 static const GLint kSrcSubImageY1 = 23;
2312 static const GLint kSrcSubImageWidth = kSrcSubImageX1 - kSrcSubImageX0;
2313 static const GLint kSrcSubImageHeight = kSrcSubImageY1 - kSrcSubImageY0;
2315 // these are only used in the texsubimage tests
2316 static const GLint kTexWidth = 1023;
2317 static const GLint kTexHeight = 511;
2318 static const GLint kTexSubXOffset = 419;
2319 static const GLint kTexSubYOffset = 103;
2322 cmds::PixelStorei pixel_store_i;
2323 cmds::PixelStorei pixel_store_i2;
2324 cmds::TexImage2D tex_image_2d;
2328 cmds::PixelStorei pixel_store_i;
2329 cmds::PixelStorei pixel_store_i2;
2330 cmds::TexImage2D tex_image_2d;
2331 cmds::TexSubImage2D tex_sub_image_2d;
2332 } texSubImageExpected;
2335 ASSERT_TRUE(GLES2Util::ComputeImageDataSizes(
2336 kSrcWidth, kSrcSubImageY1, kFormat, kType, 8, &src_size, NULL, NULL));
2337 scoped_ptr<uint8[]> src_pixels;
2338 src_pixels.reset(new uint8[src_size]);
2339 for (size_t i = 0; i < src_size; ++i) {
2340 src_pixels[i] = static_cast<int8>(i);
2343 for (int sub = 0; sub < 2; ++sub) {
2344 for (int flip_y = 0; flip_y < 2; ++flip_y) {
2345 for (size_t a = 0; a < arraysize(unpack_alignments); ++a) {
2346 GLint alignment = unpack_alignments[a];
2348 uint32 unpadded_row_size;
2349 uint32 padded_row_size;
2350 ASSERT_TRUE(GLES2Util::ComputeImageDataSizes(
2351 kSrcSubImageWidth, kSrcSubImageHeight, kFormat, kType, alignment,
2352 &size, &unpadded_row_size, &padded_row_size));
2353 ASSERT_TRUE(size <= MaxTransferBufferSize());
2354 ExpectedMemoryInfo mem = GetExpectedMemory(size);
2356 const void* commands = GetPut();
2357 gl_->PixelStorei(GL_UNPACK_ALIGNMENT, alignment);
2358 gl_->PixelStorei(GL_UNPACK_ROW_LENGTH_EXT, kSrcWidth);
2359 gl_->PixelStorei(GL_UNPACK_SKIP_PIXELS_EXT, kSrcSubImageX0);
2360 gl_->PixelStorei(GL_UNPACK_SKIP_ROWS_EXT, kSrcSubImageY0);
2361 gl_->PixelStorei(GL_UNPACK_FLIP_Y_CHROMIUM, flip_y);
2364 GL_TEXTURE_2D, kLevel, kFormat, kTexWidth, kTexHeight, kBorder,
2365 kFormat, kType, NULL);
2367 GL_TEXTURE_2D, kLevel, kTexSubXOffset, kTexSubYOffset,
2368 kSrcSubImageWidth, kSrcSubImageHeight, kFormat, kType,
2370 texSubImageExpected.pixel_store_i.Init(
2371 GL_UNPACK_ALIGNMENT, alignment);
2372 texSubImageExpected.pixel_store_i2.Init(
2373 GL_UNPACK_FLIP_Y_CHROMIUM, flip_y);
2374 texSubImageExpected.tex_image_2d.Init(
2375 GL_TEXTURE_2D, kLevel, kFormat, kTexWidth, kTexHeight, kBorder,
2376 kFormat, kType, 0, 0);
2377 texSubImageExpected.tex_sub_image_2d.Init(
2378 GL_TEXTURE_2D, kLevel, kTexSubXOffset, kTexSubYOffset,
2379 kSrcSubImageWidth, kSrcSubImageHeight, kFormat, kType, mem.id,
2380 mem.offset, GL_FALSE);
2381 EXPECT_EQ(0, memcmp(
2382 &texSubImageExpected, commands, sizeof(texSubImageExpected)));
2385 GL_TEXTURE_2D, kLevel, kFormat,
2386 kSrcSubImageWidth, kSrcSubImageHeight, kBorder, kFormat, kType,
2388 texImageExpected.pixel_store_i.Init(GL_UNPACK_ALIGNMENT, alignment);
2389 texImageExpected.pixel_store_i2.Init(
2390 GL_UNPACK_FLIP_Y_CHROMIUM, flip_y);
2391 texImageExpected.tex_image_2d.Init(
2392 GL_TEXTURE_2D, kLevel, kFormat, kSrcSubImageWidth,
2393 kSrcSubImageHeight, kBorder, kFormat, kType, mem.id, mem.offset);
2394 EXPECT_EQ(0, memcmp(
2395 &texImageExpected, commands, sizeof(texImageExpected)));
2397 uint32 src_padded_row_size;
2398 ASSERT_TRUE(GLES2Util::ComputeImagePaddedRowSize(
2399 kSrcWidth, kFormat, kType, alignment, &src_padded_row_size));
2400 uint32 bytes_per_group = GLES2Util::ComputeImageGroupSize(
2402 for (int y = 0; y < kSrcSubImageHeight; ++y) {
2403 GLint src_sub_y = flip_y ? kSrcSubImageHeight - y - 1 : y;
2404 const uint8* src_row = src_pixels.get() +
2405 (kSrcSubImageY0 + src_sub_y) * src_padded_row_size +
2406 bytes_per_group * kSrcSubImageX0;
2407 const uint8* dst_row = mem.ptr + y * padded_row_size;
2408 EXPECT_EQ(0, memcmp(src_row, dst_row, unpadded_row_size));
2416 // Binds can not be cached with bind_generates_resource = false because
2417 // our id might not be valid. More specifically if you bind on contextA then
2418 // delete on contextB the resource is still bound on contextA but GetInterger
2419 // won't return an id.
2420 TEST_F(GLES2ImplementationStrictSharedTest, BindsNotCached) {
2425 const PNameValue pairs[] = {{GL_TEXTURE_BINDING_2D, 1, },
2426 {GL_TEXTURE_BINDING_CUBE_MAP, 2, },
2427 {GL_TEXTURE_BINDING_EXTERNAL_OES, 3, },
2428 {GL_FRAMEBUFFER_BINDING, 4, },
2429 {GL_RENDERBUFFER_BINDING, 5, },
2430 {GL_ARRAY_BUFFER_BINDING, 6, },
2431 {GL_ELEMENT_ARRAY_BUFFER_BINDING, 7, }, };
2432 size_t num_pairs = sizeof(pairs) / sizeof(pairs[0]);
2433 for (size_t ii = 0; ii < num_pairs; ++ii) {
2434 const PNameValue& pv = pairs[ii];
2436 ExpectedMemoryInfo result1 =
2437 GetExpectedResultMemory(sizeof(cmds::GetIntegerv::Result));
2438 EXPECT_CALL(*command_buffer(), OnFlush())
2439 .WillOnce(SetMemory(result1.ptr,
2440 SizedResultHelper<GLuint>(pv.expected)))
2441 .RetiresOnSaturation();
2442 gl_->GetIntegerv(pv.pname, &v);
2443 EXPECT_EQ(pv.expected, v);
2447 TEST_F(GLES2ImplementationTest, GetString) {
2448 const uint32 kBucketId = GLES2Implementation::kResultBucketId;
2449 const Str7 kString = {"foobar"};
2450 // GL_CHROMIUM_map_sub GL_CHROMIUM_flipy are hard coded into
2451 // GLES2Implementation.
2452 const char* expected_str =
2454 "GL_CHROMIUM_flipy "
2455 "GL_EXT_unpack_subimage";
2456 const char kBad = 0x12;
2458 cmd::SetBucketSize set_bucket_size1;
2459 cmds::GetString get_string;
2460 cmd::GetBucketStart get_bucket_start;
2461 cmd::SetToken set_token1;
2462 cmd::SetBucketSize set_bucket_size2;
2464 ExpectedMemoryInfo mem1 = GetExpectedMemory(MaxTransferBufferSize());
2465 ExpectedMemoryInfo result1 =
2466 GetExpectedResultMemory(sizeof(cmd::GetBucketStart::Result));
2468 expected.set_bucket_size1.Init(kBucketId, 0);
2469 expected.get_string.Init(GL_EXTENSIONS, kBucketId);
2470 expected.get_bucket_start.Init(
2471 kBucketId, result1.id, result1.offset,
2472 MaxTransferBufferSize(), mem1.id, mem1.offset);
2473 expected.set_token1.Init(GetNextToken());
2474 expected.set_bucket_size2.Init(kBucketId, 0);
2475 char buf[sizeof(kString) + 1];
2476 memset(buf, kBad, sizeof(buf));
2478 EXPECT_CALL(*command_buffer(), OnFlush())
2479 .WillOnce(DoAll(SetMemory(result1.ptr, uint32(sizeof(kString))),
2480 SetMemory(mem1.ptr, kString)))
2481 .RetiresOnSaturation();
2483 const GLubyte* result = gl_->GetString(GL_EXTENSIONS);
2484 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
2485 EXPECT_STREQ(expected_str, reinterpret_cast<const char*>(result));
2488 TEST_F(GLES2ImplementationTest, PixelStoreiGLPackReverseRowOrderANGLE) {
2489 const uint32 kBucketId = GLES2Implementation::kResultBucketId;
2490 const Str7 kString = {"foobar"};
2492 cmd::SetBucketSize set_bucket_size1;
2493 cmds::GetString get_string;
2494 cmd::GetBucketStart get_bucket_start;
2495 cmd::SetToken set_token1;
2496 cmd::SetBucketSize set_bucket_size2;
2497 cmds::PixelStorei pixel_store;
2500 ExpectedMemoryInfo mem1 = GetExpectedMemory(MaxTransferBufferSize());
2501 ExpectedMemoryInfo result1 =
2502 GetExpectedResultMemory(sizeof(cmd::GetBucketStart::Result));
2505 expected.set_bucket_size1.Init(kBucketId, 0);
2506 expected.get_string.Init(GL_EXTENSIONS, kBucketId);
2507 expected.get_bucket_start.Init(
2508 kBucketId, result1.id, result1.offset,
2509 MaxTransferBufferSize(), mem1.id, mem1.offset);
2510 expected.set_token1.Init(GetNextToken());
2511 expected.set_bucket_size2.Init(kBucketId, 0);
2512 expected.pixel_store.Init(GL_PACK_REVERSE_ROW_ORDER_ANGLE, 1);
2514 EXPECT_CALL(*command_buffer(), OnFlush())
2515 .WillOnce(DoAll(SetMemory(result1.ptr, uint32(sizeof(kString))),
2516 SetMemory(mem1.ptr, kString)))
2517 .RetiresOnSaturation();
2519 gl_->PixelStorei(GL_PACK_REVERSE_ROW_ORDER_ANGLE, 1);
2520 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
2523 TEST_F(GLES2ImplementationTest, CreateProgram) {
2525 cmds::CreateProgram cmd;
2529 expected.cmd.Init(kProgramsAndShadersStartId);
2530 GLuint id = gl_->CreateProgram();
2531 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
2532 EXPECT_EQ(kProgramsAndShadersStartId, id);
2535 TEST_F(GLES2ImplementationTest, BufferDataLargerThanTransferBuffer) {
2537 cmds::BufferData set_size;
2538 cmds::BufferSubData copy_data1;
2539 cmd::SetToken set_token1;
2540 cmds::BufferSubData copy_data2;
2541 cmd::SetToken set_token2;
2543 const unsigned kUsableSize =
2544 kTransferBufferSize - GLES2Implementation::kStartingOffset;
2545 uint8 buf[kUsableSize * 2] = { 0, };
2547 ExpectedMemoryInfo mem1 = GetExpectedMemory(kUsableSize);
2548 ExpectedMemoryInfo mem2 = GetExpectedMemory(kUsableSize);
2551 expected.set_size.Init(
2552 GL_ARRAY_BUFFER, arraysize(buf), 0, 0, GL_DYNAMIC_DRAW);
2553 expected.copy_data1.Init(
2554 GL_ARRAY_BUFFER, 0, kUsableSize, mem1.id, mem1.offset);
2555 expected.set_token1.Init(GetNextToken());
2556 expected.copy_data2.Init(
2557 GL_ARRAY_BUFFER, kUsableSize, kUsableSize, mem2.id, mem2.offset);
2558 expected.set_token2.Init(GetNextToken());
2559 gl_->BufferData(GL_ARRAY_BUFFER, arraysize(buf), buf, GL_DYNAMIC_DRAW);
2560 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
2563 TEST_F(GLES2ImplementationTest, CapabilitiesAreCached) {
2564 static const GLenum kStates[] = {
2569 GL_POLYGON_OFFSET_FILL,
2570 GL_SAMPLE_ALPHA_TO_COVERAGE,
2576 cmds::Enable enable_cmd;
2580 for (size_t ii = 0; ii < arraysize(kStates); ++ii) {
2581 GLenum state = kStates[ii];
2582 expected.enable_cmd.Init(state);
2583 GLboolean result = gl_->IsEnabled(state);
2584 EXPECT_EQ(static_cast<GLboolean>(ii == 0), result);
2585 EXPECT_TRUE(NoCommandsWritten());
2586 const void* commands = GetPut();
2589 EXPECT_EQ(0, memcmp(&expected, commands, sizeof(expected)));
2592 result = gl_->IsEnabled(state);
2593 EXPECT_TRUE(result);
2594 EXPECT_TRUE(NoCommandsWritten());
2598 TEST_F(GLES2ImplementationTest, BindVertexArrayOES) {
2600 gl_->GenVertexArraysOES(1, &id);
2604 cmds::BindVertexArrayOES cmd;
2607 expected.cmd.Init(id);
2609 const void* commands = GetPut();
2610 gl_->BindVertexArrayOES(id);
2611 EXPECT_EQ(0, memcmp(&expected, commands, sizeof(expected)));
2613 gl_->BindVertexArrayOES(id);
2614 EXPECT_TRUE(NoCommandsWritten());
2617 TEST_F(GLES2ImplementationTest, BeginEndQueryEXT) {
2618 // Test GetQueryivEXT returns 0 if no current query.
2620 gl_->GetQueryivEXT(GL_ANY_SAMPLES_PASSED_EXT, GL_CURRENT_QUERY_EXT, ¶m);
2621 EXPECT_EQ(0, param);
2623 GLuint expected_ids[2] = { 1, 2 }; // These must match what's actually genned.
2625 cmds::GenQueriesEXTImmediate gen;
2628 GenCmds expected_gen_cmds;
2629 expected_gen_cmds.gen.Init(arraysize(expected_ids), &expected_ids[0]);
2630 GLuint ids[arraysize(expected_ids)] = { 0, };
2631 gl_->GenQueriesEXT(arraysize(expected_ids), &ids[0]);
2632 EXPECT_EQ(0, memcmp(
2633 &expected_gen_cmds, commands_, sizeof(expected_gen_cmds)));
2634 GLuint id1 = ids[0];
2635 GLuint id2 = ids[1];
2638 // Test BeginQueryEXT fails if id = 0.
2639 gl_->BeginQueryEXT(GL_ANY_SAMPLES_PASSED_EXT, 0);
2640 EXPECT_TRUE(NoCommandsWritten());
2641 EXPECT_EQ(GL_INVALID_OPERATION, CheckError());
2643 // Test BeginQueryEXT fails if id not GENed.
2646 // Test BeginQueryEXT inserts command.
2648 cmds::BeginQueryEXT begin_query;
2650 BeginCmds expected_begin_cmds;
2651 const void* commands = GetPut();
2652 gl_->BeginQueryEXT(GL_ANY_SAMPLES_PASSED_EXT, id1);
2653 QueryTracker::Query* query = GetQuery(id1);
2654 ASSERT_TRUE(query != NULL);
2655 expected_begin_cmds.begin_query.Init(
2656 GL_ANY_SAMPLES_PASSED_EXT, id1, query->shm_id(), query->shm_offset());
2657 EXPECT_EQ(0, memcmp(
2658 &expected_begin_cmds, commands, sizeof(expected_begin_cmds)));
2661 // Test GetQueryivEXT returns id.
2663 gl_->GetQueryivEXT(GL_ANY_SAMPLES_PASSED_EXT, GL_CURRENT_QUERY_EXT, ¶m);
2664 EXPECT_EQ(id1, static_cast<GLuint>(param));
2666 GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT, GL_CURRENT_QUERY_EXT, ¶m);
2667 EXPECT_EQ(0, param);
2669 // Test BeginQueryEXT fails if between Begin/End.
2670 gl_->BeginQueryEXT(GL_ANY_SAMPLES_PASSED_EXT, id2);
2671 EXPECT_TRUE(NoCommandsWritten());
2672 EXPECT_EQ(GL_INVALID_OPERATION, CheckError());
2674 // Test EndQueryEXT fails if target not same as current query.
2676 gl_->EndQueryEXT(GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT);
2677 EXPECT_TRUE(NoCommandsWritten());
2678 EXPECT_EQ(GL_INVALID_OPERATION, CheckError());
2680 // Test EndQueryEXT sends command
2682 cmds::EndQueryEXT end_query;
2684 EndCmds expected_end_cmds;
2685 expected_end_cmds.end_query.Init(
2686 GL_ANY_SAMPLES_PASSED_EXT, query->submit_count());
2687 commands = GetPut();
2688 gl_->EndQueryEXT(GL_ANY_SAMPLES_PASSED_EXT);
2689 EXPECT_EQ(0, memcmp(
2690 &expected_end_cmds, commands, sizeof(expected_end_cmds)));
2692 // Test EndQueryEXT fails if no current query.
2694 gl_->EndQueryEXT(GL_ANY_SAMPLES_PASSED_EXT);
2695 EXPECT_TRUE(NoCommandsWritten());
2696 EXPECT_EQ(GL_INVALID_OPERATION, CheckError());
2698 // Test 2nd Begin/End increments count.
2699 uint32 old_submit_count = query->submit_count();
2700 gl_->BeginQueryEXT(GL_ANY_SAMPLES_PASSED_EXT, id1);
2701 EXPECT_NE(old_submit_count, query->submit_count());
2702 expected_end_cmds.end_query.Init(
2703 GL_ANY_SAMPLES_PASSED_EXT, query->submit_count());
2704 commands = GetPut();
2705 gl_->EndQueryEXT(GL_ANY_SAMPLES_PASSED_EXT);
2706 EXPECT_EQ(0, memcmp(
2707 &expected_end_cmds, commands, sizeof(expected_end_cmds)));
2709 // Test BeginQueryEXT fails if target changed.
2711 gl_->BeginQueryEXT(GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT, id1);
2712 EXPECT_TRUE(NoCommandsWritten());
2713 EXPECT_EQ(GL_INVALID_OPERATION, CheckError());
2715 // Test GetQueryObjectuivEXT fails if unused id
2716 GLuint available = 0xBDu;
2718 gl_->GetQueryObjectuivEXT(id2, GL_QUERY_RESULT_AVAILABLE_EXT, &available);
2719 EXPECT_TRUE(NoCommandsWritten());
2720 EXPECT_EQ(0xBDu, available);
2721 EXPECT_EQ(GL_INVALID_OPERATION, CheckError());
2723 // Test GetQueryObjectuivEXT fails if bad id
2725 gl_->GetQueryObjectuivEXT(4567, GL_QUERY_RESULT_AVAILABLE_EXT, &available);
2726 EXPECT_TRUE(NoCommandsWritten());
2727 EXPECT_EQ(0xBDu, available);
2728 EXPECT_EQ(GL_INVALID_OPERATION, CheckError());
2730 // Test GetQueryObjectuivEXT CheckResultsAvailable
2732 gl_->GetQueryObjectuivEXT(id1, GL_QUERY_RESULT_AVAILABLE_EXT, &available);
2733 EXPECT_TRUE(NoCommandsWritten());
2734 EXPECT_EQ(0u, available);
2737 TEST_F(GLES2ImplementationTest, ErrorQuery) {
2739 gl_->GenQueriesEXT(1, &id);
2742 // Test BeginQueryEXT does NOT insert commands.
2743 gl_->BeginQueryEXT(GL_GET_ERROR_QUERY_CHROMIUM, id);
2744 EXPECT_TRUE(NoCommandsWritten());
2745 QueryTracker::Query* query = GetQuery(id);
2746 ASSERT_TRUE(query != NULL);
2748 // Test EndQueryEXT sends both begin and end command
2750 cmds::BeginQueryEXT begin_query;
2751 cmds::EndQueryEXT end_query;
2753 EndCmds expected_end_cmds;
2754 expected_end_cmds.begin_query.Init(
2755 GL_GET_ERROR_QUERY_CHROMIUM, id, query->shm_id(), query->shm_offset());
2756 expected_end_cmds.end_query.Init(
2757 GL_GET_ERROR_QUERY_CHROMIUM, query->submit_count());
2758 const void* commands = GetPut();
2759 gl_->EndQueryEXT(GL_GET_ERROR_QUERY_CHROMIUM);
2760 EXPECT_EQ(0, memcmp(
2761 &expected_end_cmds, commands, sizeof(expected_end_cmds)));
2764 // Check result is not yet available.
2765 GLuint available = 0xBDu;
2766 gl_->GetQueryObjectuivEXT(id, GL_QUERY_RESULT_AVAILABLE_EXT, &available);
2767 EXPECT_TRUE(NoCommandsWritten());
2768 EXPECT_EQ(0u, available);
2770 // Test no commands are sent if there is a client side error.
2772 // Generate a client side error
2773 gl_->ActiveTexture(GL_TEXTURE0 - 1);
2775 gl_->BeginQueryEXT(GL_GET_ERROR_QUERY_CHROMIUM, id);
2776 gl_->EndQueryEXT(GL_GET_ERROR_QUERY_CHROMIUM);
2777 EXPECT_TRUE(NoCommandsWritten());
2779 // Check result is available.
2780 gl_->GetQueryObjectuivEXT(id, GL_QUERY_RESULT_AVAILABLE_EXT, &available);
2781 EXPECT_TRUE(NoCommandsWritten());
2782 EXPECT_NE(0u, available);
2785 GLuint result = 0xBDu;
2786 gl_->GetQueryObjectuivEXT(id, GL_QUERY_RESULT_EXT, &result);
2787 EXPECT_TRUE(NoCommandsWritten());
2788 EXPECT_EQ(static_cast<GLuint>(GL_INVALID_ENUM), result);
2791 #if !defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS)
2792 TEST_F(GLES2ImplementationTest, VertexArrays) {
2793 const GLuint kAttribIndex1 = 1;
2794 const GLint kNumComponents1 = 3;
2795 const GLsizei kClientStride = 12;
2798 gl_->GenVertexArraysOES(1, &id);
2801 gl_->BindVertexArrayOES(id);
2803 // Test that VertexAttribPointer cannot be called with a bound buffer of 0
2804 // unless the offset is NULL
2805 gl_->BindBuffer(GL_ARRAY_BUFFER, 0);
2807 gl_->VertexAttribPointer(
2808 kAttribIndex1, kNumComponents1, GL_FLOAT, GL_FALSE, kClientStride,
2809 reinterpret_cast<const void*>(4));
2810 EXPECT_EQ(GL_INVALID_OPERATION, CheckError());
2812 gl_->VertexAttribPointer(
2813 kAttribIndex1, kNumComponents1, GL_FLOAT, GL_FALSE, kClientStride, NULL);
2814 EXPECT_EQ(GL_NO_ERROR, CheckError());
2818 TEST_F(GLES2ImplementationTest, Disable) {
2823 expected.cmd.Init(GL_DITHER); // Note: DITHER defaults to enabled.
2825 gl_->Disable(GL_DITHER);
2826 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
2827 // Check it's cached and not called again.
2829 gl_->Disable(GL_DITHER);
2830 EXPECT_TRUE(NoCommandsWritten());
2833 TEST_F(GLES2ImplementationTest, Enable) {
2838 expected.cmd.Init(GL_BLEND); // Note: BLEND defaults to disabled.
2840 gl_->Enable(GL_BLEND);
2841 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
2842 // Check it's cached and not called again.
2844 gl_->Enable(GL_BLEND);
2845 EXPECT_TRUE(NoCommandsWritten());
2848 TEST_F(GLES2ImplementationTest, ConsumeTextureCHROMIUM) {
2850 cmds::ConsumeTextureCHROMIUMImmediate cmd;
2854 Mailbox mailbox = Mailbox::Generate();
2856 expected.cmd.Init(GL_TEXTURE_2D, mailbox.name);
2857 gl_->ConsumeTextureCHROMIUM(GL_TEXTURE_2D, mailbox.name);
2858 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
2861 TEST_F(GLES2ImplementationTest, ProduceTextureCHROMIUM) {
2863 cmds::ProduceTextureCHROMIUMImmediate cmd;
2867 Mailbox mailbox = Mailbox::Generate();
2869 expected.cmd.Init(GL_TEXTURE_2D, mailbox.name);
2870 gl_->ProduceTextureCHROMIUM(GL_TEXTURE_2D, mailbox.name);
2871 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
2874 #include "gpu/command_buffer/client/gles2_implementation_unittest_autogen.h"
2876 } // namespace gles2