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