Standardize usage of virtual/override/final specifiers.
[chromium-blink-merge.git] / gpu / command_buffer / client / gles2_implementation_unittest.cc
blob4102060bf573a2095448282112d103b4c7884477
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 <limits>
11 #include <GLES2/gl2ext.h>
12 #include <GLES2/gl2extchromium.h>
13 #include "base/compiler_specific.h"
14 #include "gpu/command_buffer/client/client_test_helper.h"
15 #include "gpu/command_buffer/client/program_info_manager.h"
16 #include "gpu/command_buffer/client/transfer_buffer.h"
17 #include "gpu/command_buffer/common/command_buffer.h"
18 #include "testing/gtest/include/gtest/gtest.h"
19 #include "testing/gmock/include/gmock/gmock.h"
21 #if !defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS)
22 #define GLES2_SUPPORT_CLIENT_SIDE_ARRAYS
23 #endif
25 using testing::_;
26 using testing::AtLeast;
27 using testing::AnyNumber;
28 using testing::DoAll;
29 using testing::InSequence;
30 using testing::Invoke;
31 using testing::Mock;
32 using testing::Sequence;
33 using testing::StrictMock;
34 using testing::Truly;
35 using testing::Return;
37 namespace gpu {
38 namespace gles2 {
40 ACTION_P2(SetMemory, dst, obj) {
41 memcpy(dst, &obj, sizeof(obj));
44 ACTION_P3(SetMemoryFromArray, dst, array, size) {
45 memcpy(dst, array, size);
48 // Used to help set the transfer buffer result to SizedResult of a single value.
49 template <typename T>
50 class SizedResultHelper {
51 public:
52 explicit SizedResultHelper(T result)
53 : size_(sizeof(result)),
54 result_(result) {
57 private:
58 uint32 size_;
59 T result_;
62 // Struct to make it easy to pass a vec4 worth of floats.
63 struct FourFloats {
64 FourFloats(float _x, float _y, float _z, float _w)
65 : x(_x),
66 y(_y),
67 z(_z),
68 w(_w) {
71 float x;
72 float y;
73 float z;
74 float w;
77 #pragma pack(push, 1)
78 // Struct that holds 7 characters.
79 struct Str7 {
80 char str[7];
82 #pragma pack(pop)
84 class MockTransferBuffer : public TransferBufferInterface {
85 public:
86 struct ExpectedMemoryInfo {
87 uint32 offset;
88 int32 id;
89 uint8* ptr;
92 MockTransferBuffer(
93 CommandBuffer* command_buffer,
94 unsigned int size,
95 unsigned int result_size,
96 unsigned int alignment)
97 : command_buffer_(command_buffer),
98 size_(size),
99 result_size_(result_size),
100 alignment_(alignment),
101 actual_buffer_index_(0),
102 expected_buffer_index_(0),
103 last_alloc_(NULL),
104 expected_offset_(result_size),
105 actual_offset_(result_size) {
106 // We have to allocate the buffers here because
107 // we need to know their address before GLES2Implementation::Initialize
108 // is called.
109 for (int ii = 0; ii < kNumBuffers; ++ii) {
110 buffers_[ii] = command_buffer_->CreateTransferBuffer(
111 size_ + ii * alignment_,
112 &buffer_ids_[ii]);
113 EXPECT_NE(-1, buffer_ids_[ii]);
117 ~MockTransferBuffer() override {}
119 bool Initialize(unsigned int starting_buffer_size,
120 unsigned int result_size,
121 unsigned int /* min_buffer_size */,
122 unsigned int /* max_buffer_size */,
123 unsigned int alignment,
124 unsigned int size_to_flush) override;
125 int GetShmId() override;
126 void* GetResultBuffer() override;
127 int GetResultOffset() override;
128 void Free() override;
129 bool HaveBuffer() const override;
130 void* AllocUpTo(unsigned int size, unsigned int* size_allocated) override;
131 void* Alloc(unsigned int size) override;
132 RingBuffer::Offset GetOffset(void* pointer) const override;
133 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_]->memory());
173 uint8* expected_buffer() const {
174 return static_cast<uint8*>(buffers_[expected_buffer_index_]->memory());
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 scoped_refptr<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 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 // API wrapper for Buffers.
301 class GenBuffersAPI {
302 public:
303 static void Gen(GLES2Implementation* gl_impl, GLsizei n, GLuint* ids) {
304 gl_impl->GenBuffers(n, ids);
307 static void Delete(GLES2Implementation* gl_impl,
308 GLsizei n,
309 const GLuint* ids) {
310 gl_impl->DeleteBuffers(n, ids);
314 // API wrapper for Framebuffers.
315 class GenFramebuffersAPI {
316 public:
317 static void Gen(GLES2Implementation* gl_impl, GLsizei n, GLuint* ids) {
318 gl_impl->GenFramebuffers(n, ids);
321 static void Delete(GLES2Implementation* gl_impl,
322 GLsizei n,
323 const GLuint* ids) {
324 gl_impl->DeleteFramebuffers(n, ids);
328 // API wrapper for Renderbuffers.
329 class GenRenderbuffersAPI {
330 public:
331 static void Gen(GLES2Implementation* gl_impl, GLsizei n, GLuint* ids) {
332 gl_impl->GenRenderbuffers(n, ids);
335 static void Delete(GLES2Implementation* gl_impl,
336 GLsizei n,
337 const GLuint* ids) {
338 gl_impl->DeleteRenderbuffers(n, ids);
342 // API wrapper for Textures.
343 class GenTexturesAPI {
344 public:
345 static void Gen(GLES2Implementation* gl_impl, GLsizei n, GLuint* ids) {
346 gl_impl->GenTextures(n, ids);
349 static void Delete(GLES2Implementation* gl_impl,
350 GLsizei n,
351 const GLuint* ids) {
352 gl_impl->DeleteTextures(n, ids);
356 class GLES2ImplementationTest : public testing::Test {
357 protected:
358 static const int kNumTestContexts = 2;
359 static const uint8 kInitialValue = 0xBD;
360 static const int32 kNumCommandEntries = 500;
361 static const int32 kCommandBufferSizeBytes =
362 kNumCommandEntries * sizeof(CommandBufferEntry);
363 static const size_t kTransferBufferSize = 512;
365 static const GLint kMaxCombinedTextureImageUnits = 8;
366 static const GLint kMaxCubeMapTextureSize = 64;
367 static const GLint kMaxFragmentUniformVectors = 16;
368 static const GLint kMaxRenderbufferSize = 64;
369 static const GLint kMaxTextureImageUnits = 8;
370 static const GLint kMaxTextureSize = 128;
371 static const GLint kMaxVaryingVectors = 8;
372 static const GLint kMaxVertexAttribs = 8;
373 static const GLint kMaxVertexTextureImageUnits = 0;
374 static const GLint kMaxVertexUniformVectors = 128;
375 static const GLint kNumCompressedTextureFormats = 0;
376 static const GLint kNumShaderBinaryFormats = 0;
377 static const GLuint kStartId = 1024;
378 static const GLuint kBuffersStartId =
379 GLES2Implementation::kClientSideArrayId + 2 * kNumTestContexts;
380 static const GLuint kFramebuffersStartId = 1;
381 static const GLuint kProgramsAndShadersStartId = 1;
382 static const GLuint kRenderbuffersStartId = 1;
383 static const GLuint kTexturesStartId = 1;
384 static const GLuint kQueriesStartId = 1;
385 static const GLuint kVertexArraysStartId = 1;
387 typedef MockTransferBuffer::ExpectedMemoryInfo ExpectedMemoryInfo;
389 class TestContext {
390 public:
391 TestContext() : commands_(NULL), token_(0) {}
393 bool Initialize(ShareGroup* share_group,
394 bool bind_generates_resource_client,
395 bool bind_generates_resource_service,
396 bool lose_context_when_out_of_memory) {
397 command_buffer_.reset(new StrictMock<MockClientCommandBuffer>());
398 if (!command_buffer_->Initialize())
399 return false;
401 transfer_buffer_.reset(
402 new MockTransferBuffer(command_buffer_.get(),
403 kTransferBufferSize,
404 GLES2Implementation::kStartingOffset,
405 GLES2Implementation::kAlignment));
407 helper_.reset(new GLES2CmdHelper(command_buffer()));
408 helper_->Initialize(kCommandBufferSizeBytes);
410 gpu_control_.reset(new StrictMock<MockClientGpuControl>());
411 EXPECT_CALL(*gpu_control_, GetCapabilities())
412 .WillOnce(testing::Return(Capabilities()));
414 GLES2Implementation::GLStaticState state;
415 GLES2Implementation::GLStaticState::IntState& int_state = state.int_state;
416 int_state.max_combined_texture_image_units =
417 kMaxCombinedTextureImageUnits;
418 int_state.max_cube_map_texture_size = kMaxCubeMapTextureSize;
419 int_state.max_fragment_uniform_vectors = kMaxFragmentUniformVectors;
420 int_state.max_renderbuffer_size = kMaxRenderbufferSize;
421 int_state.max_texture_image_units = kMaxTextureImageUnits;
422 int_state.max_texture_size = kMaxTextureSize;
423 int_state.max_varying_vectors = kMaxVaryingVectors;
424 int_state.max_vertex_attribs = kMaxVertexAttribs;
425 int_state.max_vertex_texture_image_units = kMaxVertexTextureImageUnits;
426 int_state.max_vertex_uniform_vectors = kMaxVertexUniformVectors;
427 int_state.num_compressed_texture_formats = kNumCompressedTextureFormats;
428 int_state.num_shader_binary_formats = kNumShaderBinaryFormats;
429 int_state.bind_generates_resource_chromium =
430 bind_generates_resource_service ? 1 : 0;
432 // This just happens to work for now because IntState has 1 GLint per
433 // state.
434 // If IntState gets more complicated this code will need to get more
435 // complicated.
436 ExpectedMemoryInfo mem1 = transfer_buffer_->GetExpectedMemory(
437 sizeof(GLES2Implementation::GLStaticState::IntState) * 2 +
438 sizeof(cmds::GetShaderPrecisionFormat::Result) * 12);
441 InSequence sequence;
443 EXPECT_CALL(*command_buffer_, OnFlush())
444 .WillOnce(SetMemory(mem1.ptr + sizeof(int_state), int_state))
445 .RetiresOnSaturation();
446 GetNextToken(); // eat the token that starting up will use.
448 gl_.reset(new GLES2Implementation(helper_.get(),
449 share_group,
450 transfer_buffer_.get(),
451 bind_generates_resource_client,
452 lose_context_when_out_of_memory,
453 gpu_control_.get()));
455 if (!gl_->Initialize(kTransferBufferSize,
456 kTransferBufferSize,
457 kTransferBufferSize,
458 GLES2Implementation::kNoLimit))
459 return false;
462 EXPECT_CALL(*command_buffer_, OnFlush()).Times(1).RetiresOnSaturation();
463 helper_->CommandBufferHelper::Finish();
464 ::testing::Mock::VerifyAndClearExpectations(gl_.get());
466 scoped_refptr<Buffer> ring_buffer = helper_->get_ring_buffer();
467 commands_ = static_cast<CommandBufferEntry*>(ring_buffer->memory()) +
468 command_buffer()->GetLastState().put_offset;
469 ClearCommands();
470 EXPECT_TRUE(transfer_buffer_->InSync());
472 ::testing::Mock::VerifyAndClearExpectations(command_buffer());
473 return true;
476 void TearDown() {
477 Mock::VerifyAndClear(gl_.get());
478 EXPECT_CALL(*command_buffer(), OnFlush()).Times(AnyNumber());
479 // For command buffer.
480 EXPECT_CALL(*command_buffer(), DestroyTransferBuffer(_))
481 .Times(AtLeast(1));
482 gl_.reset();
485 MockClientCommandBuffer* command_buffer() const {
486 return command_buffer_.get();
489 int GetNextToken() { return ++token_; }
491 void ClearCommands() {
492 scoped_refptr<Buffer> ring_buffer = helper_->get_ring_buffer();
493 memset(ring_buffer->memory(), kInitialValue, ring_buffer->size());
496 scoped_ptr<MockClientCommandBuffer> command_buffer_;
497 scoped_ptr<MockClientGpuControl> gpu_control_;
498 scoped_ptr<GLES2CmdHelper> helper_;
499 scoped_ptr<MockTransferBuffer> transfer_buffer_;
500 scoped_ptr<GLES2Implementation> gl_;
501 CommandBufferEntry* commands_;
502 int token_;
505 GLES2ImplementationTest() : commands_(NULL) {}
507 void SetUp() override;
508 void TearDown() override;
510 bool NoCommandsWritten() {
511 scoped_refptr<Buffer> ring_buffer = helper_->get_ring_buffer();
512 const uint8* cmds = reinterpret_cast<const uint8*>(ring_buffer->memory());
513 const uint8* end = cmds + ring_buffer->size();
514 for (; cmds < end; ++cmds) {
515 if (*cmds != kInitialValue) {
516 return false;
519 return true;
522 QueryTracker::Query* GetQuery(GLuint id) {
523 return gl_->query_tracker_->GetQuery(id);
526 struct ContextInitOptions {
527 ContextInitOptions()
528 : bind_generates_resource_client(true),
529 bind_generates_resource_service(true),
530 lose_context_when_out_of_memory(false) {}
532 bool bind_generates_resource_client;
533 bool bind_generates_resource_service;
534 bool lose_context_when_out_of_memory;
537 bool Initialize(const ContextInitOptions& init_options) {
538 bool success = true;
539 share_group_ = new ShareGroup(init_options.bind_generates_resource_client);
541 for (int i = 0; i < kNumTestContexts; i++) {
542 if (!test_contexts_[i].Initialize(
543 share_group_.get(),
544 init_options.bind_generates_resource_client,
545 init_options.bind_generates_resource_service,
546 init_options.lose_context_when_out_of_memory))
547 success = false;
550 // Default to test context 0.
551 gpu_control_ = test_contexts_[0].gpu_control_.get();
552 helper_ = test_contexts_[0].helper_.get();
553 transfer_buffer_ = test_contexts_[0].transfer_buffer_.get();
554 gl_ = test_contexts_[0].gl_.get();
555 commands_ = test_contexts_[0].commands_;
556 return success;
559 MockClientCommandBuffer* command_buffer() const {
560 return test_contexts_[0].command_buffer_.get();
563 int GetNextToken() { return test_contexts_[0].GetNextToken(); }
565 const void* GetPut() {
566 return helper_->GetSpace(0);
569 void ClearCommands() {
570 scoped_refptr<Buffer> ring_buffer = helper_->get_ring_buffer();
571 memset(ring_buffer->memory(), kInitialValue, ring_buffer->size());
574 size_t MaxTransferBufferSize() {
575 return transfer_buffer_->MaxTransferBufferSize();
578 ExpectedMemoryInfo GetExpectedMemory(size_t size) {
579 return transfer_buffer_->GetExpectedMemory(size);
582 ExpectedMemoryInfo GetExpectedResultMemory(size_t size) {
583 return transfer_buffer_->GetExpectedResultMemory(size);
586 // Sets the ProgramInfoManager. The manager will be owned
587 // by the ShareGroup.
588 void SetProgramInfoManager(ProgramInfoManager* manager) {
589 gl_->share_group()->set_program_info_manager(manager);
592 int CheckError() {
593 ExpectedMemoryInfo result =
594 GetExpectedResultMemory(sizeof(cmds::GetError::Result));
595 EXPECT_CALL(*command_buffer(), OnFlush())
596 .WillOnce(SetMemory(result.ptr, GLuint(GL_NO_ERROR)))
597 .RetiresOnSaturation();
598 return gl_->GetError();
601 const std::string& GetLastError() {
602 return gl_->GetLastError();
605 bool GetBucketContents(uint32 bucket_id, std::vector<int8>* data) {
606 return gl_->GetBucketContents(bucket_id, data);
609 TestContext test_contexts_[kNumTestContexts];
611 scoped_refptr<ShareGroup> share_group_;
612 MockClientGpuControl* gpu_control_;
613 GLES2CmdHelper* helper_;
614 MockTransferBuffer* transfer_buffer_;
615 GLES2Implementation* gl_;
616 CommandBufferEntry* commands_;
619 void GLES2ImplementationTest::SetUp() {
620 ContextInitOptions init_options;
621 ASSERT_TRUE(Initialize(init_options));
624 void GLES2ImplementationTest::TearDown() {
625 for (int i = 0; i < kNumTestContexts; i++)
626 test_contexts_[i].TearDown();
629 class GLES2ImplementationManualInitTest : public GLES2ImplementationTest {
630 protected:
631 void SetUp() override {}
634 class GLES2ImplementationStrictSharedTest : public GLES2ImplementationTest {
635 protected:
636 void SetUp() override;
638 template <class ResApi>
639 void FlushGenerationTest() {
640 GLuint id1, id2, id3;
642 // Generate valid id.
643 ResApi::Gen(gl_, 1, &id1);
644 EXPECT_NE(id1, 0u);
646 // Delete id1 and generate id2. id1 should not be reused.
647 ResApi::Delete(gl_, 1, &id1);
648 ResApi::Gen(gl_, 1, &id2);
649 EXPECT_NE(id2, 0u);
650 EXPECT_NE(id2, id1);
652 // Expect id1 reuse after Flush.
653 gl_->Flush();
654 ResApi::Gen(gl_, 1, &id3);
655 EXPECT_EQ(id3, id1);
658 // Ids should not be reused unless the |Deleting| context does a Flush()
659 // AND triggers a lazy release after that.
660 template <class ResApi>
661 void CrossContextGenerationTest() {
662 GLES2Implementation* gl1 = test_contexts_[0].gl_.get();
663 GLES2Implementation* gl2 = test_contexts_[1].gl_.get();
664 GLuint id1, id2, id3;
666 // Delete, no flush on context 1. No reuse.
667 ResApi::Gen(gl1, 1, &id1);
668 ResApi::Delete(gl1, 1, &id1);
669 ResApi::Gen(gl1, 1, &id2);
670 EXPECT_NE(id1, id2);
672 // Flush context 2. Still no reuse.
673 gl2->Flush();
674 ResApi::Gen(gl2, 1, &id3);
675 EXPECT_NE(id1, id3);
676 EXPECT_NE(id2, id3);
678 // Flush on context 1, but no lazy release. Still no reuse.
679 gl1->Flush();
680 ResApi::Gen(gl2, 1, &id3);
681 EXPECT_NE(id1, id3);
683 // Lazy release triggered by another Delete. Should reuse id1.
684 ResApi::Delete(gl1, 1, &id2);
685 ResApi::Gen(gl2, 1, &id3);
686 EXPECT_EQ(id1, id3);
689 // Same as CrossContextGenerationTest(), but triggers an Auto Flush on
690 // the Delete(). Tests an edge case regression.
691 template <class ResApi>
692 void CrossContextGenerationAutoFlushTest() {
693 GLES2Implementation* gl1 = test_contexts_[0].gl_.get();
694 GLES2Implementation* gl2 = test_contexts_[1].gl_.get();
695 GLuint id1, id2, id3;
697 // Delete, no flush on context 1. No reuse.
698 // By half filling the buffer, an internal flush is forced on the Delete().
699 ResApi::Gen(gl1, 1, &id1);
700 gl1->helper()->Noop(kNumCommandEntries / 2);
701 ResApi::Delete(gl1, 1, &id1);
702 ResApi::Gen(gl1, 1, &id2);
703 EXPECT_NE(id1, id2);
705 // Flush context 2. Still no reuse.
706 gl2->Flush();
707 ResApi::Gen(gl2, 1, &id3);
708 EXPECT_NE(id1, id3);
709 EXPECT_NE(id2, id3);
711 // Flush on context 1, but no lazy release. Still no reuse.
712 gl1->Flush();
713 ResApi::Gen(gl2, 1, &id3);
714 EXPECT_NE(id1, id3);
716 // Lazy release triggered by another Delete. Should reuse id1.
717 ResApi::Delete(gl1, 1, &id2);
718 ResApi::Gen(gl2, 1, &id3);
719 EXPECT_EQ(id1, id3);
723 void GLES2ImplementationStrictSharedTest::SetUp() {
724 ContextInitOptions init_options;
725 init_options.bind_generates_resource_client = false;
726 init_options.bind_generates_resource_service = false;
727 ASSERT_TRUE(Initialize(init_options));
730 // GCC requires these declarations, but MSVC requires they not be present
731 #ifndef _MSC_VER
732 const uint8 GLES2ImplementationTest::kInitialValue;
733 const int32 GLES2ImplementationTest::kNumCommandEntries;
734 const int32 GLES2ImplementationTest::kCommandBufferSizeBytes;
735 const size_t GLES2ImplementationTest::kTransferBufferSize;
736 const GLint GLES2ImplementationTest::kMaxCombinedTextureImageUnits;
737 const GLint GLES2ImplementationTest::kMaxCubeMapTextureSize;
738 const GLint GLES2ImplementationTest::kMaxFragmentUniformVectors;
739 const GLint GLES2ImplementationTest::kMaxRenderbufferSize;
740 const GLint GLES2ImplementationTest::kMaxTextureImageUnits;
741 const GLint GLES2ImplementationTest::kMaxTextureSize;
742 const GLint GLES2ImplementationTest::kMaxVaryingVectors;
743 const GLint GLES2ImplementationTest::kMaxVertexAttribs;
744 const GLint GLES2ImplementationTest::kMaxVertexTextureImageUnits;
745 const GLint GLES2ImplementationTest::kMaxVertexUniformVectors;
746 const GLint GLES2ImplementationTest::kNumCompressedTextureFormats;
747 const GLint GLES2ImplementationTest::kNumShaderBinaryFormats;
748 const GLuint GLES2ImplementationTest::kStartId;
749 const GLuint GLES2ImplementationTest::kBuffersStartId;
750 const GLuint GLES2ImplementationTest::kFramebuffersStartId;
751 const GLuint GLES2ImplementationTest::kProgramsAndShadersStartId;
752 const GLuint GLES2ImplementationTest::kRenderbuffersStartId;
753 const GLuint GLES2ImplementationTest::kTexturesStartId;
754 const GLuint GLES2ImplementationTest::kQueriesStartId;
755 const GLuint GLES2ImplementationTest::kVertexArraysStartId;
756 #endif
758 TEST_F(GLES2ImplementationTest, Basic) {
759 EXPECT_TRUE(gl_->share_group() != NULL);
762 TEST_F(GLES2ImplementationTest, GetBucketContents) {
763 const uint32 kBucketId = GLES2Implementation::kResultBucketId;
764 const uint32 kTestSize = MaxTransferBufferSize() + 32;
766 scoped_ptr<uint8[]> buf(new uint8 [kTestSize]);
767 uint8* expected_data = buf.get();
768 for (uint32 ii = 0; ii < kTestSize; ++ii) {
769 expected_data[ii] = ii * 3;
772 struct Cmds {
773 cmd::GetBucketStart get_bucket_start;
774 cmd::SetToken set_token1;
775 cmd::GetBucketData get_bucket_data;
776 cmd::SetToken set_token2;
777 cmd::SetBucketSize set_bucket_size2;
780 ExpectedMemoryInfo mem1 = GetExpectedMemory(MaxTransferBufferSize());
781 ExpectedMemoryInfo result1 = GetExpectedResultMemory(sizeof(uint32));
782 ExpectedMemoryInfo mem2 = GetExpectedMemory(
783 kTestSize - MaxTransferBufferSize());
785 Cmds expected;
786 expected.get_bucket_start.Init(
787 kBucketId, result1.id, result1.offset,
788 MaxTransferBufferSize(), mem1.id, mem1.offset);
789 expected.set_token1.Init(GetNextToken());
790 expected.get_bucket_data.Init(
791 kBucketId, MaxTransferBufferSize(),
792 kTestSize - MaxTransferBufferSize(), mem2.id, mem2.offset);
793 expected.set_bucket_size2.Init(kBucketId, 0);
794 expected.set_token2.Init(GetNextToken());
796 EXPECT_CALL(*command_buffer(), OnFlush())
797 .WillOnce(DoAll(
798 SetMemory(result1.ptr, kTestSize),
799 SetMemoryFromArray(
800 mem1.ptr, expected_data, MaxTransferBufferSize())))
801 .WillOnce(SetMemoryFromArray(
802 mem2.ptr, expected_data + MaxTransferBufferSize(),
803 kTestSize - MaxTransferBufferSize()))
804 .RetiresOnSaturation();
806 std::vector<int8> data;
807 GetBucketContents(kBucketId, &data);
808 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
809 ASSERT_EQ(kTestSize, data.size());
810 EXPECT_EQ(0, memcmp(expected_data, &data[0], data.size()));
813 TEST_F(GLES2ImplementationTest, GetShaderPrecisionFormat) {
814 struct Cmds {
815 cmds::GetShaderPrecisionFormat cmd;
817 typedef cmds::GetShaderPrecisionFormat::Result Result;
819 // The first call for mediump should trigger a command buffer request.
820 GLint range1[2] = {0, 0};
821 GLint precision1 = 0;
822 Cmds expected1;
823 ExpectedMemoryInfo client_result1 = GetExpectedResultMemory(4);
824 expected1.cmd.Init(GL_FRAGMENT_SHADER, GL_MEDIUM_FLOAT,
825 client_result1.id, client_result1.offset);
826 Result server_result1 = {true, 14, 14, 10};
827 EXPECT_CALL(*command_buffer(), OnFlush())
828 .WillOnce(SetMemory(client_result1.ptr, server_result1))
829 .RetiresOnSaturation();
830 gl_->GetShaderPrecisionFormat(GL_FRAGMENT_SHADER, GL_MEDIUM_FLOAT,
831 range1, &precision1);
832 const void* commands2 = GetPut();
833 EXPECT_NE(commands_, commands2);
834 EXPECT_EQ(0, memcmp(&expected1, commands_, sizeof(expected1)));
835 EXPECT_EQ(range1[0], 14);
836 EXPECT_EQ(range1[1], 14);
837 EXPECT_EQ(precision1, 10);
839 // The second call for mediump should use the cached value and avoid
840 // triggering a command buffer request, so we do not expect a call to
841 // OnFlush() here. We do expect the results to be correct though.
842 GLint range2[2] = {0, 0};
843 GLint precision2 = 0;
844 gl_->GetShaderPrecisionFormat(GL_FRAGMENT_SHADER, GL_MEDIUM_FLOAT,
845 range2, &precision2);
846 const void* commands3 = GetPut();
847 EXPECT_EQ(commands2, commands3);
848 EXPECT_EQ(range2[0], 14);
849 EXPECT_EQ(range2[1], 14);
850 EXPECT_EQ(precision2, 10);
852 // If we then make a request for highp, we should get another command
853 // buffer request since it hasn't been cached yet.
854 GLint range3[2] = {0, 0};
855 GLint precision3 = 0;
856 Cmds expected3;
857 ExpectedMemoryInfo result3 = GetExpectedResultMemory(4);
858 expected3.cmd.Init(GL_FRAGMENT_SHADER, GL_HIGH_FLOAT,
859 result3.id, result3.offset);
860 Result result3_source = {true, 62, 62, 16};
861 EXPECT_CALL(*command_buffer(), OnFlush())
862 .WillOnce(SetMemory(result3.ptr, result3_source))
863 .RetiresOnSaturation();
864 gl_->GetShaderPrecisionFormat(GL_FRAGMENT_SHADER, GL_HIGH_FLOAT,
865 range3, &precision3);
866 const void* commands4 = GetPut();
867 EXPECT_NE(commands3, commands4);
868 EXPECT_EQ(0, memcmp(&expected3, commands3, sizeof(expected3)));
869 EXPECT_EQ(range3[0], 62);
870 EXPECT_EQ(range3[1], 62);
871 EXPECT_EQ(precision3, 16);
874 TEST_F(GLES2ImplementationTest, ShaderSource) {
875 const uint32 kBucketId = GLES2Implementation::kResultBucketId;
876 const GLuint kShaderId = 456;
877 const char* kString1 = "foobar";
878 const char* kString2 = "barfoo";
879 const size_t kString1Size = strlen(kString1);
880 const size_t kString2Size = strlen(kString2);
881 const size_t kString3Size = 1; // Want the NULL;
882 const size_t kSourceSize = kString1Size + kString2Size + kString3Size;
883 const size_t kPaddedString1Size =
884 transfer_buffer_->RoundToAlignment(kString1Size);
885 const size_t kPaddedString2Size =
886 transfer_buffer_->RoundToAlignment(kString2Size);
887 const size_t kPaddedString3Size =
888 transfer_buffer_->RoundToAlignment(kString3Size);
889 struct Cmds {
890 cmd::SetBucketSize set_bucket_size;
891 cmd::SetBucketData set_bucket_data1;
892 cmd::SetToken set_token1;
893 cmd::SetBucketData set_bucket_data2;
894 cmd::SetToken set_token2;
895 cmd::SetBucketData set_bucket_data3;
896 cmd::SetToken set_token3;
897 cmds::ShaderSourceBucket shader_source_bucket;
898 cmd::SetBucketSize clear_bucket_size;
901 ExpectedMemoryInfo mem1 = GetExpectedMemory(kPaddedString1Size);
902 ExpectedMemoryInfo mem2 = GetExpectedMemory(kPaddedString2Size);
903 ExpectedMemoryInfo mem3 = GetExpectedMemory(kPaddedString3Size);
905 Cmds expected;
906 expected.set_bucket_size.Init(kBucketId, kSourceSize);
907 expected.set_bucket_data1.Init(
908 kBucketId, 0, kString1Size, mem1.id, mem1.offset);
909 expected.set_token1.Init(GetNextToken());
910 expected.set_bucket_data2.Init(
911 kBucketId, kString1Size, kString2Size, mem2.id, mem2.offset);
912 expected.set_token2.Init(GetNextToken());
913 expected.set_bucket_data3.Init(
914 kBucketId, kString1Size + kString2Size,
915 kString3Size, mem3.id, mem3.offset);
916 expected.set_token3.Init(GetNextToken());
917 expected.shader_source_bucket.Init(kShaderId, kBucketId);
918 expected.clear_bucket_size.Init(kBucketId, 0);
919 const char* strings[] = {
920 kString1,
921 kString2,
923 gl_->ShaderSource(kShaderId, 2, strings, NULL);
924 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
927 TEST_F(GLES2ImplementationTest, GetShaderSource) {
928 const uint32 kBucketId = GLES2Implementation::kResultBucketId;
929 const GLuint kShaderId = 456;
930 const Str7 kString = {"foobar"};
931 const char kBad = 0x12;
932 struct Cmds {
933 cmd::SetBucketSize set_bucket_size1;
934 cmds::GetShaderSource get_shader_source;
935 cmd::GetBucketStart get_bucket_start;
936 cmd::SetToken set_token1;
937 cmd::SetBucketSize set_bucket_size2;
940 ExpectedMemoryInfo mem1 = GetExpectedMemory(MaxTransferBufferSize());
941 ExpectedMemoryInfo result1 = GetExpectedResultMemory(sizeof(uint32));
943 Cmds expected;
944 expected.set_bucket_size1.Init(kBucketId, 0);
945 expected.get_shader_source.Init(kShaderId, kBucketId);
946 expected.get_bucket_start.Init(
947 kBucketId, result1.id, result1.offset,
948 MaxTransferBufferSize(), mem1.id, mem1.offset);
949 expected.set_token1.Init(GetNextToken());
950 expected.set_bucket_size2.Init(kBucketId, 0);
951 char buf[sizeof(kString) + 1];
952 memset(buf, kBad, sizeof(buf));
954 EXPECT_CALL(*command_buffer(), OnFlush())
955 .WillOnce(DoAll(SetMemory(result1.ptr, uint32(sizeof(kString))),
956 SetMemory(mem1.ptr, kString)))
957 .RetiresOnSaturation();
959 GLsizei length = 0;
960 gl_->GetShaderSource(kShaderId, sizeof(buf), &length, buf);
961 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
962 EXPECT_EQ(sizeof(kString) - 1, static_cast<size_t>(length));
963 EXPECT_STREQ(kString.str, buf);
964 EXPECT_EQ(buf[sizeof(kString)], kBad);
967 #if defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS)
969 TEST_F(GLES2ImplementationTest, DrawArraysClientSideBuffers) {
970 static const float verts[][4] = {
971 { 12.0f, 23.0f, 34.0f, 45.0f, },
972 { 56.0f, 67.0f, 78.0f, 89.0f, },
973 { 13.0f, 24.0f, 35.0f, 46.0f, },
975 struct Cmds {
976 cmds::EnableVertexAttribArray enable1;
977 cmds::EnableVertexAttribArray enable2;
978 cmds::BindBuffer bind_to_emu;
979 cmds::BufferData set_size;
980 cmds::BufferSubData copy_data1;
981 cmd::SetToken set_token1;
982 cmds::VertexAttribPointer set_pointer1;
983 cmds::BufferSubData copy_data2;
984 cmd::SetToken set_token2;
985 cmds::VertexAttribPointer set_pointer2;
986 cmds::DrawArrays draw;
987 cmds::BindBuffer restore;
989 const GLuint kEmuBufferId = GLES2Implementation::kClientSideArrayId;
990 const GLuint kAttribIndex1 = 1;
991 const GLuint kAttribIndex2 = 3;
992 const GLint kNumComponents1 = 3;
993 const GLint kNumComponents2 = 2;
994 const GLsizei kClientStride = sizeof(verts[0]);
995 const GLint kFirst = 1;
996 const GLsizei kCount = 2;
997 const GLsizei kSize1 =
998 arraysize(verts) * kNumComponents1 * sizeof(verts[0][0]);
999 const GLsizei kSize2 =
1000 arraysize(verts) * kNumComponents2 * sizeof(verts[0][0]);
1001 const GLsizei kEmuOffset1 = 0;
1002 const GLsizei kEmuOffset2 = kSize1;
1003 const GLsizei kTotalSize = kSize1 + kSize2;
1005 ExpectedMemoryInfo mem1 = GetExpectedMemory(kSize1);
1006 ExpectedMemoryInfo mem2 = GetExpectedMemory(kSize2);
1008 Cmds expected;
1009 expected.enable1.Init(kAttribIndex1);
1010 expected.enable2.Init(kAttribIndex2);
1011 expected.bind_to_emu.Init(GL_ARRAY_BUFFER, kEmuBufferId);
1012 expected.set_size.Init(GL_ARRAY_BUFFER, kTotalSize, 0, 0, GL_DYNAMIC_DRAW);
1013 expected.copy_data1.Init(
1014 GL_ARRAY_BUFFER, kEmuOffset1, kSize1, mem1.id, mem1.offset);
1015 expected.set_token1.Init(GetNextToken());
1016 expected.set_pointer1.Init(
1017 kAttribIndex1, kNumComponents1, GL_FLOAT, GL_FALSE, 0, kEmuOffset1);
1018 expected.copy_data2.Init(
1019 GL_ARRAY_BUFFER, kEmuOffset2, kSize2, mem2.id, mem2.offset);
1020 expected.set_token2.Init(GetNextToken());
1021 expected.set_pointer2.Init(
1022 kAttribIndex2, kNumComponents2, GL_FLOAT, GL_FALSE, 0, kEmuOffset2);
1023 expected.draw.Init(GL_POINTS, kFirst, kCount);
1024 expected.restore.Init(GL_ARRAY_BUFFER, 0);
1025 gl_->EnableVertexAttribArray(kAttribIndex1);
1026 gl_->EnableVertexAttribArray(kAttribIndex2);
1027 gl_->VertexAttribPointer(
1028 kAttribIndex1, kNumComponents1, GL_FLOAT, GL_FALSE, kClientStride, verts);
1029 gl_->VertexAttribPointer(
1030 kAttribIndex2, kNumComponents2, GL_FLOAT, GL_FALSE, kClientStride, verts);
1031 gl_->DrawArrays(GL_POINTS, kFirst, kCount);
1032 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
1035 TEST_F(GLES2ImplementationTest, DrawArraysInstancedANGLEClientSideBuffers) {
1036 static const float verts[][4] = {
1037 { 12.0f, 23.0f, 34.0f, 45.0f, },
1038 { 56.0f, 67.0f, 78.0f, 89.0f, },
1039 { 13.0f, 24.0f, 35.0f, 46.0f, },
1041 struct Cmds {
1042 cmds::EnableVertexAttribArray enable1;
1043 cmds::EnableVertexAttribArray enable2;
1044 cmds::VertexAttribDivisorANGLE divisor;
1045 cmds::BindBuffer bind_to_emu;
1046 cmds::BufferData set_size;
1047 cmds::BufferSubData copy_data1;
1048 cmd::SetToken set_token1;
1049 cmds::VertexAttribPointer set_pointer1;
1050 cmds::BufferSubData copy_data2;
1051 cmd::SetToken set_token2;
1052 cmds::VertexAttribPointer set_pointer2;
1053 cmds::DrawArraysInstancedANGLE draw;
1054 cmds::BindBuffer restore;
1056 const GLuint kEmuBufferId = GLES2Implementation::kClientSideArrayId;
1057 const GLuint kAttribIndex1 = 1;
1058 const GLuint kAttribIndex2 = 3;
1059 const GLint kNumComponents1 = 3;
1060 const GLint kNumComponents2 = 2;
1061 const GLsizei kClientStride = sizeof(verts[0]);
1062 const GLint kFirst = 1;
1063 const GLsizei kCount = 2;
1064 const GLuint kDivisor = 1;
1065 const GLsizei kSize1 =
1066 arraysize(verts) * kNumComponents1 * sizeof(verts[0][0]);
1067 const GLsizei kSize2 =
1068 1 * kNumComponents2 * sizeof(verts[0][0]);
1069 const GLsizei kEmuOffset1 = 0;
1070 const GLsizei kEmuOffset2 = kSize1;
1071 const GLsizei kTotalSize = kSize1 + kSize2;
1073 ExpectedMemoryInfo mem1 = GetExpectedMemory(kSize1);
1074 ExpectedMemoryInfo mem2 = GetExpectedMemory(kSize2);
1076 Cmds expected;
1077 expected.enable1.Init(kAttribIndex1);
1078 expected.enable2.Init(kAttribIndex2);
1079 expected.divisor.Init(kAttribIndex2, kDivisor);
1080 expected.bind_to_emu.Init(GL_ARRAY_BUFFER, kEmuBufferId);
1081 expected.set_size.Init(GL_ARRAY_BUFFER, kTotalSize, 0, 0, GL_DYNAMIC_DRAW);
1082 expected.copy_data1.Init(
1083 GL_ARRAY_BUFFER, kEmuOffset1, kSize1, mem1.id, mem1.offset);
1084 expected.set_token1.Init(GetNextToken());
1085 expected.set_pointer1.Init(
1086 kAttribIndex1, kNumComponents1, GL_FLOAT, GL_FALSE, 0, kEmuOffset1);
1087 expected.copy_data2.Init(
1088 GL_ARRAY_BUFFER, kEmuOffset2, kSize2, mem2.id, mem2.offset);
1089 expected.set_token2.Init(GetNextToken());
1090 expected.set_pointer2.Init(
1091 kAttribIndex2, kNumComponents2, GL_FLOAT, GL_FALSE, 0, kEmuOffset2);
1092 expected.draw.Init(GL_POINTS, kFirst, kCount, 1);
1093 expected.restore.Init(GL_ARRAY_BUFFER, 0);
1094 gl_->EnableVertexAttribArray(kAttribIndex1);
1095 gl_->EnableVertexAttribArray(kAttribIndex2);
1096 gl_->VertexAttribPointer(
1097 kAttribIndex1, kNumComponents1, GL_FLOAT, GL_FALSE, kClientStride, verts);
1098 gl_->VertexAttribPointer(
1099 kAttribIndex2, kNumComponents2, GL_FLOAT, GL_FALSE, kClientStride, verts);
1100 gl_->VertexAttribDivisorANGLE(kAttribIndex2, kDivisor);
1101 gl_->DrawArraysInstancedANGLE(GL_POINTS, kFirst, kCount, 1);
1102 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
1105 TEST_F(GLES2ImplementationTest, DrawElementsClientSideBuffers) {
1106 static const float verts[][4] = {
1107 { 12.0f, 23.0f, 34.0f, 45.0f, },
1108 { 56.0f, 67.0f, 78.0f, 89.0f, },
1109 { 13.0f, 24.0f, 35.0f, 46.0f, },
1111 static const uint16 indices[] = {
1112 1, 2,
1114 struct Cmds {
1115 cmds::EnableVertexAttribArray enable1;
1116 cmds::EnableVertexAttribArray enable2;
1117 cmds::BindBuffer bind_to_index_emu;
1118 cmds::BufferData set_index_size;
1119 cmds::BufferSubData copy_data0;
1120 cmd::SetToken set_token0;
1121 cmds::BindBuffer bind_to_emu;
1122 cmds::BufferData set_size;
1123 cmds::BufferSubData copy_data1;
1124 cmd::SetToken set_token1;
1125 cmds::VertexAttribPointer set_pointer1;
1126 cmds::BufferSubData copy_data2;
1127 cmd::SetToken set_token2;
1128 cmds::VertexAttribPointer set_pointer2;
1129 cmds::DrawElements draw;
1130 cmds::BindBuffer restore;
1131 cmds::BindBuffer restore_element;
1133 const GLsizei kIndexSize = sizeof(indices);
1134 const GLuint kEmuBufferId = GLES2Implementation::kClientSideArrayId;
1135 const GLuint kEmuIndexBufferId =
1136 GLES2Implementation::kClientSideElementArrayId;
1137 const GLuint kAttribIndex1 = 1;
1138 const GLuint kAttribIndex2 = 3;
1139 const GLint kNumComponents1 = 3;
1140 const GLint kNumComponents2 = 2;
1141 const GLsizei kClientStride = sizeof(verts[0]);
1142 const GLsizei kCount = 2;
1143 const GLsizei kSize1 =
1144 arraysize(verts) * kNumComponents1 * sizeof(verts[0][0]);
1145 const GLsizei kSize2 =
1146 arraysize(verts) * kNumComponents2 * sizeof(verts[0][0]);
1147 const GLsizei kEmuOffset1 = 0;
1148 const GLsizei kEmuOffset2 = kSize1;
1149 const GLsizei kTotalSize = kSize1 + kSize2;
1151 ExpectedMemoryInfo mem1 = GetExpectedMemory(kIndexSize);
1152 ExpectedMemoryInfo mem2 = GetExpectedMemory(kSize1);
1153 ExpectedMemoryInfo mem3 = GetExpectedMemory(kSize2);
1155 Cmds expected;
1156 expected.enable1.Init(kAttribIndex1);
1157 expected.enable2.Init(kAttribIndex2);
1158 expected.bind_to_index_emu.Init(GL_ELEMENT_ARRAY_BUFFER, kEmuIndexBufferId);
1159 expected.set_index_size.Init(
1160 GL_ELEMENT_ARRAY_BUFFER, kIndexSize, 0, 0, GL_DYNAMIC_DRAW);
1161 expected.copy_data0.Init(
1162 GL_ELEMENT_ARRAY_BUFFER, 0, kIndexSize, mem1.id, mem1.offset);
1163 expected.set_token0.Init(GetNextToken());
1164 expected.bind_to_emu.Init(GL_ARRAY_BUFFER, kEmuBufferId);
1165 expected.set_size.Init(GL_ARRAY_BUFFER, kTotalSize, 0, 0, GL_DYNAMIC_DRAW);
1166 expected.copy_data1.Init(
1167 GL_ARRAY_BUFFER, kEmuOffset1, kSize1, mem2.id, mem2.offset);
1168 expected.set_token1.Init(GetNextToken());
1169 expected.set_pointer1.Init(
1170 kAttribIndex1, kNumComponents1, GL_FLOAT, GL_FALSE, 0, kEmuOffset1);
1171 expected.copy_data2.Init(
1172 GL_ARRAY_BUFFER, kEmuOffset2, kSize2, mem3.id, mem3.offset);
1173 expected.set_token2.Init(GetNextToken());
1174 expected.set_pointer2.Init(kAttribIndex2, kNumComponents2,
1175 GL_FLOAT, GL_FALSE, 0, kEmuOffset2);
1176 expected.draw.Init(GL_POINTS, kCount, GL_UNSIGNED_SHORT, 0);
1177 expected.restore.Init(GL_ARRAY_BUFFER, 0);
1178 expected.restore_element.Init(GL_ELEMENT_ARRAY_BUFFER, 0);
1179 gl_->EnableVertexAttribArray(kAttribIndex1);
1180 gl_->EnableVertexAttribArray(kAttribIndex2);
1181 gl_->VertexAttribPointer(kAttribIndex1, kNumComponents1,
1182 GL_FLOAT, GL_FALSE, kClientStride, verts);
1183 gl_->VertexAttribPointer(kAttribIndex2, kNumComponents2,
1184 GL_FLOAT, GL_FALSE, kClientStride, verts);
1185 gl_->DrawElements(GL_POINTS, kCount, GL_UNSIGNED_SHORT, indices);
1186 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
1189 TEST_F(GLES2ImplementationTest, DrawElementsClientSideBuffersIndexUint) {
1190 static const float verts[][4] = {
1191 { 12.0f, 23.0f, 34.0f, 45.0f, },
1192 { 56.0f, 67.0f, 78.0f, 89.0f, },
1193 { 13.0f, 24.0f, 35.0f, 46.0f, },
1195 static const uint32 indices[] = {
1196 1, 2,
1198 struct Cmds {
1199 cmds::EnableVertexAttribArray enable1;
1200 cmds::EnableVertexAttribArray enable2;
1201 cmds::BindBuffer bind_to_index_emu;
1202 cmds::BufferData set_index_size;
1203 cmds::BufferSubData copy_data0;
1204 cmd::SetToken set_token0;
1205 cmds::BindBuffer bind_to_emu;
1206 cmds::BufferData set_size;
1207 cmds::BufferSubData copy_data1;
1208 cmd::SetToken set_token1;
1209 cmds::VertexAttribPointer set_pointer1;
1210 cmds::BufferSubData copy_data2;
1211 cmd::SetToken set_token2;
1212 cmds::VertexAttribPointer set_pointer2;
1213 cmds::DrawElements draw;
1214 cmds::BindBuffer restore;
1215 cmds::BindBuffer restore_element;
1217 const GLsizei kIndexSize = sizeof(indices);
1218 const GLuint kEmuBufferId = GLES2Implementation::kClientSideArrayId;
1219 const GLuint kEmuIndexBufferId =
1220 GLES2Implementation::kClientSideElementArrayId;
1221 const GLuint kAttribIndex1 = 1;
1222 const GLuint kAttribIndex2 = 3;
1223 const GLint kNumComponents1 = 3;
1224 const GLint kNumComponents2 = 2;
1225 const GLsizei kClientStride = sizeof(verts[0]);
1226 const GLsizei kCount = 2;
1227 const GLsizei kSize1 =
1228 arraysize(verts) * kNumComponents1 * sizeof(verts[0][0]);
1229 const GLsizei kSize2 =
1230 arraysize(verts) * kNumComponents2 * sizeof(verts[0][0]);
1231 const GLsizei kEmuOffset1 = 0;
1232 const GLsizei kEmuOffset2 = kSize1;
1233 const GLsizei kTotalSize = kSize1 + kSize2;
1235 ExpectedMemoryInfo mem1 = GetExpectedMemory(kIndexSize);
1236 ExpectedMemoryInfo mem2 = GetExpectedMemory(kSize1);
1237 ExpectedMemoryInfo mem3 = GetExpectedMemory(kSize2);
1239 Cmds expected;
1240 expected.enable1.Init(kAttribIndex1);
1241 expected.enable2.Init(kAttribIndex2);
1242 expected.bind_to_index_emu.Init(GL_ELEMENT_ARRAY_BUFFER, kEmuIndexBufferId);
1243 expected.set_index_size.Init(
1244 GL_ELEMENT_ARRAY_BUFFER, kIndexSize, 0, 0, GL_DYNAMIC_DRAW);
1245 expected.copy_data0.Init(
1246 GL_ELEMENT_ARRAY_BUFFER, 0, kIndexSize, mem1.id, mem1.offset);
1247 expected.set_token0.Init(GetNextToken());
1248 expected.bind_to_emu.Init(GL_ARRAY_BUFFER, kEmuBufferId);
1249 expected.set_size.Init(GL_ARRAY_BUFFER, kTotalSize, 0, 0, GL_DYNAMIC_DRAW);
1250 expected.copy_data1.Init(
1251 GL_ARRAY_BUFFER, kEmuOffset1, kSize1, mem2.id, mem2.offset);
1252 expected.set_token1.Init(GetNextToken());
1253 expected.set_pointer1.Init(
1254 kAttribIndex1, kNumComponents1, GL_FLOAT, GL_FALSE, 0, kEmuOffset1);
1255 expected.copy_data2.Init(
1256 GL_ARRAY_BUFFER, kEmuOffset2, kSize2, mem3.id, mem3.offset);
1257 expected.set_token2.Init(GetNextToken());
1258 expected.set_pointer2.Init(kAttribIndex2, kNumComponents2,
1259 GL_FLOAT, GL_FALSE, 0, kEmuOffset2);
1260 expected.draw.Init(GL_POINTS, kCount, GL_UNSIGNED_INT, 0);
1261 expected.restore.Init(GL_ARRAY_BUFFER, 0);
1262 expected.restore_element.Init(GL_ELEMENT_ARRAY_BUFFER, 0);
1263 gl_->EnableVertexAttribArray(kAttribIndex1);
1264 gl_->EnableVertexAttribArray(kAttribIndex2);
1265 gl_->VertexAttribPointer(kAttribIndex1, kNumComponents1,
1266 GL_FLOAT, GL_FALSE, kClientStride, verts);
1267 gl_->VertexAttribPointer(kAttribIndex2, kNumComponents2,
1268 GL_FLOAT, GL_FALSE, kClientStride, verts);
1269 gl_->DrawElements(GL_POINTS, kCount, GL_UNSIGNED_INT, indices);
1270 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
1273 TEST_F(GLES2ImplementationTest, DrawElementsClientSideBuffersInvalidIndexUint) {
1274 static const float verts[][4] = {
1275 { 12.0f, 23.0f, 34.0f, 45.0f, },
1276 { 56.0f, 67.0f, 78.0f, 89.0f, },
1277 { 13.0f, 24.0f, 35.0f, 46.0f, },
1279 static const uint32 indices[] = {
1280 1, 0x90000000
1283 const GLuint kAttribIndex1 = 1;
1284 const GLuint kAttribIndex2 = 3;
1285 const GLint kNumComponents1 = 3;
1286 const GLint kNumComponents2 = 2;
1287 const GLsizei kClientStride = sizeof(verts[0]);
1288 const GLsizei kCount = 2;
1290 EXPECT_CALL(*command_buffer(), OnFlush())
1291 .Times(1)
1292 .RetiresOnSaturation();
1294 gl_->EnableVertexAttribArray(kAttribIndex1);
1295 gl_->EnableVertexAttribArray(kAttribIndex2);
1296 gl_->VertexAttribPointer(kAttribIndex1, kNumComponents1,
1297 GL_FLOAT, GL_FALSE, kClientStride, verts);
1298 gl_->VertexAttribPointer(kAttribIndex2, kNumComponents2,
1299 GL_FLOAT, GL_FALSE, kClientStride, verts);
1300 gl_->DrawElements(GL_POINTS, kCount, GL_UNSIGNED_INT, indices);
1302 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_OPERATION), gl_->GetError());
1305 TEST_F(GLES2ImplementationTest,
1306 DrawElementsClientSideBuffersServiceSideIndices) {
1307 static const float verts[][4] = {
1308 { 12.0f, 23.0f, 34.0f, 45.0f, },
1309 { 56.0f, 67.0f, 78.0f, 89.0f, },
1310 { 13.0f, 24.0f, 35.0f, 46.0f, },
1312 struct Cmds {
1313 cmds::EnableVertexAttribArray enable1;
1314 cmds::EnableVertexAttribArray enable2;
1315 cmds::BindBuffer bind_to_index;
1316 cmds::GetMaxValueInBufferCHROMIUM get_max;
1317 cmds::BindBuffer bind_to_emu;
1318 cmds::BufferData set_size;
1319 cmds::BufferSubData copy_data1;
1320 cmd::SetToken set_token1;
1321 cmds::VertexAttribPointer set_pointer1;
1322 cmds::BufferSubData copy_data2;
1323 cmd::SetToken set_token2;
1324 cmds::VertexAttribPointer set_pointer2;
1325 cmds::DrawElements draw;
1326 cmds::BindBuffer restore;
1328 const GLuint kEmuBufferId = GLES2Implementation::kClientSideArrayId;
1329 const GLuint kClientIndexBufferId = 0x789;
1330 const GLuint kIndexOffset = 0x40;
1331 const GLuint kMaxIndex = 2;
1332 const GLuint kAttribIndex1 = 1;
1333 const GLuint kAttribIndex2 = 3;
1334 const GLint kNumComponents1 = 3;
1335 const GLint kNumComponents2 = 2;
1336 const GLsizei kClientStride = sizeof(verts[0]);
1337 const GLsizei kCount = 2;
1338 const GLsizei kSize1 =
1339 arraysize(verts) * kNumComponents1 * sizeof(verts[0][0]);
1340 const GLsizei kSize2 =
1341 arraysize(verts) * kNumComponents2 * sizeof(verts[0][0]);
1342 const GLsizei kEmuOffset1 = 0;
1343 const GLsizei kEmuOffset2 = kSize1;
1344 const GLsizei kTotalSize = kSize1 + kSize2;
1346 ExpectedMemoryInfo mem1 = GetExpectedResultMemory(sizeof(uint32));
1347 ExpectedMemoryInfo mem2 = GetExpectedMemory(kSize1);
1348 ExpectedMemoryInfo mem3 = GetExpectedMemory(kSize2);
1351 Cmds expected;
1352 expected.enable1.Init(kAttribIndex1);
1353 expected.enable2.Init(kAttribIndex2);
1354 expected.bind_to_index.Init(GL_ELEMENT_ARRAY_BUFFER, kClientIndexBufferId);
1355 expected.get_max.Init(kClientIndexBufferId, kCount, GL_UNSIGNED_SHORT,
1356 kIndexOffset, mem1.id, mem1.offset);
1357 expected.bind_to_emu.Init(GL_ARRAY_BUFFER, kEmuBufferId);
1358 expected.set_size.Init(GL_ARRAY_BUFFER, kTotalSize, 0, 0, GL_DYNAMIC_DRAW);
1359 expected.copy_data1.Init(
1360 GL_ARRAY_BUFFER, kEmuOffset1, kSize1, mem2.id, mem2.offset);
1361 expected.set_token1.Init(GetNextToken());
1362 expected.set_pointer1.Init(kAttribIndex1, kNumComponents1,
1363 GL_FLOAT, GL_FALSE, 0, kEmuOffset1);
1364 expected.copy_data2.Init(
1365 GL_ARRAY_BUFFER, kEmuOffset2, kSize2, mem3.id, mem3.offset);
1366 expected.set_token2.Init(GetNextToken());
1367 expected.set_pointer2.Init(kAttribIndex2, kNumComponents2,
1368 GL_FLOAT, GL_FALSE, 0, kEmuOffset2);
1369 expected.draw.Init(GL_POINTS, kCount, GL_UNSIGNED_SHORT, kIndexOffset);
1370 expected.restore.Init(GL_ARRAY_BUFFER, 0);
1372 EXPECT_CALL(*command_buffer(), OnFlush())
1373 .WillOnce(SetMemory(mem1.ptr,kMaxIndex))
1374 .RetiresOnSaturation();
1376 gl_->EnableVertexAttribArray(kAttribIndex1);
1377 gl_->EnableVertexAttribArray(kAttribIndex2);
1378 gl_->BindBuffer(GL_ELEMENT_ARRAY_BUFFER, kClientIndexBufferId);
1379 gl_->VertexAttribPointer(kAttribIndex1, kNumComponents1,
1380 GL_FLOAT, GL_FALSE, kClientStride, verts);
1381 gl_->VertexAttribPointer(kAttribIndex2, kNumComponents2,
1382 GL_FLOAT, GL_FALSE, kClientStride, verts);
1383 gl_->DrawElements(GL_POINTS, kCount, GL_UNSIGNED_SHORT,
1384 reinterpret_cast<const void*>(kIndexOffset));
1385 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
1388 TEST_F(GLES2ImplementationTest, DrawElementsInstancedANGLEClientSideBuffers) {
1389 static const float verts[][4] = {
1390 { 12.0f, 23.0f, 34.0f, 45.0f, },
1391 { 56.0f, 67.0f, 78.0f, 89.0f, },
1392 { 13.0f, 24.0f, 35.0f, 46.0f, },
1394 static const uint16 indices[] = {
1395 1, 2,
1397 struct Cmds {
1398 cmds::EnableVertexAttribArray enable1;
1399 cmds::EnableVertexAttribArray enable2;
1400 cmds::VertexAttribDivisorANGLE divisor;
1401 cmds::BindBuffer bind_to_index_emu;
1402 cmds::BufferData set_index_size;
1403 cmds::BufferSubData copy_data0;
1404 cmd::SetToken set_token0;
1405 cmds::BindBuffer bind_to_emu;
1406 cmds::BufferData set_size;
1407 cmds::BufferSubData copy_data1;
1408 cmd::SetToken set_token1;
1409 cmds::VertexAttribPointer set_pointer1;
1410 cmds::BufferSubData copy_data2;
1411 cmd::SetToken set_token2;
1412 cmds::VertexAttribPointer set_pointer2;
1413 cmds::DrawElementsInstancedANGLE draw;
1414 cmds::BindBuffer restore;
1415 cmds::BindBuffer restore_element;
1417 const GLsizei kIndexSize = sizeof(indices);
1418 const GLuint kEmuBufferId = GLES2Implementation::kClientSideArrayId;
1419 const GLuint kEmuIndexBufferId =
1420 GLES2Implementation::kClientSideElementArrayId;
1421 const GLuint kAttribIndex1 = 1;
1422 const GLuint kAttribIndex2 = 3;
1423 const GLint kNumComponents1 = 3;
1424 const GLint kNumComponents2 = 2;
1425 const GLsizei kClientStride = sizeof(verts[0]);
1426 const GLsizei kCount = 2;
1427 const GLsizei kSize1 =
1428 arraysize(verts) * kNumComponents1 * sizeof(verts[0][0]);
1429 const GLsizei kSize2 =
1430 1 * kNumComponents2 * sizeof(verts[0][0]);
1431 const GLuint kDivisor = 1;
1432 const GLsizei kEmuOffset1 = 0;
1433 const GLsizei kEmuOffset2 = kSize1;
1434 const GLsizei kTotalSize = kSize1 + kSize2;
1436 ExpectedMemoryInfo mem1 = GetExpectedMemory(kIndexSize);
1437 ExpectedMemoryInfo mem2 = GetExpectedMemory(kSize1);
1438 ExpectedMemoryInfo mem3 = GetExpectedMemory(kSize2);
1440 Cmds expected;
1441 expected.enable1.Init(kAttribIndex1);
1442 expected.enable2.Init(kAttribIndex2);
1443 expected.divisor.Init(kAttribIndex2, kDivisor);
1444 expected.bind_to_index_emu.Init(GL_ELEMENT_ARRAY_BUFFER, kEmuIndexBufferId);
1445 expected.set_index_size.Init(
1446 GL_ELEMENT_ARRAY_BUFFER, kIndexSize, 0, 0, GL_DYNAMIC_DRAW);
1447 expected.copy_data0.Init(
1448 GL_ELEMENT_ARRAY_BUFFER, 0, kIndexSize, mem1.id, mem1.offset);
1449 expected.set_token0.Init(GetNextToken());
1450 expected.bind_to_emu.Init(GL_ARRAY_BUFFER, kEmuBufferId);
1451 expected.set_size.Init(GL_ARRAY_BUFFER, kTotalSize, 0, 0, GL_DYNAMIC_DRAW);
1452 expected.copy_data1.Init(
1453 GL_ARRAY_BUFFER, kEmuOffset1, kSize1, mem2.id, mem2.offset);
1454 expected.set_token1.Init(GetNextToken());
1455 expected.set_pointer1.Init(
1456 kAttribIndex1, kNumComponents1, GL_FLOAT, GL_FALSE, 0, kEmuOffset1);
1457 expected.copy_data2.Init(
1458 GL_ARRAY_BUFFER, kEmuOffset2, kSize2, mem3.id, mem3.offset);
1459 expected.set_token2.Init(GetNextToken());
1460 expected.set_pointer2.Init(kAttribIndex2, kNumComponents2,
1461 GL_FLOAT, GL_FALSE, 0, kEmuOffset2);
1462 expected.draw.Init(GL_POINTS, kCount, GL_UNSIGNED_SHORT, 0, 1);
1463 expected.restore.Init(GL_ARRAY_BUFFER, 0);
1464 expected.restore_element.Init(GL_ELEMENT_ARRAY_BUFFER, 0);
1465 gl_->EnableVertexAttribArray(kAttribIndex1);
1466 gl_->EnableVertexAttribArray(kAttribIndex2);
1467 gl_->VertexAttribPointer(kAttribIndex1, kNumComponents1,
1468 GL_FLOAT, GL_FALSE, kClientStride, verts);
1469 gl_->VertexAttribPointer(kAttribIndex2, kNumComponents2,
1470 GL_FLOAT, GL_FALSE, kClientStride, verts);
1471 gl_->VertexAttribDivisorANGLE(kAttribIndex2, kDivisor);
1472 gl_->DrawElementsInstancedANGLE(
1473 GL_POINTS, kCount, GL_UNSIGNED_SHORT, indices, 1);
1474 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
1477 TEST_F(GLES2ImplementationTest, GetVertexBufferPointerv) {
1478 static const float verts[1] = { 0.0f, };
1479 const GLuint kAttribIndex1 = 1;
1480 const GLuint kAttribIndex2 = 3;
1481 const GLint kNumComponents1 = 3;
1482 const GLint kNumComponents2 = 2;
1483 const GLsizei kStride1 = 12;
1484 const GLsizei kStride2 = 0;
1485 const GLuint kBufferId = 0x123;
1486 const GLint kOffset2 = 0x456;
1488 // It's all cached on the client side so no get commands are issued.
1489 struct Cmds {
1490 cmds::BindBuffer bind;
1491 cmds::VertexAttribPointer set_pointer;
1494 Cmds expected;
1495 expected.bind.Init(GL_ARRAY_BUFFER, kBufferId);
1496 expected.set_pointer.Init(kAttribIndex2, kNumComponents2, GL_FLOAT, GL_FALSE,
1497 kStride2, kOffset2);
1499 // Set one client side buffer.
1500 gl_->VertexAttribPointer(kAttribIndex1, kNumComponents1,
1501 GL_FLOAT, GL_FALSE, kStride1, verts);
1502 // Set one VBO
1503 gl_->BindBuffer(GL_ARRAY_BUFFER, kBufferId);
1504 gl_->VertexAttribPointer(kAttribIndex2, kNumComponents2,
1505 GL_FLOAT, GL_FALSE, kStride2,
1506 reinterpret_cast<const void*>(kOffset2));
1507 // now get them both.
1508 void* ptr1 = NULL;
1509 void* ptr2 = NULL;
1511 gl_->GetVertexAttribPointerv(
1512 kAttribIndex1, GL_VERTEX_ATTRIB_ARRAY_POINTER, &ptr1);
1513 gl_->GetVertexAttribPointerv(
1514 kAttribIndex2, GL_VERTEX_ATTRIB_ARRAY_POINTER, &ptr2);
1516 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
1517 EXPECT_TRUE(static_cast<const void*>(&verts) == ptr1);
1518 EXPECT_TRUE(ptr2 == reinterpret_cast<void*>(kOffset2));
1521 TEST_F(GLES2ImplementationTest, GetVertexAttrib) {
1522 static const float verts[1] = { 0.0f, };
1523 const GLuint kAttribIndex1 = 1;
1524 const GLuint kAttribIndex2 = 3;
1525 const GLint kNumComponents1 = 3;
1526 const GLint kNumComponents2 = 2;
1527 const GLsizei kStride1 = 12;
1528 const GLsizei kStride2 = 0;
1529 const GLuint kBufferId = 0x123;
1530 const GLint kOffset2 = 0x456;
1532 // Only one set and one get because the client side buffer's info is stored
1533 // on the client side.
1534 struct Cmds {
1535 cmds::EnableVertexAttribArray enable;
1536 cmds::BindBuffer bind;
1537 cmds::VertexAttribPointer set_pointer;
1538 cmds::GetVertexAttribfv get2; // for getting the value from attrib1
1541 ExpectedMemoryInfo mem2 = GetExpectedResultMemory(16);
1543 Cmds expected;
1544 expected.enable.Init(kAttribIndex1);
1545 expected.bind.Init(GL_ARRAY_BUFFER, kBufferId);
1546 expected.set_pointer.Init(kAttribIndex2, kNumComponents2, GL_FLOAT, GL_FALSE,
1547 kStride2, kOffset2);
1548 expected.get2.Init(kAttribIndex1,
1549 GL_CURRENT_VERTEX_ATTRIB,
1550 mem2.id, mem2.offset);
1552 FourFloats current_attrib(1.2f, 3.4f, 5.6f, 7.8f);
1554 // One call to flush to wait for last call to GetVertexAttribiv
1555 // as others are all cached.
1556 EXPECT_CALL(*command_buffer(), OnFlush())
1557 .WillOnce(SetMemory(
1558 mem2.ptr, SizedResultHelper<FourFloats>(current_attrib)))
1559 .RetiresOnSaturation();
1561 gl_->EnableVertexAttribArray(kAttribIndex1);
1562 // Set one client side buffer.
1563 gl_->VertexAttribPointer(kAttribIndex1, kNumComponents1,
1564 GL_FLOAT, GL_FALSE, kStride1, verts);
1565 // Set one VBO
1566 gl_->BindBuffer(GL_ARRAY_BUFFER, kBufferId);
1567 gl_->VertexAttribPointer(kAttribIndex2, kNumComponents2,
1568 GL_FLOAT, GL_FALSE, kStride2,
1569 reinterpret_cast<const void*>(kOffset2));
1570 // first get the service side once to see that we make a command
1571 GLint buffer_id = 0;
1572 GLint enabled = 0;
1573 GLint size = 0;
1574 GLint stride = 0;
1575 GLint type = 0;
1576 GLint normalized = 1;
1577 float current[4] = { 0.0f, };
1579 gl_->GetVertexAttribiv(
1580 kAttribIndex2, GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING, &buffer_id);
1581 EXPECT_EQ(kBufferId, static_cast<GLuint>(buffer_id));
1582 gl_->GetVertexAttribiv(
1583 kAttribIndex1, GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING, &buffer_id);
1584 gl_->GetVertexAttribiv(
1585 kAttribIndex1, GL_VERTEX_ATTRIB_ARRAY_ENABLED, &enabled);
1586 gl_->GetVertexAttribiv(
1587 kAttribIndex1, GL_VERTEX_ATTRIB_ARRAY_SIZE, &size);
1588 gl_->GetVertexAttribiv(
1589 kAttribIndex1, GL_VERTEX_ATTRIB_ARRAY_STRIDE, &stride);
1590 gl_->GetVertexAttribiv(
1591 kAttribIndex1, GL_VERTEX_ATTRIB_ARRAY_TYPE, &type);
1592 gl_->GetVertexAttribiv(
1593 kAttribIndex1, GL_VERTEX_ATTRIB_ARRAY_NORMALIZED, &normalized);
1594 gl_->GetVertexAttribfv(
1595 kAttribIndex1, GL_CURRENT_VERTEX_ATTRIB, &current[0]);
1597 EXPECT_EQ(0, buffer_id);
1598 EXPECT_EQ(GL_TRUE, enabled);
1599 EXPECT_EQ(kNumComponents1, size);
1600 EXPECT_EQ(kStride1, stride);
1601 EXPECT_EQ(GL_FLOAT, type);
1602 EXPECT_EQ(GL_FALSE, normalized);
1603 EXPECT_EQ(0, memcmp(&current_attrib, &current, sizeof(current_attrib)));
1605 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
1608 TEST_F(GLES2ImplementationTest, ReservedIds) {
1609 // Only the get error command should be issued.
1610 struct Cmds {
1611 cmds::GetError get;
1613 Cmds expected;
1615 ExpectedMemoryInfo mem1 = GetExpectedResultMemory(
1616 sizeof(cmds::GetError::Result));
1618 expected.get.Init(mem1.id, mem1.offset);
1620 // One call to flush to wait for GetError
1621 EXPECT_CALL(*command_buffer(), OnFlush())
1622 .WillOnce(SetMemory(mem1.ptr, GLuint(GL_NO_ERROR)))
1623 .RetiresOnSaturation();
1625 gl_->BindBuffer(
1626 GL_ARRAY_BUFFER,
1627 GLES2Implementation::kClientSideArrayId);
1628 gl_->BindBuffer(
1629 GL_ARRAY_BUFFER,
1630 GLES2Implementation::kClientSideElementArrayId);
1631 GLenum err = gl_->GetError();
1632 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_OPERATION), err);
1633 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
1636 #endif // defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS)
1638 TEST_F(GLES2ImplementationTest, ReadPixels2Reads) {
1639 struct Cmds {
1640 cmds::ReadPixels read1;
1641 cmd::SetToken set_token1;
1642 cmds::ReadPixels read2;
1643 cmd::SetToken set_token2;
1645 const GLint kBytesPerPixel = 4;
1646 const GLint kWidth =
1647 (kTransferBufferSize - GLES2Implementation::kStartingOffset) /
1648 kBytesPerPixel;
1649 const GLint kHeight = 2;
1650 const GLenum kFormat = GL_RGBA;
1651 const GLenum kType = GL_UNSIGNED_BYTE;
1653 ExpectedMemoryInfo mem1 =
1654 GetExpectedMemory(kWidth * kHeight / 2 * kBytesPerPixel);
1655 ExpectedMemoryInfo result1 =
1656 GetExpectedResultMemory(sizeof(cmds::ReadPixels::Result));
1657 ExpectedMemoryInfo mem2 =
1658 GetExpectedMemory(kWidth * kHeight / 2 * kBytesPerPixel);
1659 ExpectedMemoryInfo result2 =
1660 GetExpectedResultMemory(sizeof(cmds::ReadPixels::Result));
1662 Cmds expected;
1663 expected.read1.Init(
1664 0, 0, kWidth, kHeight / 2, kFormat, kType,
1665 mem1.id, mem1.offset, result1.id, result1.offset,
1666 false);
1667 expected.set_token1.Init(GetNextToken());
1668 expected.read2.Init(
1669 0, kHeight / 2, kWidth, kHeight / 2, kFormat, kType,
1670 mem2.id, mem2.offset, result2.id, result2.offset, false);
1671 expected.set_token2.Init(GetNextToken());
1672 scoped_ptr<int8[]> buffer(new int8[kWidth * kHeight * kBytesPerPixel]);
1674 EXPECT_CALL(*command_buffer(), OnFlush())
1675 .WillOnce(SetMemory(result1.ptr, static_cast<uint32>(1)))
1676 .WillOnce(SetMemory(result2.ptr, static_cast<uint32>(1)))
1677 .RetiresOnSaturation();
1679 gl_->ReadPixels(0, 0, kWidth, kHeight, kFormat, kType, buffer.get());
1680 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
1683 TEST_F(GLES2ImplementationTest, ReadPixelsBadFormatType) {
1684 struct Cmds {
1685 cmds::ReadPixels read;
1686 cmd::SetToken set_token;
1688 const GLint kBytesPerPixel = 4;
1689 const GLint kWidth = 2;
1690 const GLint kHeight = 2;
1691 const GLenum kFormat = 0;
1692 const GLenum kType = 0;
1694 ExpectedMemoryInfo mem1 =
1695 GetExpectedMemory(kWidth * kHeight * kBytesPerPixel);
1696 ExpectedMemoryInfo result1 =
1697 GetExpectedResultMemory(sizeof(cmds::ReadPixels::Result));
1699 Cmds expected;
1700 expected.read.Init(
1701 0, 0, kWidth, kHeight, kFormat, kType,
1702 mem1.id, mem1.offset, result1.id, result1.offset, false);
1703 expected.set_token.Init(GetNextToken());
1704 scoped_ptr<int8[]> buffer(new int8[kWidth * kHeight * kBytesPerPixel]);
1706 EXPECT_CALL(*command_buffer(), OnFlush())
1707 .Times(1)
1708 .RetiresOnSaturation();
1710 gl_->ReadPixels(0, 0, kWidth, kHeight, kFormat, kType, buffer.get());
1713 TEST_F(GLES2ImplementationTest, FreeUnusedSharedMemory) {
1714 struct Cmds {
1715 cmds::BufferSubData buf;
1716 cmd::SetToken set_token;
1718 const GLenum kTarget = GL_ELEMENT_ARRAY_BUFFER;
1719 const GLintptr kOffset = 15;
1720 const GLsizeiptr kSize = 16;
1722 ExpectedMemoryInfo mem1 = GetExpectedMemory(kSize);
1724 Cmds expected;
1725 expected.buf.Init(
1726 kTarget, kOffset, kSize, mem1.id, mem1.offset);
1727 expected.set_token.Init(GetNextToken());
1729 void* mem = gl_->MapBufferSubDataCHROMIUM(
1730 kTarget, kOffset, kSize, GL_WRITE_ONLY);
1731 ASSERT_TRUE(mem != NULL);
1732 gl_->UnmapBufferSubDataCHROMIUM(mem);
1733 EXPECT_CALL(*command_buffer(), DestroyTransferBuffer(_))
1734 .Times(1)
1735 .RetiresOnSaturation();
1736 gl_->FreeUnusedSharedMemory();
1739 TEST_F(GLES2ImplementationTest, MapUnmapBufferSubDataCHROMIUM) {
1740 struct Cmds {
1741 cmds::BufferSubData buf;
1742 cmd::SetToken set_token;
1744 const GLenum kTarget = GL_ELEMENT_ARRAY_BUFFER;
1745 const GLintptr kOffset = 15;
1746 const GLsizeiptr kSize = 16;
1748 uint32 offset = 0;
1749 Cmds expected;
1750 expected.buf.Init(
1751 kTarget, kOffset, kSize,
1752 command_buffer()->GetNextFreeTransferBufferId(), offset);
1753 expected.set_token.Init(GetNextToken());
1755 void* mem = gl_->MapBufferSubDataCHROMIUM(
1756 kTarget, kOffset, kSize, GL_WRITE_ONLY);
1757 ASSERT_TRUE(mem != NULL);
1758 gl_->UnmapBufferSubDataCHROMIUM(mem);
1759 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
1762 TEST_F(GLES2ImplementationTest, MapUnmapBufferSubDataCHROMIUMBadArgs) {
1763 const GLenum kTarget = GL_ELEMENT_ARRAY_BUFFER;
1764 const GLintptr kOffset = 15;
1765 const GLsizeiptr kSize = 16;
1767 ExpectedMemoryInfo result1 =
1768 GetExpectedResultMemory(sizeof(cmds::GetError::Result));
1769 ExpectedMemoryInfo result2 =
1770 GetExpectedResultMemory(sizeof(cmds::GetError::Result));
1771 ExpectedMemoryInfo result3 =
1772 GetExpectedResultMemory(sizeof(cmds::GetError::Result));
1773 ExpectedMemoryInfo result4 =
1774 GetExpectedResultMemory(sizeof(cmds::GetError::Result));
1776 // Calls to flush to wait for GetError
1777 EXPECT_CALL(*command_buffer(), OnFlush())
1778 .WillOnce(SetMemory(result1.ptr, GLuint(GL_NO_ERROR)))
1779 .WillOnce(SetMemory(result2.ptr, GLuint(GL_NO_ERROR)))
1780 .WillOnce(SetMemory(result3.ptr, GLuint(GL_NO_ERROR)))
1781 .WillOnce(SetMemory(result4.ptr, GLuint(GL_NO_ERROR)))
1782 .RetiresOnSaturation();
1784 void* mem;
1785 mem = gl_->MapBufferSubDataCHROMIUM(kTarget, -1, kSize, GL_WRITE_ONLY);
1786 ASSERT_TRUE(mem == NULL);
1787 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE), gl_->GetError());
1788 mem = gl_->MapBufferSubDataCHROMIUM(kTarget, kOffset, -1, GL_WRITE_ONLY);
1789 ASSERT_TRUE(mem == NULL);
1790 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE), gl_->GetError());
1791 mem = gl_->MapBufferSubDataCHROMIUM(kTarget, kOffset, kSize, GL_READ_ONLY);
1792 ASSERT_TRUE(mem == NULL);
1793 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_ENUM), gl_->GetError());
1794 const char* kPtr = "something";
1795 gl_->UnmapBufferSubDataCHROMIUM(kPtr);
1796 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE), gl_->GetError());
1799 TEST_F(GLES2ImplementationTest, MapUnmapTexSubImage2DCHROMIUM) {
1800 struct Cmds {
1801 cmds::TexSubImage2D tex;
1802 cmd::SetToken set_token;
1804 const GLint kLevel = 1;
1805 const GLint kXOffset = 2;
1806 const GLint kYOffset = 3;
1807 const GLint kWidth = 4;
1808 const GLint kHeight = 5;
1809 const GLenum kFormat = GL_RGBA;
1810 const GLenum kType = GL_UNSIGNED_BYTE;
1812 uint32 offset = 0;
1813 Cmds expected;
1814 expected.tex.Init(
1815 GL_TEXTURE_2D, kLevel, kXOffset, kYOffset, kWidth, kHeight, kFormat,
1816 kType,
1817 command_buffer()->GetNextFreeTransferBufferId(), offset, GL_FALSE);
1818 expected.set_token.Init(GetNextToken());
1820 void* mem = gl_->MapTexSubImage2DCHROMIUM(
1821 GL_TEXTURE_2D,
1822 kLevel,
1823 kXOffset,
1824 kYOffset,
1825 kWidth,
1826 kHeight,
1827 kFormat,
1828 kType,
1829 GL_WRITE_ONLY);
1830 ASSERT_TRUE(mem != NULL);
1831 gl_->UnmapTexSubImage2DCHROMIUM(mem);
1832 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
1835 TEST_F(GLES2ImplementationTest, MapUnmapTexSubImage2DCHROMIUMBadArgs) {
1836 const GLint kLevel = 1;
1837 const GLint kXOffset = 2;
1838 const GLint kYOffset = 3;
1839 const GLint kWidth = 4;
1840 const GLint kHeight = 5;
1841 const GLenum kFormat = GL_RGBA;
1842 const GLenum kType = GL_UNSIGNED_BYTE;
1844 ExpectedMemoryInfo result1 =
1845 GetExpectedResultMemory(sizeof(cmds::GetError::Result));
1846 ExpectedMemoryInfo result2 =
1847 GetExpectedResultMemory(sizeof(cmds::GetError::Result));
1848 ExpectedMemoryInfo result3 =
1849 GetExpectedResultMemory(sizeof(cmds::GetError::Result));
1850 ExpectedMemoryInfo result4 =
1851 GetExpectedResultMemory(sizeof(cmds::GetError::Result));
1852 ExpectedMemoryInfo result5 =
1853 GetExpectedResultMemory(sizeof(cmds::GetError::Result));
1854 ExpectedMemoryInfo result6 =
1855 GetExpectedResultMemory(sizeof(cmds::GetError::Result));
1856 ExpectedMemoryInfo result7 =
1857 GetExpectedResultMemory(sizeof(cmds::GetError::Result));
1859 // Calls to flush to wait for GetError
1860 EXPECT_CALL(*command_buffer(), OnFlush())
1861 .WillOnce(SetMemory(result1.ptr, GLuint(GL_NO_ERROR)))
1862 .WillOnce(SetMemory(result2.ptr, GLuint(GL_NO_ERROR)))
1863 .WillOnce(SetMemory(result3.ptr, GLuint(GL_NO_ERROR)))
1864 .WillOnce(SetMemory(result4.ptr, GLuint(GL_NO_ERROR)))
1865 .WillOnce(SetMemory(result5.ptr, GLuint(GL_NO_ERROR)))
1866 .WillOnce(SetMemory(result6.ptr, GLuint(GL_NO_ERROR)))
1867 .WillOnce(SetMemory(result7.ptr, GLuint(GL_NO_ERROR)))
1868 .RetiresOnSaturation();
1870 void* mem;
1871 mem = gl_->MapTexSubImage2DCHROMIUM(
1872 GL_TEXTURE_2D,
1874 kXOffset,
1875 kYOffset,
1876 kWidth,
1877 kHeight,
1878 kFormat,
1879 kType,
1880 GL_WRITE_ONLY);
1881 EXPECT_TRUE(mem == NULL);
1882 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE), gl_->GetError());
1883 mem = gl_->MapTexSubImage2DCHROMIUM(
1884 GL_TEXTURE_2D,
1885 kLevel,
1887 kYOffset,
1888 kWidth,
1889 kHeight,
1890 kFormat,
1891 kType,
1892 GL_WRITE_ONLY);
1893 EXPECT_TRUE(mem == NULL);
1894 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE), gl_->GetError());
1895 mem = gl_->MapTexSubImage2DCHROMIUM(
1896 GL_TEXTURE_2D,
1897 kLevel,
1898 kXOffset,
1900 kWidth,
1901 kHeight,
1902 kFormat,
1903 kType,
1904 GL_WRITE_ONLY);
1905 EXPECT_TRUE(mem == NULL);
1906 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE), gl_->GetError());
1907 mem = gl_->MapTexSubImage2DCHROMIUM(
1908 GL_TEXTURE_2D,
1909 kLevel,
1910 kXOffset,
1911 kYOffset,
1913 kHeight,
1914 kFormat,
1915 kType,
1916 GL_WRITE_ONLY);
1917 EXPECT_TRUE(mem == NULL);
1918 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE), gl_->GetError());
1919 mem = gl_->MapTexSubImage2DCHROMIUM(
1920 GL_TEXTURE_2D,
1921 kLevel,
1922 kXOffset,
1923 kYOffset,
1924 kWidth,
1926 kFormat,
1927 kType,
1928 GL_WRITE_ONLY);
1929 EXPECT_TRUE(mem == NULL);
1930 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE), gl_->GetError());
1931 mem = gl_->MapTexSubImage2DCHROMIUM(
1932 GL_TEXTURE_2D,
1933 kLevel,
1934 kXOffset,
1935 kYOffset,
1936 kWidth,
1937 kHeight,
1938 kFormat,
1939 kType,
1940 GL_READ_ONLY);
1941 EXPECT_TRUE(mem == NULL);
1942 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_ENUM), gl_->GetError());
1943 const char* kPtr = "something";
1944 gl_->UnmapTexSubImage2DCHROMIUM(kPtr);
1945 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE), gl_->GetError());
1948 TEST_F(GLES2ImplementationTest, GetMultipleIntegervCHROMIUMValidArgs) {
1949 const GLenum pnames[] = {
1950 GL_DEPTH_WRITEMASK,
1951 GL_COLOR_WRITEMASK,
1952 GL_STENCIL_WRITEMASK,
1954 const GLint num_results = 6;
1955 GLint results[num_results + 1];
1956 struct Cmds {
1957 cmds::GetMultipleIntegervCHROMIUM get_multiple;
1958 cmd::SetToken set_token;
1960 const GLsizei kNumPnames = arraysize(pnames);
1961 const GLsizeiptr kResultsSize = num_results * sizeof(results[0]);
1962 const size_t kPNamesSize = kNumPnames * sizeof(pnames[0]);
1964 ExpectedMemoryInfo mem1 = GetExpectedMemory(kPNamesSize + kResultsSize);
1965 ExpectedMemoryInfo result1 = GetExpectedResultMemory(
1966 sizeof(cmds::GetError::Result));
1968 const uint32 kPnamesOffset = mem1.offset;
1969 const uint32 kResultsOffset = mem1.offset + kPNamesSize;
1970 Cmds expected;
1971 expected.get_multiple.Init(
1972 mem1.id, kPnamesOffset, kNumPnames,
1973 mem1.id, kResultsOffset, kResultsSize);
1974 expected.set_token.Init(GetNextToken());
1976 const GLint kSentinel = 0x12345678;
1977 memset(results, 0, sizeof(results));
1978 results[num_results] = kSentinel;
1979 const GLint returned_results[] = {
1980 1, 0, 1, 0, 1, -1,
1982 // One call to flush to wait for results
1983 EXPECT_CALL(*command_buffer(), OnFlush())
1984 .WillOnce(SetMemoryFromArray(mem1.ptr + kPNamesSize,
1985 returned_results, sizeof(returned_results)))
1986 .WillOnce(SetMemory(result1.ptr, GLuint(GL_NO_ERROR)))
1987 .RetiresOnSaturation();
1989 gl_->GetMultipleIntegervCHROMIUM(
1990 &pnames[0], kNumPnames, &results[0], kResultsSize);
1991 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
1992 EXPECT_EQ(0, memcmp(&returned_results, results, sizeof(returned_results)));
1993 EXPECT_EQ(kSentinel, results[num_results]);
1994 EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), gl_->GetError());
1997 TEST_F(GLES2ImplementationTest, GetMultipleIntegervCHROMIUMBadArgs) {
1998 GLenum pnames[] = {
1999 GL_DEPTH_WRITEMASK,
2000 GL_COLOR_WRITEMASK,
2001 GL_STENCIL_WRITEMASK,
2003 const GLint num_results = 6;
2004 GLint results[num_results + 1];
2005 const GLsizei kNumPnames = arraysize(pnames);
2006 const GLsizeiptr kResultsSize = num_results * sizeof(results[0]);
2008 ExpectedMemoryInfo result1 =
2009 GetExpectedResultMemory(sizeof(cmds::GetError::Result));
2010 ExpectedMemoryInfo result2 =
2011 GetExpectedResultMemory(sizeof(cmds::GetError::Result));
2012 ExpectedMemoryInfo result3 =
2013 GetExpectedResultMemory(sizeof(cmds::GetError::Result));
2014 ExpectedMemoryInfo result4 =
2015 GetExpectedResultMemory(sizeof(cmds::GetError::Result));
2017 // Calls to flush to wait for GetError
2018 EXPECT_CALL(*command_buffer(), OnFlush())
2019 .WillOnce(SetMemory(result1.ptr, GLuint(GL_NO_ERROR)))
2020 .WillOnce(SetMemory(result2.ptr, GLuint(GL_NO_ERROR)))
2021 .WillOnce(SetMemory(result3.ptr, GLuint(GL_NO_ERROR)))
2022 .WillOnce(SetMemory(result4.ptr, GLuint(GL_NO_ERROR)))
2023 .RetiresOnSaturation();
2025 const GLint kSentinel = 0x12345678;
2026 memset(results, 0, sizeof(results));
2027 results[num_results] = kSentinel;
2028 // try bad size.
2029 gl_->GetMultipleIntegervCHROMIUM(
2030 &pnames[0], kNumPnames, &results[0], kResultsSize + 1);
2031 EXPECT_TRUE(NoCommandsWritten());
2032 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE), gl_->GetError());
2033 EXPECT_EQ(0, results[0]);
2034 EXPECT_EQ(kSentinel, results[num_results]);
2035 // try bad size.
2036 ClearCommands();
2037 gl_->GetMultipleIntegervCHROMIUM(
2038 &pnames[0], kNumPnames, &results[0], kResultsSize - 1);
2039 EXPECT_TRUE(NoCommandsWritten());
2040 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE), gl_->GetError());
2041 EXPECT_EQ(0, results[0]);
2042 EXPECT_EQ(kSentinel, results[num_results]);
2043 // try uncleared results.
2044 ClearCommands();
2045 results[2] = 1;
2046 gl_->GetMultipleIntegervCHROMIUM(
2047 &pnames[0], kNumPnames, &results[0], kResultsSize);
2048 EXPECT_TRUE(NoCommandsWritten());
2049 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE), gl_->GetError());
2050 EXPECT_EQ(0, results[0]);
2051 EXPECT_EQ(kSentinel, results[num_results]);
2052 // try bad enum results.
2053 ClearCommands();
2054 results[2] = 0;
2055 pnames[1] = GL_TRUE;
2056 gl_->GetMultipleIntegervCHROMIUM(
2057 &pnames[0], kNumPnames, &results[0], kResultsSize);
2058 EXPECT_TRUE(NoCommandsWritten());
2059 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_ENUM), gl_->GetError());
2060 EXPECT_EQ(0, results[0]);
2061 EXPECT_EQ(kSentinel, results[num_results]);
2064 TEST_F(GLES2ImplementationTest, GetProgramInfoCHROMIUMGoodArgs) {
2065 const uint32 kBucketId = GLES2Implementation::kResultBucketId;
2066 const GLuint kProgramId = 123;
2067 const char kBad = 0x12;
2068 GLsizei size = 0;
2069 const Str7 kString = {"foobar"};
2070 char buf[20];
2072 ExpectedMemoryInfo mem1 =
2073 GetExpectedMemory(MaxTransferBufferSize());
2074 ExpectedMemoryInfo result1 =
2075 GetExpectedResultMemory(sizeof(cmd::GetBucketStart::Result));
2076 ExpectedMemoryInfo result2 =
2077 GetExpectedResultMemory(sizeof(cmds::GetError::Result));
2079 memset(buf, kBad, sizeof(buf));
2080 EXPECT_CALL(*command_buffer(), OnFlush())
2081 .WillOnce(DoAll(SetMemory(result1.ptr, uint32(sizeof(kString))),
2082 SetMemory(mem1.ptr, kString)))
2083 .WillOnce(SetMemory(result2.ptr, GLuint(GL_NO_ERROR)))
2084 .RetiresOnSaturation();
2086 struct Cmds {
2087 cmd::SetBucketSize set_bucket_size1;
2088 cmds::GetProgramInfoCHROMIUM get_program_info;
2089 cmd::GetBucketStart get_bucket_start;
2090 cmd::SetToken set_token1;
2091 cmd::SetBucketSize set_bucket_size2;
2093 Cmds expected;
2094 expected.set_bucket_size1.Init(kBucketId, 0);
2095 expected.get_program_info.Init(kProgramId, kBucketId);
2096 expected.get_bucket_start.Init(
2097 kBucketId, result1.id, result1.offset,
2098 MaxTransferBufferSize(), mem1.id, mem1.offset);
2099 expected.set_token1.Init(GetNextToken());
2100 expected.set_bucket_size2.Init(kBucketId, 0);
2101 gl_->GetProgramInfoCHROMIUM(kProgramId, sizeof(buf), &size, &buf);
2102 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
2103 EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), gl_->GetError());
2104 EXPECT_EQ(sizeof(kString), static_cast<size_t>(size));
2105 EXPECT_STREQ(kString.str, buf);
2106 EXPECT_EQ(buf[sizeof(kString)], kBad);
2109 TEST_F(GLES2ImplementationTest, GetProgramInfoCHROMIUMBadArgs) {
2110 const uint32 kBucketId = GLES2Implementation::kResultBucketId;
2111 const GLuint kProgramId = 123;
2112 GLsizei size = 0;
2113 const Str7 kString = {"foobar"};
2114 char buf[20];
2116 ExpectedMemoryInfo mem1 = GetExpectedMemory(MaxTransferBufferSize());
2117 ExpectedMemoryInfo result1 =
2118 GetExpectedResultMemory(sizeof(cmd::GetBucketStart::Result));
2119 ExpectedMemoryInfo result2 =
2120 GetExpectedResultMemory(sizeof(cmds::GetError::Result));
2121 ExpectedMemoryInfo result3 =
2122 GetExpectedResultMemory(sizeof(cmds::GetError::Result));
2123 ExpectedMemoryInfo result4 =
2124 GetExpectedResultMemory(sizeof(cmds::GetError::Result));
2126 EXPECT_CALL(*command_buffer(), OnFlush())
2127 .WillOnce(DoAll(SetMemory(result1.ptr, uint32(sizeof(kString))),
2128 SetMemory(mem1.ptr, kString)))
2129 .WillOnce(SetMemory(result2.ptr, GLuint(GL_NO_ERROR)))
2130 .WillOnce(SetMemory(result3.ptr, GLuint(GL_NO_ERROR)))
2131 .WillOnce(SetMemory(result4.ptr, GLuint(GL_NO_ERROR)))
2132 .RetiresOnSaturation();
2134 // try bufsize not big enough.
2135 struct Cmds {
2136 cmd::SetBucketSize set_bucket_size1;
2137 cmds::GetProgramInfoCHROMIUM get_program_info;
2138 cmd::GetBucketStart get_bucket_start;
2139 cmd::SetToken set_token1;
2140 cmd::SetBucketSize set_bucket_size2;
2142 Cmds expected;
2143 expected.set_bucket_size1.Init(kBucketId, 0);
2144 expected.get_program_info.Init(kProgramId, kBucketId);
2145 expected.get_bucket_start.Init(
2146 kBucketId, result1.id, result1.offset,
2147 MaxTransferBufferSize(), mem1.id, mem1.offset);
2148 expected.set_token1.Init(GetNextToken());
2149 expected.set_bucket_size2.Init(kBucketId, 0);
2150 gl_->GetProgramInfoCHROMIUM(kProgramId, 6, &size, &buf);
2151 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
2152 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_OPERATION), gl_->GetError());
2153 ClearCommands();
2155 // try bad bufsize
2156 gl_->GetProgramInfoCHROMIUM(kProgramId, -1, &size, &buf);
2157 EXPECT_TRUE(NoCommandsWritten());
2158 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE), gl_->GetError());
2159 ClearCommands();
2160 // try no size ptr.
2161 gl_->GetProgramInfoCHROMIUM(kProgramId, sizeof(buf), NULL, &buf);
2162 EXPECT_TRUE(NoCommandsWritten());
2163 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE), gl_->GetError());
2166 // Test that things are cached
2167 TEST_F(GLES2ImplementationTest, GetIntegerCacheRead) {
2168 struct PNameValue {
2169 GLenum pname;
2170 GLint expected;
2172 const PNameValue pairs[] = {
2173 {GL_ACTIVE_TEXTURE, GL_TEXTURE0, },
2174 {GL_TEXTURE_BINDING_2D, 0, },
2175 {GL_TEXTURE_BINDING_CUBE_MAP, 0, },
2176 {GL_TEXTURE_BINDING_EXTERNAL_OES, 0, },
2177 {GL_FRAMEBUFFER_BINDING, 0, },
2178 {GL_RENDERBUFFER_BINDING, 0, },
2179 {GL_ARRAY_BUFFER_BINDING, 0, },
2180 {GL_ELEMENT_ARRAY_BUFFER_BINDING, 0, },
2181 {GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, kMaxCombinedTextureImageUnits, },
2182 {GL_MAX_CUBE_MAP_TEXTURE_SIZE, kMaxCubeMapTextureSize, },
2183 {GL_MAX_FRAGMENT_UNIFORM_VECTORS, kMaxFragmentUniformVectors, },
2184 {GL_MAX_RENDERBUFFER_SIZE, kMaxRenderbufferSize, },
2185 {GL_MAX_TEXTURE_IMAGE_UNITS, kMaxTextureImageUnits, },
2186 {GL_MAX_TEXTURE_SIZE, kMaxTextureSize, },
2187 {GL_MAX_VARYING_VECTORS, kMaxVaryingVectors, },
2188 {GL_MAX_VERTEX_ATTRIBS, kMaxVertexAttribs, },
2189 {GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, kMaxVertexTextureImageUnits, },
2190 {GL_MAX_VERTEX_UNIFORM_VECTORS, kMaxVertexUniformVectors, },
2191 {GL_NUM_COMPRESSED_TEXTURE_FORMATS, kNumCompressedTextureFormats, },
2192 {GL_NUM_SHADER_BINARY_FORMATS, kNumShaderBinaryFormats, }, };
2193 size_t num_pairs = sizeof(pairs) / sizeof(pairs[0]);
2194 for (size_t ii = 0; ii < num_pairs; ++ii) {
2195 const PNameValue& pv = pairs[ii];
2196 GLint v = -1;
2197 gl_->GetIntegerv(pv.pname, &v);
2198 EXPECT_TRUE(NoCommandsWritten());
2199 EXPECT_EQ(pv.expected, v);
2202 ExpectedMemoryInfo result1 =
2203 GetExpectedResultMemory(sizeof(cmds::GetError::Result));
2205 EXPECT_CALL(*command_buffer(), OnFlush())
2206 .WillOnce(SetMemory(result1.ptr, GLuint(GL_NO_ERROR)))
2207 .RetiresOnSaturation();
2208 EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), gl_->GetError());
2211 TEST_F(GLES2ImplementationTest, GetIntegerCacheWrite) {
2212 struct PNameValue {
2213 GLenum pname;
2214 GLint expected;
2216 gl_->ActiveTexture(GL_TEXTURE4);
2217 gl_->BindBuffer(GL_ARRAY_BUFFER, 2);
2218 gl_->BindBuffer(GL_ELEMENT_ARRAY_BUFFER, 3);
2219 gl_->BindFramebuffer(GL_FRAMEBUFFER, 4);
2220 gl_->BindRenderbuffer(GL_RENDERBUFFER, 5);
2221 gl_->BindTexture(GL_TEXTURE_2D, 6);
2222 gl_->BindTexture(GL_TEXTURE_CUBE_MAP, 7);
2223 gl_->BindTexture(GL_TEXTURE_EXTERNAL_OES, 8);
2225 const PNameValue pairs[] = {{GL_ACTIVE_TEXTURE, GL_TEXTURE4, },
2226 {GL_ARRAY_BUFFER_BINDING, 2, },
2227 {GL_ELEMENT_ARRAY_BUFFER_BINDING, 3, },
2228 {GL_FRAMEBUFFER_BINDING, 4, },
2229 {GL_RENDERBUFFER_BINDING, 5, },
2230 {GL_TEXTURE_BINDING_2D, 6, },
2231 {GL_TEXTURE_BINDING_CUBE_MAP, 7, },
2232 {GL_TEXTURE_BINDING_EXTERNAL_OES, 8, }, };
2233 size_t num_pairs = sizeof(pairs) / sizeof(pairs[0]);
2234 for (size_t ii = 0; ii < num_pairs; ++ii) {
2235 const PNameValue& pv = pairs[ii];
2236 GLint v = -1;
2237 gl_->GetIntegerv(pv.pname, &v);
2238 EXPECT_EQ(pv.expected, v);
2241 ExpectedMemoryInfo result1 =
2242 GetExpectedResultMemory(sizeof(cmds::GetError::Result));
2244 EXPECT_CALL(*command_buffer(), OnFlush())
2245 .WillOnce(SetMemory(result1.ptr, GLuint(GL_NO_ERROR)))
2246 .RetiresOnSaturation();
2247 EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), gl_->GetError());
2250 static bool CheckRect(
2251 int width, int height, GLenum format, GLenum type, int alignment,
2252 bool flip_y, const uint8* r1, const uint8* r2) {
2253 uint32 size = 0;
2254 uint32 unpadded_row_size = 0;
2255 uint32 padded_row_size = 0;
2256 if (!GLES2Util::ComputeImageDataSizes(
2257 width, height, format, type, alignment, &size, &unpadded_row_size,
2258 &padded_row_size)) {
2259 return false;
2262 int r2_stride = flip_y ?
2263 -static_cast<int>(padded_row_size) :
2264 static_cast<int>(padded_row_size);
2265 r2 = flip_y ? (r2 + (height - 1) * padded_row_size) : r2;
2267 for (int y = 0; y < height; ++y) {
2268 if (memcmp(r1, r2, unpadded_row_size) != 0) {
2269 return false;
2271 r1 += padded_row_size;
2272 r2 += r2_stride;
2274 return true;
2277 ACTION_P8(CheckRectAction, width, height, format, type, alignment, flip_y,
2278 r1, r2) {
2279 EXPECT_TRUE(CheckRect(
2280 width, height, format, type, alignment, flip_y, r1, r2));
2283 // Test TexImage2D with and without flip_y
2284 TEST_F(GLES2ImplementationTest, TexImage2D) {
2285 struct Cmds {
2286 cmds::TexImage2D tex_image_2d;
2287 cmd::SetToken set_token;
2289 struct Cmds2 {
2290 cmds::TexImage2D tex_image_2d;
2291 cmd::SetToken set_token;
2293 const GLenum kTarget = GL_TEXTURE_2D;
2294 const GLint kLevel = 0;
2295 const GLenum kFormat = GL_RGB;
2296 const GLsizei kWidth = 3;
2297 const GLsizei kHeight = 4;
2298 const GLint kBorder = 0;
2299 const GLenum kType = GL_UNSIGNED_BYTE;
2300 const GLint kPixelStoreUnpackAlignment = 4;
2301 static uint8 pixels[] = {
2302 11, 12, 13, 13, 14, 15, 15, 16, 17, 101, 102, 103,
2303 21, 22, 23, 23, 24, 25, 25, 26, 27, 201, 202, 203,
2304 31, 32, 33, 33, 34, 35, 35, 36, 37, 123, 124, 125,
2305 41, 42, 43, 43, 44, 45, 45, 46, 47,
2308 ExpectedMemoryInfo mem1 = GetExpectedMemory(sizeof(pixels));
2310 Cmds expected;
2311 expected.tex_image_2d.Init(
2312 kTarget, kLevel, kFormat, kWidth, kHeight, kFormat, kType,
2313 mem1.id, mem1.offset);
2314 expected.set_token.Init(GetNextToken());
2315 gl_->TexImage2D(
2316 kTarget, kLevel, kFormat, kWidth, kHeight, kBorder, kFormat, kType,
2317 pixels);
2318 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
2319 EXPECT_TRUE(CheckRect(
2320 kWidth, kHeight, kFormat, kType, kPixelStoreUnpackAlignment, false,
2321 pixels, mem1.ptr));
2323 ClearCommands();
2324 gl_->PixelStorei(GL_UNPACK_FLIP_Y_CHROMIUM, GL_TRUE);
2326 ExpectedMemoryInfo mem2 = GetExpectedMemory(sizeof(pixels));
2327 Cmds2 expected2;
2328 expected2.tex_image_2d.Init(
2329 kTarget, kLevel, kFormat, kWidth, kHeight, kFormat, kType,
2330 mem2.id, mem2.offset);
2331 expected2.set_token.Init(GetNextToken());
2332 const void* commands2 = GetPut();
2333 gl_->TexImage2D(
2334 kTarget, kLevel, kFormat, kWidth, kHeight, kBorder, kFormat, kType,
2335 pixels);
2336 EXPECT_EQ(0, memcmp(&expected2, commands2, sizeof(expected2)));
2337 EXPECT_TRUE(CheckRect(
2338 kWidth, kHeight, kFormat, kType, kPixelStoreUnpackAlignment, true,
2339 pixels, mem2.ptr));
2342 // Test TexImage2D with 2 writes
2343 TEST_F(GLES2ImplementationTest, TexImage2D2Writes) {
2344 struct Cmds {
2345 cmds::TexImage2D tex_image_2d;
2346 cmds::TexSubImage2D tex_sub_image_2d1;
2347 cmd::SetToken set_token1;
2348 cmds::TexSubImage2D tex_sub_image_2d2;
2349 cmd::SetToken set_token2;
2351 const GLenum kTarget = GL_TEXTURE_2D;
2352 const GLint kLevel = 0;
2353 const GLenum kFormat = GL_RGB;
2354 const GLint kBorder = 0;
2355 const GLenum kType = GL_UNSIGNED_BYTE;
2356 const GLint kPixelStoreUnpackAlignment = 4;
2357 const GLsizei kWidth = 3;
2359 uint32 size = 0;
2360 uint32 unpadded_row_size = 0;
2361 uint32 padded_row_size = 0;
2362 ASSERT_TRUE(GLES2Util::ComputeImageDataSizes(
2363 kWidth, 2, kFormat, kType, kPixelStoreUnpackAlignment,
2364 &size, &unpadded_row_size, &padded_row_size));
2365 const GLsizei kHeight = (MaxTransferBufferSize() / padded_row_size) * 2;
2366 ASSERT_TRUE(GLES2Util::ComputeImageDataSizes(
2367 kWidth, kHeight, kFormat, kType, kPixelStoreUnpackAlignment,
2368 &size, NULL, NULL));
2369 uint32 half_size = 0;
2370 ASSERT_TRUE(GLES2Util::ComputeImageDataSizes(
2371 kWidth, kHeight / 2, kFormat, kType, kPixelStoreUnpackAlignment,
2372 &half_size, NULL, NULL));
2374 scoped_ptr<uint8[]> pixels(new uint8[size]);
2375 for (uint32 ii = 0; ii < size; ++ii) {
2376 pixels[ii] = static_cast<uint8>(ii);
2379 ExpectedMemoryInfo mem1 = GetExpectedMemory(half_size);
2380 ExpectedMemoryInfo mem2 = GetExpectedMemory(half_size);
2382 Cmds expected;
2383 expected.tex_image_2d.Init(
2384 kTarget, kLevel, kFormat, kWidth, kHeight, kFormat, kType,
2385 0, 0);
2386 expected.tex_sub_image_2d1.Init(
2387 kTarget, kLevel, 0, 0, kWidth, kHeight / 2, kFormat, kType,
2388 mem1.id, mem1.offset, true);
2389 expected.set_token1.Init(GetNextToken());
2390 expected.tex_sub_image_2d2.Init(
2391 kTarget, kLevel, 0, kHeight / 2, kWidth, kHeight / 2, kFormat, kType,
2392 mem2.id, mem2.offset, true);
2393 expected.set_token2.Init(GetNextToken());
2395 // TODO(gman): Make it possible to run this test
2396 // EXPECT_CALL(*command_buffer(), OnFlush())
2397 // .WillOnce(CheckRectAction(
2398 // kWidth, kHeight / 2, kFormat, kType, kPixelStoreUnpackAlignment,
2399 // false, pixels.get(),
2400 // GetExpectedTransferAddressFromOffsetAs<uint8>(offset1, half_size)))
2401 // .RetiresOnSaturation();
2403 gl_->TexImage2D(
2404 kTarget, kLevel, kFormat, kWidth, kHeight, kBorder, kFormat, kType,
2405 pixels.get());
2406 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
2407 EXPECT_TRUE(CheckRect(
2408 kWidth, kHeight / 2, kFormat, kType, kPixelStoreUnpackAlignment, false,
2409 pixels.get() + kHeight / 2 * padded_row_size, mem2.ptr));
2411 ClearCommands();
2412 gl_->PixelStorei(GL_UNPACK_FLIP_Y_CHROMIUM, GL_TRUE);
2413 const void* commands2 = GetPut();
2414 ExpectedMemoryInfo mem3 = GetExpectedMemory(half_size);
2415 ExpectedMemoryInfo mem4 = GetExpectedMemory(half_size);
2416 expected.tex_image_2d.Init(
2417 kTarget, kLevel, kFormat, kWidth, kHeight, kFormat, kType,
2418 0, 0);
2419 expected.tex_sub_image_2d1.Init(
2420 kTarget, kLevel, 0, kHeight / 2, kWidth, kHeight / 2, kFormat, kType,
2421 mem3.id, mem3.offset, true);
2422 expected.set_token1.Init(GetNextToken());
2423 expected.tex_sub_image_2d2.Init(
2424 kTarget, kLevel, 0, 0, kWidth, kHeight / 2, kFormat, kType,
2425 mem4.id, mem4.offset, true);
2426 expected.set_token2.Init(GetNextToken());
2428 // TODO(gman): Make it possible to run this test
2429 // EXPECT_CALL(*command_buffer(), OnFlush())
2430 // .WillOnce(CheckRectAction(
2431 // kWidth, kHeight / 2, kFormat, kType, kPixelStoreUnpackAlignment,
2432 // true, pixels.get(),
2433 // GetExpectedTransferAddressFromOffsetAs<uint8>(offset3, half_size)))
2434 // .RetiresOnSaturation();
2436 gl_->TexImage2D(
2437 kTarget, kLevel, kFormat, kWidth, kHeight, kBorder, kFormat, kType,
2438 pixels.get());
2439 EXPECT_EQ(0, memcmp(&expected, commands2, sizeof(expected)));
2440 EXPECT_TRUE(CheckRect(
2441 kWidth, kHeight / 2, kFormat, kType, kPixelStoreUnpackAlignment, true,
2442 pixels.get() + kHeight / 2 * padded_row_size, mem4.ptr));
2445 // Test TexSubImage2D with GL_PACK_FLIP_Y set and partial multirow transfers
2446 TEST_F(GLES2ImplementationTest, TexSubImage2DFlipY) {
2447 const GLsizei kTextureWidth = MaxTransferBufferSize() / 4;
2448 const GLsizei kTextureHeight = 7;
2449 const GLsizei kSubImageWidth = MaxTransferBufferSize() / 8;
2450 const GLsizei kSubImageHeight = 4;
2451 const GLint kSubImageXOffset = 1;
2452 const GLint kSubImageYOffset = 2;
2453 const GLenum kFormat = GL_RGBA;
2454 const GLenum kType = GL_UNSIGNED_BYTE;
2455 const GLenum kTarget = GL_TEXTURE_2D;
2456 const GLint kLevel = 0;
2457 const GLint kBorder = 0;
2458 const GLint kPixelStoreUnpackAlignment = 4;
2460 struct Cmds {
2461 cmds::PixelStorei pixel_store_i1;
2462 cmds::TexImage2D tex_image_2d;
2463 cmds::PixelStorei pixel_store_i2;
2464 cmds::TexSubImage2D tex_sub_image_2d1;
2465 cmd::SetToken set_token1;
2466 cmds::TexSubImage2D tex_sub_image_2d2;
2467 cmd::SetToken set_token2;
2470 uint32 sub_2_high_size = 0;
2471 ASSERT_TRUE(GLES2Util::ComputeImageDataSizes(
2472 kSubImageWidth, 2, kFormat, kType, kPixelStoreUnpackAlignment,
2473 &sub_2_high_size, NULL, NULL));
2475 ExpectedMemoryInfo mem1 = GetExpectedMemory(sub_2_high_size);
2476 ExpectedMemoryInfo mem2 = GetExpectedMemory(sub_2_high_size);
2478 Cmds expected;
2479 expected.pixel_store_i1.Init(GL_UNPACK_ALIGNMENT, kPixelStoreUnpackAlignment);
2480 expected.tex_image_2d.Init(
2481 kTarget, kLevel, kFormat, kTextureWidth, kTextureHeight, kFormat,
2482 kType, 0, 0);
2483 expected.pixel_store_i2.Init(GL_UNPACK_FLIP_Y_CHROMIUM, GL_TRUE);
2484 expected.tex_sub_image_2d1.Init(kTarget, kLevel, kSubImageXOffset,
2485 kSubImageYOffset + 2, kSubImageWidth, 2, kFormat, kType,
2486 mem1.id, mem1.offset, false);
2487 expected.set_token1.Init(GetNextToken());
2488 expected.tex_sub_image_2d2.Init(kTarget, kLevel, kSubImageXOffset,
2489 kSubImageYOffset, kSubImageWidth , 2, kFormat, kType,
2490 mem2.id, mem2.offset, false);
2491 expected.set_token2.Init(GetNextToken());
2493 gl_->PixelStorei(GL_UNPACK_ALIGNMENT, kPixelStoreUnpackAlignment);
2494 gl_->TexImage2D(
2495 kTarget, kLevel, kFormat, kTextureWidth, kTextureHeight, kBorder, kFormat,
2496 kType, NULL);
2497 gl_->PixelStorei(GL_UNPACK_FLIP_Y_CHROMIUM, GL_TRUE);
2498 scoped_ptr<uint32[]> pixels(new uint32[kSubImageWidth * kSubImageHeight]);
2499 for (int y = 0; y < kSubImageHeight; ++y) {
2500 for (int x = 0; x < kSubImageWidth; ++x) {
2501 pixels.get()[kSubImageWidth * y + x] = x | (y << 16);
2504 gl_->TexSubImage2D(
2505 GL_TEXTURE_2D, 0, kSubImageXOffset, kSubImageYOffset, kSubImageWidth,
2506 kSubImageHeight, GL_RGBA, GL_UNSIGNED_BYTE, pixels.get());
2508 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
2509 EXPECT_TRUE(CheckRect(
2510 kSubImageWidth, 2, kFormat, kType, kPixelStoreUnpackAlignment, true,
2511 reinterpret_cast<uint8*>(pixels.get() + 2 * kSubImageWidth),
2512 mem2.ptr));
2515 TEST_F(GLES2ImplementationTest, SubImageUnpack) {
2516 static const GLint unpack_alignments[] = { 1, 2, 4, 8 };
2518 static const GLenum kFormat = GL_RGB;
2519 static const GLenum kType = GL_UNSIGNED_BYTE;
2520 static const GLint kLevel = 0;
2521 static const GLint kBorder = 0;
2522 // We're testing using the unpack params to pull a subimage out of a larger
2523 // source of pixels. Here we specify the subimage by its border rows /
2524 // columns.
2525 static const GLint kSrcWidth = 33;
2526 static const GLint kSrcSubImageX0 = 11;
2527 static const GLint kSrcSubImageX1 = 20;
2528 static const GLint kSrcSubImageY0 = 18;
2529 static const GLint kSrcSubImageY1 = 23;
2530 static const GLint kSrcSubImageWidth = kSrcSubImageX1 - kSrcSubImageX0;
2531 static const GLint kSrcSubImageHeight = kSrcSubImageY1 - kSrcSubImageY0;
2533 // these are only used in the texsubimage tests
2534 static const GLint kTexWidth = 1023;
2535 static const GLint kTexHeight = 511;
2536 static const GLint kTexSubXOffset = 419;
2537 static const GLint kTexSubYOffset = 103;
2539 struct {
2540 cmds::PixelStorei pixel_store_i;
2541 cmds::PixelStorei pixel_store_i2;
2542 cmds::TexImage2D tex_image_2d;
2543 } texImageExpected;
2545 struct {
2546 cmds::PixelStorei pixel_store_i;
2547 cmds::PixelStorei pixel_store_i2;
2548 cmds::TexImage2D tex_image_2d;
2549 cmds::TexSubImage2D tex_sub_image_2d;
2550 } texSubImageExpected;
2552 uint32 src_size;
2553 ASSERT_TRUE(GLES2Util::ComputeImageDataSizes(
2554 kSrcWidth, kSrcSubImageY1, kFormat, kType, 8, &src_size, NULL, NULL));
2555 scoped_ptr<uint8[]> src_pixels;
2556 src_pixels.reset(new uint8[src_size]);
2557 for (size_t i = 0; i < src_size; ++i) {
2558 src_pixels[i] = static_cast<int8>(i);
2561 for (int sub = 0; sub < 2; ++sub) {
2562 for (int flip_y = 0; flip_y < 2; ++flip_y) {
2563 for (size_t a = 0; a < arraysize(unpack_alignments); ++a) {
2564 GLint alignment = unpack_alignments[a];
2565 uint32 size;
2566 uint32 unpadded_row_size;
2567 uint32 padded_row_size;
2568 ASSERT_TRUE(GLES2Util::ComputeImageDataSizes(
2569 kSrcSubImageWidth, kSrcSubImageHeight, kFormat, kType, alignment,
2570 &size, &unpadded_row_size, &padded_row_size));
2571 ASSERT_TRUE(size <= MaxTransferBufferSize());
2572 ExpectedMemoryInfo mem = GetExpectedMemory(size);
2574 const void* commands = GetPut();
2575 gl_->PixelStorei(GL_UNPACK_ALIGNMENT, alignment);
2576 gl_->PixelStorei(GL_UNPACK_ROW_LENGTH_EXT, kSrcWidth);
2577 gl_->PixelStorei(GL_UNPACK_SKIP_PIXELS_EXT, kSrcSubImageX0);
2578 gl_->PixelStorei(GL_UNPACK_SKIP_ROWS_EXT, kSrcSubImageY0);
2579 gl_->PixelStorei(GL_UNPACK_FLIP_Y_CHROMIUM, flip_y);
2580 if (sub) {
2581 gl_->TexImage2D(
2582 GL_TEXTURE_2D, kLevel, kFormat, kTexWidth, kTexHeight, kBorder,
2583 kFormat, kType, NULL);
2584 gl_->TexSubImage2D(
2585 GL_TEXTURE_2D, kLevel, kTexSubXOffset, kTexSubYOffset,
2586 kSrcSubImageWidth, kSrcSubImageHeight, kFormat, kType,
2587 src_pixels.get());
2588 texSubImageExpected.pixel_store_i.Init(
2589 GL_UNPACK_ALIGNMENT, alignment);
2590 texSubImageExpected.pixel_store_i2.Init(
2591 GL_UNPACK_FLIP_Y_CHROMIUM, flip_y);
2592 texSubImageExpected.tex_image_2d.Init(
2593 GL_TEXTURE_2D, kLevel, kFormat, kTexWidth, kTexHeight,
2594 kFormat, kType, 0, 0);
2595 texSubImageExpected.tex_sub_image_2d.Init(
2596 GL_TEXTURE_2D, kLevel, kTexSubXOffset, kTexSubYOffset,
2597 kSrcSubImageWidth, kSrcSubImageHeight, kFormat, kType, mem.id,
2598 mem.offset, GL_FALSE);
2599 EXPECT_EQ(0, memcmp(
2600 &texSubImageExpected, commands, sizeof(texSubImageExpected)));
2601 } else {
2602 gl_->TexImage2D(
2603 GL_TEXTURE_2D, kLevel, kFormat,
2604 kSrcSubImageWidth, kSrcSubImageHeight, kBorder, kFormat, kType,
2605 src_pixels.get());
2606 texImageExpected.pixel_store_i.Init(GL_UNPACK_ALIGNMENT, alignment);
2607 texImageExpected.pixel_store_i2.Init(
2608 GL_UNPACK_FLIP_Y_CHROMIUM, flip_y);
2609 texImageExpected.tex_image_2d.Init(
2610 GL_TEXTURE_2D, kLevel, kFormat, kSrcSubImageWidth,
2611 kSrcSubImageHeight, kFormat, kType, mem.id, mem.offset);
2612 EXPECT_EQ(0, memcmp(
2613 &texImageExpected, commands, sizeof(texImageExpected)));
2615 uint32 src_padded_row_size;
2616 ASSERT_TRUE(GLES2Util::ComputeImagePaddedRowSize(
2617 kSrcWidth, kFormat, kType, alignment, &src_padded_row_size));
2618 uint32 bytes_per_group = GLES2Util::ComputeImageGroupSize(
2619 kFormat, kType);
2620 for (int y = 0; y < kSrcSubImageHeight; ++y) {
2621 GLint src_sub_y = flip_y ? kSrcSubImageHeight - y - 1 : y;
2622 const uint8* src_row = src_pixels.get() +
2623 (kSrcSubImageY0 + src_sub_y) * src_padded_row_size +
2624 bytes_per_group * kSrcSubImageX0;
2625 const uint8* dst_row = mem.ptr + y * padded_row_size;
2626 EXPECT_EQ(0, memcmp(src_row, dst_row, unpadded_row_size));
2628 ClearCommands();
2634 // Test texture related calls with invalid arguments.
2635 TEST_F(GLES2ImplementationTest, TextureInvalidArguments) {
2636 struct Cmds {
2637 cmds::TexImage2D tex_image_2d;
2638 cmd::SetToken set_token;
2640 const GLenum kTarget = GL_TEXTURE_2D;
2641 const GLint kLevel = 0;
2642 const GLenum kFormat = GL_RGB;
2643 const GLsizei kWidth = 3;
2644 const GLsizei kHeight = 4;
2645 const GLint kBorder = 0;
2646 const GLint kInvalidBorder = 1;
2647 const GLenum kType = GL_UNSIGNED_BYTE;
2648 const GLint kPixelStoreUnpackAlignment = 4;
2649 static uint8 pixels[] = {
2650 11, 12, 13, 13, 14, 15, 15, 16, 17, 101, 102, 103,
2651 21, 22, 23, 23, 24, 25, 25, 26, 27, 201, 202, 203,
2652 31, 32, 33, 33, 34, 35, 35, 36, 37, 123, 124, 125,
2653 41, 42, 43, 43, 44, 45, 45, 46, 47,
2656 // Verify that something works.
2658 ExpectedMemoryInfo mem1 = GetExpectedMemory(sizeof(pixels));
2660 Cmds expected;
2661 expected.tex_image_2d.Init(
2662 kTarget, kLevel, kFormat, kWidth, kHeight, kFormat, kType,
2663 mem1.id, mem1.offset);
2664 expected.set_token.Init(GetNextToken());
2665 gl_->TexImage2D(
2666 kTarget, kLevel, kFormat, kWidth, kHeight, kBorder, kFormat, kType,
2667 pixels);
2668 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
2669 EXPECT_TRUE(CheckRect(
2670 kWidth, kHeight, kFormat, kType, kPixelStoreUnpackAlignment, false,
2671 pixels, mem1.ptr));
2673 ClearCommands();
2675 // Use invalid border.
2676 gl_->TexImage2D(
2677 kTarget, kLevel, kFormat, kWidth, kHeight, kInvalidBorder, kFormat, kType,
2678 pixels);
2680 EXPECT_TRUE(NoCommandsWritten());
2681 EXPECT_EQ(GL_INVALID_VALUE, CheckError());
2683 ClearCommands();
2685 gl_->AsyncTexImage2DCHROMIUM(
2686 kTarget, kLevel, kFormat, kWidth, kHeight, kInvalidBorder, kFormat, kType,
2687 NULL);
2689 EXPECT_TRUE(NoCommandsWritten());
2690 EXPECT_EQ(GL_INVALID_VALUE, CheckError());
2692 ClearCommands();
2694 // Checking for CompressedTexImage2D argument validation is a bit tricky due
2695 // to (runtime-detected) compression formats. Try to infer the error with an
2696 // aux check.
2697 const GLenum kCompressedFormat = GL_ETC1_RGB8_OES;
2698 gl_->CompressedTexImage2D(
2699 kTarget, kLevel, kCompressedFormat, kWidth, kHeight, kBorder,
2700 arraysize(pixels), pixels);
2702 // In the above, kCompressedFormat and arraysize(pixels) are possibly wrong
2703 // values. First ensure that these do not cause failures at the client. If
2704 // this check ever fails, it probably means that client checks more than at
2705 // the time of writing of this test. In this case, more code needs to be
2706 // written for this test.
2707 EXPECT_FALSE(NoCommandsWritten());
2709 ClearCommands();
2711 // Changing border to invalid border should make the call fail at the client
2712 // checks.
2713 gl_->CompressedTexImage2D(
2714 kTarget, kLevel, kCompressedFormat, kWidth, kHeight, kInvalidBorder,
2715 arraysize(pixels), pixels);
2716 EXPECT_TRUE(NoCommandsWritten());
2717 EXPECT_EQ(GL_INVALID_VALUE, CheckError());
2721 // Binds can not be cached with bind_generates_resource = false because
2722 // our id might not be valid. More specifically if you bind on contextA then
2723 // delete on contextB the resource is still bound on contextA but GetInterger
2724 // won't return an id.
2725 TEST_F(GLES2ImplementationStrictSharedTest, BindsNotCached) {
2726 struct PNameValue {
2727 GLenum pname;
2728 GLint expected;
2730 const PNameValue pairs[] = {{GL_TEXTURE_BINDING_2D, 1, },
2731 {GL_TEXTURE_BINDING_CUBE_MAP, 2, },
2732 {GL_TEXTURE_BINDING_EXTERNAL_OES, 3, },
2733 {GL_FRAMEBUFFER_BINDING, 4, },
2734 {GL_RENDERBUFFER_BINDING, 5, },
2735 {GL_ARRAY_BUFFER_BINDING, 6, },
2736 {GL_ELEMENT_ARRAY_BUFFER_BINDING, 7, }, };
2737 size_t num_pairs = sizeof(pairs) / sizeof(pairs[0]);
2738 for (size_t ii = 0; ii < num_pairs; ++ii) {
2739 const PNameValue& pv = pairs[ii];
2740 GLint v = -1;
2741 ExpectedMemoryInfo result1 =
2742 GetExpectedResultMemory(sizeof(cmds::GetIntegerv::Result));
2743 EXPECT_CALL(*command_buffer(), OnFlush())
2744 .WillOnce(SetMemory(result1.ptr,
2745 SizedResultHelper<GLuint>(pv.expected)))
2746 .RetiresOnSaturation();
2747 gl_->GetIntegerv(pv.pname, &v);
2748 EXPECT_EQ(pv.expected, v);
2752 // glGen* Ids must not be reused until glDelete* commands have been
2753 // flushed by glFlush.
2754 TEST_F(GLES2ImplementationStrictSharedTest, FlushGenerationTestBuffers) {
2755 FlushGenerationTest<GenBuffersAPI>();
2757 TEST_F(GLES2ImplementationStrictSharedTest, FlushGenerationTestFramebuffers) {
2758 FlushGenerationTest<GenFramebuffersAPI>();
2760 TEST_F(GLES2ImplementationStrictSharedTest, FlushGenerationTestRenderbuffers) {
2761 FlushGenerationTest<GenRenderbuffersAPI>();
2763 TEST_F(GLES2ImplementationStrictSharedTest, FlushGenerationTestTextures) {
2764 FlushGenerationTest<GenTexturesAPI>();
2767 // glGen* Ids must not be reused cross-context until glDelete* commands are
2768 // flushed by glFlush, and the Ids are lazily freed after.
2769 TEST_F(GLES2ImplementationStrictSharedTest, CrossContextGenerationTestBuffers) {
2770 CrossContextGenerationTest<GenBuffersAPI>();
2772 TEST_F(GLES2ImplementationStrictSharedTest,
2773 CrossContextGenerationTestFramebuffers) {
2774 CrossContextGenerationTest<GenFramebuffersAPI>();
2776 TEST_F(GLES2ImplementationStrictSharedTest,
2777 CrossContextGenerationTestRenderbuffers) {
2778 CrossContextGenerationTest<GenRenderbuffersAPI>();
2780 TEST_F(GLES2ImplementationStrictSharedTest,
2781 CrossContextGenerationTestTextures) {
2782 CrossContextGenerationTest<GenTexturesAPI>();
2785 // Test Delete which causes auto flush. Tests a regression case that occurred
2786 // in testing.
2787 TEST_F(GLES2ImplementationStrictSharedTest,
2788 CrossContextGenerationAutoFlushTestBuffers) {
2789 CrossContextGenerationAutoFlushTest<GenBuffersAPI>();
2791 TEST_F(GLES2ImplementationStrictSharedTest,
2792 CrossContextGenerationAutoFlushTestFramebuffers) {
2793 CrossContextGenerationAutoFlushTest<GenFramebuffersAPI>();
2795 TEST_F(GLES2ImplementationStrictSharedTest,
2796 CrossContextGenerationAutoFlushTestRenderbuffers) {
2797 CrossContextGenerationAutoFlushTest<GenRenderbuffersAPI>();
2799 TEST_F(GLES2ImplementationStrictSharedTest,
2800 CrossContextGenerationAutoFlushTestTextures) {
2801 CrossContextGenerationAutoFlushTest<GenTexturesAPI>();
2804 TEST_F(GLES2ImplementationTest, GetString) {
2805 const uint32 kBucketId = GLES2Implementation::kResultBucketId;
2806 const Str7 kString = {"foobar"};
2807 // GL_CHROMIUM_map_sub GL_CHROMIUM_flipy are hard coded into
2808 // GLES2Implementation.
2809 const char* expected_str =
2810 "foobar "
2811 "GL_CHROMIUM_flipy "
2812 "GL_EXT_unpack_subimage "
2813 "GL_CHROMIUM_map_sub";
2814 const char kBad = 0x12;
2815 struct Cmds {
2816 cmd::SetBucketSize set_bucket_size1;
2817 cmds::GetString get_string;
2818 cmd::GetBucketStart get_bucket_start;
2819 cmd::SetToken set_token1;
2820 cmd::SetBucketSize set_bucket_size2;
2822 ExpectedMemoryInfo mem1 = GetExpectedMemory(MaxTransferBufferSize());
2823 ExpectedMemoryInfo result1 =
2824 GetExpectedResultMemory(sizeof(cmd::GetBucketStart::Result));
2825 Cmds expected;
2826 expected.set_bucket_size1.Init(kBucketId, 0);
2827 expected.get_string.Init(GL_EXTENSIONS, kBucketId);
2828 expected.get_bucket_start.Init(
2829 kBucketId, result1.id, result1.offset,
2830 MaxTransferBufferSize(), mem1.id, mem1.offset);
2831 expected.set_token1.Init(GetNextToken());
2832 expected.set_bucket_size2.Init(kBucketId, 0);
2833 char buf[sizeof(kString) + 1];
2834 memset(buf, kBad, sizeof(buf));
2836 EXPECT_CALL(*command_buffer(), OnFlush())
2837 .WillOnce(DoAll(SetMemory(result1.ptr, uint32(sizeof(kString))),
2838 SetMemory(mem1.ptr, kString)))
2839 .RetiresOnSaturation();
2841 const GLubyte* result = gl_->GetString(GL_EXTENSIONS);
2842 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
2843 EXPECT_STREQ(expected_str, reinterpret_cast<const char*>(result));
2846 TEST_F(GLES2ImplementationTest, PixelStoreiGLPackReverseRowOrderANGLE) {
2847 const uint32 kBucketId = GLES2Implementation::kResultBucketId;
2848 const Str7 kString = {"foobar"};
2849 struct Cmds {
2850 cmd::SetBucketSize set_bucket_size1;
2851 cmds::GetString get_string;
2852 cmd::GetBucketStart get_bucket_start;
2853 cmd::SetToken set_token1;
2854 cmd::SetBucketSize set_bucket_size2;
2855 cmds::PixelStorei pixel_store;
2858 ExpectedMemoryInfo mem1 = GetExpectedMemory(MaxTransferBufferSize());
2859 ExpectedMemoryInfo result1 =
2860 GetExpectedResultMemory(sizeof(cmd::GetBucketStart::Result));
2862 Cmds expected;
2863 expected.set_bucket_size1.Init(kBucketId, 0);
2864 expected.get_string.Init(GL_EXTENSIONS, kBucketId);
2865 expected.get_bucket_start.Init(
2866 kBucketId, result1.id, result1.offset,
2867 MaxTransferBufferSize(), mem1.id, mem1.offset);
2868 expected.set_token1.Init(GetNextToken());
2869 expected.set_bucket_size2.Init(kBucketId, 0);
2870 expected.pixel_store.Init(GL_PACK_REVERSE_ROW_ORDER_ANGLE, 1);
2872 EXPECT_CALL(*command_buffer(), OnFlush())
2873 .WillOnce(DoAll(SetMemory(result1.ptr, uint32(sizeof(kString))),
2874 SetMemory(mem1.ptr, kString)))
2875 .RetiresOnSaturation();
2877 gl_->PixelStorei(GL_PACK_REVERSE_ROW_ORDER_ANGLE, 1);
2878 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
2881 TEST_F(GLES2ImplementationTest, CreateProgram) {
2882 struct Cmds {
2883 cmds::CreateProgram cmd;
2886 Cmds expected;
2887 expected.cmd.Init(kProgramsAndShadersStartId);
2888 GLuint id = gl_->CreateProgram();
2889 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
2890 EXPECT_EQ(kProgramsAndShadersStartId, id);
2893 TEST_F(GLES2ImplementationTest, BufferDataLargerThanTransferBuffer) {
2894 struct Cmds {
2895 cmds::BufferData set_size;
2896 cmds::BufferSubData copy_data1;
2897 cmd::SetToken set_token1;
2898 cmds::BufferSubData copy_data2;
2899 cmd::SetToken set_token2;
2901 const unsigned kUsableSize =
2902 kTransferBufferSize - GLES2Implementation::kStartingOffset;
2903 uint8 buf[kUsableSize * 2] = { 0, };
2905 ExpectedMemoryInfo mem1 = GetExpectedMemory(kUsableSize);
2906 ExpectedMemoryInfo mem2 = GetExpectedMemory(kUsableSize);
2908 Cmds expected;
2909 expected.set_size.Init(
2910 GL_ARRAY_BUFFER, arraysize(buf), 0, 0, GL_DYNAMIC_DRAW);
2911 expected.copy_data1.Init(
2912 GL_ARRAY_BUFFER, 0, kUsableSize, mem1.id, mem1.offset);
2913 expected.set_token1.Init(GetNextToken());
2914 expected.copy_data2.Init(
2915 GL_ARRAY_BUFFER, kUsableSize, kUsableSize, mem2.id, mem2.offset);
2916 expected.set_token2.Init(GetNextToken());
2917 gl_->BufferData(GL_ARRAY_BUFFER, arraysize(buf), buf, GL_DYNAMIC_DRAW);
2918 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
2921 TEST_F(GLES2ImplementationTest, CapabilitiesAreCached) {
2922 static const GLenum kStates[] = {
2923 GL_DITHER,
2924 GL_BLEND,
2925 GL_CULL_FACE,
2926 GL_DEPTH_TEST,
2927 GL_POLYGON_OFFSET_FILL,
2928 GL_SAMPLE_ALPHA_TO_COVERAGE,
2929 GL_SAMPLE_COVERAGE,
2930 GL_SCISSOR_TEST,
2931 GL_STENCIL_TEST,
2933 struct Cmds {
2934 cmds::Enable enable_cmd;
2936 Cmds expected;
2938 for (size_t ii = 0; ii < arraysize(kStates); ++ii) {
2939 GLenum state = kStates[ii];
2940 expected.enable_cmd.Init(state);
2941 GLboolean result = gl_->IsEnabled(state);
2942 EXPECT_EQ(static_cast<GLboolean>(ii == 0), result);
2943 EXPECT_TRUE(NoCommandsWritten());
2944 const void* commands = GetPut();
2945 if (!result) {
2946 gl_->Enable(state);
2947 EXPECT_EQ(0, memcmp(&expected, commands, sizeof(expected)));
2949 ClearCommands();
2950 result = gl_->IsEnabled(state);
2951 EXPECT_TRUE(result);
2952 EXPECT_TRUE(NoCommandsWritten());
2956 TEST_F(GLES2ImplementationTest, BindVertexArrayOES) {
2957 GLuint id = 0;
2958 gl_->GenVertexArraysOES(1, &id);
2959 ClearCommands();
2961 struct Cmds {
2962 cmds::BindVertexArrayOES cmd;
2964 Cmds expected;
2965 expected.cmd.Init(id);
2967 const void* commands = GetPut();
2968 gl_->BindVertexArrayOES(id);
2969 EXPECT_EQ(0, memcmp(&expected, commands, sizeof(expected)));
2970 ClearCommands();
2971 gl_->BindVertexArrayOES(id);
2972 EXPECT_TRUE(NoCommandsWritten());
2975 TEST_F(GLES2ImplementationTest, BeginEndQueryEXT) {
2976 // Test GetQueryivEXT returns 0 if no current query.
2977 GLint param = -1;
2978 gl_->GetQueryivEXT(GL_ANY_SAMPLES_PASSED_EXT, GL_CURRENT_QUERY_EXT, &param);
2979 EXPECT_EQ(0, param);
2981 GLuint expected_ids[2] = { 1, 2 }; // These must match what's actually genned.
2982 struct GenCmds {
2983 cmds::GenQueriesEXTImmediate gen;
2984 GLuint data[2];
2986 GenCmds expected_gen_cmds;
2987 expected_gen_cmds.gen.Init(arraysize(expected_ids), &expected_ids[0]);
2988 GLuint ids[arraysize(expected_ids)] = { 0, };
2989 gl_->GenQueriesEXT(arraysize(expected_ids), &ids[0]);
2990 EXPECT_EQ(0, memcmp(
2991 &expected_gen_cmds, commands_, sizeof(expected_gen_cmds)));
2992 GLuint id1 = ids[0];
2993 GLuint id2 = ids[1];
2994 ClearCommands();
2996 // Test BeginQueryEXT fails if id = 0.
2997 gl_->BeginQueryEXT(GL_ANY_SAMPLES_PASSED_EXT, 0);
2998 EXPECT_TRUE(NoCommandsWritten());
2999 EXPECT_EQ(GL_INVALID_OPERATION, CheckError());
3001 // Test BeginQueryEXT inserts command.
3002 struct BeginCmds {
3003 cmds::BeginQueryEXT begin_query;
3005 BeginCmds expected_begin_cmds;
3006 const void* commands = GetPut();
3007 gl_->BeginQueryEXT(GL_ANY_SAMPLES_PASSED_EXT, id1);
3008 QueryTracker::Query* query = GetQuery(id1);
3009 ASSERT_TRUE(query != NULL);
3010 expected_begin_cmds.begin_query.Init(
3011 GL_ANY_SAMPLES_PASSED_EXT, id1, query->shm_id(), query->shm_offset());
3012 EXPECT_EQ(0, memcmp(
3013 &expected_begin_cmds, commands, sizeof(expected_begin_cmds)));
3014 ClearCommands();
3016 // Test GetQueryivEXT returns id.
3017 param = -1;
3018 gl_->GetQueryivEXT(GL_ANY_SAMPLES_PASSED_EXT, GL_CURRENT_QUERY_EXT, &param);
3019 EXPECT_EQ(id1, static_cast<GLuint>(param));
3020 gl_->GetQueryivEXT(
3021 GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT, GL_CURRENT_QUERY_EXT, &param);
3022 EXPECT_EQ(0, param);
3024 // Test BeginQueryEXT fails if between Begin/End.
3025 gl_->BeginQueryEXT(GL_ANY_SAMPLES_PASSED_EXT, id2);
3026 EXPECT_TRUE(NoCommandsWritten());
3027 EXPECT_EQ(GL_INVALID_OPERATION, CheckError());
3029 // Test EndQueryEXT fails if target not same as current query.
3030 ClearCommands();
3031 gl_->EndQueryEXT(GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT);
3032 EXPECT_TRUE(NoCommandsWritten());
3033 EXPECT_EQ(GL_INVALID_OPERATION, CheckError());
3035 // Test EndQueryEXT sends command
3036 struct EndCmds {
3037 cmds::EndQueryEXT end_query;
3039 EndCmds expected_end_cmds;
3040 expected_end_cmds.end_query.Init(
3041 GL_ANY_SAMPLES_PASSED_EXT, query->submit_count());
3042 commands = GetPut();
3043 gl_->EndQueryEXT(GL_ANY_SAMPLES_PASSED_EXT);
3044 EXPECT_EQ(0, memcmp(
3045 &expected_end_cmds, commands, sizeof(expected_end_cmds)));
3047 // Test EndQueryEXT fails if no current query.
3048 ClearCommands();
3049 gl_->EndQueryEXT(GL_ANY_SAMPLES_PASSED_EXT);
3050 EXPECT_TRUE(NoCommandsWritten());
3051 EXPECT_EQ(GL_INVALID_OPERATION, CheckError());
3053 // Test 2nd Begin/End increments count.
3054 base::subtle::Atomic32 old_submit_count = query->submit_count();
3055 gl_->BeginQueryEXT(GL_ANY_SAMPLES_PASSED_EXT, id1);
3056 EXPECT_NE(old_submit_count, query->submit_count());
3057 expected_end_cmds.end_query.Init(
3058 GL_ANY_SAMPLES_PASSED_EXT, query->submit_count());
3059 commands = GetPut();
3060 gl_->EndQueryEXT(GL_ANY_SAMPLES_PASSED_EXT);
3061 EXPECT_EQ(0, memcmp(
3062 &expected_end_cmds, commands, sizeof(expected_end_cmds)));
3064 // Test BeginQueryEXT fails if target changed.
3065 ClearCommands();
3066 gl_->BeginQueryEXT(GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT, id1);
3067 EXPECT_TRUE(NoCommandsWritten());
3068 EXPECT_EQ(GL_INVALID_OPERATION, CheckError());
3070 // Test GetQueryObjectuivEXT fails if unused id
3071 GLuint available = 0xBDu;
3072 ClearCommands();
3073 gl_->GetQueryObjectuivEXT(id2, GL_QUERY_RESULT_AVAILABLE_EXT, &available);
3074 EXPECT_TRUE(NoCommandsWritten());
3075 EXPECT_EQ(0xBDu, available);
3076 EXPECT_EQ(GL_INVALID_OPERATION, CheckError());
3078 // Test GetQueryObjectuivEXT fails if bad id
3079 ClearCommands();
3080 gl_->GetQueryObjectuivEXT(4567, GL_QUERY_RESULT_AVAILABLE_EXT, &available);
3081 EXPECT_TRUE(NoCommandsWritten());
3082 EXPECT_EQ(0xBDu, available);
3083 EXPECT_EQ(GL_INVALID_OPERATION, CheckError());
3085 // Test GetQueryObjectuivEXT CheckResultsAvailable
3086 ClearCommands();
3087 gl_->GetQueryObjectuivEXT(id1, GL_QUERY_RESULT_AVAILABLE_EXT, &available);
3088 EXPECT_EQ(0u, available);
3091 TEST_F(GLES2ImplementationTest, ErrorQuery) {
3092 GLuint id = 0;
3093 gl_->GenQueriesEXT(1, &id);
3094 ClearCommands();
3096 // Test BeginQueryEXT does NOT insert commands.
3097 gl_->BeginQueryEXT(GL_GET_ERROR_QUERY_CHROMIUM, id);
3098 EXPECT_TRUE(NoCommandsWritten());
3099 QueryTracker::Query* query = GetQuery(id);
3100 ASSERT_TRUE(query != NULL);
3102 // Test EndQueryEXT sends both begin and end command
3103 struct EndCmds {
3104 cmds::BeginQueryEXT begin_query;
3105 cmds::EndQueryEXT end_query;
3107 EndCmds expected_end_cmds;
3108 expected_end_cmds.begin_query.Init(
3109 GL_GET_ERROR_QUERY_CHROMIUM, id, query->shm_id(), query->shm_offset());
3110 expected_end_cmds.end_query.Init(
3111 GL_GET_ERROR_QUERY_CHROMIUM, query->submit_count());
3112 const void* commands = GetPut();
3113 gl_->EndQueryEXT(GL_GET_ERROR_QUERY_CHROMIUM);
3114 EXPECT_EQ(0, memcmp(
3115 &expected_end_cmds, commands, sizeof(expected_end_cmds)));
3116 ClearCommands();
3118 // Check result is not yet available.
3119 GLuint available = 0xBDu;
3120 gl_->GetQueryObjectuivEXT(id, GL_QUERY_RESULT_AVAILABLE_EXT, &available);
3121 EXPECT_TRUE(NoCommandsWritten());
3122 EXPECT_EQ(0u, available);
3124 // Test no commands are sent if there is a client side error.
3126 // Generate a client side error
3127 gl_->ActiveTexture(GL_TEXTURE0 - 1);
3129 gl_->BeginQueryEXT(GL_GET_ERROR_QUERY_CHROMIUM, id);
3130 gl_->EndQueryEXT(GL_GET_ERROR_QUERY_CHROMIUM);
3131 EXPECT_TRUE(NoCommandsWritten());
3133 // Check result is available.
3134 gl_->GetQueryObjectuivEXT(id, GL_QUERY_RESULT_AVAILABLE_EXT, &available);
3135 EXPECT_TRUE(NoCommandsWritten());
3136 EXPECT_NE(0u, available);
3138 // Check result.
3139 GLuint result = 0xBDu;
3140 gl_->GetQueryObjectuivEXT(id, GL_QUERY_RESULT_EXT, &result);
3141 EXPECT_TRUE(NoCommandsWritten());
3142 EXPECT_EQ(static_cast<GLuint>(GL_INVALID_ENUM), result);
3145 #if !defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS)
3146 TEST_F(GLES2ImplementationTest, VertexArrays) {
3147 const GLuint kAttribIndex1 = 1;
3148 const GLint kNumComponents1 = 3;
3149 const GLsizei kClientStride = 12;
3151 GLuint id = 0;
3152 gl_->GenVertexArraysOES(1, &id);
3153 ClearCommands();
3155 gl_->BindVertexArrayOES(id);
3157 // Test that VertexAttribPointer cannot be called with a bound buffer of 0
3158 // unless the offset is NULL
3159 gl_->BindBuffer(GL_ARRAY_BUFFER, 0);
3161 gl_->VertexAttribPointer(
3162 kAttribIndex1, kNumComponents1, GL_FLOAT, GL_FALSE, kClientStride,
3163 reinterpret_cast<const void*>(4));
3164 EXPECT_EQ(GL_INVALID_OPERATION, CheckError());
3166 gl_->VertexAttribPointer(
3167 kAttribIndex1, kNumComponents1, GL_FLOAT, GL_FALSE, kClientStride, NULL);
3168 EXPECT_EQ(GL_NO_ERROR, CheckError());
3170 #endif
3172 TEST_F(GLES2ImplementationTest, Disable) {
3173 struct Cmds {
3174 cmds::Disable cmd;
3176 Cmds expected;
3177 expected.cmd.Init(GL_DITHER); // Note: DITHER defaults to enabled.
3179 gl_->Disable(GL_DITHER);
3180 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
3181 // Check it's cached and not called again.
3182 ClearCommands();
3183 gl_->Disable(GL_DITHER);
3184 EXPECT_TRUE(NoCommandsWritten());
3187 TEST_F(GLES2ImplementationTest, Enable) {
3188 struct Cmds {
3189 cmds::Enable cmd;
3191 Cmds expected;
3192 expected.cmd.Init(GL_BLEND); // Note: BLEND defaults to disabled.
3194 gl_->Enable(GL_BLEND);
3195 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
3196 // Check it's cached and not called again.
3197 ClearCommands();
3198 gl_->Enable(GL_BLEND);
3199 EXPECT_TRUE(NoCommandsWritten());
3202 TEST_F(GLES2ImplementationTest, ConsumeTextureCHROMIUM) {
3203 struct Cmds {
3204 cmds::ConsumeTextureCHROMIUMImmediate cmd;
3205 GLbyte data[64];
3208 Mailbox mailbox = Mailbox::Generate();
3209 Cmds expected;
3210 expected.cmd.Init(GL_TEXTURE_2D, mailbox.name);
3211 gl_->ConsumeTextureCHROMIUM(GL_TEXTURE_2D, mailbox.name);
3212 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
3215 TEST_F(GLES2ImplementationTest, CreateAndConsumeTextureCHROMIUM) {
3216 struct Cmds {
3217 cmds::CreateAndConsumeTextureCHROMIUMImmediate cmd;
3218 GLbyte data[64];
3221 Mailbox mailbox = Mailbox::Generate();
3222 Cmds expected;
3223 expected.cmd.Init(GL_TEXTURE_2D, kTexturesStartId, mailbox.name);
3224 GLuint id = gl_->CreateAndConsumeTextureCHROMIUM(GL_TEXTURE_2D, mailbox.name);
3225 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
3226 EXPECT_EQ(kTexturesStartId, id);
3229 TEST_F(GLES2ImplementationTest, ProduceTextureCHROMIUM) {
3230 struct Cmds {
3231 cmds::ProduceTextureCHROMIUMImmediate cmd;
3232 GLbyte data[64];
3235 Mailbox mailbox = Mailbox::Generate();
3236 Cmds expected;
3237 expected.cmd.Init(GL_TEXTURE_2D, mailbox.name);
3238 gl_->ProduceTextureCHROMIUM(GL_TEXTURE_2D, mailbox.name);
3239 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
3242 TEST_F(GLES2ImplementationTest, ProduceTextureDirectCHROMIUM) {
3243 struct Cmds {
3244 cmds::ProduceTextureDirectCHROMIUMImmediate cmd;
3245 GLbyte data[64];
3248 Mailbox mailbox = Mailbox::Generate();
3249 Cmds expected;
3250 expected.cmd.Init(kTexturesStartId, GL_TEXTURE_2D, mailbox.name);
3251 gl_->ProduceTextureDirectCHROMIUM(
3252 kTexturesStartId, GL_TEXTURE_2D, mailbox.name);
3253 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
3256 TEST_F(GLES2ImplementationTest, LimitSizeAndOffsetTo32Bit) {
3257 GLsizeiptr size;
3258 GLintptr offset;
3259 if (sizeof(size) <= 4 || sizeof(offset) <= 4)
3260 return;
3261 // The below two casts should be no-op, as we return early if
3262 // it's 32-bit system.
3263 int64 value64 = 0x100000000;
3264 size = static_cast<GLsizeiptr>(value64);
3265 offset = static_cast<GLintptr>(value64);
3267 const char kSizeOverflowMessage[] = "size more than 32-bit";
3268 const char kOffsetOverflowMessage[] = "offset more than 32-bit";
3270 const GLfloat buf[] = { 1.0, 1.0, 1.0, 1.0 };
3271 const GLubyte indices[] = { 0 };
3273 const GLuint kClientArrayBufferId = 0x789;
3274 const GLuint kClientElementArrayBufferId = 0x790;
3275 gl_->BindBuffer(GL_ARRAY_BUFFER, kClientArrayBufferId);
3276 gl_->BindBuffer(GL_ELEMENT_ARRAY_BUFFER, kClientElementArrayBufferId);
3277 EXPECT_EQ(GL_NO_ERROR, CheckError());
3279 // Call BufferData() should succeed with legal paramaters.
3280 gl_->BufferData(GL_ARRAY_BUFFER, sizeof(buf), buf, GL_DYNAMIC_DRAW);
3281 gl_->BufferData(
3282 GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_DYNAMIC_DRAW);
3283 EXPECT_EQ(GL_NO_ERROR, CheckError());
3285 // BufferData: size
3286 gl_->BufferData(GL_ARRAY_BUFFER, size, buf, GL_DYNAMIC_DRAW);
3287 EXPECT_EQ(GL_INVALID_OPERATION, CheckError());
3288 EXPECT_STREQ(kSizeOverflowMessage, GetLastError().c_str());
3290 // Call BufferSubData() should succeed with legal paramaters.
3291 gl_->BufferSubData(GL_ARRAY_BUFFER, 0, sizeof(buf[0]), buf);
3292 EXPECT_EQ(GL_NO_ERROR, CheckError());
3294 // BufferSubData: offset
3295 gl_->BufferSubData(GL_ARRAY_BUFFER, offset, 1, buf);
3296 EXPECT_EQ(GL_INVALID_OPERATION, CheckError());
3297 EXPECT_STREQ(kOffsetOverflowMessage, GetLastError().c_str());
3299 // BufferSubData: size
3300 EXPECT_EQ(GL_NO_ERROR, CheckError());
3301 gl_->BufferSubData(GL_ARRAY_BUFFER, 0, size, buf);
3302 EXPECT_EQ(GL_INVALID_OPERATION, CheckError());
3303 EXPECT_STREQ(kSizeOverflowMessage, GetLastError().c_str());
3305 // Call MapBufferSubDataCHROMIUM() should succeed with legal paramaters.
3306 void* mem =
3307 gl_->MapBufferSubDataCHROMIUM(GL_ARRAY_BUFFER, 0, 1, GL_WRITE_ONLY);
3308 EXPECT_TRUE(NULL != mem);
3309 EXPECT_EQ(GL_NO_ERROR, CheckError());
3310 gl_->UnmapBufferSubDataCHROMIUM(mem);
3312 // MapBufferSubDataCHROMIUM: offset
3313 EXPECT_TRUE(NULL == gl_->MapBufferSubDataCHROMIUM(
3314 GL_ARRAY_BUFFER, offset, 1, GL_WRITE_ONLY));
3315 EXPECT_EQ(GL_INVALID_OPERATION, CheckError());
3316 EXPECT_STREQ(kOffsetOverflowMessage, GetLastError().c_str());
3318 // MapBufferSubDataCHROMIUM: size
3319 EXPECT_EQ(GL_NO_ERROR, CheckError());
3320 EXPECT_TRUE(NULL == gl_->MapBufferSubDataCHROMIUM(
3321 GL_ARRAY_BUFFER, 0, size, GL_WRITE_ONLY));
3322 EXPECT_EQ(GL_INVALID_OPERATION, CheckError());
3323 EXPECT_STREQ(kSizeOverflowMessage, GetLastError().c_str());
3325 // Call DrawElements() should succeed with legal paramaters.
3326 gl_->DrawElements(GL_POINTS, 1, GL_UNSIGNED_BYTE, NULL);
3327 EXPECT_EQ(GL_NO_ERROR, CheckError());
3329 // DrawElements: offset
3330 gl_->DrawElements(
3331 GL_POINTS, 1, GL_UNSIGNED_BYTE, reinterpret_cast<void*>(offset));
3332 EXPECT_EQ(GL_INVALID_OPERATION, CheckError());
3333 EXPECT_STREQ(kOffsetOverflowMessage, GetLastError().c_str());
3335 // Call DrawElementsInstancedANGLE() should succeed with legal paramaters.
3336 gl_->DrawElementsInstancedANGLE(GL_POINTS, 1, GL_UNSIGNED_BYTE, NULL, 1);
3337 EXPECT_EQ(GL_NO_ERROR, CheckError());
3339 // DrawElementsInstancedANGLE: offset
3340 gl_->DrawElementsInstancedANGLE(
3341 GL_POINTS, 1, GL_UNSIGNED_BYTE, reinterpret_cast<void*>(offset), 1);
3342 EXPECT_EQ(GL_INVALID_OPERATION, CheckError());
3343 EXPECT_STREQ(kOffsetOverflowMessage, GetLastError().c_str());
3345 // Call VertexAttribPointer() should succeed with legal paramaters.
3346 const GLuint kAttribIndex = 1;
3347 const GLsizei kStride = 4;
3348 gl_->VertexAttribPointer(
3349 kAttribIndex, 1, GL_FLOAT, GL_FALSE, kStride, NULL);
3350 EXPECT_EQ(GL_NO_ERROR, CheckError());
3352 // VertexAttribPointer: offset
3353 gl_->VertexAttribPointer(
3354 kAttribIndex, 1, GL_FLOAT, GL_FALSE, kStride,
3355 reinterpret_cast<void*>(offset));
3356 EXPECT_EQ(GL_INVALID_OPERATION, CheckError());
3357 EXPECT_STREQ(kOffsetOverflowMessage, GetLastError().c_str());
3360 TEST_F(GLES2ImplementationManualInitTest, LoseContextOnOOM) {
3361 ContextInitOptions init_options;
3362 init_options.lose_context_when_out_of_memory = true;
3363 ASSERT_TRUE(Initialize(init_options));
3365 struct Cmds {
3366 cmds::LoseContextCHROMIUM cmd;
3369 GLsizei max = std::numeric_limits<GLsizei>::max();
3370 EXPECT_CALL(*gpu_control_, CreateGpuMemoryBufferImage(max, max, _, _))
3371 .WillOnce(Return(-1));
3372 gl_->CreateGpuMemoryBufferImageCHROMIUM(max, max, GL_RGBA, GL_MAP_CHROMIUM);
3373 // The context should be lost.
3374 Cmds expected;
3375 expected.cmd.Init(GL_GUILTY_CONTEXT_RESET_ARB, GL_UNKNOWN_CONTEXT_RESET_ARB);
3376 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
3379 TEST_F(GLES2ImplementationManualInitTest, NoLoseContextOnOOM) {
3380 ContextInitOptions init_options;
3381 ASSERT_TRUE(Initialize(init_options));
3383 struct Cmds {
3384 cmds::LoseContextCHROMIUM cmd;
3387 GLsizei max = std::numeric_limits<GLsizei>::max();
3388 EXPECT_CALL(*gpu_control_, CreateGpuMemoryBufferImage(max, max, _, _))
3389 .WillOnce(Return(-1));
3390 gl_->CreateGpuMemoryBufferImageCHROMIUM(max, max, GL_RGBA, GL_MAP_CHROMIUM);
3391 // The context should not be lost.
3392 EXPECT_TRUE(NoCommandsWritten());
3395 TEST_F(GLES2ImplementationManualInitTest, FailInitOnBGRMismatch1) {
3396 ContextInitOptions init_options;
3397 init_options.bind_generates_resource_client = false;
3398 init_options.bind_generates_resource_service = true;
3399 EXPECT_FALSE(Initialize(init_options));
3402 TEST_F(GLES2ImplementationManualInitTest, FailInitOnBGRMismatch2) {
3403 ContextInitOptions init_options;
3404 init_options.bind_generates_resource_client = true;
3405 init_options.bind_generates_resource_service = false;
3406 EXPECT_FALSE(Initialize(init_options));
3409 #include "gpu/command_buffer/client/gles2_implementation_unittest_autogen.h"
3411 } // namespace gles2
3412 } // namespace gpu