Revert of Merge duplicate code in invalidation helper. (patchset #2 id:40001 of https...
[chromium-blink-merge.git] / gpu / command_buffer / client / gles2_implementation_unittest.cc
blobb560ec058b7d460eb2150d37a8cdeb4505700790
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 // Tests for GLES2Implementation.
7 #include "gpu/command_buffer/client/gles2_implementation.h"
9 #include <GLES2/gl2.h>
10 #include <GLES2/gl2ext.h>
11 #include <GLES2/gl2extchromium.h>
12 #include <GLES3/gl3.h>
13 #include "base/compiler_specific.h"
14 #include "gpu/command_buffer/client/client_test_helper.h"
15 #include "gpu/command_buffer/client/gles2_cmd_helper.h"
16 #include "gpu/command_buffer/client/program_info_manager.h"
17 #include "gpu/command_buffer/client/query_tracker.h"
18 #include "gpu/command_buffer/client/ring_buffer.h"
19 #include "gpu/command_buffer/client/transfer_buffer.h"
20 #include "gpu/command_buffer/common/command_buffer.h"
21 #include "testing/gtest/include/gtest/gtest.h"
22 #include "testing/gmock/include/gmock/gmock.h"
24 #if !defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS)
25 #define GLES2_SUPPORT_CLIENT_SIDE_ARRAYS
26 #endif
28 using testing::_;
29 using testing::AtLeast;
30 using testing::AnyNumber;
31 using testing::DoAll;
32 using testing::InSequence;
33 using testing::Invoke;
34 using testing::Mock;
35 using testing::Sequence;
36 using testing::StrictMock;
37 using testing::Truly;
38 using testing::Return;
40 namespace gpu {
41 namespace gles2 {
43 ACTION_P2(SetMemory, dst, obj) {
44 memcpy(dst, &obj, sizeof(obj));
47 ACTION_P3(SetMemoryFromArray, dst, array, size) {
48 memcpy(dst, array, size);
51 // Used to help set the transfer buffer result to SizedResult of a single value.
52 template <typename T>
53 class SizedResultHelper {
54 public:
55 explicit SizedResultHelper(T result)
56 : size_(sizeof(result)) {
57 memcpy(result_, &result, sizeof(T));
60 private:
61 uint32 size_;
62 char result_[sizeof(T)];
65 // Struct to make it easy to pass a vec4 worth of floats.
66 struct FourFloats {
67 FourFloats(float _x, float _y, float _z, float _w)
68 : x(_x),
69 y(_y),
70 z(_z),
71 w(_w) {
74 float x;
75 float y;
76 float z;
77 float w;
80 #pragma pack(push, 1)
81 // Struct that holds 7 characters.
82 struct Str7 {
83 char str[7];
85 #pragma pack(pop)
87 class MockTransferBuffer : public TransferBufferInterface {
88 public:
89 struct ExpectedMemoryInfo {
90 uint32 offset;
91 int32 id;
92 uint8* ptr;
95 MockTransferBuffer(
96 CommandBuffer* command_buffer,
97 unsigned int size,
98 unsigned int result_size,
99 unsigned int alignment,
100 bool initialize_fail)
101 : command_buffer_(command_buffer),
102 size_(size),
103 result_size_(result_size),
104 alignment_(alignment),
105 actual_buffer_index_(0),
106 expected_buffer_index_(0),
107 last_alloc_(NULL),
108 expected_offset_(result_size),
109 actual_offset_(result_size),
110 initialize_fail_(initialize_fail) {
111 // We have to allocate the buffers here because
112 // we need to know their address before GLES2Implementation::Initialize
113 // is called.
114 for (int ii = 0; ii < kNumBuffers; ++ii) {
115 buffers_[ii] = command_buffer_->CreateTransferBuffer(
116 size_ + ii * alignment_,
117 &buffer_ids_[ii]);
118 EXPECT_NE(-1, buffer_ids_[ii]);
122 ~MockTransferBuffer() override {}
124 bool Initialize(unsigned int starting_buffer_size,
125 unsigned int result_size,
126 unsigned int /* min_buffer_size */,
127 unsigned int /* max_buffer_size */,
128 unsigned int alignment,
129 unsigned int size_to_flush) override;
130 int GetShmId() override;
131 void* GetResultBuffer() override;
132 int GetResultOffset() override;
133 void Free() override;
134 bool HaveBuffer() const override;
135 void* AllocUpTo(unsigned int size, unsigned int* size_allocated) override;
136 void* Alloc(unsigned int size) override;
137 RingBuffer::Offset GetOffset(void* pointer) const override;
138 void DiscardBlock(void* p) override;
139 void FreePendingToken(void* p, unsigned int /* token */) override;
140 unsigned int GetSize() const override;
141 unsigned int GetFreeSize() const override;
143 size_t MaxTransferBufferSize() {
144 return size_ - result_size_;
147 unsigned int RoundToAlignment(unsigned int size) {
148 return (size + alignment_ - 1) & ~(alignment_ - 1);
151 bool InSync() {
152 return expected_buffer_index_ == actual_buffer_index_ &&
153 expected_offset_ == actual_offset_;
156 ExpectedMemoryInfo GetExpectedMemory(size_t size) {
157 ExpectedMemoryInfo mem;
158 mem.offset = AllocateExpectedTransferBuffer(size);
159 mem.id = GetExpectedTransferBufferId();
160 mem.ptr = static_cast<uint8*>(
161 GetExpectedTransferAddressFromOffset(mem.offset, size));
162 return mem;
165 ExpectedMemoryInfo GetExpectedResultMemory(size_t size) {
166 ExpectedMemoryInfo mem;
167 mem.offset = GetExpectedResultBufferOffset();
168 mem.id = GetExpectedResultBufferId();
169 mem.ptr = static_cast<uint8*>(
170 GetExpectedTransferAddressFromOffset(mem.offset, size));
171 return mem;
174 private:
175 static const int kNumBuffers = 2;
177 uint8* actual_buffer() const {
178 return static_cast<uint8*>(buffers_[actual_buffer_index_]->memory());
181 uint8* expected_buffer() const {
182 return static_cast<uint8*>(buffers_[expected_buffer_index_]->memory());
185 uint32 AllocateExpectedTransferBuffer(size_t size) {
186 EXPECT_LE(size, MaxTransferBufferSize());
188 // Toggle which buffer we get each time to simulate the buffer being
189 // reallocated.
190 expected_buffer_index_ = (expected_buffer_index_ + 1) % kNumBuffers;
192 if (expected_offset_ + size > size_) {
193 expected_offset_ = result_size_;
195 uint32 offset = expected_offset_;
196 expected_offset_ += RoundToAlignment(size);
198 // Make sure each buffer has a different offset.
199 return offset + expected_buffer_index_ * alignment_;
202 void* GetExpectedTransferAddressFromOffset(uint32 offset, size_t size) {
203 EXPECT_GE(offset, expected_buffer_index_ * alignment_);
204 EXPECT_LE(offset + size, size_ + expected_buffer_index_ * alignment_);
205 return expected_buffer() + offset;
208 int GetExpectedResultBufferId() {
209 return buffer_ids_[expected_buffer_index_];
212 uint32 GetExpectedResultBufferOffset() {
213 return expected_buffer_index_ * alignment_;
216 int GetExpectedTransferBufferId() {
217 return buffer_ids_[expected_buffer_index_];
220 CommandBuffer* command_buffer_;
221 size_t size_;
222 size_t result_size_;
223 uint32 alignment_;
224 int buffer_ids_[kNumBuffers];
225 scoped_refptr<Buffer> buffers_[kNumBuffers];
226 int actual_buffer_index_;
227 int expected_buffer_index_;
228 void* last_alloc_;
229 uint32 expected_offset_;
230 uint32 actual_offset_;
231 bool initialize_fail_;
233 DISALLOW_COPY_AND_ASSIGN(MockTransferBuffer);
236 bool MockTransferBuffer::Initialize(
237 unsigned int starting_buffer_size,
238 unsigned int result_size,
239 unsigned int /* min_buffer_size */,
240 unsigned int /* max_buffer_size */,
241 unsigned int alignment,
242 unsigned int /* size_to_flush */) {
243 // Just check they match.
244 return size_ == starting_buffer_size &&
245 result_size_ == result_size &&
246 alignment_ == alignment && !initialize_fail_;
249 int MockTransferBuffer::GetShmId() {
250 return buffer_ids_[actual_buffer_index_];
253 void* MockTransferBuffer::GetResultBuffer() {
254 return actual_buffer() + actual_buffer_index_ * alignment_;
257 int MockTransferBuffer::GetResultOffset() {
258 return actual_buffer_index_ * alignment_;
261 void MockTransferBuffer::Free() {
262 NOTREACHED();
265 bool MockTransferBuffer::HaveBuffer() const {
266 return true;
269 void* MockTransferBuffer::AllocUpTo(
270 unsigned int size, unsigned int* size_allocated) {
271 EXPECT_TRUE(size_allocated != NULL);
272 EXPECT_TRUE(last_alloc_ == NULL);
274 // Toggle which buffer we get each time to simulate the buffer being
275 // reallocated.
276 actual_buffer_index_ = (actual_buffer_index_ + 1) % kNumBuffers;
278 size = std::min(static_cast<size_t>(size), MaxTransferBufferSize());
279 if (actual_offset_ + size > size_) {
280 actual_offset_ = result_size_;
282 uint32 offset = actual_offset_;
283 actual_offset_ += RoundToAlignment(size);
284 *size_allocated = size;
286 // Make sure each buffer has a different offset.
287 last_alloc_ = actual_buffer() + offset + actual_buffer_index_ * alignment_;
288 return last_alloc_;
291 void* MockTransferBuffer::Alloc(unsigned int size) {
292 EXPECT_LE(size, MaxTransferBufferSize());
293 unsigned int temp = 0;
294 void* p = AllocUpTo(size, &temp);
295 EXPECT_EQ(temp, size);
296 return p;
299 RingBuffer::Offset MockTransferBuffer::GetOffset(void* pointer) const {
300 // Make sure each buffer has a different offset.
301 return static_cast<uint8*>(pointer) - actual_buffer();
304 void MockTransferBuffer::DiscardBlock(void* p) {
305 EXPECT_EQ(last_alloc_, p);
306 last_alloc_ = NULL;
309 void MockTransferBuffer::FreePendingToken(void* p, unsigned int /* token */) {
310 EXPECT_EQ(last_alloc_, p);
311 last_alloc_ = NULL;
314 unsigned int MockTransferBuffer::GetSize() const {
315 return 0;
318 unsigned int MockTransferBuffer::GetFreeSize() const {
319 return 0;
322 // API wrapper for Buffers.
323 class GenBuffersAPI {
324 public:
325 static void Gen(GLES2Implementation* gl_impl, GLsizei n, GLuint* ids) {
326 gl_impl->GenBuffers(n, ids);
329 static void Delete(GLES2Implementation* gl_impl,
330 GLsizei n,
331 const GLuint* ids) {
332 gl_impl->DeleteBuffers(n, ids);
336 // API wrapper for Framebuffers.
337 class GenFramebuffersAPI {
338 public:
339 static void Gen(GLES2Implementation* gl_impl, GLsizei n, GLuint* ids) {
340 gl_impl->GenFramebuffers(n, ids);
343 static void Delete(GLES2Implementation* gl_impl,
344 GLsizei n,
345 const GLuint* ids) {
346 gl_impl->DeleteFramebuffers(n, ids);
350 // API wrapper for Renderbuffers.
351 class GenRenderbuffersAPI {
352 public:
353 static void Gen(GLES2Implementation* gl_impl, GLsizei n, GLuint* ids) {
354 gl_impl->GenRenderbuffers(n, ids);
357 static void Delete(GLES2Implementation* gl_impl,
358 GLsizei n,
359 const GLuint* ids) {
360 gl_impl->DeleteRenderbuffers(n, ids);
364 // API wrapper for Textures.
365 class GenTexturesAPI {
366 public:
367 static void Gen(GLES2Implementation* gl_impl, GLsizei n, GLuint* ids) {
368 gl_impl->GenTextures(n, ids);
371 static void Delete(GLES2Implementation* gl_impl,
372 GLsizei n,
373 const GLuint* ids) {
374 gl_impl->DeleteTextures(n, ids);
378 class GLES2ImplementationTest : public testing::Test {
379 protected:
380 static const int kNumTestContexts = 2;
381 static const uint8 kInitialValue = 0xBD;
382 static const int32 kNumCommandEntries = 500;
383 static const int32 kCommandBufferSizeBytes =
384 kNumCommandEntries * sizeof(CommandBufferEntry);
385 static const size_t kTransferBufferSize = 512;
387 static const GLint kMaxCombinedTextureImageUnits = 8;
388 static const GLint kMaxCubeMapTextureSize = 64;
389 static const GLint kMaxFragmentUniformVectors = 16;
390 static const GLint kMaxRenderbufferSize = 64;
391 static const GLint kMaxTextureImageUnits = 8;
392 static const GLint kMaxTextureSize = 128;
393 static const GLint kMaxVaryingVectors = 8;
394 static const GLint kMaxVertexAttribs = 8;
395 static const GLint kMaxVertexTextureImageUnits = 0;
396 static const GLint kMaxVertexUniformVectors = 128;
397 static const GLint kNumCompressedTextureFormats = 0;
398 static const GLint kNumShaderBinaryFormats = 0;
399 static const GLuint kMaxTransformFeedbackSeparateAttribs = 4;
400 static const GLuint kMaxUniformBufferBindings = 36;
401 static const GLuint kStartId = 1024;
402 static const GLuint kBuffersStartId = 1;
403 static const GLuint kFramebuffersStartId = 1;
404 static const GLuint kProgramsAndShadersStartId = 1;
405 static const GLuint kRenderbuffersStartId = 1;
406 static const GLuint kSamplersStartId = 1;
407 static const GLuint kTexturesStartId = 1;
408 static const GLuint kTransformFeedbacksStartId = 1;
409 static const GLuint kQueriesStartId = 1;
410 static const GLuint kVertexArraysStartId = 1;
411 static const GLuint kValuebuffersStartId = 1;
413 typedef MockTransferBuffer::ExpectedMemoryInfo ExpectedMemoryInfo;
415 class TestContext {
416 public:
417 TestContext() : commands_(NULL), token_(0) {}
419 bool Initialize(ShareGroup* share_group,
420 bool bind_generates_resource_client,
421 bool bind_generates_resource_service,
422 bool lose_context_when_out_of_memory,
423 bool transfer_buffer_initialize_fail,
424 bool sync_query,
425 bool occlusion_query_boolean,
426 bool timer_queries) {
427 command_buffer_.reset(new StrictMock<MockClientCommandBuffer>());
428 if (!command_buffer_->Initialize())
429 return false;
431 transfer_buffer_.reset(
432 new MockTransferBuffer(command_buffer_.get(),
433 kTransferBufferSize,
434 GLES2Implementation::kStartingOffset,
435 GLES2Implementation::kAlignment,
436 transfer_buffer_initialize_fail));
438 helper_.reset(new GLES2CmdHelper(command_buffer()));
439 helper_->Initialize(kCommandBufferSizeBytes);
441 gpu_control_.reset(new StrictMock<MockClientGpuControl>());
442 Capabilities capabilities;
443 capabilities.VisitPrecisions(
444 [](GLenum shader, GLenum type,
445 Capabilities::ShaderPrecision* precision) {
446 precision->min_range = 3;
447 precision->max_range = 5;
448 precision->precision = 7;
450 capabilities.max_combined_texture_image_units =
451 kMaxCombinedTextureImageUnits;
452 capabilities.max_cube_map_texture_size = kMaxCubeMapTextureSize;
453 capabilities.max_fragment_uniform_vectors = kMaxFragmentUniformVectors;
454 capabilities.max_renderbuffer_size = kMaxRenderbufferSize;
455 capabilities.max_texture_image_units = kMaxTextureImageUnits;
456 capabilities.max_texture_size = kMaxTextureSize;
457 capabilities.max_varying_vectors = kMaxVaryingVectors;
458 capabilities.max_vertex_attribs = kMaxVertexAttribs;
459 capabilities.max_vertex_texture_image_units = kMaxVertexTextureImageUnits;
460 capabilities.max_vertex_uniform_vectors = kMaxVertexUniformVectors;
461 capabilities.num_compressed_texture_formats =
462 kNumCompressedTextureFormats;
463 capabilities.num_shader_binary_formats = kNumShaderBinaryFormats;
464 capabilities.max_transform_feedback_separate_attribs =
465 kMaxTransformFeedbackSeparateAttribs;
466 capabilities.max_uniform_buffer_bindings = kMaxUniformBufferBindings;
467 capabilities.bind_generates_resource_chromium =
468 bind_generates_resource_service ? 1 : 0;
469 capabilities.sync_query = sync_query;
470 capabilities.occlusion_query_boolean = occlusion_query_boolean;
471 capabilities.timer_queries = timer_queries;
472 EXPECT_CALL(*gpu_control_, GetCapabilities())
473 .WillOnce(testing::Return(capabilities));
476 InSequence sequence;
478 const bool support_client_side_arrays = true;
479 gl_.reset(new GLES2Implementation(helper_.get(),
480 share_group,
481 transfer_buffer_.get(),
482 bind_generates_resource_client,
483 lose_context_when_out_of_memory,
484 support_client_side_arrays,
485 gpu_control_.get()));
487 if (!gl_->Initialize(kTransferBufferSize,
488 kTransferBufferSize,
489 kTransferBufferSize,
490 GLES2Implementation::kNoLimit))
491 return false;
494 helper_->CommandBufferHelper::Finish();
495 ::testing::Mock::VerifyAndClearExpectations(gl_.get());
497 scoped_refptr<Buffer> ring_buffer = helper_->get_ring_buffer();
498 commands_ = static_cast<CommandBufferEntry*>(ring_buffer->memory()) +
499 command_buffer()->GetPutOffset();
500 ClearCommands();
501 EXPECT_TRUE(transfer_buffer_->InSync());
503 ::testing::Mock::VerifyAndClearExpectations(command_buffer());
504 return true;
507 void TearDown() {
508 Mock::VerifyAndClear(gl_.get());
509 EXPECT_CALL(*command_buffer(), OnFlush()).Times(AnyNumber());
510 // For command buffer.
511 EXPECT_CALL(*command_buffer(), DestroyTransferBuffer(_))
512 .Times(AtLeast(1));
513 gl_.reset();
516 MockClientCommandBuffer* command_buffer() const {
517 return command_buffer_.get();
520 int GetNextToken() { return ++token_; }
522 void ClearCommands() {
523 scoped_refptr<Buffer> ring_buffer = helper_->get_ring_buffer();
524 memset(ring_buffer->memory(), kInitialValue, ring_buffer->size());
527 scoped_ptr<MockClientCommandBuffer> command_buffer_;
528 scoped_ptr<MockClientGpuControl> gpu_control_;
529 scoped_ptr<GLES2CmdHelper> helper_;
530 scoped_ptr<MockTransferBuffer> transfer_buffer_;
531 scoped_ptr<GLES2Implementation> gl_;
532 CommandBufferEntry* commands_;
533 int token_;
536 GLES2ImplementationTest() : commands_(NULL) {}
538 void SetUp() override;
539 void TearDown() override;
541 bool NoCommandsWritten() {
542 scoped_refptr<Buffer> ring_buffer = helper_->get_ring_buffer();
543 const uint8* cmds = reinterpret_cast<const uint8*>(ring_buffer->memory());
544 const uint8* end = cmds + ring_buffer->size();
545 for (; cmds < end; ++cmds) {
546 if (*cmds != kInitialValue) {
547 return false;
550 return true;
553 QueryTracker::Query* GetQuery(GLuint id) {
554 return gl_->query_tracker_->GetQuery(id);
557 QueryTracker* GetQueryTracker() {
558 return gl_->query_tracker_.get();
561 struct ContextInitOptions {
562 ContextInitOptions()
563 : bind_generates_resource_client(true),
564 bind_generates_resource_service(true),
565 lose_context_when_out_of_memory(false),
566 transfer_buffer_initialize_fail(false),
567 sync_query(true),
568 occlusion_query_boolean(true),
569 timer_queries(true) {}
571 bool bind_generates_resource_client;
572 bool bind_generates_resource_service;
573 bool lose_context_when_out_of_memory;
574 bool transfer_buffer_initialize_fail;
575 bool sync_query;
576 bool occlusion_query_boolean;
577 bool timer_queries;
580 bool Initialize(const ContextInitOptions& init_options) {
581 bool success = true;
582 share_group_ = new ShareGroup(init_options.bind_generates_resource_client);
584 for (int i = 0; i < kNumTestContexts; i++) {
585 if (!test_contexts_[i].Initialize(
586 share_group_.get(),
587 init_options.bind_generates_resource_client,
588 init_options.bind_generates_resource_service,
589 init_options.lose_context_when_out_of_memory,
590 init_options.transfer_buffer_initialize_fail,
591 init_options.sync_query,
592 init_options.occlusion_query_boolean,
593 init_options.timer_queries))
594 success = false;
597 // Default to test context 0.
598 gpu_control_ = test_contexts_[0].gpu_control_.get();
599 helper_ = test_contexts_[0].helper_.get();
600 transfer_buffer_ = test_contexts_[0].transfer_buffer_.get();
601 gl_ = test_contexts_[0].gl_.get();
602 commands_ = test_contexts_[0].commands_;
603 return success;
606 MockClientCommandBuffer* command_buffer() const {
607 return test_contexts_[0].command_buffer_.get();
610 int GetNextToken() { return test_contexts_[0].GetNextToken(); }
612 const void* GetPut() {
613 return helper_->GetSpace(0);
616 void ClearCommands() {
617 scoped_refptr<Buffer> ring_buffer = helper_->get_ring_buffer();
618 memset(ring_buffer->memory(), kInitialValue, ring_buffer->size());
621 size_t MaxTransferBufferSize() {
622 return transfer_buffer_->MaxTransferBufferSize();
625 void SetMappedMemoryLimit(size_t limit) {
626 gl_->mapped_memory_->set_max_allocated_bytes(limit);
629 ExpectedMemoryInfo GetExpectedMemory(size_t size) {
630 return transfer_buffer_->GetExpectedMemory(size);
633 ExpectedMemoryInfo GetExpectedResultMemory(size_t size) {
634 return transfer_buffer_->GetExpectedResultMemory(size);
637 ExpectedMemoryInfo GetExpectedMappedMemory(size_t size) {
638 ExpectedMemoryInfo mem;
640 // Temporarily allocate memory and expect that memory block to be reused.
641 mem.ptr = static_cast<uint8*>(gl_->mapped_memory_->Alloc(size,
642 &mem.id,
643 &mem.offset));
644 gl_->mapped_memory_->Free(mem.ptr);
646 return mem;
649 // Sets the ProgramInfoManager. The manager will be owned
650 // by the ShareGroup.
651 void SetProgramInfoManager(ProgramInfoManager* manager) {
652 gl_->share_group()->set_program_info_manager(manager);
655 int CheckError() {
656 ExpectedMemoryInfo result =
657 GetExpectedResultMemory(sizeof(cmds::GetError::Result));
658 EXPECT_CALL(*command_buffer(), OnFlush())
659 .WillOnce(SetMemory(result.ptr, GLuint(GL_NO_ERROR)))
660 .RetiresOnSaturation();
661 return gl_->GetError();
664 const std::string& GetLastError() {
665 return gl_->GetLastError();
668 bool GetBucketContents(uint32 bucket_id, std::vector<int8>* data) {
669 return gl_->GetBucketContents(bucket_id, data);
672 TestContext test_contexts_[kNumTestContexts];
674 scoped_refptr<ShareGroup> share_group_;
675 MockClientGpuControl* gpu_control_;
676 GLES2CmdHelper* helper_;
677 MockTransferBuffer* transfer_buffer_;
678 GLES2Implementation* gl_;
679 CommandBufferEntry* commands_;
682 void GLES2ImplementationTest::SetUp() {
683 ContextInitOptions init_options;
684 ASSERT_TRUE(Initialize(init_options));
687 void GLES2ImplementationTest::TearDown() {
688 for (int i = 0; i < kNumTestContexts; i++)
689 test_contexts_[i].TearDown();
692 class GLES2ImplementationManualInitTest : public GLES2ImplementationTest {
693 protected:
694 void SetUp() override {}
697 class GLES2ImplementationStrictSharedTest : public GLES2ImplementationTest {
698 protected:
699 void SetUp() override;
701 template <class ResApi>
702 void FlushGenerationTest() {
703 GLuint id1, id2, id3;
705 // Generate valid id.
706 ResApi::Gen(gl_, 1, &id1);
707 EXPECT_NE(id1, 0u);
709 // Delete id1 and generate id2. id1 should not be reused.
710 ResApi::Delete(gl_, 1, &id1);
711 ResApi::Gen(gl_, 1, &id2);
712 EXPECT_NE(id2, 0u);
713 EXPECT_NE(id2, id1);
715 // Expect id1 reuse after Flush.
716 gl_->Flush();
717 ResApi::Gen(gl_, 1, &id3);
718 EXPECT_EQ(id3, id1);
721 // Ids should not be reused unless the |Deleting| context does a Flush()
722 // AND triggers a lazy release after that.
723 template <class ResApi>
724 void CrossContextGenerationTest() {
725 GLES2Implementation* gl1 = test_contexts_[0].gl_.get();
726 GLES2Implementation* gl2 = test_contexts_[1].gl_.get();
727 GLuint id1, id2, id3;
729 // Delete, no flush on context 1. No reuse.
730 ResApi::Gen(gl1, 1, &id1);
731 ResApi::Delete(gl1, 1, &id1);
732 ResApi::Gen(gl1, 1, &id2);
733 EXPECT_NE(id1, id2);
735 // Flush context 2. Still no reuse.
736 gl2->Flush();
737 ResApi::Gen(gl2, 1, &id3);
738 EXPECT_NE(id1, id3);
739 EXPECT_NE(id2, id3);
741 // Flush on context 1, but no lazy release. Still no reuse.
742 gl1->Flush();
743 ResApi::Gen(gl2, 1, &id3);
744 EXPECT_NE(id1, id3);
746 // Lazy release triggered by another Delete. Should reuse id1.
747 ResApi::Delete(gl1, 1, &id2);
748 ResApi::Gen(gl2, 1, &id3);
749 EXPECT_EQ(id1, id3);
752 // Same as CrossContextGenerationTest(), but triggers an Auto Flush on
753 // the Delete(). Tests an edge case regression.
754 template <class ResApi>
755 void CrossContextGenerationAutoFlushTest() {
756 GLES2Implementation* gl1 = test_contexts_[0].gl_.get();
757 GLES2Implementation* gl2 = test_contexts_[1].gl_.get();
758 GLuint id1, id2, id3;
760 // Delete, no flush on context 1. No reuse.
761 // By half filling the buffer, an internal flush is forced on the Delete().
762 ResApi::Gen(gl1, 1, &id1);
763 gl1->helper()->Noop(kNumCommandEntries / 2);
764 ResApi::Delete(gl1, 1, &id1);
765 ResApi::Gen(gl1, 1, &id2);
766 EXPECT_NE(id1, id2);
768 // Flush context 2. Still no reuse.
769 gl2->Flush();
770 ResApi::Gen(gl2, 1, &id3);
771 EXPECT_NE(id1, id3);
772 EXPECT_NE(id2, id3);
774 // Flush on context 1, but no lazy release. Still no reuse.
775 gl1->Flush();
776 ResApi::Gen(gl2, 1, &id3);
777 EXPECT_NE(id1, id3);
779 // Lazy release triggered by another Delete. Should reuse id1.
780 ResApi::Delete(gl1, 1, &id2);
781 ResApi::Gen(gl2, 1, &id3);
782 EXPECT_EQ(id1, id3);
786 void GLES2ImplementationStrictSharedTest::SetUp() {
787 ContextInitOptions init_options;
788 init_options.bind_generates_resource_client = false;
789 init_options.bind_generates_resource_service = false;
790 ASSERT_TRUE(Initialize(init_options));
793 // GCC requires these declarations, but MSVC requires they not be present
794 #ifndef _MSC_VER
795 const uint8 GLES2ImplementationTest::kInitialValue;
796 const int32 GLES2ImplementationTest::kNumCommandEntries;
797 const int32 GLES2ImplementationTest::kCommandBufferSizeBytes;
798 const size_t GLES2ImplementationTest::kTransferBufferSize;
799 const GLint GLES2ImplementationTest::kMaxCombinedTextureImageUnits;
800 const GLint GLES2ImplementationTest::kMaxCubeMapTextureSize;
801 const GLint GLES2ImplementationTest::kMaxFragmentUniformVectors;
802 const GLint GLES2ImplementationTest::kMaxRenderbufferSize;
803 const GLint GLES2ImplementationTest::kMaxTextureImageUnits;
804 const GLint GLES2ImplementationTest::kMaxTextureSize;
805 const GLint GLES2ImplementationTest::kMaxVaryingVectors;
806 const GLint GLES2ImplementationTest::kMaxVertexAttribs;
807 const GLint GLES2ImplementationTest::kMaxVertexTextureImageUnits;
808 const GLint GLES2ImplementationTest::kMaxVertexUniformVectors;
809 const GLint GLES2ImplementationTest::kNumCompressedTextureFormats;
810 const GLint GLES2ImplementationTest::kNumShaderBinaryFormats;
811 const GLuint GLES2ImplementationTest::kStartId;
812 const GLuint GLES2ImplementationTest::kBuffersStartId;
813 const GLuint GLES2ImplementationTest::kFramebuffersStartId;
814 const GLuint GLES2ImplementationTest::kProgramsAndShadersStartId;
815 const GLuint GLES2ImplementationTest::kRenderbuffersStartId;
816 const GLuint GLES2ImplementationTest::kSamplersStartId;
817 const GLuint GLES2ImplementationTest::kTexturesStartId;
818 const GLuint GLES2ImplementationTest::kTransformFeedbacksStartId;
819 const GLuint GLES2ImplementationTest::kQueriesStartId;
820 const GLuint GLES2ImplementationTest::kVertexArraysStartId;
821 const GLuint GLES2ImplementationTest::kValuebuffersStartId;
822 #endif
824 TEST_F(GLES2ImplementationTest, Basic) {
825 EXPECT_TRUE(gl_->share_group() != NULL);
828 TEST_F(GLES2ImplementationTest, GetBucketContents) {
829 const uint32 kBucketId = GLES2Implementation::kResultBucketId;
830 const uint32 kTestSize = MaxTransferBufferSize() + 32;
832 scoped_ptr<uint8[]> buf(new uint8 [kTestSize]);
833 uint8* expected_data = buf.get();
834 for (uint32 ii = 0; ii < kTestSize; ++ii) {
835 expected_data[ii] = ii * 3;
838 struct Cmds {
839 cmd::GetBucketStart get_bucket_start;
840 cmd::SetToken set_token1;
841 cmd::GetBucketData get_bucket_data;
842 cmd::SetToken set_token2;
843 cmd::SetBucketSize set_bucket_size2;
846 ExpectedMemoryInfo mem1 = GetExpectedMemory(MaxTransferBufferSize());
847 ExpectedMemoryInfo result1 = GetExpectedResultMemory(sizeof(uint32));
848 ExpectedMemoryInfo mem2 = GetExpectedMemory(
849 kTestSize - MaxTransferBufferSize());
851 Cmds expected;
852 expected.get_bucket_start.Init(
853 kBucketId, result1.id, result1.offset,
854 MaxTransferBufferSize(), mem1.id, mem1.offset);
855 expected.set_token1.Init(GetNextToken());
856 expected.get_bucket_data.Init(
857 kBucketId, MaxTransferBufferSize(),
858 kTestSize - MaxTransferBufferSize(), mem2.id, mem2.offset);
859 expected.set_bucket_size2.Init(kBucketId, 0);
860 expected.set_token2.Init(GetNextToken());
862 EXPECT_CALL(*command_buffer(), OnFlush())
863 .WillOnce(DoAll(
864 SetMemory(result1.ptr, kTestSize),
865 SetMemoryFromArray(
866 mem1.ptr, expected_data, MaxTransferBufferSize())))
867 .WillOnce(SetMemoryFromArray(
868 mem2.ptr, expected_data + MaxTransferBufferSize(),
869 kTestSize - MaxTransferBufferSize()))
870 .RetiresOnSaturation();
872 std::vector<int8> data;
873 GetBucketContents(kBucketId, &data);
874 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
875 ASSERT_EQ(kTestSize, data.size());
876 EXPECT_EQ(0, memcmp(expected_data, &data[0], data.size()));
879 TEST_F(GLES2ImplementationTest, GetShaderPrecisionFormat) {
880 struct Cmds {
881 cmds::GetShaderPrecisionFormat cmd;
883 typedef cmds::GetShaderPrecisionFormat::Result Result;
884 const unsigned kDummyType1 = 3;
885 const unsigned kDummyType2 = 4;
887 // The first call for dummy type 1 should trigger a command buffer request.
888 GLint range1[2] = {0, 0};
889 GLint precision1 = 0;
890 Cmds expected1;
891 ExpectedMemoryInfo client_result1 = GetExpectedResultMemory(4);
892 expected1.cmd.Init(GL_FRAGMENT_SHADER, kDummyType1, client_result1.id,
893 client_result1.offset);
894 Result server_result1 = {true, 14, 14, 10};
895 EXPECT_CALL(*command_buffer(), OnFlush())
896 .WillOnce(SetMemory(client_result1.ptr, server_result1))
897 .RetiresOnSaturation();
898 gl_->GetShaderPrecisionFormat(GL_FRAGMENT_SHADER, kDummyType1, range1,
899 &precision1);
900 const void* commands2 = GetPut();
901 EXPECT_NE(commands_, commands2);
902 EXPECT_EQ(0, memcmp(&expected1, commands_, sizeof(expected1)));
903 EXPECT_EQ(range1[0], 14);
904 EXPECT_EQ(range1[1], 14);
905 EXPECT_EQ(precision1, 10);
907 // The second call for dummy type 1 should use the cached value and avoid
908 // triggering a command buffer request, so we do not expect a call to
909 // OnFlush() here. We do expect the results to be correct though.
910 GLint range2[2] = {0, 0};
911 GLint precision2 = 0;
912 gl_->GetShaderPrecisionFormat(GL_FRAGMENT_SHADER, kDummyType1, range2,
913 &precision2);
914 const void* commands3 = GetPut();
915 EXPECT_EQ(commands2, commands3);
916 EXPECT_EQ(range2[0], 14);
917 EXPECT_EQ(range2[1], 14);
918 EXPECT_EQ(precision2, 10);
920 // If we then make a request for dummy type 2, we should get another command
921 // buffer request since it hasn't been cached yet.
922 GLint range3[2] = {0, 0};
923 GLint precision3 = 0;
924 Cmds expected3;
925 ExpectedMemoryInfo result3 = GetExpectedResultMemory(4);
926 expected3.cmd.Init(GL_FRAGMENT_SHADER, kDummyType2, result3.id,
927 result3.offset);
928 Result result3_source = {true, 62, 62, 16};
929 EXPECT_CALL(*command_buffer(), OnFlush())
930 .WillOnce(SetMemory(result3.ptr, result3_source))
931 .RetiresOnSaturation();
932 gl_->GetShaderPrecisionFormat(GL_FRAGMENT_SHADER, kDummyType2, range3,
933 &precision3);
934 const void* commands4 = GetPut();
935 EXPECT_NE(commands3, commands4);
936 EXPECT_EQ(0, memcmp(&expected3, commands3, sizeof(expected3)));
937 EXPECT_EQ(range3[0], 62);
938 EXPECT_EQ(range3[1], 62);
939 EXPECT_EQ(precision3, 16);
941 // Any call for predefined types should use the cached value from the
942 // Capabilities and avoid triggering a command buffer request, so we do not
943 // expect a call to OnFlush() here. We do expect the results to be correct
944 // though.
945 GLint range4[2] = {0, 0};
946 GLint precision4 = 0;
947 gl_->GetShaderPrecisionFormat(GL_FRAGMENT_SHADER, GL_MEDIUM_FLOAT, range4,
948 &precision4);
949 const void* commands5 = GetPut();
950 EXPECT_EQ(commands4, commands5);
951 EXPECT_EQ(range4[0], 3);
952 EXPECT_EQ(range4[1], 5);
953 EXPECT_EQ(precision4, 7);
956 TEST_F(GLES2ImplementationTest, GetShaderSource) {
957 const uint32 kBucketId = GLES2Implementation::kResultBucketId;
958 const GLuint kShaderId = 456;
959 const Str7 kString = {"foobar"};
960 const char kBad = 0x12;
961 struct Cmds {
962 cmd::SetBucketSize set_bucket_size1;
963 cmds::GetShaderSource get_shader_source;
964 cmd::GetBucketStart get_bucket_start;
965 cmd::SetToken set_token1;
966 cmd::SetBucketSize set_bucket_size2;
969 ExpectedMemoryInfo mem1 = GetExpectedMemory(MaxTransferBufferSize());
970 ExpectedMemoryInfo result1 = GetExpectedResultMemory(sizeof(uint32));
972 Cmds expected;
973 expected.set_bucket_size1.Init(kBucketId, 0);
974 expected.get_shader_source.Init(kShaderId, kBucketId);
975 expected.get_bucket_start.Init(
976 kBucketId, result1.id, result1.offset,
977 MaxTransferBufferSize(), mem1.id, mem1.offset);
978 expected.set_token1.Init(GetNextToken());
979 expected.set_bucket_size2.Init(kBucketId, 0);
980 char buf[sizeof(kString) + 1];
981 memset(buf, kBad, sizeof(buf));
983 EXPECT_CALL(*command_buffer(), OnFlush())
984 .WillOnce(DoAll(SetMemory(result1.ptr, uint32(sizeof(kString))),
985 SetMemory(mem1.ptr, kString)))
986 .RetiresOnSaturation();
988 GLsizei length = 0;
989 gl_->GetShaderSource(kShaderId, sizeof(buf), &length, buf);
990 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
991 EXPECT_EQ(sizeof(kString) - 1, static_cast<size_t>(length));
992 EXPECT_STREQ(kString.str, buf);
993 EXPECT_EQ(buf[sizeof(kString)], kBad);
996 #if defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS)
998 TEST_F(GLES2ImplementationTest, DrawArraysClientSideBuffers) {
999 static const float verts[][4] = {
1000 { 12.0f, 23.0f, 34.0f, 45.0f, },
1001 { 56.0f, 67.0f, 78.0f, 89.0f, },
1002 { 13.0f, 24.0f, 35.0f, 46.0f, },
1004 struct Cmds {
1005 cmds::EnableVertexAttribArray enable1;
1006 cmds::EnableVertexAttribArray enable2;
1007 cmds::BindBuffer bind_to_emu;
1008 cmds::BufferData set_size;
1009 cmds::BufferSubData copy_data1;
1010 cmd::SetToken set_token1;
1011 cmds::VertexAttribPointer set_pointer1;
1012 cmds::BufferSubData copy_data2;
1013 cmd::SetToken set_token2;
1014 cmds::VertexAttribPointer set_pointer2;
1015 cmds::DrawArrays draw;
1016 cmds::BindBuffer restore;
1018 const GLuint kEmuBufferId = GLES2Implementation::kClientSideArrayId;
1019 const GLuint kAttribIndex1 = 1;
1020 const GLuint kAttribIndex2 = 3;
1021 const GLint kNumComponents1 = 3;
1022 const GLint kNumComponents2 = 2;
1023 const GLsizei kClientStride = sizeof(verts[0]);
1024 const GLint kFirst = 1;
1025 const GLsizei kCount = 2;
1026 const GLsizei kSize1 =
1027 arraysize(verts) * kNumComponents1 * sizeof(verts[0][0]);
1028 const GLsizei kSize2 =
1029 arraysize(verts) * kNumComponents2 * sizeof(verts[0][0]);
1030 const GLsizei kEmuOffset1 = 0;
1031 const GLsizei kEmuOffset2 = kSize1;
1032 const GLsizei kTotalSize = kSize1 + kSize2;
1034 ExpectedMemoryInfo mem1 = GetExpectedMemory(kSize1);
1035 ExpectedMemoryInfo mem2 = GetExpectedMemory(kSize2);
1037 Cmds expected;
1038 expected.enable1.Init(kAttribIndex1);
1039 expected.enable2.Init(kAttribIndex2);
1040 expected.bind_to_emu.Init(GL_ARRAY_BUFFER, kEmuBufferId);
1041 expected.set_size.Init(GL_ARRAY_BUFFER, kTotalSize, 0, 0, GL_DYNAMIC_DRAW);
1042 expected.copy_data1.Init(
1043 GL_ARRAY_BUFFER, kEmuOffset1, kSize1, mem1.id, mem1.offset);
1044 expected.set_token1.Init(GetNextToken());
1045 expected.set_pointer1.Init(
1046 kAttribIndex1, kNumComponents1, GL_FLOAT, GL_FALSE, 0, kEmuOffset1);
1047 expected.copy_data2.Init(
1048 GL_ARRAY_BUFFER, kEmuOffset2, kSize2, mem2.id, mem2.offset);
1049 expected.set_token2.Init(GetNextToken());
1050 expected.set_pointer2.Init(
1051 kAttribIndex2, kNumComponents2, GL_FLOAT, GL_FALSE, 0, kEmuOffset2);
1052 expected.draw.Init(GL_POINTS, kFirst, kCount);
1053 expected.restore.Init(GL_ARRAY_BUFFER, 0);
1054 gl_->EnableVertexAttribArray(kAttribIndex1);
1055 gl_->EnableVertexAttribArray(kAttribIndex2);
1056 gl_->VertexAttribPointer(
1057 kAttribIndex1, kNumComponents1, GL_FLOAT, GL_FALSE, kClientStride, verts);
1058 gl_->VertexAttribPointer(
1059 kAttribIndex2, kNumComponents2, GL_FLOAT, GL_FALSE, kClientStride, verts);
1060 gl_->DrawArrays(GL_POINTS, kFirst, kCount);
1061 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
1064 TEST_F(GLES2ImplementationTest, DrawArraysInstancedANGLEClientSideBuffers) {
1065 static const float verts[][4] = {
1066 { 12.0f, 23.0f, 34.0f, 45.0f, },
1067 { 56.0f, 67.0f, 78.0f, 89.0f, },
1068 { 13.0f, 24.0f, 35.0f, 46.0f, },
1070 struct Cmds {
1071 cmds::EnableVertexAttribArray enable1;
1072 cmds::EnableVertexAttribArray enable2;
1073 cmds::VertexAttribDivisorANGLE divisor;
1074 cmds::BindBuffer bind_to_emu;
1075 cmds::BufferData set_size;
1076 cmds::BufferSubData copy_data1;
1077 cmd::SetToken set_token1;
1078 cmds::VertexAttribPointer set_pointer1;
1079 cmds::BufferSubData copy_data2;
1080 cmd::SetToken set_token2;
1081 cmds::VertexAttribPointer set_pointer2;
1082 cmds::DrawArraysInstancedANGLE draw;
1083 cmds::BindBuffer restore;
1085 const GLuint kEmuBufferId = GLES2Implementation::kClientSideArrayId;
1086 const GLuint kAttribIndex1 = 1;
1087 const GLuint kAttribIndex2 = 3;
1088 const GLint kNumComponents1 = 3;
1089 const GLint kNumComponents2 = 2;
1090 const GLsizei kClientStride = sizeof(verts[0]);
1091 const GLint kFirst = 1;
1092 const GLsizei kCount = 2;
1093 const GLuint kDivisor = 1;
1094 const GLsizei kSize1 =
1095 arraysize(verts) * kNumComponents1 * sizeof(verts[0][0]);
1096 const GLsizei kSize2 =
1097 1 * kNumComponents2 * sizeof(verts[0][0]);
1098 const GLsizei kEmuOffset1 = 0;
1099 const GLsizei kEmuOffset2 = kSize1;
1100 const GLsizei kTotalSize = kSize1 + kSize2;
1102 ExpectedMemoryInfo mem1 = GetExpectedMemory(kSize1);
1103 ExpectedMemoryInfo mem2 = GetExpectedMemory(kSize2);
1105 Cmds expected;
1106 expected.enable1.Init(kAttribIndex1);
1107 expected.enable2.Init(kAttribIndex2);
1108 expected.divisor.Init(kAttribIndex2, kDivisor);
1109 expected.bind_to_emu.Init(GL_ARRAY_BUFFER, kEmuBufferId);
1110 expected.set_size.Init(GL_ARRAY_BUFFER, kTotalSize, 0, 0, GL_DYNAMIC_DRAW);
1111 expected.copy_data1.Init(
1112 GL_ARRAY_BUFFER, kEmuOffset1, kSize1, mem1.id, mem1.offset);
1113 expected.set_token1.Init(GetNextToken());
1114 expected.set_pointer1.Init(
1115 kAttribIndex1, kNumComponents1, GL_FLOAT, GL_FALSE, 0, kEmuOffset1);
1116 expected.copy_data2.Init(
1117 GL_ARRAY_BUFFER, kEmuOffset2, kSize2, mem2.id, mem2.offset);
1118 expected.set_token2.Init(GetNextToken());
1119 expected.set_pointer2.Init(
1120 kAttribIndex2, kNumComponents2, GL_FLOAT, GL_FALSE, 0, kEmuOffset2);
1121 expected.draw.Init(GL_POINTS, kFirst, kCount, 1);
1122 expected.restore.Init(GL_ARRAY_BUFFER, 0);
1123 gl_->EnableVertexAttribArray(kAttribIndex1);
1124 gl_->EnableVertexAttribArray(kAttribIndex2);
1125 gl_->VertexAttribPointer(
1126 kAttribIndex1, kNumComponents1, GL_FLOAT, GL_FALSE, kClientStride, verts);
1127 gl_->VertexAttribPointer(
1128 kAttribIndex2, kNumComponents2, GL_FLOAT, GL_FALSE, kClientStride, verts);
1129 gl_->VertexAttribDivisorANGLE(kAttribIndex2, kDivisor);
1130 gl_->DrawArraysInstancedANGLE(GL_POINTS, kFirst, kCount, 1);
1131 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
1134 TEST_F(GLES2ImplementationTest, DrawElementsClientSideBuffers) {
1135 static const float verts[][4] = {
1136 { 12.0f, 23.0f, 34.0f, 45.0f, },
1137 { 56.0f, 67.0f, 78.0f, 89.0f, },
1138 { 13.0f, 24.0f, 35.0f, 46.0f, },
1140 static const uint16 indices[] = {
1141 1, 2,
1143 struct Cmds {
1144 cmds::EnableVertexAttribArray enable1;
1145 cmds::EnableVertexAttribArray enable2;
1146 cmds::BindBuffer bind_to_index_emu;
1147 cmds::BufferData set_index_size;
1148 cmds::BufferSubData copy_data0;
1149 cmd::SetToken set_token0;
1150 cmds::BindBuffer bind_to_emu;
1151 cmds::BufferData set_size;
1152 cmds::BufferSubData copy_data1;
1153 cmd::SetToken set_token1;
1154 cmds::VertexAttribPointer set_pointer1;
1155 cmds::BufferSubData copy_data2;
1156 cmd::SetToken set_token2;
1157 cmds::VertexAttribPointer set_pointer2;
1158 cmds::DrawElements draw;
1159 cmds::BindBuffer restore;
1160 cmds::BindBuffer restore_element;
1162 const GLsizei kIndexSize = sizeof(indices);
1163 const GLuint kEmuBufferId = GLES2Implementation::kClientSideArrayId;
1164 const GLuint kEmuIndexBufferId =
1165 GLES2Implementation::kClientSideElementArrayId;
1166 const GLuint kAttribIndex1 = 1;
1167 const GLuint kAttribIndex2 = 3;
1168 const GLint kNumComponents1 = 3;
1169 const GLint kNumComponents2 = 2;
1170 const GLsizei kClientStride = sizeof(verts[0]);
1171 const GLsizei kCount = 2;
1172 const GLsizei kSize1 =
1173 arraysize(verts) * kNumComponents1 * sizeof(verts[0][0]);
1174 const GLsizei kSize2 =
1175 arraysize(verts) * kNumComponents2 * sizeof(verts[0][0]);
1176 const GLsizei kEmuOffset1 = 0;
1177 const GLsizei kEmuOffset2 = kSize1;
1178 const GLsizei kTotalSize = kSize1 + kSize2;
1180 ExpectedMemoryInfo mem1 = GetExpectedMemory(kIndexSize);
1181 ExpectedMemoryInfo mem2 = GetExpectedMemory(kSize1);
1182 ExpectedMemoryInfo mem3 = GetExpectedMemory(kSize2);
1184 Cmds expected;
1185 expected.enable1.Init(kAttribIndex1);
1186 expected.enable2.Init(kAttribIndex2);
1187 expected.bind_to_index_emu.Init(GL_ELEMENT_ARRAY_BUFFER, kEmuIndexBufferId);
1188 expected.set_index_size.Init(
1189 GL_ELEMENT_ARRAY_BUFFER, kIndexSize, 0, 0, GL_DYNAMIC_DRAW);
1190 expected.copy_data0.Init(
1191 GL_ELEMENT_ARRAY_BUFFER, 0, kIndexSize, mem1.id, mem1.offset);
1192 expected.set_token0.Init(GetNextToken());
1193 expected.bind_to_emu.Init(GL_ARRAY_BUFFER, kEmuBufferId);
1194 expected.set_size.Init(GL_ARRAY_BUFFER, kTotalSize, 0, 0, GL_DYNAMIC_DRAW);
1195 expected.copy_data1.Init(
1196 GL_ARRAY_BUFFER, kEmuOffset1, kSize1, mem2.id, mem2.offset);
1197 expected.set_token1.Init(GetNextToken());
1198 expected.set_pointer1.Init(
1199 kAttribIndex1, kNumComponents1, GL_FLOAT, GL_FALSE, 0, kEmuOffset1);
1200 expected.copy_data2.Init(
1201 GL_ARRAY_BUFFER, kEmuOffset2, kSize2, mem3.id, mem3.offset);
1202 expected.set_token2.Init(GetNextToken());
1203 expected.set_pointer2.Init(kAttribIndex2, kNumComponents2,
1204 GL_FLOAT, GL_FALSE, 0, kEmuOffset2);
1205 expected.draw.Init(GL_POINTS, kCount, GL_UNSIGNED_SHORT, 0);
1206 expected.restore.Init(GL_ARRAY_BUFFER, 0);
1207 expected.restore_element.Init(GL_ELEMENT_ARRAY_BUFFER, 0);
1208 gl_->EnableVertexAttribArray(kAttribIndex1);
1209 gl_->EnableVertexAttribArray(kAttribIndex2);
1210 gl_->VertexAttribPointer(kAttribIndex1, kNumComponents1,
1211 GL_FLOAT, GL_FALSE, kClientStride, verts);
1212 gl_->VertexAttribPointer(kAttribIndex2, kNumComponents2,
1213 GL_FLOAT, GL_FALSE, kClientStride, verts);
1214 gl_->DrawElements(GL_POINTS, kCount, GL_UNSIGNED_SHORT, indices);
1215 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
1218 TEST_F(GLES2ImplementationTest, DrawElementsClientSideBuffersIndexUint) {
1219 static const float verts[][4] = {
1220 { 12.0f, 23.0f, 34.0f, 45.0f, },
1221 { 56.0f, 67.0f, 78.0f, 89.0f, },
1222 { 13.0f, 24.0f, 35.0f, 46.0f, },
1224 static const uint32 indices[] = {
1225 1, 2,
1227 struct Cmds {
1228 cmds::EnableVertexAttribArray enable1;
1229 cmds::EnableVertexAttribArray enable2;
1230 cmds::BindBuffer bind_to_index_emu;
1231 cmds::BufferData set_index_size;
1232 cmds::BufferSubData copy_data0;
1233 cmd::SetToken set_token0;
1234 cmds::BindBuffer bind_to_emu;
1235 cmds::BufferData set_size;
1236 cmds::BufferSubData copy_data1;
1237 cmd::SetToken set_token1;
1238 cmds::VertexAttribPointer set_pointer1;
1239 cmds::BufferSubData copy_data2;
1240 cmd::SetToken set_token2;
1241 cmds::VertexAttribPointer set_pointer2;
1242 cmds::DrawElements draw;
1243 cmds::BindBuffer restore;
1244 cmds::BindBuffer restore_element;
1246 const GLsizei kIndexSize = sizeof(indices);
1247 const GLuint kEmuBufferId = GLES2Implementation::kClientSideArrayId;
1248 const GLuint kEmuIndexBufferId =
1249 GLES2Implementation::kClientSideElementArrayId;
1250 const GLuint kAttribIndex1 = 1;
1251 const GLuint kAttribIndex2 = 3;
1252 const GLint kNumComponents1 = 3;
1253 const GLint kNumComponents2 = 2;
1254 const GLsizei kClientStride = sizeof(verts[0]);
1255 const GLsizei kCount = 2;
1256 const GLsizei kSize1 =
1257 arraysize(verts) * kNumComponents1 * sizeof(verts[0][0]);
1258 const GLsizei kSize2 =
1259 arraysize(verts) * kNumComponents2 * sizeof(verts[0][0]);
1260 const GLsizei kEmuOffset1 = 0;
1261 const GLsizei kEmuOffset2 = kSize1;
1262 const GLsizei kTotalSize = kSize1 + kSize2;
1264 ExpectedMemoryInfo mem1 = GetExpectedMemory(kIndexSize);
1265 ExpectedMemoryInfo mem2 = GetExpectedMemory(kSize1);
1266 ExpectedMemoryInfo mem3 = GetExpectedMemory(kSize2);
1268 Cmds expected;
1269 expected.enable1.Init(kAttribIndex1);
1270 expected.enable2.Init(kAttribIndex2);
1271 expected.bind_to_index_emu.Init(GL_ELEMENT_ARRAY_BUFFER, kEmuIndexBufferId);
1272 expected.set_index_size.Init(
1273 GL_ELEMENT_ARRAY_BUFFER, kIndexSize, 0, 0, GL_DYNAMIC_DRAW);
1274 expected.copy_data0.Init(
1275 GL_ELEMENT_ARRAY_BUFFER, 0, kIndexSize, mem1.id, mem1.offset);
1276 expected.set_token0.Init(GetNextToken());
1277 expected.bind_to_emu.Init(GL_ARRAY_BUFFER, kEmuBufferId);
1278 expected.set_size.Init(GL_ARRAY_BUFFER, kTotalSize, 0, 0, GL_DYNAMIC_DRAW);
1279 expected.copy_data1.Init(
1280 GL_ARRAY_BUFFER, kEmuOffset1, kSize1, mem2.id, mem2.offset);
1281 expected.set_token1.Init(GetNextToken());
1282 expected.set_pointer1.Init(
1283 kAttribIndex1, kNumComponents1, GL_FLOAT, GL_FALSE, 0, kEmuOffset1);
1284 expected.copy_data2.Init(
1285 GL_ARRAY_BUFFER, kEmuOffset2, kSize2, mem3.id, mem3.offset);
1286 expected.set_token2.Init(GetNextToken());
1287 expected.set_pointer2.Init(kAttribIndex2, kNumComponents2,
1288 GL_FLOAT, GL_FALSE, 0, kEmuOffset2);
1289 expected.draw.Init(GL_POINTS, kCount, GL_UNSIGNED_INT, 0);
1290 expected.restore.Init(GL_ARRAY_BUFFER, 0);
1291 expected.restore_element.Init(GL_ELEMENT_ARRAY_BUFFER, 0);
1292 gl_->EnableVertexAttribArray(kAttribIndex1);
1293 gl_->EnableVertexAttribArray(kAttribIndex2);
1294 gl_->VertexAttribPointer(kAttribIndex1, kNumComponents1,
1295 GL_FLOAT, GL_FALSE, kClientStride, verts);
1296 gl_->VertexAttribPointer(kAttribIndex2, kNumComponents2,
1297 GL_FLOAT, GL_FALSE, kClientStride, verts);
1298 gl_->DrawElements(GL_POINTS, kCount, GL_UNSIGNED_INT, indices);
1299 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
1302 TEST_F(GLES2ImplementationTest, DrawElementsClientSideBuffersInvalidIndexUint) {
1303 static const float verts[][4] = {
1304 { 12.0f, 23.0f, 34.0f, 45.0f, },
1305 { 56.0f, 67.0f, 78.0f, 89.0f, },
1306 { 13.0f, 24.0f, 35.0f, 46.0f, },
1308 static const uint32 indices[] = {
1309 1, 0x90000000
1312 const GLuint kAttribIndex1 = 1;
1313 const GLuint kAttribIndex2 = 3;
1314 const GLint kNumComponents1 = 3;
1315 const GLint kNumComponents2 = 2;
1316 const GLsizei kClientStride = sizeof(verts[0]);
1317 const GLsizei kCount = 2;
1319 EXPECT_CALL(*command_buffer(), OnFlush())
1320 .Times(1)
1321 .RetiresOnSaturation();
1323 gl_->EnableVertexAttribArray(kAttribIndex1);
1324 gl_->EnableVertexAttribArray(kAttribIndex2);
1325 gl_->VertexAttribPointer(kAttribIndex1, kNumComponents1,
1326 GL_FLOAT, GL_FALSE, kClientStride, verts);
1327 gl_->VertexAttribPointer(kAttribIndex2, kNumComponents2,
1328 GL_FLOAT, GL_FALSE, kClientStride, verts);
1329 gl_->DrawElements(GL_POINTS, kCount, GL_UNSIGNED_INT, indices);
1331 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_OPERATION), gl_->GetError());
1334 TEST_F(GLES2ImplementationTest,
1335 DrawElementsClientSideBuffersServiceSideIndices) {
1336 static const float verts[][4] = {
1337 { 12.0f, 23.0f, 34.0f, 45.0f, },
1338 { 56.0f, 67.0f, 78.0f, 89.0f, },
1339 { 13.0f, 24.0f, 35.0f, 46.0f, },
1341 struct Cmds {
1342 cmds::EnableVertexAttribArray enable1;
1343 cmds::EnableVertexAttribArray enable2;
1344 cmds::BindBuffer bind_to_index;
1345 cmds::GetMaxValueInBufferCHROMIUM get_max;
1346 cmds::BindBuffer bind_to_emu;
1347 cmds::BufferData set_size;
1348 cmds::BufferSubData copy_data1;
1349 cmd::SetToken set_token1;
1350 cmds::VertexAttribPointer set_pointer1;
1351 cmds::BufferSubData copy_data2;
1352 cmd::SetToken set_token2;
1353 cmds::VertexAttribPointer set_pointer2;
1354 cmds::DrawElements draw;
1355 cmds::BindBuffer restore;
1357 const GLuint kEmuBufferId = GLES2Implementation::kClientSideArrayId;
1358 const GLuint kClientIndexBufferId = 0x789;
1359 const GLuint kIndexOffset = 0x40;
1360 const GLuint kMaxIndex = 2;
1361 const GLuint kAttribIndex1 = 1;
1362 const GLuint kAttribIndex2 = 3;
1363 const GLint kNumComponents1 = 3;
1364 const GLint kNumComponents2 = 2;
1365 const GLsizei kClientStride = sizeof(verts[0]);
1366 const GLsizei kCount = 2;
1367 const GLsizei kSize1 =
1368 arraysize(verts) * kNumComponents1 * sizeof(verts[0][0]);
1369 const GLsizei kSize2 =
1370 arraysize(verts) * kNumComponents2 * sizeof(verts[0][0]);
1371 const GLsizei kEmuOffset1 = 0;
1372 const GLsizei kEmuOffset2 = kSize1;
1373 const GLsizei kTotalSize = kSize1 + kSize2;
1375 ExpectedMemoryInfo mem1 = GetExpectedResultMemory(sizeof(uint32));
1376 ExpectedMemoryInfo mem2 = GetExpectedMemory(kSize1);
1377 ExpectedMemoryInfo mem3 = GetExpectedMemory(kSize2);
1380 Cmds expected;
1381 expected.enable1.Init(kAttribIndex1);
1382 expected.enable2.Init(kAttribIndex2);
1383 expected.bind_to_index.Init(GL_ELEMENT_ARRAY_BUFFER, kClientIndexBufferId);
1384 expected.get_max.Init(kClientIndexBufferId, kCount, GL_UNSIGNED_SHORT,
1385 kIndexOffset, mem1.id, mem1.offset);
1386 expected.bind_to_emu.Init(GL_ARRAY_BUFFER, kEmuBufferId);
1387 expected.set_size.Init(GL_ARRAY_BUFFER, kTotalSize, 0, 0, GL_DYNAMIC_DRAW);
1388 expected.copy_data1.Init(
1389 GL_ARRAY_BUFFER, kEmuOffset1, kSize1, mem2.id, mem2.offset);
1390 expected.set_token1.Init(GetNextToken());
1391 expected.set_pointer1.Init(kAttribIndex1, kNumComponents1,
1392 GL_FLOAT, GL_FALSE, 0, kEmuOffset1);
1393 expected.copy_data2.Init(
1394 GL_ARRAY_BUFFER, kEmuOffset2, kSize2, mem3.id, mem3.offset);
1395 expected.set_token2.Init(GetNextToken());
1396 expected.set_pointer2.Init(kAttribIndex2, kNumComponents2,
1397 GL_FLOAT, GL_FALSE, 0, kEmuOffset2);
1398 expected.draw.Init(GL_POINTS, kCount, GL_UNSIGNED_SHORT, kIndexOffset);
1399 expected.restore.Init(GL_ARRAY_BUFFER, 0);
1401 EXPECT_CALL(*command_buffer(), OnFlush())
1402 .WillOnce(SetMemory(mem1.ptr,kMaxIndex))
1403 .RetiresOnSaturation();
1405 gl_->EnableVertexAttribArray(kAttribIndex1);
1406 gl_->EnableVertexAttribArray(kAttribIndex2);
1407 gl_->BindBuffer(GL_ELEMENT_ARRAY_BUFFER, kClientIndexBufferId);
1408 gl_->VertexAttribPointer(kAttribIndex1, kNumComponents1,
1409 GL_FLOAT, GL_FALSE, kClientStride, verts);
1410 gl_->VertexAttribPointer(kAttribIndex2, kNumComponents2,
1411 GL_FLOAT, GL_FALSE, kClientStride, verts);
1412 gl_->DrawElements(GL_POINTS, kCount, GL_UNSIGNED_SHORT,
1413 reinterpret_cast<const void*>(kIndexOffset));
1414 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
1417 TEST_F(GLES2ImplementationTest, DrawElementsInstancedANGLEClientSideBuffers) {
1418 static const float verts[][4] = {
1419 { 12.0f, 23.0f, 34.0f, 45.0f, },
1420 { 56.0f, 67.0f, 78.0f, 89.0f, },
1421 { 13.0f, 24.0f, 35.0f, 46.0f, },
1423 static const uint16 indices[] = {
1424 1, 2,
1426 struct Cmds {
1427 cmds::EnableVertexAttribArray enable1;
1428 cmds::EnableVertexAttribArray enable2;
1429 cmds::VertexAttribDivisorANGLE divisor;
1430 cmds::BindBuffer bind_to_index_emu;
1431 cmds::BufferData set_index_size;
1432 cmds::BufferSubData copy_data0;
1433 cmd::SetToken set_token0;
1434 cmds::BindBuffer bind_to_emu;
1435 cmds::BufferData set_size;
1436 cmds::BufferSubData copy_data1;
1437 cmd::SetToken set_token1;
1438 cmds::VertexAttribPointer set_pointer1;
1439 cmds::BufferSubData copy_data2;
1440 cmd::SetToken set_token2;
1441 cmds::VertexAttribPointer set_pointer2;
1442 cmds::DrawElementsInstancedANGLE draw;
1443 cmds::BindBuffer restore;
1444 cmds::BindBuffer restore_element;
1446 const GLsizei kIndexSize = sizeof(indices);
1447 const GLuint kEmuBufferId = GLES2Implementation::kClientSideArrayId;
1448 const GLuint kEmuIndexBufferId =
1449 GLES2Implementation::kClientSideElementArrayId;
1450 const GLuint kAttribIndex1 = 1;
1451 const GLuint kAttribIndex2 = 3;
1452 const GLint kNumComponents1 = 3;
1453 const GLint kNumComponents2 = 2;
1454 const GLsizei kClientStride = sizeof(verts[0]);
1455 const GLsizei kCount = 2;
1456 const GLsizei kSize1 =
1457 arraysize(verts) * kNumComponents1 * sizeof(verts[0][0]);
1458 const GLsizei kSize2 =
1459 1 * kNumComponents2 * sizeof(verts[0][0]);
1460 const GLuint kDivisor = 1;
1461 const GLsizei kEmuOffset1 = 0;
1462 const GLsizei kEmuOffset2 = kSize1;
1463 const GLsizei kTotalSize = kSize1 + kSize2;
1465 ExpectedMemoryInfo mem1 = GetExpectedMemory(kIndexSize);
1466 ExpectedMemoryInfo mem2 = GetExpectedMemory(kSize1);
1467 ExpectedMemoryInfo mem3 = GetExpectedMemory(kSize2);
1469 Cmds expected;
1470 expected.enable1.Init(kAttribIndex1);
1471 expected.enable2.Init(kAttribIndex2);
1472 expected.divisor.Init(kAttribIndex2, kDivisor);
1473 expected.bind_to_index_emu.Init(GL_ELEMENT_ARRAY_BUFFER, kEmuIndexBufferId);
1474 expected.set_index_size.Init(
1475 GL_ELEMENT_ARRAY_BUFFER, kIndexSize, 0, 0, GL_DYNAMIC_DRAW);
1476 expected.copy_data0.Init(
1477 GL_ELEMENT_ARRAY_BUFFER, 0, kIndexSize, mem1.id, mem1.offset);
1478 expected.set_token0.Init(GetNextToken());
1479 expected.bind_to_emu.Init(GL_ARRAY_BUFFER, kEmuBufferId);
1480 expected.set_size.Init(GL_ARRAY_BUFFER, kTotalSize, 0, 0, GL_DYNAMIC_DRAW);
1481 expected.copy_data1.Init(
1482 GL_ARRAY_BUFFER, kEmuOffset1, kSize1, mem2.id, mem2.offset);
1483 expected.set_token1.Init(GetNextToken());
1484 expected.set_pointer1.Init(
1485 kAttribIndex1, kNumComponents1, GL_FLOAT, GL_FALSE, 0, kEmuOffset1);
1486 expected.copy_data2.Init(
1487 GL_ARRAY_BUFFER, kEmuOffset2, kSize2, mem3.id, mem3.offset);
1488 expected.set_token2.Init(GetNextToken());
1489 expected.set_pointer2.Init(kAttribIndex2, kNumComponents2,
1490 GL_FLOAT, GL_FALSE, 0, kEmuOffset2);
1491 expected.draw.Init(GL_POINTS, kCount, GL_UNSIGNED_SHORT, 0, 1);
1492 expected.restore.Init(GL_ARRAY_BUFFER, 0);
1493 expected.restore_element.Init(GL_ELEMENT_ARRAY_BUFFER, 0);
1494 gl_->EnableVertexAttribArray(kAttribIndex1);
1495 gl_->EnableVertexAttribArray(kAttribIndex2);
1496 gl_->VertexAttribPointer(kAttribIndex1, kNumComponents1,
1497 GL_FLOAT, GL_FALSE, kClientStride, verts);
1498 gl_->VertexAttribPointer(kAttribIndex2, kNumComponents2,
1499 GL_FLOAT, GL_FALSE, kClientStride, verts);
1500 gl_->VertexAttribDivisorANGLE(kAttribIndex2, kDivisor);
1501 gl_->DrawElementsInstancedANGLE(
1502 GL_POINTS, kCount, GL_UNSIGNED_SHORT, indices, 1);
1503 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
1506 TEST_F(GLES2ImplementationTest, GetVertexBufferPointerv) {
1507 static const float verts[1] = { 0.0f, };
1508 const GLuint kAttribIndex1 = 1;
1509 const GLuint kAttribIndex2 = 3;
1510 const GLint kNumComponents1 = 3;
1511 const GLint kNumComponents2 = 2;
1512 const GLsizei kStride1 = 12;
1513 const GLsizei kStride2 = 0;
1514 const GLuint kBufferId = 0x123;
1515 const GLint kOffset2 = 0x456;
1517 // It's all cached on the client side so no get commands are issued.
1518 struct Cmds {
1519 cmds::BindBuffer bind;
1520 cmds::VertexAttribPointer set_pointer;
1523 Cmds expected;
1524 expected.bind.Init(GL_ARRAY_BUFFER, kBufferId);
1525 expected.set_pointer.Init(kAttribIndex2, kNumComponents2, GL_FLOAT, GL_FALSE,
1526 kStride2, kOffset2);
1528 // Set one client side buffer.
1529 gl_->VertexAttribPointer(kAttribIndex1, kNumComponents1,
1530 GL_FLOAT, GL_FALSE, kStride1, verts);
1531 // Set one VBO
1532 gl_->BindBuffer(GL_ARRAY_BUFFER, kBufferId);
1533 gl_->VertexAttribPointer(kAttribIndex2, kNumComponents2,
1534 GL_FLOAT, GL_FALSE, kStride2,
1535 reinterpret_cast<const void*>(kOffset2));
1536 // now get them both.
1537 void* ptr1 = NULL;
1538 void* ptr2 = NULL;
1540 gl_->GetVertexAttribPointerv(
1541 kAttribIndex1, GL_VERTEX_ATTRIB_ARRAY_POINTER, &ptr1);
1542 gl_->GetVertexAttribPointerv(
1543 kAttribIndex2, GL_VERTEX_ATTRIB_ARRAY_POINTER, &ptr2);
1545 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
1546 EXPECT_TRUE(static_cast<const void*>(&verts) == ptr1);
1547 EXPECT_TRUE(ptr2 == reinterpret_cast<void*>(kOffset2));
1550 TEST_F(GLES2ImplementationTest, GetVertexAttrib) {
1551 static const float verts[1] = { 0.0f, };
1552 const GLuint kAttribIndex1 = 1;
1553 const GLuint kAttribIndex2 = 3;
1554 const GLint kNumComponents1 = 3;
1555 const GLint kNumComponents2 = 2;
1556 const GLsizei kStride1 = 12;
1557 const GLsizei kStride2 = 0;
1558 const GLuint kBufferId = 0x123;
1559 const GLint kOffset2 = 0x456;
1561 // Only one set and one get because the client side buffer's info is stored
1562 // on the client side.
1563 struct Cmds {
1564 cmds::EnableVertexAttribArray enable;
1565 cmds::BindBuffer bind;
1566 cmds::VertexAttribPointer set_pointer;
1567 cmds::GetVertexAttribfv get2; // for getting the value from attrib1
1570 ExpectedMemoryInfo mem2 = GetExpectedResultMemory(16);
1572 Cmds expected;
1573 expected.enable.Init(kAttribIndex1);
1574 expected.bind.Init(GL_ARRAY_BUFFER, kBufferId);
1575 expected.set_pointer.Init(kAttribIndex2, kNumComponents2, GL_FLOAT, GL_FALSE,
1576 kStride2, kOffset2);
1577 expected.get2.Init(kAttribIndex1,
1578 GL_CURRENT_VERTEX_ATTRIB,
1579 mem2.id, mem2.offset);
1581 FourFloats current_attrib(1.2f, 3.4f, 5.6f, 7.8f);
1583 // One call to flush to wait for last call to GetVertexAttribiv
1584 // as others are all cached.
1585 EXPECT_CALL(*command_buffer(), OnFlush())
1586 .WillOnce(SetMemory(
1587 mem2.ptr, SizedResultHelper<FourFloats>(current_attrib)))
1588 .RetiresOnSaturation();
1590 gl_->EnableVertexAttribArray(kAttribIndex1);
1591 // Set one client side buffer.
1592 gl_->VertexAttribPointer(kAttribIndex1, kNumComponents1,
1593 GL_FLOAT, GL_FALSE, kStride1, verts);
1594 // Set one VBO
1595 gl_->BindBuffer(GL_ARRAY_BUFFER, kBufferId);
1596 gl_->VertexAttribPointer(kAttribIndex2, kNumComponents2,
1597 GL_FLOAT, GL_FALSE, kStride2,
1598 reinterpret_cast<const void*>(kOffset2));
1599 // first get the service side once to see that we make a command
1600 GLint buffer_id = 0;
1601 GLint enabled = 0;
1602 GLint size = 0;
1603 GLint stride = 0;
1604 GLint type = 0;
1605 GLint normalized = 1;
1606 float current[4] = { 0.0f, };
1608 gl_->GetVertexAttribiv(
1609 kAttribIndex2, GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING, &buffer_id);
1610 EXPECT_EQ(kBufferId, static_cast<GLuint>(buffer_id));
1611 gl_->GetVertexAttribiv(
1612 kAttribIndex1, GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING, &buffer_id);
1613 gl_->GetVertexAttribiv(
1614 kAttribIndex1, GL_VERTEX_ATTRIB_ARRAY_ENABLED, &enabled);
1615 gl_->GetVertexAttribiv(
1616 kAttribIndex1, GL_VERTEX_ATTRIB_ARRAY_SIZE, &size);
1617 gl_->GetVertexAttribiv(
1618 kAttribIndex1, GL_VERTEX_ATTRIB_ARRAY_STRIDE, &stride);
1619 gl_->GetVertexAttribiv(
1620 kAttribIndex1, GL_VERTEX_ATTRIB_ARRAY_TYPE, &type);
1621 gl_->GetVertexAttribiv(
1622 kAttribIndex1, GL_VERTEX_ATTRIB_ARRAY_NORMALIZED, &normalized);
1623 gl_->GetVertexAttribfv(
1624 kAttribIndex1, GL_CURRENT_VERTEX_ATTRIB, &current[0]);
1626 EXPECT_EQ(0, buffer_id);
1627 EXPECT_EQ(GL_TRUE, enabled);
1628 EXPECT_EQ(kNumComponents1, size);
1629 EXPECT_EQ(kStride1, stride);
1630 EXPECT_EQ(GL_FLOAT, type);
1631 EXPECT_EQ(GL_FALSE, normalized);
1632 EXPECT_EQ(0, memcmp(&current_attrib, &current, sizeof(current_attrib)));
1634 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
1637 TEST_F(GLES2ImplementationTest, ReservedIds) {
1638 // Only the get error command should be issued.
1639 struct Cmds {
1640 cmds::GetError get;
1642 Cmds expected;
1644 ExpectedMemoryInfo mem1 = GetExpectedResultMemory(
1645 sizeof(cmds::GetError::Result));
1647 expected.get.Init(mem1.id, mem1.offset);
1649 // One call to flush to wait for GetError
1650 EXPECT_CALL(*command_buffer(), OnFlush())
1651 .WillOnce(SetMemory(mem1.ptr, GLuint(GL_NO_ERROR)))
1652 .RetiresOnSaturation();
1654 gl_->BindBuffer(
1655 GL_ARRAY_BUFFER,
1656 GLES2Implementation::kClientSideArrayId);
1657 gl_->BindBuffer(
1658 GL_ARRAY_BUFFER,
1659 GLES2Implementation::kClientSideElementArrayId);
1660 GLenum err = gl_->GetError();
1661 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_OPERATION), err);
1662 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
1665 #endif // defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS)
1667 TEST_F(GLES2ImplementationTest, ReadPixels2Reads) {
1668 struct Cmds {
1669 cmds::ReadPixels read1;
1670 cmd::SetToken set_token1;
1671 cmds::ReadPixels read2;
1672 cmd::SetToken set_token2;
1674 const GLint kBytesPerPixel = 4;
1675 const GLint kWidth =
1676 (kTransferBufferSize - GLES2Implementation::kStartingOffset) /
1677 kBytesPerPixel;
1678 const GLint kHeight = 2;
1679 const GLenum kFormat = GL_RGBA;
1680 const GLenum kType = GL_UNSIGNED_BYTE;
1682 ExpectedMemoryInfo mem1 =
1683 GetExpectedMemory(kWidth * kHeight / 2 * kBytesPerPixel);
1684 ExpectedMemoryInfo result1 =
1685 GetExpectedResultMemory(sizeof(cmds::ReadPixels::Result));
1686 ExpectedMemoryInfo mem2 =
1687 GetExpectedMemory(kWidth * kHeight / 2 * kBytesPerPixel);
1688 ExpectedMemoryInfo result2 =
1689 GetExpectedResultMemory(sizeof(cmds::ReadPixels::Result));
1691 Cmds expected;
1692 expected.read1.Init(
1693 0, 0, kWidth, kHeight / 2, kFormat, kType,
1694 mem1.id, mem1.offset, result1.id, result1.offset,
1695 false);
1696 expected.set_token1.Init(GetNextToken());
1697 expected.read2.Init(
1698 0, kHeight / 2, kWidth, kHeight / 2, kFormat, kType,
1699 mem2.id, mem2.offset, result2.id, result2.offset, false);
1700 expected.set_token2.Init(GetNextToken());
1701 scoped_ptr<int8[]> buffer(new int8[kWidth * kHeight * kBytesPerPixel]);
1703 EXPECT_CALL(*command_buffer(), OnFlush())
1704 .WillOnce(SetMemory(result1.ptr, static_cast<uint32>(1)))
1705 .WillOnce(SetMemory(result2.ptr, static_cast<uint32>(1)))
1706 .RetiresOnSaturation();
1708 gl_->ReadPixels(0, 0, kWidth, kHeight, kFormat, kType, buffer.get());
1709 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
1712 TEST_F(GLES2ImplementationTest, ReadPixelsBadFormatType) {
1713 struct Cmds {
1714 cmds::ReadPixels read;
1715 cmd::SetToken set_token;
1717 const GLint kBytesPerPixel = 4;
1718 const GLint kWidth = 2;
1719 const GLint kHeight = 2;
1720 const GLenum kFormat = 0;
1721 const GLenum kType = 0;
1723 ExpectedMemoryInfo mem1 =
1724 GetExpectedMemory(kWidth * kHeight * kBytesPerPixel);
1725 ExpectedMemoryInfo result1 =
1726 GetExpectedResultMemory(sizeof(cmds::ReadPixels::Result));
1728 Cmds expected;
1729 expected.read.Init(
1730 0, 0, kWidth, kHeight, kFormat, kType,
1731 mem1.id, mem1.offset, result1.id, result1.offset, false);
1732 expected.set_token.Init(GetNextToken());
1733 scoped_ptr<int8[]> buffer(new int8[kWidth * kHeight * kBytesPerPixel]);
1735 EXPECT_CALL(*command_buffer(), OnFlush())
1736 .Times(1)
1737 .RetiresOnSaturation();
1739 gl_->ReadPixels(0, 0, kWidth, kHeight, kFormat, kType, buffer.get());
1742 TEST_F(GLES2ImplementationTest, FreeUnusedSharedMemory) {
1743 struct Cmds {
1744 cmds::BufferSubData buf;
1745 cmd::SetToken set_token;
1747 const GLenum kTarget = GL_ELEMENT_ARRAY_BUFFER;
1748 const GLintptr kOffset = 15;
1749 const GLsizeiptr kSize = 16;
1751 ExpectedMemoryInfo mem1 = GetExpectedMemory(kSize);
1753 Cmds expected;
1754 expected.buf.Init(
1755 kTarget, kOffset, kSize, mem1.id, mem1.offset);
1756 expected.set_token.Init(GetNextToken());
1758 void* mem = gl_->MapBufferSubDataCHROMIUM(
1759 kTarget, kOffset, kSize, GL_WRITE_ONLY);
1760 ASSERT_TRUE(mem != NULL);
1761 gl_->UnmapBufferSubDataCHROMIUM(mem);
1762 EXPECT_CALL(*command_buffer(), DestroyTransferBuffer(_))
1763 .Times(1)
1764 .RetiresOnSaturation();
1765 gl_->FreeUnusedSharedMemory();
1768 TEST_F(GLES2ImplementationTest, MapUnmapBufferSubDataCHROMIUM) {
1769 struct Cmds {
1770 cmds::BufferSubData buf;
1771 cmd::SetToken set_token;
1773 const GLenum kTarget = GL_ELEMENT_ARRAY_BUFFER;
1774 const GLintptr kOffset = 15;
1775 const GLsizeiptr kSize = 16;
1777 uint32 offset = 0;
1778 Cmds expected;
1779 expected.buf.Init(
1780 kTarget, kOffset, kSize,
1781 command_buffer()->GetNextFreeTransferBufferId(), offset);
1782 expected.set_token.Init(GetNextToken());
1784 void* mem = gl_->MapBufferSubDataCHROMIUM(
1785 kTarget, kOffset, kSize, GL_WRITE_ONLY);
1786 ASSERT_TRUE(mem != NULL);
1787 gl_->UnmapBufferSubDataCHROMIUM(mem);
1788 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
1791 TEST_F(GLES2ImplementationTest, MapUnmapBufferSubDataCHROMIUMBadArgs) {
1792 const GLenum kTarget = GL_ELEMENT_ARRAY_BUFFER;
1793 const GLintptr kOffset = 15;
1794 const GLsizeiptr kSize = 16;
1796 ExpectedMemoryInfo result1 =
1797 GetExpectedResultMemory(sizeof(cmds::GetError::Result));
1798 ExpectedMemoryInfo result2 =
1799 GetExpectedResultMemory(sizeof(cmds::GetError::Result));
1800 ExpectedMemoryInfo result3 =
1801 GetExpectedResultMemory(sizeof(cmds::GetError::Result));
1802 ExpectedMemoryInfo result4 =
1803 GetExpectedResultMemory(sizeof(cmds::GetError::Result));
1805 // Calls to flush to wait for GetError
1806 EXPECT_CALL(*command_buffer(), OnFlush())
1807 .WillOnce(SetMemory(result1.ptr, GLuint(GL_NO_ERROR)))
1808 .WillOnce(SetMemory(result2.ptr, GLuint(GL_NO_ERROR)))
1809 .WillOnce(SetMemory(result3.ptr, GLuint(GL_NO_ERROR)))
1810 .WillOnce(SetMemory(result4.ptr, GLuint(GL_NO_ERROR)))
1811 .RetiresOnSaturation();
1813 void* mem;
1814 mem = gl_->MapBufferSubDataCHROMIUM(kTarget, -1, kSize, GL_WRITE_ONLY);
1815 ASSERT_TRUE(mem == NULL);
1816 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE), gl_->GetError());
1817 mem = gl_->MapBufferSubDataCHROMIUM(kTarget, kOffset, -1, GL_WRITE_ONLY);
1818 ASSERT_TRUE(mem == NULL);
1819 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE), gl_->GetError());
1820 mem = gl_->MapBufferSubDataCHROMIUM(kTarget, kOffset, kSize, GL_READ_ONLY);
1821 ASSERT_TRUE(mem == NULL);
1822 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_ENUM), gl_->GetError());
1823 const char* kPtr = "something";
1824 gl_->UnmapBufferSubDataCHROMIUM(kPtr);
1825 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE), gl_->GetError());
1828 TEST_F(GLES2ImplementationTest, MapUnmapTexSubImage2DCHROMIUM) {
1829 struct Cmds {
1830 cmds::TexSubImage2D tex;
1831 cmd::SetToken set_token;
1833 const GLint kLevel = 1;
1834 const GLint kXOffset = 2;
1835 const GLint kYOffset = 3;
1836 const GLint kWidth = 4;
1837 const GLint kHeight = 5;
1838 const GLenum kFormat = GL_RGBA;
1839 const GLenum kType = GL_UNSIGNED_BYTE;
1841 uint32 offset = 0;
1842 Cmds expected;
1843 expected.tex.Init(
1844 GL_TEXTURE_2D, kLevel, kXOffset, kYOffset, kWidth, kHeight, kFormat,
1845 kType,
1846 command_buffer()->GetNextFreeTransferBufferId(), offset, GL_FALSE);
1847 expected.set_token.Init(GetNextToken());
1849 void* mem = gl_->MapTexSubImage2DCHROMIUM(
1850 GL_TEXTURE_2D,
1851 kLevel,
1852 kXOffset,
1853 kYOffset,
1854 kWidth,
1855 kHeight,
1856 kFormat,
1857 kType,
1858 GL_WRITE_ONLY);
1859 ASSERT_TRUE(mem != NULL);
1860 gl_->UnmapTexSubImage2DCHROMIUM(mem);
1861 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
1864 TEST_F(GLES2ImplementationTest, MapUnmapTexSubImage2DCHROMIUMBadArgs) {
1865 const GLint kLevel = 1;
1866 const GLint kXOffset = 2;
1867 const GLint kYOffset = 3;
1868 const GLint kWidth = 4;
1869 const GLint kHeight = 5;
1870 const GLenum kFormat = GL_RGBA;
1871 const GLenum kType = GL_UNSIGNED_BYTE;
1873 ExpectedMemoryInfo result1 =
1874 GetExpectedResultMemory(sizeof(cmds::GetError::Result));
1875 ExpectedMemoryInfo result2 =
1876 GetExpectedResultMemory(sizeof(cmds::GetError::Result));
1877 ExpectedMemoryInfo result3 =
1878 GetExpectedResultMemory(sizeof(cmds::GetError::Result));
1879 ExpectedMemoryInfo result4 =
1880 GetExpectedResultMemory(sizeof(cmds::GetError::Result));
1881 ExpectedMemoryInfo result5 =
1882 GetExpectedResultMemory(sizeof(cmds::GetError::Result));
1883 ExpectedMemoryInfo result6 =
1884 GetExpectedResultMemory(sizeof(cmds::GetError::Result));
1885 ExpectedMemoryInfo result7 =
1886 GetExpectedResultMemory(sizeof(cmds::GetError::Result));
1888 // Calls to flush to wait for GetError
1889 EXPECT_CALL(*command_buffer(), OnFlush())
1890 .WillOnce(SetMemory(result1.ptr, GLuint(GL_NO_ERROR)))
1891 .WillOnce(SetMemory(result2.ptr, GLuint(GL_NO_ERROR)))
1892 .WillOnce(SetMemory(result3.ptr, GLuint(GL_NO_ERROR)))
1893 .WillOnce(SetMemory(result4.ptr, GLuint(GL_NO_ERROR)))
1894 .WillOnce(SetMemory(result5.ptr, GLuint(GL_NO_ERROR)))
1895 .WillOnce(SetMemory(result6.ptr, GLuint(GL_NO_ERROR)))
1896 .WillOnce(SetMemory(result7.ptr, GLuint(GL_NO_ERROR)))
1897 .RetiresOnSaturation();
1899 void* mem;
1900 mem = gl_->MapTexSubImage2DCHROMIUM(
1901 GL_TEXTURE_2D,
1903 kXOffset,
1904 kYOffset,
1905 kWidth,
1906 kHeight,
1907 kFormat,
1908 kType,
1909 GL_WRITE_ONLY);
1910 EXPECT_TRUE(mem == NULL);
1911 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE), gl_->GetError());
1912 mem = gl_->MapTexSubImage2DCHROMIUM(
1913 GL_TEXTURE_2D,
1914 kLevel,
1916 kYOffset,
1917 kWidth,
1918 kHeight,
1919 kFormat,
1920 kType,
1921 GL_WRITE_ONLY);
1922 EXPECT_TRUE(mem == NULL);
1923 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE), gl_->GetError());
1924 mem = gl_->MapTexSubImage2DCHROMIUM(
1925 GL_TEXTURE_2D,
1926 kLevel,
1927 kXOffset,
1929 kWidth,
1930 kHeight,
1931 kFormat,
1932 kType,
1933 GL_WRITE_ONLY);
1934 EXPECT_TRUE(mem == NULL);
1935 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE), gl_->GetError());
1936 mem = gl_->MapTexSubImage2DCHROMIUM(
1937 GL_TEXTURE_2D,
1938 kLevel,
1939 kXOffset,
1940 kYOffset,
1942 kHeight,
1943 kFormat,
1944 kType,
1945 GL_WRITE_ONLY);
1946 EXPECT_TRUE(mem == NULL);
1947 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE), gl_->GetError());
1948 mem = gl_->MapTexSubImage2DCHROMIUM(
1949 GL_TEXTURE_2D,
1950 kLevel,
1951 kXOffset,
1952 kYOffset,
1953 kWidth,
1955 kFormat,
1956 kType,
1957 GL_WRITE_ONLY);
1958 EXPECT_TRUE(mem == NULL);
1959 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE), gl_->GetError());
1960 mem = gl_->MapTexSubImage2DCHROMIUM(
1961 GL_TEXTURE_2D,
1962 kLevel,
1963 kXOffset,
1964 kYOffset,
1965 kWidth,
1966 kHeight,
1967 kFormat,
1968 kType,
1969 GL_READ_ONLY);
1970 EXPECT_TRUE(mem == NULL);
1971 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_ENUM), gl_->GetError());
1972 const char* kPtr = "something";
1973 gl_->UnmapTexSubImage2DCHROMIUM(kPtr);
1974 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE), gl_->GetError());
1977 TEST_F(GLES2ImplementationTest, GetProgramInfoCHROMIUMGoodArgs) {
1978 const uint32 kBucketId = GLES2Implementation::kResultBucketId;
1979 const GLuint kProgramId = 123;
1980 const char kBad = 0x12;
1981 GLsizei size = 0;
1982 const Str7 kString = {"foobar"};
1983 char buf[20];
1985 ExpectedMemoryInfo mem1 =
1986 GetExpectedMemory(MaxTransferBufferSize());
1987 ExpectedMemoryInfo result1 =
1988 GetExpectedResultMemory(sizeof(cmd::GetBucketStart::Result));
1989 ExpectedMemoryInfo result2 =
1990 GetExpectedResultMemory(sizeof(cmds::GetError::Result));
1992 memset(buf, kBad, sizeof(buf));
1993 EXPECT_CALL(*command_buffer(), OnFlush())
1994 .WillOnce(DoAll(SetMemory(result1.ptr, uint32(sizeof(kString))),
1995 SetMemory(mem1.ptr, kString)))
1996 .WillOnce(SetMemory(result2.ptr, GLuint(GL_NO_ERROR)))
1997 .RetiresOnSaturation();
1999 struct Cmds {
2000 cmd::SetBucketSize set_bucket_size1;
2001 cmds::GetProgramInfoCHROMIUM get_program_info;
2002 cmd::GetBucketStart get_bucket_start;
2003 cmd::SetToken set_token1;
2004 cmd::SetBucketSize set_bucket_size2;
2006 Cmds expected;
2007 expected.set_bucket_size1.Init(kBucketId, 0);
2008 expected.get_program_info.Init(kProgramId, kBucketId);
2009 expected.get_bucket_start.Init(
2010 kBucketId, result1.id, result1.offset,
2011 MaxTransferBufferSize(), mem1.id, mem1.offset);
2012 expected.set_token1.Init(GetNextToken());
2013 expected.set_bucket_size2.Init(kBucketId, 0);
2014 gl_->GetProgramInfoCHROMIUM(kProgramId, sizeof(buf), &size, &buf);
2015 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
2016 EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), gl_->GetError());
2017 EXPECT_EQ(sizeof(kString), static_cast<size_t>(size));
2018 EXPECT_STREQ(kString.str, buf);
2019 EXPECT_EQ(buf[sizeof(kString)], kBad);
2022 TEST_F(GLES2ImplementationTest, GetProgramInfoCHROMIUMBadArgs) {
2023 const uint32 kBucketId = GLES2Implementation::kResultBucketId;
2024 const GLuint kProgramId = 123;
2025 GLsizei size = 0;
2026 const Str7 kString = {"foobar"};
2027 char buf[20];
2029 ExpectedMemoryInfo mem1 = GetExpectedMemory(MaxTransferBufferSize());
2030 ExpectedMemoryInfo result1 =
2031 GetExpectedResultMemory(sizeof(cmd::GetBucketStart::Result));
2032 ExpectedMemoryInfo result2 =
2033 GetExpectedResultMemory(sizeof(cmds::GetError::Result));
2034 ExpectedMemoryInfo result3 =
2035 GetExpectedResultMemory(sizeof(cmds::GetError::Result));
2036 ExpectedMemoryInfo result4 =
2037 GetExpectedResultMemory(sizeof(cmds::GetError::Result));
2039 EXPECT_CALL(*command_buffer(), OnFlush())
2040 .WillOnce(DoAll(SetMemory(result1.ptr, uint32(sizeof(kString))),
2041 SetMemory(mem1.ptr, kString)))
2042 .WillOnce(SetMemory(result2.ptr, GLuint(GL_NO_ERROR)))
2043 .WillOnce(SetMemory(result3.ptr, GLuint(GL_NO_ERROR)))
2044 .WillOnce(SetMemory(result4.ptr, GLuint(GL_NO_ERROR)))
2045 .RetiresOnSaturation();
2047 // try bufsize not big enough.
2048 struct Cmds {
2049 cmd::SetBucketSize set_bucket_size1;
2050 cmds::GetProgramInfoCHROMIUM get_program_info;
2051 cmd::GetBucketStart get_bucket_start;
2052 cmd::SetToken set_token1;
2053 cmd::SetBucketSize set_bucket_size2;
2055 Cmds expected;
2056 expected.set_bucket_size1.Init(kBucketId, 0);
2057 expected.get_program_info.Init(kProgramId, kBucketId);
2058 expected.get_bucket_start.Init(
2059 kBucketId, result1.id, result1.offset,
2060 MaxTransferBufferSize(), mem1.id, mem1.offset);
2061 expected.set_token1.Init(GetNextToken());
2062 expected.set_bucket_size2.Init(kBucketId, 0);
2063 gl_->GetProgramInfoCHROMIUM(kProgramId, 6, &size, &buf);
2064 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
2065 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_OPERATION), gl_->GetError());
2066 ClearCommands();
2068 // try bad bufsize
2069 gl_->GetProgramInfoCHROMIUM(kProgramId, -1, &size, &buf);
2070 EXPECT_TRUE(NoCommandsWritten());
2071 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE), gl_->GetError());
2072 ClearCommands();
2073 // try no size ptr.
2074 gl_->GetProgramInfoCHROMIUM(kProgramId, sizeof(buf), NULL, &buf);
2075 EXPECT_TRUE(NoCommandsWritten());
2076 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE), gl_->GetError());
2079 TEST_F(GLES2ImplementationTest, GetUniformBlocksCHROMIUMGoodArgs) {
2080 const uint32 kBucketId = GLES2Implementation::kResultBucketId;
2081 const GLuint kProgramId = 123;
2082 const char kBad = 0x12;
2083 GLsizei size = 0;
2084 const Str7 kString = {"foobar"};
2085 char buf[20];
2087 ExpectedMemoryInfo mem1 =
2088 GetExpectedMemory(MaxTransferBufferSize());
2089 ExpectedMemoryInfo result1 =
2090 GetExpectedResultMemory(sizeof(cmd::GetBucketStart::Result));
2091 ExpectedMemoryInfo result2 =
2092 GetExpectedResultMemory(sizeof(cmds::GetError::Result));
2094 memset(buf, kBad, sizeof(buf));
2095 EXPECT_CALL(*command_buffer(), OnFlush())
2096 .WillOnce(DoAll(SetMemory(result1.ptr, uint32(sizeof(kString))),
2097 SetMemory(mem1.ptr, kString)))
2098 .WillOnce(SetMemory(result2.ptr, GLuint(GL_NO_ERROR)))
2099 .RetiresOnSaturation();
2101 struct Cmds {
2102 cmd::SetBucketSize set_bucket_size1;
2103 cmds::GetUniformBlocksCHROMIUM get_uniform_blocks;
2104 cmd::GetBucketStart get_bucket_start;
2105 cmd::SetToken set_token1;
2106 cmd::SetBucketSize set_bucket_size2;
2108 Cmds expected;
2109 expected.set_bucket_size1.Init(kBucketId, 0);
2110 expected.get_uniform_blocks.Init(kProgramId, kBucketId);
2111 expected.get_bucket_start.Init(
2112 kBucketId, result1.id, result1.offset,
2113 MaxTransferBufferSize(), mem1.id, mem1.offset);
2114 expected.set_token1.Init(GetNextToken());
2115 expected.set_bucket_size2.Init(kBucketId, 0);
2116 gl_->GetUniformBlocksCHROMIUM(kProgramId, sizeof(buf), &size, &buf);
2117 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
2118 EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), gl_->GetError());
2119 EXPECT_EQ(sizeof(kString), static_cast<size_t>(size));
2120 EXPECT_STREQ(kString.str, buf);
2121 EXPECT_EQ(buf[sizeof(kString)], kBad);
2124 TEST_F(GLES2ImplementationTest, GetUniformBlocksCHROMIUMBadArgs) {
2125 const uint32 kBucketId = GLES2Implementation::kResultBucketId;
2126 const GLuint kProgramId = 123;
2127 GLsizei size = 0;
2128 const Str7 kString = {"foobar"};
2129 char buf[20];
2131 ExpectedMemoryInfo mem1 = GetExpectedMemory(MaxTransferBufferSize());
2132 ExpectedMemoryInfo result1 =
2133 GetExpectedResultMemory(sizeof(cmd::GetBucketStart::Result));
2134 ExpectedMemoryInfo result2 =
2135 GetExpectedResultMemory(sizeof(cmds::GetError::Result));
2136 ExpectedMemoryInfo result3 =
2137 GetExpectedResultMemory(sizeof(cmds::GetError::Result));
2138 ExpectedMemoryInfo result4 =
2139 GetExpectedResultMemory(sizeof(cmds::GetError::Result));
2141 EXPECT_CALL(*command_buffer(), OnFlush())
2142 .WillOnce(DoAll(SetMemory(result1.ptr, uint32(sizeof(kString))),
2143 SetMemory(mem1.ptr, kString)))
2144 .WillOnce(SetMemory(result2.ptr, GLuint(GL_NO_ERROR)))
2145 .WillOnce(SetMemory(result3.ptr, GLuint(GL_NO_ERROR)))
2146 .WillOnce(SetMemory(result4.ptr, GLuint(GL_NO_ERROR)))
2147 .RetiresOnSaturation();
2149 // try bufsize not big enough.
2150 struct Cmds {
2151 cmd::SetBucketSize set_bucket_size1;
2152 cmds::GetUniformBlocksCHROMIUM get_uniform_blocks;
2153 cmd::GetBucketStart get_bucket_start;
2154 cmd::SetToken set_token1;
2155 cmd::SetBucketSize set_bucket_size2;
2157 Cmds expected;
2158 expected.set_bucket_size1.Init(kBucketId, 0);
2159 expected.get_uniform_blocks.Init(kProgramId, kBucketId);
2160 expected.get_bucket_start.Init(
2161 kBucketId, result1.id, result1.offset,
2162 MaxTransferBufferSize(), mem1.id, mem1.offset);
2163 expected.set_token1.Init(GetNextToken());
2164 expected.set_bucket_size2.Init(kBucketId, 0);
2165 gl_->GetUniformBlocksCHROMIUM(kProgramId, 6, &size, &buf);
2166 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
2167 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_OPERATION), gl_->GetError());
2168 ClearCommands();
2170 // try bad bufsize
2171 gl_->GetUniformBlocksCHROMIUM(kProgramId, -1, &size, &buf);
2172 EXPECT_TRUE(NoCommandsWritten());
2173 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE), gl_->GetError());
2174 ClearCommands();
2175 // try no size ptr.
2176 gl_->GetUniformBlocksCHROMIUM(kProgramId, sizeof(buf), NULL, &buf);
2177 EXPECT_TRUE(NoCommandsWritten());
2178 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE), gl_->GetError());
2181 // Test that things are cached
2182 TEST_F(GLES2ImplementationTest, GetIntegerCacheRead) {
2183 struct PNameValue {
2184 GLenum pname;
2185 GLint expected;
2187 const PNameValue pairs[] = {
2188 {GL_ACTIVE_TEXTURE, GL_TEXTURE0, },
2189 {GL_TEXTURE_BINDING_2D, 0, },
2190 {GL_TEXTURE_BINDING_CUBE_MAP, 0, },
2191 {GL_TEXTURE_BINDING_EXTERNAL_OES, 0, },
2192 {GL_FRAMEBUFFER_BINDING, 0, },
2193 {GL_RENDERBUFFER_BINDING, 0, },
2194 {GL_ARRAY_BUFFER_BINDING, 0, },
2195 {GL_ELEMENT_ARRAY_BUFFER_BINDING, 0, },
2196 {GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, kMaxCombinedTextureImageUnits, },
2197 {GL_MAX_CUBE_MAP_TEXTURE_SIZE, kMaxCubeMapTextureSize, },
2198 {GL_MAX_FRAGMENT_UNIFORM_VECTORS, kMaxFragmentUniformVectors, },
2199 {GL_MAX_RENDERBUFFER_SIZE, kMaxRenderbufferSize, },
2200 {GL_MAX_TEXTURE_IMAGE_UNITS, kMaxTextureImageUnits, },
2201 {GL_MAX_TEXTURE_SIZE, kMaxTextureSize, },
2202 {GL_MAX_VARYING_VECTORS, kMaxVaryingVectors, },
2203 {GL_MAX_VERTEX_ATTRIBS, kMaxVertexAttribs, },
2204 {GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, kMaxVertexTextureImageUnits, },
2205 {GL_MAX_VERTEX_UNIFORM_VECTORS, kMaxVertexUniformVectors, },
2206 {GL_NUM_COMPRESSED_TEXTURE_FORMATS, kNumCompressedTextureFormats, },
2207 {GL_NUM_SHADER_BINARY_FORMATS, kNumShaderBinaryFormats, }, };
2208 size_t num_pairs = sizeof(pairs) / sizeof(pairs[0]);
2209 for (size_t ii = 0; ii < num_pairs; ++ii) {
2210 const PNameValue& pv = pairs[ii];
2211 GLint v = -1;
2212 gl_->GetIntegerv(pv.pname, &v);
2213 EXPECT_TRUE(NoCommandsWritten());
2214 EXPECT_EQ(pv.expected, v);
2217 ExpectedMemoryInfo result1 =
2218 GetExpectedResultMemory(sizeof(cmds::GetError::Result));
2220 EXPECT_CALL(*command_buffer(), OnFlush())
2221 .WillOnce(SetMemory(result1.ptr, GLuint(GL_NO_ERROR)))
2222 .RetiresOnSaturation();
2223 EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), gl_->GetError());
2226 TEST_F(GLES2ImplementationTest, GetIntegerDisjointValue) {
2227 ExpectedMemoryInfo mem = GetExpectedMappedMemory(sizeof(DisjointValueSync));
2228 gl_->SetDisjointValueSyncCHROMIUM();
2229 ASSERT_EQ(mem.id, GetQueryTracker()->DisjointCountSyncShmID());
2230 ASSERT_EQ(mem.offset, GetQueryTracker()->DisjointCountSyncShmOffset());
2231 DisjointValueSync* disjoint_sync =
2232 reinterpret_cast<DisjointValueSync*>(mem.ptr);
2234 ClearCommands();
2235 GLint disjoint_value = -1;
2236 gl_->GetIntegerv(GL_GPU_DISJOINT_EXT, &disjoint_value);
2237 EXPECT_TRUE(NoCommandsWritten());
2238 EXPECT_EQ(0, disjoint_value);
2240 // After setting disjoint, it should be true.
2241 disjoint_value = -1;
2242 disjoint_sync->SetDisjointCount(1);
2243 gl_->GetIntegerv(GL_GPU_DISJOINT_EXT, &disjoint_value);
2244 EXPECT_TRUE(NoCommandsWritten());
2245 EXPECT_EQ(1, disjoint_value);
2247 // After checking disjoint, it should be false again.
2248 disjoint_value = -1;
2249 gl_->GetIntegerv(GL_GPU_DISJOINT_EXT, &disjoint_value);
2250 EXPECT_TRUE(NoCommandsWritten());
2251 EXPECT_EQ(0, disjoint_value);
2253 // Check for errors.
2254 ExpectedMemoryInfo result1 =
2255 GetExpectedResultMemory(sizeof(cmds::GetError::Result));
2256 EXPECT_CALL(*command_buffer(), OnFlush())
2257 .WillOnce(SetMemory(result1.ptr, GLuint(GL_NO_ERROR)))
2258 .RetiresOnSaturation();
2259 EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), gl_->GetError());
2262 TEST_F(GLES2ImplementationTest, GetIntegerCacheWrite) {
2263 struct PNameValue {
2264 GLenum pname;
2265 GLint expected;
2267 gl_->ActiveTexture(GL_TEXTURE4);
2268 gl_->BindBuffer(GL_ARRAY_BUFFER, 2);
2269 gl_->BindBuffer(GL_ELEMENT_ARRAY_BUFFER, 3);
2270 gl_->BindFramebuffer(GL_FRAMEBUFFER, 4);
2271 gl_->BindRenderbuffer(GL_RENDERBUFFER, 5);
2272 gl_->BindTexture(GL_TEXTURE_2D, 6);
2273 gl_->BindTexture(GL_TEXTURE_CUBE_MAP, 7);
2274 gl_->BindTexture(GL_TEXTURE_EXTERNAL_OES, 8);
2276 const PNameValue pairs[] = {{GL_ACTIVE_TEXTURE, GL_TEXTURE4, },
2277 {GL_ARRAY_BUFFER_BINDING, 2, },
2278 {GL_ELEMENT_ARRAY_BUFFER_BINDING, 3, },
2279 {GL_FRAMEBUFFER_BINDING, 4, },
2280 {GL_RENDERBUFFER_BINDING, 5, },
2281 {GL_TEXTURE_BINDING_2D, 6, },
2282 {GL_TEXTURE_BINDING_CUBE_MAP, 7, },
2283 {GL_TEXTURE_BINDING_EXTERNAL_OES, 8, }, };
2284 size_t num_pairs = sizeof(pairs) / sizeof(pairs[0]);
2285 for (size_t ii = 0; ii < num_pairs; ++ii) {
2286 const PNameValue& pv = pairs[ii];
2287 GLint v = -1;
2288 gl_->GetIntegerv(pv.pname, &v);
2289 EXPECT_EQ(pv.expected, v);
2292 ExpectedMemoryInfo result1 =
2293 GetExpectedResultMemory(sizeof(cmds::GetError::Result));
2295 EXPECT_CALL(*command_buffer(), OnFlush())
2296 .WillOnce(SetMemory(result1.ptr, GLuint(GL_NO_ERROR)))
2297 .RetiresOnSaturation();
2298 EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), gl_->GetError());
2301 static bool CheckRect(
2302 int width, int height, GLenum format, GLenum type, int alignment,
2303 const uint8* r1, const uint8* r2) {
2304 uint32 size = 0;
2305 uint32 unpadded_row_size = 0;
2306 uint32 padded_row_size = 0;
2307 if (!GLES2Util::ComputeImageDataSizes(
2308 width, height, 1, format, type, alignment, &size, &unpadded_row_size,
2309 &padded_row_size)) {
2310 return false;
2313 int r2_stride = static_cast<int>(padded_row_size);
2315 for (int y = 0; y < height; ++y) {
2316 if (memcmp(r1, r2, unpadded_row_size) != 0) {
2317 return false;
2319 r1 += padded_row_size;
2320 r2 += r2_stride;
2322 return true;
2325 ACTION_P7(CheckRectAction, width, height, format, type, alignment, r1, r2) {
2326 EXPECT_TRUE(CheckRect(
2327 width, height, format, type, alignment, r1, r2));
2330 TEST_F(GLES2ImplementationTest, TexImage2D) {
2331 struct Cmds {
2332 cmds::TexImage2D tex_image_2d;
2333 cmd::SetToken set_token;
2335 struct Cmds2 {
2336 cmds::TexImage2D tex_image_2d;
2337 cmd::SetToken set_token;
2339 const GLenum kTarget = GL_TEXTURE_2D;
2340 const GLint kLevel = 0;
2341 const GLenum kFormat = GL_RGB;
2342 const GLsizei kWidth = 3;
2343 const GLsizei kHeight = 4;
2344 const GLint kBorder = 0;
2345 const GLenum kType = GL_UNSIGNED_BYTE;
2346 const GLint kPixelStoreUnpackAlignment = 4;
2347 static uint8 pixels[] = {
2348 11, 12, 13, 13, 14, 15, 15, 16, 17, 101, 102, 103,
2349 21, 22, 23, 23, 24, 25, 25, 26, 27, 201, 202, 203,
2350 31, 32, 33, 33, 34, 35, 35, 36, 37, 123, 124, 125,
2351 41, 42, 43, 43, 44, 45, 45, 46, 47,
2354 ExpectedMemoryInfo mem1 = GetExpectedMemory(sizeof(pixels));
2356 Cmds expected;
2357 expected.tex_image_2d.Init(
2358 kTarget, kLevel, kFormat, kWidth, kHeight, kFormat, kType,
2359 mem1.id, mem1.offset);
2360 expected.set_token.Init(GetNextToken());
2361 gl_->TexImage2D(
2362 kTarget, kLevel, kFormat, kWidth, kHeight, kBorder, kFormat, kType,
2363 pixels);
2364 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
2365 EXPECT_TRUE(CheckRect(
2366 kWidth, kHeight, kFormat, kType, kPixelStoreUnpackAlignment,
2367 pixels, mem1.ptr));
2370 TEST_F(GLES2ImplementationTest, TexImage2DViaMappedMem) {
2371 struct Cmds {
2372 cmds::TexImage2D tex_image_2d;
2373 cmd::SetToken set_token;
2375 const GLenum kTarget = GL_TEXTURE_2D;
2376 const GLint kLevel = 0;
2377 const GLenum kFormat = GL_RGB;
2378 const GLsizei kWidth = 3;
2379 const GLint kBorder = 0;
2380 const GLenum kType = GL_UNSIGNED_BYTE;
2381 const GLint kPixelStoreUnpackAlignment = 4;
2383 uint32 size = 0;
2384 uint32 unpadded_row_size = 0;
2385 uint32 padded_row_size = 0;
2386 ASSERT_TRUE(GLES2Util::ComputeImageDataSizes(
2387 kWidth, 2, 1, kFormat, kType, kPixelStoreUnpackAlignment,
2388 &size, &unpadded_row_size, &padded_row_size));
2389 const GLsizei kMaxHeight = (MaxTransferBufferSize() / padded_row_size) * 2;
2390 const GLsizei kHeight = kMaxHeight * 2;
2391 ASSERT_TRUE(GLES2Util::ComputeImageDataSizes(
2392 kWidth, kHeight, 1, kFormat, kType, kPixelStoreUnpackAlignment,
2393 &size, &unpadded_row_size, &padded_row_size));
2395 scoped_ptr<uint8[]> pixels(new uint8[size]);
2396 for (uint32 ii = 0; ii < size; ++ii) {
2397 pixels[ii] = static_cast<uint8>(ii);
2400 ExpectedMemoryInfo mem1 = GetExpectedMappedMemory(size);
2402 Cmds expected;
2403 expected.tex_image_2d.Init(
2404 kTarget, kLevel, kFormat, kWidth, kHeight, kFormat, kType,
2405 mem1.id, mem1.offset);
2406 expected.set_token.Init(GetNextToken());
2407 gl_->TexImage2D(
2408 kTarget, kLevel, kFormat, kWidth, kHeight, kBorder, kFormat, kType,
2409 pixels.get());
2410 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
2411 EXPECT_TRUE(CheckRect(
2412 kWidth, kHeight, kFormat, kType, kPixelStoreUnpackAlignment,
2413 pixels.get(), mem1.ptr));
2416 // Test TexImage2D with 2 writes
2417 TEST_F(GLES2ImplementationTest, TexImage2DViaTexSubImage2D) {
2418 // Set limit to 1 to effectively disable mapped memory.
2419 SetMappedMemoryLimit(1);
2421 struct Cmds {
2422 cmds::TexImage2D tex_image_2d;
2423 cmds::TexSubImage2D tex_sub_image_2d1;
2424 cmd::SetToken set_token1;
2425 cmds::TexSubImage2D tex_sub_image_2d2;
2426 cmd::SetToken set_token2;
2428 const GLenum kTarget = GL_TEXTURE_2D;
2429 const GLint kLevel = 0;
2430 const GLenum kFormat = GL_RGB;
2431 const GLint kBorder = 0;
2432 const GLenum kType = GL_UNSIGNED_BYTE;
2433 const GLint kPixelStoreUnpackAlignment = 4;
2434 const GLsizei kWidth = 3;
2436 uint32 size = 0;
2437 uint32 unpadded_row_size = 0;
2438 uint32 padded_row_size = 0;
2439 ASSERT_TRUE(GLES2Util::ComputeImageDataSizes(
2440 kWidth, 2, 1, kFormat, kType, kPixelStoreUnpackAlignment,
2441 &size, &unpadded_row_size, &padded_row_size));
2442 const GLsizei kHeight = (MaxTransferBufferSize() / padded_row_size) * 2;
2443 ASSERT_TRUE(GLES2Util::ComputeImageDataSizes(
2444 kWidth, kHeight, 1, kFormat, kType, kPixelStoreUnpackAlignment,
2445 &size, NULL, NULL));
2446 uint32 half_size = 0;
2447 ASSERT_TRUE(GLES2Util::ComputeImageDataSizes(
2448 kWidth, kHeight / 2, 1, kFormat, kType, kPixelStoreUnpackAlignment,
2449 &half_size, NULL, NULL));
2451 scoped_ptr<uint8[]> pixels(new uint8[size]);
2452 for (uint32 ii = 0; ii < size; ++ii) {
2453 pixels[ii] = static_cast<uint8>(ii);
2456 ExpectedMemoryInfo mem1 = GetExpectedMemory(half_size);
2457 ExpectedMemoryInfo mem2 = GetExpectedMemory(half_size);
2459 Cmds expected;
2460 expected.tex_image_2d.Init(
2461 kTarget, kLevel, kFormat, kWidth, kHeight, kFormat, kType,
2462 0, 0);
2463 expected.tex_sub_image_2d1.Init(
2464 kTarget, kLevel, 0, 0, kWidth, kHeight / 2, kFormat, kType,
2465 mem1.id, mem1.offset, true);
2466 expected.set_token1.Init(GetNextToken());
2467 expected.tex_sub_image_2d2.Init(
2468 kTarget, kLevel, 0, kHeight / 2, kWidth, kHeight / 2, kFormat, kType,
2469 mem2.id, mem2.offset, true);
2470 expected.set_token2.Init(GetNextToken());
2472 // TODO(gman): Make it possible to run this test
2473 // EXPECT_CALL(*command_buffer(), OnFlush())
2474 // .WillOnce(CheckRectAction(
2475 // kWidth, kHeight / 2, kFormat, kType, kPixelStoreUnpackAlignment,
2476 // false, pixels.get(),
2477 // GetExpectedTransferAddressFromOffsetAs<uint8>(offset1, half_size)))
2478 // .RetiresOnSaturation();
2480 gl_->TexImage2D(
2481 kTarget, kLevel, kFormat, kWidth, kHeight, kBorder, kFormat, kType,
2482 pixels.get());
2483 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
2484 EXPECT_TRUE(CheckRect(
2485 kWidth, kHeight / 2, kFormat, kType, kPixelStoreUnpackAlignment,
2486 pixels.get() + kHeight / 2 * padded_row_size, mem2.ptr));
2489 TEST_F(GLES2ImplementationTest, SubImageUnpack) {
2490 static const GLint unpack_alignments[] = { 1, 2, 4, 8 };
2492 static const GLenum kFormat = GL_RGB;
2493 static const GLenum kType = GL_UNSIGNED_BYTE;
2494 static const GLint kLevel = 0;
2495 static const GLint kBorder = 0;
2496 // We're testing using the unpack params to pull a subimage out of a larger
2497 // source of pixels. Here we specify the subimage by its border rows /
2498 // columns.
2499 static const GLint kSrcWidth = 33;
2500 static const GLint kSrcSubImageX0 = 11;
2501 static const GLint kSrcSubImageX1 = 20;
2502 static const GLint kSrcSubImageY0 = 18;
2503 static const GLint kSrcSubImageY1 = 23;
2504 static const GLint kSrcSubImageWidth = kSrcSubImageX1 - kSrcSubImageX0;
2505 static const GLint kSrcSubImageHeight = kSrcSubImageY1 - kSrcSubImageY0;
2507 // these are only used in the texsubimage tests
2508 static const GLint kTexWidth = 1023;
2509 static const GLint kTexHeight = 511;
2510 static const GLint kTexSubXOffset = 419;
2511 static const GLint kTexSubYOffset = 103;
2513 struct {
2514 cmds::PixelStorei pixel_store_i;
2515 cmds::TexImage2D tex_image_2d;
2516 } texImageExpected;
2518 struct {
2519 cmds::PixelStorei pixel_store_i;
2520 cmds::TexImage2D tex_image_2d;
2521 cmds::TexSubImage2D tex_sub_image_2d;
2522 } texSubImageExpected;
2524 uint32 src_size;
2525 ASSERT_TRUE(GLES2Util::ComputeImageDataSizes(
2526 kSrcWidth, kSrcSubImageY1, 1, kFormat, kType, 8, &src_size, NULL, NULL));
2527 scoped_ptr<uint8[]> src_pixels;
2528 src_pixels.reset(new uint8[src_size]);
2529 for (size_t i = 0; i < src_size; ++i) {
2530 src_pixels[i] = static_cast<int8>(i);
2533 for (int sub = 0; sub < 2; ++sub) {
2534 for (size_t a = 0; a < arraysize(unpack_alignments); ++a) {
2535 GLint alignment = unpack_alignments[a];
2536 uint32 size;
2537 uint32 unpadded_row_size;
2538 uint32 padded_row_size;
2539 ASSERT_TRUE(GLES2Util::ComputeImageDataSizes(
2540 kSrcSubImageWidth, kSrcSubImageHeight, 1, kFormat, kType, alignment,
2541 &size, &unpadded_row_size, &padded_row_size));
2542 ASSERT_TRUE(size <= MaxTransferBufferSize());
2543 ExpectedMemoryInfo mem = GetExpectedMemory(size);
2545 const void* commands = GetPut();
2546 gl_->PixelStorei(GL_UNPACK_ALIGNMENT, alignment);
2547 gl_->PixelStorei(GL_UNPACK_ROW_LENGTH_EXT, kSrcWidth);
2548 gl_->PixelStorei(GL_UNPACK_SKIP_PIXELS_EXT, kSrcSubImageX0);
2549 gl_->PixelStorei(GL_UNPACK_SKIP_ROWS_EXT, kSrcSubImageY0);
2550 if (sub) {
2551 gl_->TexImage2D(
2552 GL_TEXTURE_2D, kLevel, kFormat, kTexWidth, kTexHeight, kBorder,
2553 kFormat, kType, NULL);
2554 gl_->TexSubImage2D(
2555 GL_TEXTURE_2D, kLevel, kTexSubXOffset, kTexSubYOffset,
2556 kSrcSubImageWidth, kSrcSubImageHeight, kFormat, kType,
2557 src_pixels.get());
2558 texSubImageExpected.pixel_store_i.Init(
2559 GL_UNPACK_ALIGNMENT, alignment);
2560 texSubImageExpected.tex_image_2d.Init(
2561 GL_TEXTURE_2D, kLevel, kFormat, kTexWidth, kTexHeight,
2562 kFormat, kType, 0, 0);
2563 texSubImageExpected.tex_sub_image_2d.Init(
2564 GL_TEXTURE_2D, kLevel, kTexSubXOffset, kTexSubYOffset,
2565 kSrcSubImageWidth, kSrcSubImageHeight, kFormat, kType, mem.id,
2566 mem.offset, GL_FALSE);
2567 EXPECT_EQ(0, memcmp(
2568 &texSubImageExpected, commands, sizeof(texSubImageExpected)));
2569 } else {
2570 gl_->TexImage2D(
2571 GL_TEXTURE_2D, kLevel, kFormat,
2572 kSrcSubImageWidth, kSrcSubImageHeight, kBorder, kFormat, kType,
2573 src_pixels.get());
2574 texImageExpected.pixel_store_i.Init(GL_UNPACK_ALIGNMENT, alignment);
2575 texImageExpected.tex_image_2d.Init(
2576 GL_TEXTURE_2D, kLevel, kFormat, kSrcSubImageWidth,
2577 kSrcSubImageHeight, kFormat, kType, mem.id, mem.offset);
2578 EXPECT_EQ(0, memcmp(
2579 &texImageExpected, commands, sizeof(texImageExpected)));
2581 uint32 src_padded_row_size;
2582 ASSERT_TRUE(GLES2Util::ComputeImagePaddedRowSize(
2583 kSrcWidth, kFormat, kType, alignment, &src_padded_row_size));
2584 uint32 bytes_per_group = GLES2Util::ComputeImageGroupSize(
2585 kFormat, kType);
2586 for (int y = 0; y < kSrcSubImageHeight; ++y) {
2587 const uint8* src_row = src_pixels.get() +
2588 (kSrcSubImageY0 + y) * src_padded_row_size +
2589 bytes_per_group * kSrcSubImageX0;
2590 const uint8* dst_row = mem.ptr + y * padded_row_size;
2591 EXPECT_EQ(0, memcmp(src_row, dst_row, unpadded_row_size));
2593 ClearCommands();
2598 // Test texture related calls with invalid arguments.
2599 TEST_F(GLES2ImplementationTest, TextureInvalidArguments) {
2600 struct Cmds {
2601 cmds::TexImage2D tex_image_2d;
2602 cmd::SetToken set_token;
2604 const GLenum kTarget = GL_TEXTURE_2D;
2605 const GLint kLevel = 0;
2606 const GLenum kFormat = GL_RGB;
2607 const GLsizei kWidth = 3;
2608 const GLsizei kHeight = 4;
2609 const GLint kBorder = 0;
2610 const GLint kInvalidBorder = 1;
2611 const GLenum kType = GL_UNSIGNED_BYTE;
2612 const GLint kPixelStoreUnpackAlignment = 4;
2613 static uint8 pixels[] = {
2614 11, 12, 13, 13, 14, 15, 15, 16, 17, 101, 102, 103,
2615 21, 22, 23, 23, 24, 25, 25, 26, 27, 201, 202, 203,
2616 31, 32, 33, 33, 34, 35, 35, 36, 37, 123, 124, 125,
2617 41, 42, 43, 43, 44, 45, 45, 46, 47,
2620 // Verify that something works.
2622 ExpectedMemoryInfo mem1 = GetExpectedMemory(sizeof(pixels));
2624 Cmds expected;
2625 expected.tex_image_2d.Init(
2626 kTarget, kLevel, kFormat, kWidth, kHeight, kFormat, kType,
2627 mem1.id, mem1.offset);
2628 expected.set_token.Init(GetNextToken());
2629 gl_->TexImage2D(
2630 kTarget, kLevel, kFormat, kWidth, kHeight, kBorder, kFormat, kType,
2631 pixels);
2632 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
2633 EXPECT_TRUE(CheckRect(
2634 kWidth, kHeight, kFormat, kType, kPixelStoreUnpackAlignment,
2635 pixels, mem1.ptr));
2637 ClearCommands();
2639 // Use invalid border.
2640 gl_->TexImage2D(
2641 kTarget, kLevel, kFormat, kWidth, kHeight, kInvalidBorder, kFormat, kType,
2642 pixels);
2644 EXPECT_TRUE(NoCommandsWritten());
2645 EXPECT_EQ(GL_INVALID_VALUE, CheckError());
2647 ClearCommands();
2649 // Checking for CompressedTexImage2D argument validation is a bit tricky due
2650 // to (runtime-detected) compression formats. Try to infer the error with an
2651 // aux check.
2652 const GLenum kCompressedFormat = GL_ETC1_RGB8_OES;
2653 gl_->CompressedTexImage2D(
2654 kTarget, kLevel, kCompressedFormat, kWidth, kHeight, kBorder,
2655 arraysize(pixels), pixels);
2657 // In the above, kCompressedFormat and arraysize(pixels) are possibly wrong
2658 // values. First ensure that these do not cause failures at the client. If
2659 // this check ever fails, it probably means that client checks more than at
2660 // the time of writing of this test. In this case, more code needs to be
2661 // written for this test.
2662 EXPECT_FALSE(NoCommandsWritten());
2664 ClearCommands();
2666 // Changing border to invalid border should make the call fail at the client
2667 // checks.
2668 gl_->CompressedTexImage2D(
2669 kTarget, kLevel, kCompressedFormat, kWidth, kHeight, kInvalidBorder,
2670 arraysize(pixels), pixels);
2671 EXPECT_TRUE(NoCommandsWritten());
2672 EXPECT_EQ(GL_INVALID_VALUE, CheckError());
2675 TEST_F(GLES2ImplementationTest, TexImage3DSingleCommand) {
2676 struct Cmds {
2677 cmds::TexImage3D tex_image_3d;
2679 const GLenum kTarget = GL_TEXTURE_3D;
2680 const GLint kLevel = 0;
2681 const GLint kBorder = 0;
2682 const GLenum kFormat = GL_RGB;
2683 const GLenum kType = GL_UNSIGNED_BYTE;
2684 const GLint kPixelStoreUnpackAlignment = 4;
2685 const GLsizei kWidth = 3;
2686 const GLsizei kDepth = 2;
2688 uint32 size = 0;
2689 uint32 unpadded_row_size = 0;
2690 uint32 padded_row_size = 0;
2691 ASSERT_TRUE(GLES2Util::ComputeImageDataSizes(
2692 kWidth, 2, kDepth, kFormat, kType, kPixelStoreUnpackAlignment,
2693 &size, &unpadded_row_size, &padded_row_size));
2694 // Makes sure we can just send over the data in one command.
2695 const GLsizei kHeight = MaxTransferBufferSize() / padded_row_size / kDepth;
2696 ASSERT_TRUE(GLES2Util::ComputeImageDataSizes(
2697 kWidth, kHeight, kDepth, kFormat, kType, kPixelStoreUnpackAlignment,
2698 &size, NULL, NULL));
2700 scoped_ptr<uint8[]> pixels(new uint8[size]);
2701 for (uint32 ii = 0; ii < size; ++ii) {
2702 pixels[ii] = static_cast<uint8>(ii);
2705 ExpectedMemoryInfo mem = GetExpectedMemory(size);
2707 Cmds expected;
2708 expected.tex_image_3d.Init(
2709 kTarget, kLevel, kFormat, kWidth, kHeight, kDepth,
2710 kFormat, kType, mem.id, mem.offset);
2712 gl_->TexImage3D(
2713 kTarget, kLevel, kFormat, kWidth, kHeight, kDepth, kBorder,
2714 kFormat, kType, pixels.get());
2716 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
2717 EXPECT_TRUE(CheckRect(
2718 kWidth, kHeight * kDepth, kFormat, kType, kPixelStoreUnpackAlignment,
2719 reinterpret_cast<uint8*>(pixels.get()), mem.ptr));
2722 TEST_F(GLES2ImplementationTest, TexImage3DViaMappedMem) {
2723 struct Cmds {
2724 cmds::TexImage3D tex_image_3d;
2726 const GLenum kTarget = GL_TEXTURE_3D;
2727 const GLint kLevel = 0;
2728 const GLint kBorder = 0;
2729 const GLenum kFormat = GL_RGB;
2730 const GLenum kType = GL_UNSIGNED_BYTE;
2731 const GLint kPixelStoreUnpackAlignment = 4;
2732 const GLsizei kWidth = 3;
2733 const GLsizei kDepth = 2;
2735 uint32 size = 0;
2736 uint32 unpadded_row_size = 0;
2737 uint32 padded_row_size = 0;
2738 ASSERT_TRUE(GLES2Util::ComputeImageDataSizes(
2739 kWidth, 2, kDepth, kFormat, kType, kPixelStoreUnpackAlignment,
2740 &size, &unpadded_row_size, &padded_row_size));
2741 // Makes sure we can just send over the data in one command.
2742 const GLsizei kMaxHeight = MaxTransferBufferSize() / padded_row_size / kDepth;
2743 const GLsizei kHeight = kMaxHeight * 2;
2744 ASSERT_TRUE(GLES2Util::ComputeImageDataSizes(
2745 kWidth, kHeight, kDepth, kFormat, kType, kPixelStoreUnpackAlignment,
2746 &size, NULL, NULL));
2748 scoped_ptr<uint8[]> pixels(new uint8[size]);
2749 for (uint32 ii = 0; ii < size; ++ii) {
2750 pixels[ii] = static_cast<uint8>(ii);
2753 ExpectedMemoryInfo mem = GetExpectedMappedMemory(size);
2755 Cmds expected;
2756 expected.tex_image_3d.Init(
2757 kTarget, kLevel, kFormat, kWidth, kHeight, kDepth,
2758 kFormat, kType, mem.id, mem.offset);
2760 gl_->TexImage3D(
2761 kTarget, kLevel, kFormat, kWidth, kHeight, kDepth, kBorder,
2762 kFormat, kType, pixels.get());
2764 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
2765 EXPECT_TRUE(CheckRect(
2766 kWidth, kHeight * kDepth, kFormat, kType, kPixelStoreUnpackAlignment,
2767 reinterpret_cast<uint8*>(pixels.get()), mem.ptr));
2770 TEST_F(GLES2ImplementationTest, TexImage3DViaTexSubImage3D) {
2771 // Set limit to 1 to effectively disable mapped memory.
2772 SetMappedMemoryLimit(1);
2774 struct Cmds {
2775 cmds::TexImage3D tex_image_3d;
2776 cmds::TexSubImage3D tex_sub_image_3d1;
2777 cmd::SetToken set_token;
2778 cmds::TexSubImage3D tex_sub_image_3d2;
2780 const GLenum kTarget = GL_TEXTURE_3D;
2781 const GLint kLevel = 0;
2782 const GLint kBorder = 0;
2783 const GLenum kFormat = GL_RGB;
2784 const GLenum kType = GL_UNSIGNED_BYTE;
2785 const GLint kPixelStoreUnpackAlignment = 4;
2786 const GLsizei kWidth = 3;
2788 uint32 size = 0;
2789 uint32 unpadded_row_size = 0;
2790 uint32 padded_row_size = 0;
2791 ASSERT_TRUE(GLES2Util::ComputeImageDataSizes(
2792 kWidth, 2, 1, kFormat, kType, kPixelStoreUnpackAlignment,
2793 &size, &unpadded_row_size, &padded_row_size));
2794 // Makes sure the data is more than one command can hold.
2795 const GLsizei kHeight = MaxTransferBufferSize() / padded_row_size + 3;
2796 ASSERT_TRUE(GLES2Util::ComputeImageDataSizes(
2797 kWidth, kHeight, 1, kFormat, kType, kPixelStoreUnpackAlignment,
2798 &size, NULL, NULL));
2799 uint32 first_size = padded_row_size * (kHeight - 3);
2800 uint32 second_size =
2801 padded_row_size * 3 - (padded_row_size - unpadded_row_size);
2802 EXPECT_EQ(size, first_size + second_size);
2803 ExpectedMemoryInfo mem1 = GetExpectedMemory(first_size);
2804 ExpectedMemoryInfo mem2 = GetExpectedMemory(second_size);
2805 scoped_ptr<uint8[]> pixels(new uint8[size]);
2806 for (uint32 ii = 0; ii < size; ++ii) {
2807 pixels[ii] = static_cast<uint8>(ii);
2810 Cmds expected;
2811 expected.tex_image_3d.Init(
2812 kTarget, kLevel, kFormat, kWidth, kHeight, 1, kFormat, kType, 0, 0);
2813 expected.tex_sub_image_3d1.Init(
2814 kTarget, kLevel, 0, 0, 0, kWidth, kHeight - 3, 1, kFormat, kType,
2815 mem1.id, mem1.offset, GL_TRUE);
2816 expected.tex_sub_image_3d2.Init(
2817 kTarget, kLevel, 0, kHeight - 3, 0, kWidth, 3, 1, kFormat, kType,
2818 mem2.id, mem2.offset, GL_TRUE);
2819 expected.set_token.Init(GetNextToken());
2821 gl_->TexImage3D(
2822 kTarget, kLevel, kFormat, kWidth, kHeight, 1, kBorder,
2823 kFormat, kType, pixels.get());
2824 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
2827 // Test TexSubImage3D with 4 writes
2828 TEST_F(GLES2ImplementationTest, TexSubImage3D4Writes) {
2829 struct Cmds {
2830 cmds::TexSubImage3D tex_sub_image_3d1_1;
2831 cmd::SetToken set_token1;
2832 cmds::TexSubImage3D tex_sub_image_3d1_2;
2833 cmd::SetToken set_token2;
2834 cmds::TexSubImage3D tex_sub_image_3d2_1;
2835 cmd::SetToken set_token3;
2836 cmds::TexSubImage3D tex_sub_image_3d2_2;
2838 const GLenum kTarget = GL_TEXTURE_3D;
2839 const GLint kLevel = 0;
2840 const GLint kXOffset = 0;
2841 const GLint kYOffset = 0;
2842 const GLint kZOffset = 0;
2843 const GLenum kFormat = GL_RGB;
2844 const GLenum kType = GL_UNSIGNED_BYTE;
2845 const GLint kPixelStoreUnpackAlignment = 4;
2846 const GLsizei kWidth = 3;
2847 const GLsizei kDepth = 2;
2849 uint32 size = 0;
2850 uint32 unpadded_row_size = 0;
2851 uint32 padded_row_size = 0;
2852 ASSERT_TRUE(GLES2Util::ComputeImageDataSizes(
2853 kWidth, 2, 1, kFormat, kType, kPixelStoreUnpackAlignment,
2854 &size, &unpadded_row_size, &padded_row_size));
2855 const GLsizei kHeight = MaxTransferBufferSize() / padded_row_size + 2;
2856 ASSERT_TRUE(GLES2Util::ComputeImageDataSizes(
2857 kWidth, kHeight, kDepth, kFormat, kType, kPixelStoreUnpackAlignment,
2858 &size, NULL, NULL));
2859 uint32 first_size = (kHeight - 2) * padded_row_size;
2860 uint32 second_size = 2 * padded_row_size;
2861 uint32 third_size = first_size;
2862 uint32 fourth_size = second_size - (padded_row_size - unpadded_row_size);
2863 EXPECT_EQ(size, first_size + second_size + third_size + fourth_size);
2865 scoped_ptr<uint8[]> pixels(new uint8[size]);
2866 for (uint32 ii = 0; ii < size; ++ii) {
2867 pixels[ii] = static_cast<uint8>(ii);
2870 ExpectedMemoryInfo mem1_1 = GetExpectedMemory(first_size);
2871 ExpectedMemoryInfo mem1_2 = GetExpectedMemory(second_size);
2872 ExpectedMemoryInfo mem2_1 = GetExpectedMemory(third_size);
2873 ExpectedMemoryInfo mem2_2 = GetExpectedMemory(fourth_size);
2875 Cmds expected;
2876 expected.tex_sub_image_3d1_1.Init(
2877 kTarget, kLevel, kXOffset, kYOffset, kZOffset,
2878 kWidth, kHeight - 2, 1, kFormat, kType,
2879 mem1_1.id, mem1_1.offset, GL_FALSE);
2880 expected.tex_sub_image_3d1_2.Init(
2881 kTarget, kLevel, kXOffset, kYOffset + kHeight - 2, kZOffset,
2882 kWidth, 2, 1, kFormat, kType, mem1_2.id, mem1_2.offset, GL_FALSE);
2883 expected.tex_sub_image_3d2_1.Init(
2884 kTarget, kLevel, kXOffset, kYOffset, kZOffset + 1,
2885 kWidth, kHeight - 2, 1, kFormat, kType,
2886 mem2_1.id, mem2_1.offset, GL_FALSE);
2887 expected.tex_sub_image_3d2_2.Init(
2888 kTarget, kLevel, kXOffset, kYOffset + kHeight - 2, kZOffset + 1,
2889 kWidth, 2, 1, kFormat, kType, mem2_2.id, mem2_2.offset, GL_FALSE);
2890 expected.set_token1.Init(GetNextToken());
2891 expected.set_token2.Init(GetNextToken());
2892 expected.set_token3.Init(GetNextToken());
2894 gl_->TexSubImage3D(
2895 kTarget, kLevel, kXOffset, kYOffset, kZOffset, kWidth, kHeight, kDepth,
2896 kFormat, kType, pixels.get());
2898 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
2899 uint32 offset_to_last = first_size + second_size + third_size;
2900 EXPECT_TRUE(CheckRect(
2901 kWidth, 2, kFormat, kType, kPixelStoreUnpackAlignment,
2902 reinterpret_cast<uint8*>(pixels.get()) + offset_to_last, mem2_2.ptr));
2905 // glGen* Ids must not be reused until glDelete* commands have been
2906 // flushed by glFlush.
2907 TEST_F(GLES2ImplementationStrictSharedTest, FlushGenerationTestBuffers) {
2908 FlushGenerationTest<GenBuffersAPI>();
2910 TEST_F(GLES2ImplementationStrictSharedTest, FlushGenerationTestFramebuffers) {
2911 FlushGenerationTest<GenFramebuffersAPI>();
2913 TEST_F(GLES2ImplementationStrictSharedTest, FlushGenerationTestRenderbuffers) {
2914 FlushGenerationTest<GenRenderbuffersAPI>();
2916 TEST_F(GLES2ImplementationStrictSharedTest, FlushGenerationTestTextures) {
2917 FlushGenerationTest<GenTexturesAPI>();
2920 // glGen* Ids must not be reused cross-context until glDelete* commands are
2921 // flushed by glFlush, and the Ids are lazily freed after.
2922 TEST_F(GLES2ImplementationStrictSharedTest, CrossContextGenerationTestBuffers) {
2923 CrossContextGenerationTest<GenBuffersAPI>();
2925 TEST_F(GLES2ImplementationStrictSharedTest,
2926 CrossContextGenerationTestFramebuffers) {
2927 CrossContextGenerationTest<GenFramebuffersAPI>();
2929 TEST_F(GLES2ImplementationStrictSharedTest,
2930 CrossContextGenerationTestRenderbuffers) {
2931 CrossContextGenerationTest<GenRenderbuffersAPI>();
2933 TEST_F(GLES2ImplementationStrictSharedTest,
2934 CrossContextGenerationTestTextures) {
2935 CrossContextGenerationTest<GenTexturesAPI>();
2938 // Test Delete which causes auto flush. Tests a regression case that occurred
2939 // in testing.
2940 TEST_F(GLES2ImplementationStrictSharedTest,
2941 CrossContextGenerationAutoFlushTestBuffers) {
2942 CrossContextGenerationAutoFlushTest<GenBuffersAPI>();
2944 TEST_F(GLES2ImplementationStrictSharedTest,
2945 CrossContextGenerationAutoFlushTestFramebuffers) {
2946 CrossContextGenerationAutoFlushTest<GenFramebuffersAPI>();
2948 TEST_F(GLES2ImplementationStrictSharedTest,
2949 CrossContextGenerationAutoFlushTestRenderbuffers) {
2950 CrossContextGenerationAutoFlushTest<GenRenderbuffersAPI>();
2952 TEST_F(GLES2ImplementationStrictSharedTest,
2953 CrossContextGenerationAutoFlushTestTextures) {
2954 CrossContextGenerationAutoFlushTest<GenTexturesAPI>();
2957 TEST_F(GLES2ImplementationTest, GetString) {
2958 const uint32 kBucketId = GLES2Implementation::kResultBucketId;
2959 const Str7 kString = {"foobar"};
2960 // GL_CHROMIUM_map_sub is hard coded into GLES2Implementation.
2961 const char* expected_str =
2962 "foobar "
2963 "GL_EXT_unpack_subimage "
2964 "GL_CHROMIUM_map_sub";
2965 const char kBad = 0x12;
2966 struct Cmds {
2967 cmd::SetBucketSize set_bucket_size1;
2968 cmds::GetString get_string;
2969 cmd::GetBucketStart get_bucket_start;
2970 cmd::SetToken set_token1;
2971 cmd::SetBucketSize set_bucket_size2;
2973 ExpectedMemoryInfo mem1 = GetExpectedMemory(MaxTransferBufferSize());
2974 ExpectedMemoryInfo result1 =
2975 GetExpectedResultMemory(sizeof(cmd::GetBucketStart::Result));
2976 Cmds expected;
2977 expected.set_bucket_size1.Init(kBucketId, 0);
2978 expected.get_string.Init(GL_EXTENSIONS, kBucketId);
2979 expected.get_bucket_start.Init(
2980 kBucketId, result1.id, result1.offset,
2981 MaxTransferBufferSize(), mem1.id, mem1.offset);
2982 expected.set_token1.Init(GetNextToken());
2983 expected.set_bucket_size2.Init(kBucketId, 0);
2984 char buf[sizeof(kString) + 1];
2985 memset(buf, kBad, sizeof(buf));
2987 EXPECT_CALL(*command_buffer(), OnFlush())
2988 .WillOnce(DoAll(SetMemory(result1.ptr, uint32(sizeof(kString))),
2989 SetMemory(mem1.ptr, kString)))
2990 .RetiresOnSaturation();
2992 const GLubyte* result = gl_->GetString(GL_EXTENSIONS);
2993 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
2994 EXPECT_STREQ(expected_str, reinterpret_cast<const char*>(result));
2997 TEST_F(GLES2ImplementationTest, PixelStoreiGLPackReverseRowOrderANGLE) {
2998 const uint32 kBucketId = GLES2Implementation::kResultBucketId;
2999 const Str7 kString = {"foobar"};
3000 struct Cmds {
3001 cmd::SetBucketSize set_bucket_size1;
3002 cmds::GetString get_string;
3003 cmd::GetBucketStart get_bucket_start;
3004 cmd::SetToken set_token1;
3005 cmd::SetBucketSize set_bucket_size2;
3006 cmds::PixelStorei pixel_store;
3009 ExpectedMemoryInfo mem1 = GetExpectedMemory(MaxTransferBufferSize());
3010 ExpectedMemoryInfo result1 =
3011 GetExpectedResultMemory(sizeof(cmd::GetBucketStart::Result));
3013 Cmds expected;
3014 expected.set_bucket_size1.Init(kBucketId, 0);
3015 expected.get_string.Init(GL_EXTENSIONS, kBucketId);
3016 expected.get_bucket_start.Init(
3017 kBucketId, result1.id, result1.offset,
3018 MaxTransferBufferSize(), mem1.id, mem1.offset);
3019 expected.set_token1.Init(GetNextToken());
3020 expected.set_bucket_size2.Init(kBucketId, 0);
3021 expected.pixel_store.Init(GL_PACK_REVERSE_ROW_ORDER_ANGLE, 1);
3023 EXPECT_CALL(*command_buffer(), OnFlush())
3024 .WillOnce(DoAll(SetMemory(result1.ptr, uint32(sizeof(kString))),
3025 SetMemory(mem1.ptr, kString)))
3026 .RetiresOnSaturation();
3028 gl_->PixelStorei(GL_PACK_REVERSE_ROW_ORDER_ANGLE, 1);
3029 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
3032 TEST_F(GLES2ImplementationTest, CreateProgram) {
3033 struct Cmds {
3034 cmds::CreateProgram cmd;
3037 Cmds expected;
3038 expected.cmd.Init(kProgramsAndShadersStartId);
3039 GLuint id = gl_->CreateProgram();
3040 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
3041 EXPECT_EQ(kProgramsAndShadersStartId, id);
3044 TEST_F(GLES2ImplementationTest, BufferDataLargerThanTransferBuffer) {
3045 struct Cmds {
3046 cmds::BufferData set_size;
3047 cmds::BufferSubData copy_data1;
3048 cmd::SetToken set_token1;
3049 cmds::BufferSubData copy_data2;
3050 cmd::SetToken set_token2;
3052 const unsigned kUsableSize =
3053 kTransferBufferSize - GLES2Implementation::kStartingOffset;
3054 uint8 buf[kUsableSize * 2] = { 0, };
3056 ExpectedMemoryInfo mem1 = GetExpectedMemory(kUsableSize);
3057 ExpectedMemoryInfo mem2 = GetExpectedMemory(kUsableSize);
3059 Cmds expected;
3060 expected.set_size.Init(
3061 GL_ARRAY_BUFFER, arraysize(buf), 0, 0, GL_DYNAMIC_DRAW);
3062 expected.copy_data1.Init(
3063 GL_ARRAY_BUFFER, 0, kUsableSize, mem1.id, mem1.offset);
3064 expected.set_token1.Init(GetNextToken());
3065 expected.copy_data2.Init(
3066 GL_ARRAY_BUFFER, kUsableSize, kUsableSize, mem2.id, mem2.offset);
3067 expected.set_token2.Init(GetNextToken());
3068 gl_->BufferData(GL_ARRAY_BUFFER, arraysize(buf), buf, GL_DYNAMIC_DRAW);
3069 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
3072 TEST_F(GLES2ImplementationTest, CapabilitiesAreCached) {
3073 static const GLenum kStates[] = {
3074 GL_DITHER,
3075 GL_BLEND,
3076 GL_CULL_FACE,
3077 GL_DEPTH_TEST,
3078 GL_POLYGON_OFFSET_FILL,
3079 GL_SAMPLE_ALPHA_TO_COVERAGE,
3080 GL_SAMPLE_COVERAGE,
3081 GL_SCISSOR_TEST,
3082 GL_STENCIL_TEST,
3084 struct Cmds {
3085 cmds::Enable enable_cmd;
3087 Cmds expected;
3089 for (size_t ii = 0; ii < arraysize(kStates); ++ii) {
3090 GLenum state = kStates[ii];
3091 expected.enable_cmd.Init(state);
3092 GLboolean result = gl_->IsEnabled(state);
3093 EXPECT_EQ(static_cast<GLboolean>(ii == 0), result);
3094 EXPECT_TRUE(NoCommandsWritten());
3095 const void* commands = GetPut();
3096 if (!result) {
3097 gl_->Enable(state);
3098 EXPECT_EQ(0, memcmp(&expected, commands, sizeof(expected)));
3100 ClearCommands();
3101 result = gl_->IsEnabled(state);
3102 EXPECT_TRUE(result);
3103 EXPECT_TRUE(NoCommandsWritten());
3107 TEST_F(GLES2ImplementationTest, BindVertexArrayOES) {
3108 GLuint id = 0;
3109 gl_->GenVertexArraysOES(1, &id);
3110 ClearCommands();
3112 struct Cmds {
3113 cmds::BindVertexArrayOES cmd;
3115 Cmds expected;
3116 expected.cmd.Init(id);
3118 const void* commands = GetPut();
3119 gl_->BindVertexArrayOES(id);
3120 EXPECT_EQ(0, memcmp(&expected, commands, sizeof(expected)));
3121 ClearCommands();
3122 gl_->BindVertexArrayOES(id);
3123 EXPECT_TRUE(NoCommandsWritten());
3126 TEST_F(GLES2ImplementationTest, BeginEndQueryEXT) {
3127 // Test GetQueryivEXT returns 0 if no current query.
3128 GLint param = -1;
3129 gl_->GetQueryivEXT(GL_ANY_SAMPLES_PASSED_EXT, GL_CURRENT_QUERY_EXT, &param);
3130 EXPECT_EQ(0, param);
3132 GLuint expected_ids[2] = { 1, 2 }; // These must match what's actually genned.
3133 struct GenCmds {
3134 cmds::GenQueriesEXTImmediate gen;
3135 GLuint data[2];
3137 GenCmds expected_gen_cmds;
3138 expected_gen_cmds.gen.Init(arraysize(expected_ids), &expected_ids[0]);
3139 GLuint ids[arraysize(expected_ids)] = { 0, };
3140 gl_->GenQueriesEXT(arraysize(expected_ids), &ids[0]);
3141 EXPECT_EQ(0, memcmp(
3142 &expected_gen_cmds, commands_, sizeof(expected_gen_cmds)));
3143 GLuint id1 = ids[0];
3144 GLuint id2 = ids[1];
3145 ClearCommands();
3147 // Test BeginQueryEXT fails if id = 0.
3148 gl_->BeginQueryEXT(GL_ANY_SAMPLES_PASSED_EXT, 0);
3149 EXPECT_TRUE(NoCommandsWritten());
3150 EXPECT_EQ(GL_INVALID_OPERATION, CheckError());
3152 // Test BeginQueryEXT inserts command.
3153 struct BeginCmds {
3154 cmds::BeginQueryEXT begin_query;
3156 BeginCmds expected_begin_cmds;
3157 const void* commands = GetPut();
3158 gl_->BeginQueryEXT(GL_ANY_SAMPLES_PASSED_EXT, id1);
3159 QueryTracker::Query* query = GetQuery(id1);
3160 ASSERT_TRUE(query != NULL);
3161 expected_begin_cmds.begin_query.Init(
3162 GL_ANY_SAMPLES_PASSED_EXT, id1, query->shm_id(), query->shm_offset());
3163 EXPECT_EQ(0, memcmp(
3164 &expected_begin_cmds, commands, sizeof(expected_begin_cmds)));
3165 ClearCommands();
3167 // Test GetQueryivEXT returns id.
3168 param = -1;
3169 gl_->GetQueryivEXT(GL_ANY_SAMPLES_PASSED_EXT, GL_CURRENT_QUERY_EXT, &param);
3170 EXPECT_EQ(id1, static_cast<GLuint>(param));
3171 gl_->GetQueryivEXT(
3172 GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT, GL_CURRENT_QUERY_EXT, &param);
3173 EXPECT_EQ(0, param);
3175 // Test BeginQueryEXT fails if between Begin/End.
3176 gl_->BeginQueryEXT(GL_ANY_SAMPLES_PASSED_EXT, id2);
3177 EXPECT_TRUE(NoCommandsWritten());
3178 EXPECT_EQ(GL_INVALID_OPERATION, CheckError());
3180 // Test EndQueryEXT fails if target not same as current query.
3181 ClearCommands();
3182 gl_->EndQueryEXT(GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT);
3183 EXPECT_TRUE(NoCommandsWritten());
3184 EXPECT_EQ(GL_INVALID_OPERATION, CheckError());
3186 // Test EndQueryEXT sends command
3187 struct EndCmds {
3188 cmds::EndQueryEXT end_query;
3190 EndCmds expected_end_cmds;
3191 expected_end_cmds.end_query.Init(
3192 GL_ANY_SAMPLES_PASSED_EXT, query->submit_count());
3193 commands = GetPut();
3194 gl_->EndQueryEXT(GL_ANY_SAMPLES_PASSED_EXT);
3195 EXPECT_EQ(0, memcmp(
3196 &expected_end_cmds, commands, sizeof(expected_end_cmds)));
3198 // Test EndQueryEXT fails if no current query.
3199 ClearCommands();
3200 gl_->EndQueryEXT(GL_ANY_SAMPLES_PASSED_EXT);
3201 EXPECT_TRUE(NoCommandsWritten());
3202 EXPECT_EQ(GL_INVALID_OPERATION, CheckError());
3204 // Test 2nd Begin/End increments count.
3205 base::subtle::Atomic32 old_submit_count = query->submit_count();
3206 gl_->BeginQueryEXT(GL_ANY_SAMPLES_PASSED_EXT, id1);
3207 EXPECT_NE(old_submit_count, query->submit_count());
3208 expected_end_cmds.end_query.Init(
3209 GL_ANY_SAMPLES_PASSED_EXT, query->submit_count());
3210 commands = GetPut();
3211 gl_->EndQueryEXT(GL_ANY_SAMPLES_PASSED_EXT);
3212 EXPECT_EQ(0, memcmp(
3213 &expected_end_cmds, commands, sizeof(expected_end_cmds)));
3215 // Test BeginQueryEXT fails if target changed.
3216 ClearCommands();
3217 gl_->BeginQueryEXT(GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT, id1);
3218 EXPECT_TRUE(NoCommandsWritten());
3219 EXPECT_EQ(GL_INVALID_OPERATION, CheckError());
3221 // Test GetQueryObjectuivEXT fails if unused id
3222 GLuint available = 0xBDu;
3223 ClearCommands();
3224 gl_->GetQueryObjectuivEXT(id2, GL_QUERY_RESULT_AVAILABLE_EXT, &available);
3225 EXPECT_TRUE(NoCommandsWritten());
3226 EXPECT_EQ(0xBDu, available);
3227 EXPECT_EQ(GL_INVALID_OPERATION, CheckError());
3229 // Test GetQueryObjectuivEXT fails if bad id
3230 ClearCommands();
3231 gl_->GetQueryObjectuivEXT(4567, GL_QUERY_RESULT_AVAILABLE_EXT, &available);
3232 EXPECT_TRUE(NoCommandsWritten());
3233 EXPECT_EQ(0xBDu, available);
3234 EXPECT_EQ(GL_INVALID_OPERATION, CheckError());
3236 // Test GetQueryObjectuivEXT CheckResultsAvailable
3237 ClearCommands();
3238 gl_->GetQueryObjectuivEXT(id1, GL_QUERY_RESULT_AVAILABLE_EXT, &available);
3239 EXPECT_EQ(0u, available);
3241 // Test GetQueryObjectui64vEXT fails if unused id
3242 GLuint64 available2 = 0xBDu;
3243 ClearCommands();
3244 gl_->GetQueryObjectui64vEXT(id2, GL_QUERY_RESULT_AVAILABLE_EXT, &available2);
3245 EXPECT_TRUE(NoCommandsWritten());
3246 EXPECT_EQ(0xBDu, available2);
3247 EXPECT_EQ(GL_INVALID_OPERATION, CheckError());
3249 // Test GetQueryObjectui64vEXT fails if bad id
3250 ClearCommands();
3251 gl_->GetQueryObjectui64vEXT(4567, GL_QUERY_RESULT_AVAILABLE_EXT, &available2);
3252 EXPECT_TRUE(NoCommandsWritten());
3253 EXPECT_EQ(0xBDu, available2);
3254 EXPECT_EQ(GL_INVALID_OPERATION, CheckError());
3256 // Test GetQueryObjectui64vEXT CheckResultsAvailable
3257 ClearCommands();
3258 gl_->GetQueryObjectui64vEXT(id1, GL_QUERY_RESULT_AVAILABLE_EXT, &available2);
3259 EXPECT_EQ(0u, available2);
3262 TEST_F(GLES2ImplementationManualInitTest, BadQueryTargets) {
3263 ContextInitOptions init_options;
3264 init_options.sync_query = false;
3265 init_options.occlusion_query_boolean = false;
3266 init_options.timer_queries = false;
3267 ASSERT_TRUE(Initialize(init_options));
3269 GLuint id = 0;
3270 gl_->GenQueriesEXT(1, &id);
3271 ClearCommands();
3273 gl_->BeginQueryEXT(GL_COMMANDS_COMPLETED_CHROMIUM, id);
3274 EXPECT_EQ(GL_INVALID_OPERATION, CheckError());
3275 EXPECT_EQ(nullptr, GetQuery(id));
3277 gl_->BeginQueryEXT(GL_ANY_SAMPLES_PASSED, id);
3278 EXPECT_EQ(GL_INVALID_OPERATION, CheckError());
3279 EXPECT_EQ(nullptr, GetQuery(id));
3281 gl_->BeginQueryEXT(GL_ANY_SAMPLES_PASSED_CONSERVATIVE, id);
3282 EXPECT_EQ(GL_INVALID_OPERATION, CheckError());
3283 EXPECT_EQ(nullptr, GetQuery(id));
3285 gl_->BeginQueryEXT(GL_TIME_ELAPSED_EXT, id);
3286 EXPECT_EQ(GL_INVALID_OPERATION, CheckError());
3287 EXPECT_EQ(nullptr, GetQuery(id));
3289 gl_->BeginQueryEXT(0x123, id);
3290 EXPECT_EQ(GL_INVALID_ENUM, CheckError());
3291 EXPECT_EQ(nullptr, GetQuery(id));
3293 gl_->QueryCounterEXT(id, GL_TIMESTAMP_EXT);
3294 EXPECT_EQ(GL_INVALID_OPERATION, CheckError());
3295 EXPECT_EQ(nullptr, GetQuery(id));
3297 gl_->QueryCounterEXT(id, 0x123);
3298 EXPECT_EQ(GL_INVALID_ENUM, CheckError());
3299 EXPECT_EQ(nullptr, GetQuery(id));
3302 TEST_F(GLES2ImplementationTest, SetDisjointSync) {
3303 struct SetDisjointSyncCmd {
3304 cmds::SetDisjointValueSyncCHROMIUM disjoint_sync;
3306 SetDisjointSyncCmd expected_disjoint_sync_cmd;
3307 const void* commands = GetPut();
3308 gl_->SetDisjointValueSyncCHROMIUM();
3309 expected_disjoint_sync_cmd.disjoint_sync.Init(
3310 GetQueryTracker()->DisjointCountSyncShmID(),
3311 GetQueryTracker()->DisjointCountSyncShmOffset());
3313 EXPECT_EQ(0, memcmp(&expected_disjoint_sync_cmd, commands,
3314 sizeof(expected_disjoint_sync_cmd)));
3317 TEST_F(GLES2ImplementationTest, QueryCounterEXT) {
3318 GLuint expected_ids[2] = { 1, 2 }; // These must match what's actually genned.
3319 struct GenCmds {
3320 cmds::GenQueriesEXTImmediate gen;
3321 GLuint data[2];
3323 GenCmds expected_gen_cmds;
3324 expected_gen_cmds.gen.Init(arraysize(expected_ids), &expected_ids[0]);
3325 GLuint ids[arraysize(expected_ids)] = { 0, };
3326 gl_->GenQueriesEXT(arraysize(expected_ids), &ids[0]);
3327 EXPECT_EQ(0, memcmp(
3328 &expected_gen_cmds, commands_, sizeof(expected_gen_cmds)));
3329 GLuint id1 = ids[0];
3330 GLuint id2 = ids[1];
3331 ClearCommands();
3333 // Make sure disjoint value is synchronized already.
3334 gl_->SetDisjointValueSyncCHROMIUM();
3335 ClearCommands();
3337 // Test QueryCounterEXT fails if id = 0.
3338 gl_->QueryCounterEXT(0, GL_TIMESTAMP_EXT);
3339 EXPECT_TRUE(NoCommandsWritten());
3340 EXPECT_EQ(GL_INVALID_OPERATION, CheckError());
3342 // Test QueryCounterEXT fails if target is unknown.
3343 ClearCommands();
3344 gl_->QueryCounterEXT(id1, GL_TIME_ELAPSED_EXT);
3345 EXPECT_TRUE(NoCommandsWritten());
3346 EXPECT_EQ(GL_INVALID_ENUM, CheckError());
3348 // Test QueryCounterEXT inserts command.
3349 struct QueryCounterCmds {
3350 cmds::QueryCounterEXT query_counter;
3352 QueryCounterCmds expected_query_counter_cmds;
3353 const void* commands = GetPut();
3354 gl_->QueryCounterEXT(id1, GL_TIMESTAMP_EXT);
3355 EXPECT_EQ(GL_NO_ERROR, CheckError());
3356 QueryTracker::Query* query = GetQuery(id1);
3357 ASSERT_TRUE(query != NULL);
3358 expected_query_counter_cmds.query_counter.Init(
3359 id1, GL_TIMESTAMP_EXT, query->shm_id(), query->shm_offset(),
3360 query->submit_count());
3361 EXPECT_EQ(0, memcmp(&expected_query_counter_cmds, commands,
3362 sizeof(expected_query_counter_cmds)));
3363 ClearCommands();
3365 // Test 2nd QueryCounterEXT succeeds.
3366 commands = GetPut();
3367 gl_->QueryCounterEXT(id2, GL_TIMESTAMP_EXT);
3368 EXPECT_EQ(GL_NO_ERROR, CheckError());
3369 QueryTracker::Query* query2 = GetQuery(id2);
3370 ASSERT_TRUE(query2 != NULL);
3371 expected_query_counter_cmds.query_counter.Init(
3372 id2, GL_TIMESTAMP_EXT, query2->shm_id(), query2->shm_offset(),
3373 query2->submit_count());
3374 EXPECT_EQ(0, memcmp(&expected_query_counter_cmds, commands,
3375 sizeof(expected_query_counter_cmds)));
3376 ClearCommands();
3378 // Test QueryCounterEXT increments count.
3379 base::subtle::Atomic32 old_submit_count = query->submit_count();
3380 commands = GetPut();
3381 gl_->QueryCounterEXT(id1, GL_TIMESTAMP_EXT);
3382 EXPECT_EQ(GL_NO_ERROR, CheckError());
3383 EXPECT_NE(old_submit_count, query->submit_count());
3384 expected_query_counter_cmds.query_counter.Init(
3385 id1, GL_TIMESTAMP_EXT, query->shm_id(), query->shm_offset(),
3386 query->submit_count());
3387 EXPECT_EQ(0, memcmp(&expected_query_counter_cmds, commands,
3388 sizeof(expected_query_counter_cmds)));
3389 ClearCommands();
3391 // Test GetQueryObjectuivEXT CheckResultsAvailable
3392 GLuint available = 0xBDu;
3393 ClearCommands();
3394 gl_->GetQueryObjectuivEXT(id1, GL_QUERY_RESULT_AVAILABLE_EXT, &available);
3395 EXPECT_EQ(0u, available);
3397 // Test GetQueryObjectui64vEXT CheckResultsAvailable
3398 GLuint64 available2 = 0xBDu;
3399 ClearCommands();
3400 gl_->GetQueryObjectui64vEXT(id1, GL_QUERY_RESULT_AVAILABLE_EXT, &available2);
3401 EXPECT_EQ(0u, available2);
3404 TEST_F(GLES2ImplementationTest, ErrorQuery) {
3405 GLuint id = 0;
3406 gl_->GenQueriesEXT(1, &id);
3407 ClearCommands();
3409 // Test BeginQueryEXT does NOT insert commands.
3410 gl_->BeginQueryEXT(GL_GET_ERROR_QUERY_CHROMIUM, id);
3411 EXPECT_TRUE(NoCommandsWritten());
3412 QueryTracker::Query* query = GetQuery(id);
3413 ASSERT_TRUE(query != NULL);
3415 // Test EndQueryEXT sends both begin and end command
3416 struct EndCmds {
3417 cmds::BeginQueryEXT begin_query;
3418 cmds::EndQueryEXT end_query;
3420 EndCmds expected_end_cmds;
3421 expected_end_cmds.begin_query.Init(
3422 GL_GET_ERROR_QUERY_CHROMIUM, id, query->shm_id(), query->shm_offset());
3423 expected_end_cmds.end_query.Init(
3424 GL_GET_ERROR_QUERY_CHROMIUM, query->submit_count());
3425 const void* commands = GetPut();
3426 gl_->EndQueryEXT(GL_GET_ERROR_QUERY_CHROMIUM);
3427 EXPECT_EQ(0, memcmp(
3428 &expected_end_cmds, commands, sizeof(expected_end_cmds)));
3429 ClearCommands();
3431 // Check result is not yet available.
3432 GLuint available = 0xBDu;
3433 gl_->GetQueryObjectuivEXT(id, GL_QUERY_RESULT_AVAILABLE_EXT, &available);
3434 EXPECT_TRUE(NoCommandsWritten());
3435 EXPECT_EQ(0u, available);
3437 // Test no commands are sent if there is a client side error.
3439 // Generate a client side error
3440 gl_->ActiveTexture(GL_TEXTURE0 - 1);
3442 gl_->BeginQueryEXT(GL_GET_ERROR_QUERY_CHROMIUM, id);
3443 gl_->EndQueryEXT(GL_GET_ERROR_QUERY_CHROMIUM);
3444 EXPECT_TRUE(NoCommandsWritten());
3446 // Check result is available.
3447 gl_->GetQueryObjectuivEXT(id, GL_QUERY_RESULT_AVAILABLE_EXT, &available);
3448 EXPECT_TRUE(NoCommandsWritten());
3449 EXPECT_NE(0u, available);
3451 // Check result.
3452 GLuint result = 0xBDu;
3453 gl_->GetQueryObjectuivEXT(id, GL_QUERY_RESULT_EXT, &result);
3454 EXPECT_TRUE(NoCommandsWritten());
3455 EXPECT_EQ(static_cast<GLuint>(GL_INVALID_ENUM), result);
3458 #if !defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS)
3459 TEST_F(GLES2ImplementationTest, VertexArrays) {
3460 const GLuint kAttribIndex1 = 1;
3461 const GLint kNumComponents1 = 3;
3462 const GLsizei kClientStride = 12;
3464 GLuint id = 0;
3465 gl_->GenVertexArraysOES(1, &id);
3466 ClearCommands();
3468 gl_->BindVertexArrayOES(id);
3470 // Test that VertexAttribPointer cannot be called with a bound buffer of 0
3471 // unless the offset is NULL
3472 gl_->BindBuffer(GL_ARRAY_BUFFER, 0);
3474 gl_->VertexAttribPointer(
3475 kAttribIndex1, kNumComponents1, GL_FLOAT, GL_FALSE, kClientStride,
3476 reinterpret_cast<const void*>(4));
3477 EXPECT_EQ(GL_INVALID_OPERATION, CheckError());
3479 gl_->VertexAttribPointer(
3480 kAttribIndex1, kNumComponents1, GL_FLOAT, GL_FALSE, kClientStride, NULL);
3481 EXPECT_EQ(GL_NO_ERROR, CheckError());
3483 #endif
3485 TEST_F(GLES2ImplementationTest, Disable) {
3486 struct Cmds {
3487 cmds::Disable cmd;
3489 Cmds expected;
3490 expected.cmd.Init(GL_DITHER); // Note: DITHER defaults to enabled.
3492 gl_->Disable(GL_DITHER);
3493 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
3494 // Check it's cached and not called again.
3495 ClearCommands();
3496 gl_->Disable(GL_DITHER);
3497 EXPECT_TRUE(NoCommandsWritten());
3500 TEST_F(GLES2ImplementationTest, Enable) {
3501 struct Cmds {
3502 cmds::Enable cmd;
3504 Cmds expected;
3505 expected.cmd.Init(GL_BLEND); // Note: BLEND defaults to disabled.
3507 gl_->Enable(GL_BLEND);
3508 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
3509 // Check it's cached and not called again.
3510 ClearCommands();
3511 gl_->Enable(GL_BLEND);
3512 EXPECT_TRUE(NoCommandsWritten());
3515 TEST_F(GLES2ImplementationTest, ConsumeTextureCHROMIUM) {
3516 struct Cmds {
3517 cmds::ConsumeTextureCHROMIUMImmediate cmd;
3518 GLbyte data[64];
3521 Mailbox mailbox = Mailbox::Generate();
3522 Cmds expected;
3523 expected.cmd.Init(GL_TEXTURE_2D, mailbox.name);
3524 gl_->ConsumeTextureCHROMIUM(GL_TEXTURE_2D, mailbox.name);
3525 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
3528 TEST_F(GLES2ImplementationTest, CreateAndConsumeTextureCHROMIUM) {
3529 struct Cmds {
3530 cmds::CreateAndConsumeTextureCHROMIUMImmediate cmd;
3531 GLbyte data[64];
3534 Mailbox mailbox = Mailbox::Generate();
3535 Cmds expected;
3536 expected.cmd.Init(GL_TEXTURE_2D, kTexturesStartId, mailbox.name);
3537 GLuint id = gl_->CreateAndConsumeTextureCHROMIUM(GL_TEXTURE_2D, mailbox.name);
3538 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
3539 EXPECT_EQ(kTexturesStartId, id);
3542 TEST_F(GLES2ImplementationTest, ProduceTextureCHROMIUM) {
3543 struct Cmds {
3544 cmds::ProduceTextureCHROMIUMImmediate cmd;
3545 GLbyte data[64];
3548 Mailbox mailbox = Mailbox::Generate();
3549 Cmds expected;
3550 expected.cmd.Init(GL_TEXTURE_2D, mailbox.name);
3551 gl_->ProduceTextureCHROMIUM(GL_TEXTURE_2D, mailbox.name);
3552 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
3555 TEST_F(GLES2ImplementationTest, ProduceTextureDirectCHROMIUM) {
3556 struct Cmds {
3557 cmds::ProduceTextureDirectCHROMIUMImmediate cmd;
3558 GLbyte data[64];
3561 Mailbox mailbox = Mailbox::Generate();
3562 Cmds expected;
3563 expected.cmd.Init(kTexturesStartId, GL_TEXTURE_2D, mailbox.name);
3564 gl_->ProduceTextureDirectCHROMIUM(
3565 kTexturesStartId, GL_TEXTURE_2D, mailbox.name);
3566 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
3569 TEST_F(GLES2ImplementationTest, LimitSizeAndOffsetTo32Bit) {
3570 GLsizeiptr size;
3571 GLintptr offset;
3572 if (sizeof(size) <= 4 || sizeof(offset) <= 4)
3573 return;
3574 // The below two casts should be no-op, as we return early if
3575 // it's 32-bit system.
3576 int64 value64 = 0x100000000;
3577 size = static_cast<GLsizeiptr>(value64);
3578 offset = static_cast<GLintptr>(value64);
3580 const char kSizeOverflowMessage[] = "size more than 32-bit";
3581 const char kOffsetOverflowMessage[] = "offset more than 32-bit";
3583 const GLfloat buf[] = { 1.0, 1.0, 1.0, 1.0 };
3584 const GLubyte indices[] = { 0 };
3586 const GLuint kClientArrayBufferId = 0x789;
3587 const GLuint kClientElementArrayBufferId = 0x790;
3588 gl_->BindBuffer(GL_ARRAY_BUFFER, kClientArrayBufferId);
3589 gl_->BindBuffer(GL_ELEMENT_ARRAY_BUFFER, kClientElementArrayBufferId);
3590 EXPECT_EQ(GL_NO_ERROR, CheckError());
3592 // Call BufferData() should succeed with legal paramaters.
3593 gl_->BufferData(GL_ARRAY_BUFFER, sizeof(buf), buf, GL_DYNAMIC_DRAW);
3594 gl_->BufferData(
3595 GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_DYNAMIC_DRAW);
3596 EXPECT_EQ(GL_NO_ERROR, CheckError());
3598 // BufferData: size
3599 gl_->BufferData(GL_ARRAY_BUFFER, size, buf, GL_DYNAMIC_DRAW);
3600 EXPECT_EQ(GL_INVALID_OPERATION, CheckError());
3601 EXPECT_STREQ(kSizeOverflowMessage, GetLastError().c_str());
3603 // Call BufferSubData() should succeed with legal paramaters.
3604 gl_->BufferSubData(GL_ARRAY_BUFFER, 0, sizeof(buf[0]), buf);
3605 EXPECT_EQ(GL_NO_ERROR, CheckError());
3607 // BufferSubData: offset
3608 gl_->BufferSubData(GL_ARRAY_BUFFER, offset, 1, buf);
3609 EXPECT_EQ(GL_INVALID_OPERATION, CheckError());
3610 EXPECT_STREQ(kOffsetOverflowMessage, GetLastError().c_str());
3612 // BufferSubData: size
3613 EXPECT_EQ(GL_NO_ERROR, CheckError());
3614 gl_->BufferSubData(GL_ARRAY_BUFFER, 0, size, buf);
3615 EXPECT_EQ(GL_INVALID_OPERATION, CheckError());
3616 EXPECT_STREQ(kSizeOverflowMessage, GetLastError().c_str());
3618 // Call MapBufferSubDataCHROMIUM() should succeed with legal paramaters.
3619 void* mem =
3620 gl_->MapBufferSubDataCHROMIUM(GL_ARRAY_BUFFER, 0, 1, GL_WRITE_ONLY);
3621 EXPECT_TRUE(NULL != mem);
3622 EXPECT_EQ(GL_NO_ERROR, CheckError());
3623 gl_->UnmapBufferSubDataCHROMIUM(mem);
3625 // MapBufferSubDataCHROMIUM: offset
3626 EXPECT_TRUE(NULL == gl_->MapBufferSubDataCHROMIUM(
3627 GL_ARRAY_BUFFER, offset, 1, GL_WRITE_ONLY));
3628 EXPECT_EQ(GL_INVALID_OPERATION, CheckError());
3629 EXPECT_STREQ(kOffsetOverflowMessage, GetLastError().c_str());
3631 // MapBufferSubDataCHROMIUM: size
3632 EXPECT_EQ(GL_NO_ERROR, CheckError());
3633 EXPECT_TRUE(NULL == gl_->MapBufferSubDataCHROMIUM(
3634 GL_ARRAY_BUFFER, 0, size, GL_WRITE_ONLY));
3635 EXPECT_EQ(GL_INVALID_OPERATION, CheckError());
3636 EXPECT_STREQ(kSizeOverflowMessage, GetLastError().c_str());
3638 // Call DrawElements() should succeed with legal paramaters.
3639 gl_->DrawElements(GL_POINTS, 1, GL_UNSIGNED_BYTE, NULL);
3640 EXPECT_EQ(GL_NO_ERROR, CheckError());
3642 // DrawElements: offset
3643 gl_->DrawElements(
3644 GL_POINTS, 1, GL_UNSIGNED_BYTE, reinterpret_cast<void*>(offset));
3645 EXPECT_EQ(GL_INVALID_OPERATION, CheckError());
3646 EXPECT_STREQ(kOffsetOverflowMessage, GetLastError().c_str());
3648 // Call DrawElementsInstancedANGLE() should succeed with legal paramaters.
3649 gl_->DrawElementsInstancedANGLE(GL_POINTS, 1, GL_UNSIGNED_BYTE, NULL, 1);
3650 EXPECT_EQ(GL_NO_ERROR, CheckError());
3652 // DrawElementsInstancedANGLE: offset
3653 gl_->DrawElementsInstancedANGLE(
3654 GL_POINTS, 1, GL_UNSIGNED_BYTE, reinterpret_cast<void*>(offset), 1);
3655 EXPECT_EQ(GL_INVALID_OPERATION, CheckError());
3656 EXPECT_STREQ(kOffsetOverflowMessage, GetLastError().c_str());
3658 // Call VertexAttribPointer() should succeed with legal paramaters.
3659 const GLuint kAttribIndex = 1;
3660 const GLsizei kStride = 4;
3661 gl_->VertexAttribPointer(
3662 kAttribIndex, 1, GL_FLOAT, GL_FALSE, kStride, NULL);
3663 EXPECT_EQ(GL_NO_ERROR, CheckError());
3665 // VertexAttribPointer: offset
3666 gl_->VertexAttribPointer(
3667 kAttribIndex, 1, GL_FLOAT, GL_FALSE, kStride,
3668 reinterpret_cast<void*>(offset));
3669 EXPECT_EQ(GL_INVALID_OPERATION, CheckError());
3670 EXPECT_STREQ(kOffsetOverflowMessage, GetLastError().c_str());
3673 TEST_F(GLES2ImplementationTest, TraceBeginCHROMIUM) {
3674 const uint32 kCategoryBucketId = GLES2Implementation::kResultBucketId;
3675 const uint32 kNameBucketId = GLES2Implementation::kResultBucketId + 1;
3676 const std::string category_name = "test category";
3677 const std::string trace_name = "test trace";
3678 const size_t kPaddedString1Size =
3679 transfer_buffer_->RoundToAlignment(category_name.size() + 1);
3680 const size_t kPaddedString2Size =
3681 transfer_buffer_->RoundToAlignment(trace_name.size() + 1);
3683 gl_->TraceBeginCHROMIUM(category_name.c_str(), trace_name.c_str());
3684 EXPECT_EQ(GL_NO_ERROR, CheckError());
3686 struct Cmds {
3687 cmd::SetBucketSize category_size1;
3688 cmd::SetBucketData category_data;
3689 cmd::SetToken set_token1;
3690 cmd::SetBucketSize name_size1;
3691 cmd::SetBucketData name_data;
3692 cmd::SetToken set_token2;
3693 cmds::TraceBeginCHROMIUM trace_call_begin;
3694 cmd::SetBucketSize category_size2;
3695 cmd::SetBucketSize name_size2;
3698 ExpectedMemoryInfo mem1 = GetExpectedMemory(kPaddedString1Size);
3699 ExpectedMemoryInfo mem2 = GetExpectedMemory(kPaddedString2Size);
3701 ASSERT_STREQ(category_name.c_str(), reinterpret_cast<char*>(mem1.ptr));
3702 ASSERT_STREQ(trace_name.c_str(), reinterpret_cast<char*>(mem2.ptr));
3704 Cmds expected;
3705 expected.category_size1.Init(kCategoryBucketId, category_name.size() + 1);
3706 expected.category_data.Init(
3707 kCategoryBucketId, 0, category_name.size() + 1, mem1.id, mem1.offset);
3708 expected.set_token1.Init(GetNextToken());
3709 expected.name_size1.Init(kNameBucketId, trace_name.size() + 1);
3710 expected.name_data.Init(
3711 kNameBucketId, 0, trace_name.size() + 1, mem2.id, mem2.offset);
3712 expected.set_token2.Init(GetNextToken());
3713 expected.trace_call_begin.Init(kCategoryBucketId, kNameBucketId);
3714 expected.category_size2.Init(kCategoryBucketId, 0);
3715 expected.name_size2.Init(kNameBucketId, 0);
3717 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
3720 TEST_F(GLES2ImplementationTest, AllowNestedTracesCHROMIUM) {
3721 const std::string category1_name = "test category 1";
3722 const std::string trace1_name = "test trace 1";
3723 const std::string category2_name = "test category 2";
3724 const std::string trace2_name = "test trace 2";
3726 gl_->TraceBeginCHROMIUM(category1_name.c_str(), trace1_name.c_str());
3727 EXPECT_EQ(GL_NO_ERROR, CheckError());
3729 gl_->TraceBeginCHROMIUM(category2_name.c_str(), trace2_name.c_str());
3730 EXPECT_EQ(GL_NO_ERROR, CheckError());
3732 gl_->TraceEndCHROMIUM();
3733 EXPECT_EQ(GL_NO_ERROR, CheckError());
3735 gl_->TraceEndCHROMIUM();
3736 EXPECT_EQ(GL_NO_ERROR, CheckError());
3738 // No more corresponding begin tracer marker should error.
3739 gl_->TraceEndCHROMIUM();
3740 EXPECT_EQ(GL_INVALID_OPERATION, CheckError());
3743 TEST_F(GLES2ImplementationTest, IsEnabled) {
3744 // If we use a valid enum, its state is cached on client side, so no command
3745 // is actually generated, and this test will fail.
3746 // TODO(zmo): it seems we never need the command. Maybe remove it.
3747 GLenum kCap = 1;
3748 struct Cmds {
3749 cmds::IsEnabled cmd;
3752 Cmds expected;
3753 ExpectedMemoryInfo result1 =
3754 GetExpectedResultMemory(sizeof(cmds::IsEnabled::Result));
3755 expected.cmd.Init(kCap, result1.id, result1.offset);
3757 EXPECT_CALL(*command_buffer(), OnFlush())
3758 .WillOnce(SetMemory(result1.ptr, uint32_t(GL_TRUE)))
3759 .RetiresOnSaturation();
3761 GLboolean result = gl_->IsEnabled(kCap);
3762 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
3763 EXPECT_TRUE(result);
3766 TEST_F(GLES2ImplementationTest, ClientWaitSync) {
3767 const GLuint client_sync_id = 36;
3768 struct Cmds {
3769 cmds::ClientWaitSync cmd;
3772 Cmds expected;
3773 ExpectedMemoryInfo result1 =
3774 GetExpectedResultMemory(sizeof(cmds::ClientWaitSync::Result));
3775 const GLuint64 kTimeout = 0xABCDEF0123456789;
3776 uint32_t v32_0 = 0, v32_1 = 0;
3777 GLES2Util::MapUint64ToTwoUint32(kTimeout, &v32_0, &v32_1);
3778 expected.cmd.Init(client_sync_id, GL_SYNC_FLUSH_COMMANDS_BIT,
3779 v32_0, v32_1, result1.id, result1.offset);
3781 EXPECT_CALL(*command_buffer(), OnFlush())
3782 .WillOnce(SetMemory(result1.ptr, uint32_t(GL_CONDITION_SATISFIED)))
3783 .RetiresOnSaturation();
3785 GLenum result = gl_->ClientWaitSync(
3786 reinterpret_cast<GLsync>(client_sync_id), GL_SYNC_FLUSH_COMMANDS_BIT,
3787 kTimeout);
3788 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
3789 EXPECT_EQ(static_cast<GLenum>(GL_CONDITION_SATISFIED), result);
3792 TEST_F(GLES2ImplementationTest, WaitSync) {
3793 const GLuint kClientSyncId = 36;
3794 struct Cmds {
3795 cmds::WaitSync cmd;
3797 Cmds expected;
3798 const GLuint64 kTimeout = GL_TIMEOUT_IGNORED;
3799 uint32_t v32_0 = 0, v32_1 = 0;
3800 GLES2Util::MapUint64ToTwoUint32(kTimeout, &v32_0, &v32_1);
3801 expected.cmd.Init(kClientSyncId, 0, v32_0, v32_1);
3803 gl_->WaitSync(reinterpret_cast<GLsync>(kClientSyncId), 0, kTimeout);
3804 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
3807 TEST_F(GLES2ImplementationTest, MapBufferRangeUnmapBufferWrite) {
3808 ExpectedMemoryInfo result =
3809 GetExpectedResultMemory(sizeof(cmds::MapBufferRange::Result));
3811 EXPECT_CALL(*command_buffer(), OnFlush())
3812 .WillOnce(SetMemory(result.ptr, uint32_t(1)))
3813 .RetiresOnSaturation();
3815 const GLuint kBufferId = 123;
3816 gl_->BindBuffer(GL_ARRAY_BUFFER, kBufferId);
3818 void* mem = gl_->MapBufferRange(GL_ARRAY_BUFFER, 10, 64, GL_MAP_WRITE_BIT);
3819 EXPECT_TRUE(mem != nullptr);
3821 EXPECT_TRUE(gl_->UnmapBuffer(GL_ARRAY_BUFFER));
3824 TEST_F(GLES2ImplementationTest, MapBufferRangeWriteWithInvalidateBit) {
3825 ExpectedMemoryInfo result =
3826 GetExpectedResultMemory(sizeof(cmds::MapBufferRange::Result));
3828 EXPECT_CALL(*command_buffer(), OnFlush())
3829 .WillOnce(SetMemory(result.ptr, uint32_t(1)))
3830 .RetiresOnSaturation();
3832 const GLuint kBufferId = 123;
3833 gl_->BindBuffer(GL_ARRAY_BUFFER, kBufferId);
3835 GLsizeiptr kSize = 64;
3836 void* mem = gl_->MapBufferRange(
3837 GL_ARRAY_BUFFER, 10, kSize,
3838 GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_RANGE_BIT);
3839 EXPECT_TRUE(mem != nullptr);
3840 std::vector<int8_t> zero(kSize);
3841 memset(&zero[0], 0, kSize);
3842 EXPECT_EQ(0, memcmp(mem, &zero[0], kSize));
3845 TEST_F(GLES2ImplementationTest, MapBufferRangeWriteWithGLError) {
3846 ExpectedMemoryInfo result =
3847 GetExpectedResultMemory(sizeof(cmds::MapBufferRange::Result));
3849 // Return a result of 0 to indicate an GL error.
3850 EXPECT_CALL(*command_buffer(), OnFlush())
3851 .WillOnce(SetMemory(result.ptr, uint32_t(0)))
3852 .RetiresOnSaturation();
3854 const GLuint kBufferId = 123;
3855 gl_->BindBuffer(GL_ARRAY_BUFFER, kBufferId);
3857 void* mem = gl_->MapBufferRange(GL_ARRAY_BUFFER, 10, 64, GL_MAP_WRITE_BIT);
3858 EXPECT_TRUE(mem == nullptr);
3861 TEST_F(GLES2ImplementationTest, MapBufferRangeUnmapBufferRead) {
3862 ExpectedMemoryInfo result =
3863 GetExpectedResultMemory(sizeof(cmds::MapBufferRange::Result));
3865 EXPECT_CALL(*command_buffer(), OnFlush())
3866 .WillOnce(SetMemory(result.ptr, uint32_t(1)))
3867 .RetiresOnSaturation();
3869 const GLuint kBufferId = 123;
3870 gl_->BindBuffer(GL_ARRAY_BUFFER, kBufferId);
3872 void* mem = gl_->MapBufferRange(GL_ARRAY_BUFFER, 10, 64, GL_MAP_READ_BIT);
3873 EXPECT_TRUE(mem != nullptr);
3875 EXPECT_TRUE(gl_->UnmapBuffer(GL_ARRAY_BUFFER));
3878 TEST_F(GLES2ImplementationTest, MapBufferRangeReadWithGLError) {
3879 ExpectedMemoryInfo result =
3880 GetExpectedResultMemory(sizeof(cmds::MapBufferRange::Result));
3882 // Return a result of 0 to indicate an GL error.
3883 EXPECT_CALL(*command_buffer(), OnFlush())
3884 .WillOnce(SetMemory(result.ptr, uint32_t(0)))
3885 .RetiresOnSaturation();
3887 const GLuint kBufferId = 123;
3888 gl_->BindBuffer(GL_ARRAY_BUFFER, kBufferId);
3890 void* mem = gl_->MapBufferRange(GL_ARRAY_BUFFER, 10, 64, GL_MAP_READ_BIT);
3891 EXPECT_TRUE(mem == nullptr);
3894 TEST_F(GLES2ImplementationTest, UnmapBufferFails) {
3895 // No bound buffer.
3896 EXPECT_FALSE(gl_->UnmapBuffer(GL_ARRAY_BUFFER));
3897 EXPECT_EQ(GL_INVALID_OPERATION, CheckError());
3899 const GLuint kBufferId = 123;
3900 gl_->BindBuffer(GL_ARRAY_BUFFER, kBufferId);
3902 // Buffer is unmapped.
3903 EXPECT_FALSE(gl_->UnmapBuffer(GL_ARRAY_BUFFER));
3904 EXPECT_EQ(GL_INVALID_OPERATION, CheckError());
3907 TEST_F(GLES2ImplementationTest, BufferDataUnmapsDataStore) {
3908 ExpectedMemoryInfo result =
3909 GetExpectedResultMemory(sizeof(cmds::MapBufferRange::Result));
3911 EXPECT_CALL(*command_buffer(), OnFlush())
3912 .WillOnce(SetMemory(result.ptr, uint32_t(1)))
3913 .RetiresOnSaturation();
3915 const GLuint kBufferId = 123;
3916 gl_->BindBuffer(GL_ARRAY_BUFFER, kBufferId);
3918 void* mem = gl_->MapBufferRange(GL_ARRAY_BUFFER, 10, 64, GL_MAP_WRITE_BIT);
3919 EXPECT_TRUE(mem != nullptr);
3921 std::vector<uint8_t> data(16);
3922 // BufferData unmaps the data store.
3923 gl_->BufferData(GL_ARRAY_BUFFER, 16, &data[0], GL_STREAM_DRAW);
3925 EXPECT_FALSE(gl_->UnmapBuffer(GL_ARRAY_BUFFER));
3926 EXPECT_EQ(GL_INVALID_OPERATION, CheckError());
3929 TEST_F(GLES2ImplementationTest, DeleteBuffersUnmapsDataStore) {
3930 ExpectedMemoryInfo result =
3931 GetExpectedResultMemory(sizeof(cmds::MapBufferRange::Result));
3933 EXPECT_CALL(*command_buffer(), OnFlush())
3934 .WillOnce(SetMemory(result.ptr, uint32_t(1)))
3935 .RetiresOnSaturation();
3937 const GLuint kBufferId = 123;
3938 gl_->BindBuffer(GL_ARRAY_BUFFER, kBufferId);
3940 void* mem = gl_->MapBufferRange(GL_ARRAY_BUFFER, 10, 64, GL_MAP_WRITE_BIT);
3941 EXPECT_TRUE(mem != nullptr);
3943 std::vector<uint8_t> data(16);
3944 // DeleteBuffers unmaps the data store.
3945 gl_->DeleteBuffers(1, &kBufferId);
3947 EXPECT_FALSE(gl_->UnmapBuffer(GL_ARRAY_BUFFER));
3948 EXPECT_EQ(GL_INVALID_OPERATION, CheckError());
3951 TEST_F(GLES2ImplementationTest, GetInternalformativ) {
3952 const GLint kNumSampleCounts = 8;
3953 struct Cmds {
3954 cmds::GetInternalformativ cmd;
3956 typedef cmds::GetInternalformativ::Result::Type ResultType;
3957 ResultType result = 0;
3958 Cmds expected;
3959 ExpectedMemoryInfo result1 =
3960 GetExpectedResultMemory(sizeof(uint32_t) + sizeof(ResultType));
3961 expected.cmd.Init(123, GL_RGBA8, GL_NUM_SAMPLE_COUNTS,
3962 result1.id, result1.offset);
3963 EXPECT_CALL(*command_buffer(), OnFlush())
3964 .WillOnce(SetMemory(result1.ptr,
3965 SizedResultHelper<ResultType>(kNumSampleCounts)))
3966 .RetiresOnSaturation();
3967 gl_->GetInternalformativ(123, GL_RGBA8, GL_NUM_SAMPLE_COUNTS, 1, &result);
3968 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
3969 EXPECT_EQ(static_cast<ResultType>(kNumSampleCounts), result);
3972 TEST_F(GLES2ImplementationManualInitTest, LoseContextOnOOM) {
3973 ContextInitOptions init_options;
3974 init_options.lose_context_when_out_of_memory = true;
3975 ASSERT_TRUE(Initialize(init_options));
3977 struct Cmds {
3978 cmds::LoseContextCHROMIUM cmd;
3981 GLsizei max = std::numeric_limits<GLsizei>::max();
3982 EXPECT_CALL(*gpu_control_, CreateGpuMemoryBufferImage(max, max, _, _))
3983 .WillOnce(Return(-1));
3984 gl_->CreateGpuMemoryBufferImageCHROMIUM(max, max, GL_RGBA, GL_MAP_CHROMIUM);
3985 // The context should be lost.
3986 Cmds expected;
3987 expected.cmd.Init(GL_GUILTY_CONTEXT_RESET_ARB, GL_UNKNOWN_CONTEXT_RESET_ARB);
3988 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
3991 TEST_F(GLES2ImplementationManualInitTest, NoLoseContextOnOOM) {
3992 ContextInitOptions init_options;
3993 ASSERT_TRUE(Initialize(init_options));
3995 struct Cmds {
3996 cmds::LoseContextCHROMIUM cmd;
3999 GLsizei max = std::numeric_limits<GLsizei>::max();
4000 EXPECT_CALL(*gpu_control_, CreateGpuMemoryBufferImage(max, max, _, _))
4001 .WillOnce(Return(-1));
4002 gl_->CreateGpuMemoryBufferImageCHROMIUM(max, max, GL_RGBA, GL_MAP_CHROMIUM);
4003 // The context should not be lost.
4004 EXPECT_TRUE(NoCommandsWritten());
4007 TEST_F(GLES2ImplementationManualInitTest, FailInitOnBGRMismatch1) {
4008 ContextInitOptions init_options;
4009 init_options.bind_generates_resource_client = false;
4010 init_options.bind_generates_resource_service = true;
4011 EXPECT_FALSE(Initialize(init_options));
4014 TEST_F(GLES2ImplementationManualInitTest, FailInitOnBGRMismatch2) {
4015 ContextInitOptions init_options;
4016 init_options.bind_generates_resource_client = true;
4017 init_options.bind_generates_resource_service = false;
4018 EXPECT_FALSE(Initialize(init_options));
4021 TEST_F(GLES2ImplementationManualInitTest, FailInitOnTransferBufferFail) {
4022 ContextInitOptions init_options;
4023 init_options.transfer_buffer_initialize_fail = true;
4024 EXPECT_FALSE(Initialize(init_options));
4027 #include "gpu/command_buffer/client/gles2_implementation_unittest_autogen.h"
4029 } // namespace gles2
4030 } // namespace gpu