Upstreaming browser/ui/uikit_ui_util from iOS.
[chromium-blink-merge.git] / gpu / command_buffer / client / gles2_implementation_unittest.cc
blob2580c8cec99d89556fdd167a37541179da8e488f
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;
141 size_t MaxTransferBufferSize() {
142 return size_ - result_size_;
145 unsigned int RoundToAlignment(unsigned int size) {
146 return (size + alignment_ - 1) & ~(alignment_ - 1);
149 bool InSync() {
150 return expected_buffer_index_ == actual_buffer_index_ &&
151 expected_offset_ == actual_offset_;
154 ExpectedMemoryInfo GetExpectedMemory(size_t size) {
155 ExpectedMemoryInfo mem;
156 mem.offset = AllocateExpectedTransferBuffer(size);
157 mem.id = GetExpectedTransferBufferId();
158 mem.ptr = static_cast<uint8*>(
159 GetExpectedTransferAddressFromOffset(mem.offset, size));
160 return mem;
163 ExpectedMemoryInfo GetExpectedResultMemory(size_t size) {
164 ExpectedMemoryInfo mem;
165 mem.offset = GetExpectedResultBufferOffset();
166 mem.id = GetExpectedResultBufferId();
167 mem.ptr = static_cast<uint8*>(
168 GetExpectedTransferAddressFromOffset(mem.offset, size));
169 return mem;
172 private:
173 static const int kNumBuffers = 2;
175 uint8* actual_buffer() const {
176 return static_cast<uint8*>(buffers_[actual_buffer_index_]->memory());
179 uint8* expected_buffer() const {
180 return static_cast<uint8*>(buffers_[expected_buffer_index_]->memory());
183 uint32 AllocateExpectedTransferBuffer(size_t size) {
184 EXPECT_LE(size, MaxTransferBufferSize());
186 // Toggle which buffer we get each time to simulate the buffer being
187 // reallocated.
188 expected_buffer_index_ = (expected_buffer_index_ + 1) % kNumBuffers;
190 if (expected_offset_ + size > size_) {
191 expected_offset_ = result_size_;
193 uint32 offset = expected_offset_;
194 expected_offset_ += RoundToAlignment(size);
196 // Make sure each buffer has a different offset.
197 return offset + expected_buffer_index_ * alignment_;
200 void* GetExpectedTransferAddressFromOffset(uint32 offset, size_t size) {
201 EXPECT_GE(offset, expected_buffer_index_ * alignment_);
202 EXPECT_LE(offset + size, size_ + expected_buffer_index_ * alignment_);
203 return expected_buffer() + offset;
206 int GetExpectedResultBufferId() {
207 return buffer_ids_[expected_buffer_index_];
210 uint32 GetExpectedResultBufferOffset() {
211 return expected_buffer_index_ * alignment_;
214 int GetExpectedTransferBufferId() {
215 return buffer_ids_[expected_buffer_index_];
218 CommandBuffer* command_buffer_;
219 size_t size_;
220 size_t result_size_;
221 uint32 alignment_;
222 int buffer_ids_[kNumBuffers];
223 scoped_refptr<Buffer> buffers_[kNumBuffers];
224 int actual_buffer_index_;
225 int expected_buffer_index_;
226 void* last_alloc_;
227 uint32 expected_offset_;
228 uint32 actual_offset_;
229 bool initialize_fail_;
231 DISALLOW_COPY_AND_ASSIGN(MockTransferBuffer);
234 bool MockTransferBuffer::Initialize(
235 unsigned int starting_buffer_size,
236 unsigned int result_size,
237 unsigned int /* min_buffer_size */,
238 unsigned int /* max_buffer_size */,
239 unsigned int alignment,
240 unsigned int /* size_to_flush */) {
241 // Just check they match.
242 return size_ == starting_buffer_size &&
243 result_size_ == result_size &&
244 alignment_ == alignment && !initialize_fail_;
247 int MockTransferBuffer::GetShmId() {
248 return buffer_ids_[actual_buffer_index_];
251 void* MockTransferBuffer::GetResultBuffer() {
252 return actual_buffer() + actual_buffer_index_ * alignment_;
255 int MockTransferBuffer::GetResultOffset() {
256 return actual_buffer_index_ * alignment_;
259 void MockTransferBuffer::Free() {
260 NOTREACHED();
263 bool MockTransferBuffer::HaveBuffer() const {
264 return true;
267 void* MockTransferBuffer::AllocUpTo(
268 unsigned int size, unsigned int* size_allocated) {
269 EXPECT_TRUE(size_allocated != NULL);
270 EXPECT_TRUE(last_alloc_ == NULL);
272 // Toggle which buffer we get each time to simulate the buffer being
273 // reallocated.
274 actual_buffer_index_ = (actual_buffer_index_ + 1) % kNumBuffers;
276 size = std::min(static_cast<size_t>(size), MaxTransferBufferSize());
277 if (actual_offset_ + size > size_) {
278 actual_offset_ = result_size_;
280 uint32 offset = actual_offset_;
281 actual_offset_ += RoundToAlignment(size);
282 *size_allocated = size;
284 // Make sure each buffer has a different offset.
285 last_alloc_ = actual_buffer() + offset + actual_buffer_index_ * alignment_;
286 return last_alloc_;
289 void* MockTransferBuffer::Alloc(unsigned int size) {
290 EXPECT_LE(size, MaxTransferBufferSize());
291 unsigned int temp = 0;
292 void* p = AllocUpTo(size, &temp);
293 EXPECT_EQ(temp, size);
294 return p;
297 RingBuffer::Offset MockTransferBuffer::GetOffset(void* pointer) const {
298 // Make sure each buffer has a different offset.
299 return static_cast<uint8*>(pointer) - actual_buffer();
302 void MockTransferBuffer::DiscardBlock(void* p) {
303 EXPECT_EQ(last_alloc_, p);
304 last_alloc_ = NULL;
307 void MockTransferBuffer::FreePendingToken(void* p, unsigned int /* token */) {
308 EXPECT_EQ(last_alloc_, p);
309 last_alloc_ = NULL;
312 // API wrapper for Buffers.
313 class GenBuffersAPI {
314 public:
315 static void Gen(GLES2Implementation* gl_impl, GLsizei n, GLuint* ids) {
316 gl_impl->GenBuffers(n, ids);
319 static void Delete(GLES2Implementation* gl_impl,
320 GLsizei n,
321 const GLuint* ids) {
322 gl_impl->DeleteBuffers(n, ids);
326 // API wrapper for Framebuffers.
327 class GenFramebuffersAPI {
328 public:
329 static void Gen(GLES2Implementation* gl_impl, GLsizei n, GLuint* ids) {
330 gl_impl->GenFramebuffers(n, ids);
333 static void Delete(GLES2Implementation* gl_impl,
334 GLsizei n,
335 const GLuint* ids) {
336 gl_impl->DeleteFramebuffers(n, ids);
340 // API wrapper for Renderbuffers.
341 class GenRenderbuffersAPI {
342 public:
343 static void Gen(GLES2Implementation* gl_impl, GLsizei n, GLuint* ids) {
344 gl_impl->GenRenderbuffers(n, ids);
347 static void Delete(GLES2Implementation* gl_impl,
348 GLsizei n,
349 const GLuint* ids) {
350 gl_impl->DeleteRenderbuffers(n, ids);
354 // API wrapper for Textures.
355 class GenTexturesAPI {
356 public:
357 static void Gen(GLES2Implementation* gl_impl, GLsizei n, GLuint* ids) {
358 gl_impl->GenTextures(n, ids);
361 static void Delete(GLES2Implementation* gl_impl,
362 GLsizei n,
363 const GLuint* ids) {
364 gl_impl->DeleteTextures(n, ids);
368 class GLES2ImplementationTest : public testing::Test {
369 protected:
370 static const int kNumTestContexts = 2;
371 static const uint8 kInitialValue = 0xBD;
372 static const int32 kNumCommandEntries = 500;
373 static const int32 kCommandBufferSizeBytes =
374 kNumCommandEntries * sizeof(CommandBufferEntry);
375 static const size_t kTransferBufferSize = 512;
377 static const GLint kMaxCombinedTextureImageUnits = 8;
378 static const GLint kMaxCubeMapTextureSize = 64;
379 static const GLint kMaxFragmentUniformVectors = 16;
380 static const GLint kMaxRenderbufferSize = 64;
381 static const GLint kMaxTextureImageUnits = 8;
382 static const GLint kMaxTextureSize = 128;
383 static const GLint kMaxVaryingVectors = 8;
384 static const GLint kMaxVertexAttribs = 8;
385 static const GLint kMaxVertexTextureImageUnits = 0;
386 static const GLint kMaxVertexUniformVectors = 128;
387 static const GLint kNumCompressedTextureFormats = 0;
388 static const GLint kNumShaderBinaryFormats = 0;
389 static const GLuint kMaxTransformFeedbackSeparateAttribs = 4;
390 static const GLuint kMaxUniformBufferBindings = 36;
391 static const GLuint kStartId = 1024;
392 static const GLuint kBuffersStartId = 1;
393 static const GLuint kFramebuffersStartId = 1;
394 static const GLuint kProgramsAndShadersStartId = 1;
395 static const GLuint kRenderbuffersStartId = 1;
396 static const GLuint kSamplersStartId = 1;
397 static const GLuint kTexturesStartId = 1;
398 static const GLuint kTransformFeedbacksStartId = 1;
399 static const GLuint kQueriesStartId = 1;
400 static const GLuint kVertexArraysStartId = 1;
401 static const GLuint kValuebuffersStartId = 1;
403 typedef MockTransferBuffer::ExpectedMemoryInfo ExpectedMemoryInfo;
405 class TestContext {
406 public:
407 TestContext() : commands_(NULL), token_(0) {}
409 bool Initialize(ShareGroup* share_group,
410 bool bind_generates_resource_client,
411 bool bind_generates_resource_service,
412 bool lose_context_when_out_of_memory,
413 bool transfer_buffer_initialize_fail,
414 bool sync_query,
415 bool occlusion_query_boolean,
416 bool timer_queries) {
417 command_buffer_.reset(new StrictMock<MockClientCommandBuffer>());
418 if (!command_buffer_->Initialize())
419 return false;
421 transfer_buffer_.reset(
422 new MockTransferBuffer(command_buffer_.get(),
423 kTransferBufferSize,
424 GLES2Implementation::kStartingOffset,
425 GLES2Implementation::kAlignment,
426 transfer_buffer_initialize_fail));
428 helper_.reset(new GLES2CmdHelper(command_buffer()));
429 helper_->Initialize(kCommandBufferSizeBytes);
431 gpu_control_.reset(new StrictMock<MockClientGpuControl>());
432 Capabilities capabilities;
433 capabilities.VisitPrecisions(
434 [](GLenum shader, GLenum type,
435 Capabilities::ShaderPrecision* precision) {
436 precision->min_range = 3;
437 precision->max_range = 5;
438 precision->precision = 7;
440 capabilities.max_combined_texture_image_units =
441 kMaxCombinedTextureImageUnits;
442 capabilities.max_cube_map_texture_size = kMaxCubeMapTextureSize;
443 capabilities.max_fragment_uniform_vectors = kMaxFragmentUniformVectors;
444 capabilities.max_renderbuffer_size = kMaxRenderbufferSize;
445 capabilities.max_texture_image_units = kMaxTextureImageUnits;
446 capabilities.max_texture_size = kMaxTextureSize;
447 capabilities.max_varying_vectors = kMaxVaryingVectors;
448 capabilities.max_vertex_attribs = kMaxVertexAttribs;
449 capabilities.max_vertex_texture_image_units = kMaxVertexTextureImageUnits;
450 capabilities.max_vertex_uniform_vectors = kMaxVertexUniformVectors;
451 capabilities.num_compressed_texture_formats =
452 kNumCompressedTextureFormats;
453 capabilities.num_shader_binary_formats = kNumShaderBinaryFormats;
454 capabilities.max_transform_feedback_separate_attribs =
455 kMaxTransformFeedbackSeparateAttribs;
456 capabilities.max_uniform_buffer_bindings = kMaxUniformBufferBindings;
457 capabilities.bind_generates_resource_chromium =
458 bind_generates_resource_service ? 1 : 0;
459 capabilities.sync_query = sync_query;
460 capabilities.occlusion_query_boolean = occlusion_query_boolean;
461 capabilities.timer_queries = timer_queries;
462 EXPECT_CALL(*gpu_control_, GetCapabilities())
463 .WillOnce(testing::Return(capabilities));
466 InSequence sequence;
468 const bool support_client_side_arrays = true;
469 gl_.reset(new GLES2Implementation(helper_.get(),
470 share_group,
471 transfer_buffer_.get(),
472 bind_generates_resource_client,
473 lose_context_when_out_of_memory,
474 support_client_side_arrays,
475 gpu_control_.get()));
477 if (!gl_->Initialize(kTransferBufferSize,
478 kTransferBufferSize,
479 kTransferBufferSize,
480 GLES2Implementation::kNoLimit))
481 return false;
484 helper_->CommandBufferHelper::Finish();
485 ::testing::Mock::VerifyAndClearExpectations(gl_.get());
487 scoped_refptr<Buffer> ring_buffer = helper_->get_ring_buffer();
488 commands_ = static_cast<CommandBufferEntry*>(ring_buffer->memory()) +
489 command_buffer()->GetPutOffset();
490 ClearCommands();
491 EXPECT_TRUE(transfer_buffer_->InSync());
493 ::testing::Mock::VerifyAndClearExpectations(command_buffer());
494 return true;
497 void TearDown() {
498 Mock::VerifyAndClear(gl_.get());
499 EXPECT_CALL(*command_buffer(), OnFlush()).Times(AnyNumber());
500 // For command buffer.
501 EXPECT_CALL(*command_buffer(), DestroyTransferBuffer(_))
502 .Times(AtLeast(1));
503 gl_.reset();
506 MockClientCommandBuffer* command_buffer() const {
507 return command_buffer_.get();
510 int GetNextToken() { return ++token_; }
512 void ClearCommands() {
513 scoped_refptr<Buffer> ring_buffer = helper_->get_ring_buffer();
514 memset(ring_buffer->memory(), kInitialValue, ring_buffer->size());
517 scoped_ptr<MockClientCommandBuffer> command_buffer_;
518 scoped_ptr<MockClientGpuControl> gpu_control_;
519 scoped_ptr<GLES2CmdHelper> helper_;
520 scoped_ptr<MockTransferBuffer> transfer_buffer_;
521 scoped_ptr<GLES2Implementation> gl_;
522 CommandBufferEntry* commands_;
523 int token_;
526 GLES2ImplementationTest() : commands_(NULL) {}
528 void SetUp() override;
529 void TearDown() override;
531 bool NoCommandsWritten() {
532 scoped_refptr<Buffer> ring_buffer = helper_->get_ring_buffer();
533 const uint8* cmds = reinterpret_cast<const uint8*>(ring_buffer->memory());
534 const uint8* end = cmds + ring_buffer->size();
535 for (; cmds < end; ++cmds) {
536 if (*cmds != kInitialValue) {
537 return false;
540 return true;
543 QueryTracker::Query* GetQuery(GLuint id) {
544 return gl_->query_tracker_->GetQuery(id);
547 struct ContextInitOptions {
548 ContextInitOptions()
549 : bind_generates_resource_client(true),
550 bind_generates_resource_service(true),
551 lose_context_when_out_of_memory(false),
552 transfer_buffer_initialize_fail(false),
553 sync_query(true),
554 occlusion_query_boolean(true),
555 timer_queries(true) {}
557 bool bind_generates_resource_client;
558 bool bind_generates_resource_service;
559 bool lose_context_when_out_of_memory;
560 bool transfer_buffer_initialize_fail;
561 bool sync_query;
562 bool occlusion_query_boolean;
563 bool timer_queries;
566 bool Initialize(const ContextInitOptions& init_options) {
567 bool success = true;
568 share_group_ = new ShareGroup(init_options.bind_generates_resource_client);
570 for (int i = 0; i < kNumTestContexts; i++) {
571 if (!test_contexts_[i].Initialize(
572 share_group_.get(),
573 init_options.bind_generates_resource_client,
574 init_options.bind_generates_resource_service,
575 init_options.lose_context_when_out_of_memory,
576 init_options.transfer_buffer_initialize_fail,
577 init_options.sync_query,
578 init_options.occlusion_query_boolean,
579 init_options.timer_queries))
580 success = false;
583 // Default to test context 0.
584 gpu_control_ = test_contexts_[0].gpu_control_.get();
585 helper_ = test_contexts_[0].helper_.get();
586 transfer_buffer_ = test_contexts_[0].transfer_buffer_.get();
587 gl_ = test_contexts_[0].gl_.get();
588 commands_ = test_contexts_[0].commands_;
589 return success;
592 MockClientCommandBuffer* command_buffer() const {
593 return test_contexts_[0].command_buffer_.get();
596 int GetNextToken() { return test_contexts_[0].GetNextToken(); }
598 const void* GetPut() {
599 return helper_->GetSpace(0);
602 void ClearCommands() {
603 scoped_refptr<Buffer> ring_buffer = helper_->get_ring_buffer();
604 memset(ring_buffer->memory(), kInitialValue, ring_buffer->size());
607 size_t MaxTransferBufferSize() {
608 return transfer_buffer_->MaxTransferBufferSize();
611 void SetMappedMemoryLimit(size_t limit) {
612 gl_->mapped_memory_->set_max_allocated_bytes(limit);
615 ExpectedMemoryInfo GetExpectedMemory(size_t size) {
616 return transfer_buffer_->GetExpectedMemory(size);
619 ExpectedMemoryInfo GetExpectedResultMemory(size_t size) {
620 return transfer_buffer_->GetExpectedResultMemory(size);
623 ExpectedMemoryInfo GetExpectedMappedMemory(size_t size) {
624 ExpectedMemoryInfo mem;
626 // Temporarily allocate memory and expect that memory block to be reused.
627 mem.ptr = static_cast<uint8*>(gl_->mapped_memory_->Alloc(size,
628 &mem.id,
629 &mem.offset));
630 gl_->mapped_memory_->Free(mem.ptr);
632 return mem;
635 // Sets the ProgramInfoManager. The manager will be owned
636 // by the ShareGroup.
637 void SetProgramInfoManager(ProgramInfoManager* manager) {
638 gl_->share_group()->set_program_info_manager(manager);
641 int CheckError() {
642 ExpectedMemoryInfo result =
643 GetExpectedResultMemory(sizeof(cmds::GetError::Result));
644 EXPECT_CALL(*command_buffer(), OnFlush())
645 .WillOnce(SetMemory(result.ptr, GLuint(GL_NO_ERROR)))
646 .RetiresOnSaturation();
647 return gl_->GetError();
650 const std::string& GetLastError() {
651 return gl_->GetLastError();
654 bool GetBucketContents(uint32 bucket_id, std::vector<int8>* data) {
655 return gl_->GetBucketContents(bucket_id, data);
658 TestContext test_contexts_[kNumTestContexts];
660 scoped_refptr<ShareGroup> share_group_;
661 MockClientGpuControl* gpu_control_;
662 GLES2CmdHelper* helper_;
663 MockTransferBuffer* transfer_buffer_;
664 GLES2Implementation* gl_;
665 CommandBufferEntry* commands_;
668 void GLES2ImplementationTest::SetUp() {
669 ContextInitOptions init_options;
670 ASSERT_TRUE(Initialize(init_options));
673 void GLES2ImplementationTest::TearDown() {
674 for (int i = 0; i < kNumTestContexts; i++)
675 test_contexts_[i].TearDown();
678 class GLES2ImplementationManualInitTest : public GLES2ImplementationTest {
679 protected:
680 void SetUp() override {}
683 class GLES2ImplementationStrictSharedTest : public GLES2ImplementationTest {
684 protected:
685 void SetUp() override;
687 template <class ResApi>
688 void FlushGenerationTest() {
689 GLuint id1, id2, id3;
691 // Generate valid id.
692 ResApi::Gen(gl_, 1, &id1);
693 EXPECT_NE(id1, 0u);
695 // Delete id1 and generate id2. id1 should not be reused.
696 ResApi::Delete(gl_, 1, &id1);
697 ResApi::Gen(gl_, 1, &id2);
698 EXPECT_NE(id2, 0u);
699 EXPECT_NE(id2, id1);
701 // Expect id1 reuse after Flush.
702 gl_->Flush();
703 ResApi::Gen(gl_, 1, &id3);
704 EXPECT_EQ(id3, id1);
707 // Ids should not be reused unless the |Deleting| context does a Flush()
708 // AND triggers a lazy release after that.
709 template <class ResApi>
710 void CrossContextGenerationTest() {
711 GLES2Implementation* gl1 = test_contexts_[0].gl_.get();
712 GLES2Implementation* gl2 = test_contexts_[1].gl_.get();
713 GLuint id1, id2, id3;
715 // Delete, no flush on context 1. No reuse.
716 ResApi::Gen(gl1, 1, &id1);
717 ResApi::Delete(gl1, 1, &id1);
718 ResApi::Gen(gl1, 1, &id2);
719 EXPECT_NE(id1, id2);
721 // Flush context 2. Still no reuse.
722 gl2->Flush();
723 ResApi::Gen(gl2, 1, &id3);
724 EXPECT_NE(id1, id3);
725 EXPECT_NE(id2, id3);
727 // Flush on context 1, but no lazy release. Still no reuse.
728 gl1->Flush();
729 ResApi::Gen(gl2, 1, &id3);
730 EXPECT_NE(id1, id3);
732 // Lazy release triggered by another Delete. Should reuse id1.
733 ResApi::Delete(gl1, 1, &id2);
734 ResApi::Gen(gl2, 1, &id3);
735 EXPECT_EQ(id1, id3);
738 // Same as CrossContextGenerationTest(), but triggers an Auto Flush on
739 // the Delete(). Tests an edge case regression.
740 template <class ResApi>
741 void CrossContextGenerationAutoFlushTest() {
742 GLES2Implementation* gl1 = test_contexts_[0].gl_.get();
743 GLES2Implementation* gl2 = test_contexts_[1].gl_.get();
744 GLuint id1, id2, id3;
746 // Delete, no flush on context 1. No reuse.
747 // By half filling the buffer, an internal flush is forced on the Delete().
748 ResApi::Gen(gl1, 1, &id1);
749 gl1->helper()->Noop(kNumCommandEntries / 2);
750 ResApi::Delete(gl1, 1, &id1);
751 ResApi::Gen(gl1, 1, &id2);
752 EXPECT_NE(id1, id2);
754 // Flush context 2. Still no reuse.
755 gl2->Flush();
756 ResApi::Gen(gl2, 1, &id3);
757 EXPECT_NE(id1, id3);
758 EXPECT_NE(id2, id3);
760 // Flush on context 1, but no lazy release. Still no reuse.
761 gl1->Flush();
762 ResApi::Gen(gl2, 1, &id3);
763 EXPECT_NE(id1, id3);
765 // Lazy release triggered by another Delete. Should reuse id1.
766 ResApi::Delete(gl1, 1, &id2);
767 ResApi::Gen(gl2, 1, &id3);
768 EXPECT_EQ(id1, id3);
772 void GLES2ImplementationStrictSharedTest::SetUp() {
773 ContextInitOptions init_options;
774 init_options.bind_generates_resource_client = false;
775 init_options.bind_generates_resource_service = false;
776 ASSERT_TRUE(Initialize(init_options));
779 // GCC requires these declarations, but MSVC requires they not be present
780 #ifndef _MSC_VER
781 const uint8 GLES2ImplementationTest::kInitialValue;
782 const int32 GLES2ImplementationTest::kNumCommandEntries;
783 const int32 GLES2ImplementationTest::kCommandBufferSizeBytes;
784 const size_t GLES2ImplementationTest::kTransferBufferSize;
785 const GLint GLES2ImplementationTest::kMaxCombinedTextureImageUnits;
786 const GLint GLES2ImplementationTest::kMaxCubeMapTextureSize;
787 const GLint GLES2ImplementationTest::kMaxFragmentUniformVectors;
788 const GLint GLES2ImplementationTest::kMaxRenderbufferSize;
789 const GLint GLES2ImplementationTest::kMaxTextureImageUnits;
790 const GLint GLES2ImplementationTest::kMaxTextureSize;
791 const GLint GLES2ImplementationTest::kMaxVaryingVectors;
792 const GLint GLES2ImplementationTest::kMaxVertexAttribs;
793 const GLint GLES2ImplementationTest::kMaxVertexTextureImageUnits;
794 const GLint GLES2ImplementationTest::kMaxVertexUniformVectors;
795 const GLint GLES2ImplementationTest::kNumCompressedTextureFormats;
796 const GLint GLES2ImplementationTest::kNumShaderBinaryFormats;
797 const GLuint GLES2ImplementationTest::kStartId;
798 const GLuint GLES2ImplementationTest::kBuffersStartId;
799 const GLuint GLES2ImplementationTest::kFramebuffersStartId;
800 const GLuint GLES2ImplementationTest::kProgramsAndShadersStartId;
801 const GLuint GLES2ImplementationTest::kRenderbuffersStartId;
802 const GLuint GLES2ImplementationTest::kSamplersStartId;
803 const GLuint GLES2ImplementationTest::kTexturesStartId;
804 const GLuint GLES2ImplementationTest::kTransformFeedbacksStartId;
805 const GLuint GLES2ImplementationTest::kQueriesStartId;
806 const GLuint GLES2ImplementationTest::kVertexArraysStartId;
807 const GLuint GLES2ImplementationTest::kValuebuffersStartId;
808 #endif
810 TEST_F(GLES2ImplementationTest, Basic) {
811 EXPECT_TRUE(gl_->share_group() != NULL);
814 TEST_F(GLES2ImplementationTest, GetBucketContents) {
815 const uint32 kBucketId = GLES2Implementation::kResultBucketId;
816 const uint32 kTestSize = MaxTransferBufferSize() + 32;
818 scoped_ptr<uint8[]> buf(new uint8 [kTestSize]);
819 uint8* expected_data = buf.get();
820 for (uint32 ii = 0; ii < kTestSize; ++ii) {
821 expected_data[ii] = ii * 3;
824 struct Cmds {
825 cmd::GetBucketStart get_bucket_start;
826 cmd::SetToken set_token1;
827 cmd::GetBucketData get_bucket_data;
828 cmd::SetToken set_token2;
829 cmd::SetBucketSize set_bucket_size2;
832 ExpectedMemoryInfo mem1 = GetExpectedMemory(MaxTransferBufferSize());
833 ExpectedMemoryInfo result1 = GetExpectedResultMemory(sizeof(uint32));
834 ExpectedMemoryInfo mem2 = GetExpectedMemory(
835 kTestSize - MaxTransferBufferSize());
837 Cmds expected;
838 expected.get_bucket_start.Init(
839 kBucketId, result1.id, result1.offset,
840 MaxTransferBufferSize(), mem1.id, mem1.offset);
841 expected.set_token1.Init(GetNextToken());
842 expected.get_bucket_data.Init(
843 kBucketId, MaxTransferBufferSize(),
844 kTestSize - MaxTransferBufferSize(), mem2.id, mem2.offset);
845 expected.set_bucket_size2.Init(kBucketId, 0);
846 expected.set_token2.Init(GetNextToken());
848 EXPECT_CALL(*command_buffer(), OnFlush())
849 .WillOnce(DoAll(
850 SetMemory(result1.ptr, kTestSize),
851 SetMemoryFromArray(
852 mem1.ptr, expected_data, MaxTransferBufferSize())))
853 .WillOnce(SetMemoryFromArray(
854 mem2.ptr, expected_data + MaxTransferBufferSize(),
855 kTestSize - MaxTransferBufferSize()))
856 .RetiresOnSaturation();
858 std::vector<int8> data;
859 GetBucketContents(kBucketId, &data);
860 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
861 ASSERT_EQ(kTestSize, data.size());
862 EXPECT_EQ(0, memcmp(expected_data, &data[0], data.size()));
865 TEST_F(GLES2ImplementationTest, GetShaderPrecisionFormat) {
866 struct Cmds {
867 cmds::GetShaderPrecisionFormat cmd;
869 typedef cmds::GetShaderPrecisionFormat::Result Result;
870 const unsigned kDummyType1 = 3;
871 const unsigned kDummyType2 = 4;
873 // The first call for dummy type 1 should trigger a command buffer request.
874 GLint range1[2] = {0, 0};
875 GLint precision1 = 0;
876 Cmds expected1;
877 ExpectedMemoryInfo client_result1 = GetExpectedResultMemory(4);
878 expected1.cmd.Init(GL_FRAGMENT_SHADER, kDummyType1, client_result1.id,
879 client_result1.offset);
880 Result server_result1 = {true, 14, 14, 10};
881 EXPECT_CALL(*command_buffer(), OnFlush())
882 .WillOnce(SetMemory(client_result1.ptr, server_result1))
883 .RetiresOnSaturation();
884 gl_->GetShaderPrecisionFormat(GL_FRAGMENT_SHADER, kDummyType1, range1,
885 &precision1);
886 const void* commands2 = GetPut();
887 EXPECT_NE(commands_, commands2);
888 EXPECT_EQ(0, memcmp(&expected1, commands_, sizeof(expected1)));
889 EXPECT_EQ(range1[0], 14);
890 EXPECT_EQ(range1[1], 14);
891 EXPECT_EQ(precision1, 10);
893 // The second call for dummy type 1 should use the cached value and avoid
894 // triggering a command buffer request, so we do not expect a call to
895 // OnFlush() here. We do expect the results to be correct though.
896 GLint range2[2] = {0, 0};
897 GLint precision2 = 0;
898 gl_->GetShaderPrecisionFormat(GL_FRAGMENT_SHADER, kDummyType1, range2,
899 &precision2);
900 const void* commands3 = GetPut();
901 EXPECT_EQ(commands2, commands3);
902 EXPECT_EQ(range2[0], 14);
903 EXPECT_EQ(range2[1], 14);
904 EXPECT_EQ(precision2, 10);
906 // If we then make a request for dummy type 2, we should get another command
907 // buffer request since it hasn't been cached yet.
908 GLint range3[2] = {0, 0};
909 GLint precision3 = 0;
910 Cmds expected3;
911 ExpectedMemoryInfo result3 = GetExpectedResultMemory(4);
912 expected3.cmd.Init(GL_FRAGMENT_SHADER, kDummyType2, result3.id,
913 result3.offset);
914 Result result3_source = {true, 62, 62, 16};
915 EXPECT_CALL(*command_buffer(), OnFlush())
916 .WillOnce(SetMemory(result3.ptr, result3_source))
917 .RetiresOnSaturation();
918 gl_->GetShaderPrecisionFormat(GL_FRAGMENT_SHADER, kDummyType2, range3,
919 &precision3);
920 const void* commands4 = GetPut();
921 EXPECT_NE(commands3, commands4);
922 EXPECT_EQ(0, memcmp(&expected3, commands3, sizeof(expected3)));
923 EXPECT_EQ(range3[0], 62);
924 EXPECT_EQ(range3[1], 62);
925 EXPECT_EQ(precision3, 16);
927 // Any call for predefined types should use the cached value from the
928 // Capabilities and avoid triggering a command buffer request, so we do not
929 // expect a call to OnFlush() here. We do expect the results to be correct
930 // though.
931 GLint range4[2] = {0, 0};
932 GLint precision4 = 0;
933 gl_->GetShaderPrecisionFormat(GL_FRAGMENT_SHADER, GL_MEDIUM_FLOAT, range4,
934 &precision4);
935 const void* commands5 = GetPut();
936 EXPECT_EQ(commands4, commands5);
937 EXPECT_EQ(range4[0], 3);
938 EXPECT_EQ(range4[1], 5);
939 EXPECT_EQ(precision4, 7);
942 TEST_F(GLES2ImplementationTest, GetShaderSource) {
943 const uint32 kBucketId = GLES2Implementation::kResultBucketId;
944 const GLuint kShaderId = 456;
945 const Str7 kString = {"foobar"};
946 const char kBad = 0x12;
947 struct Cmds {
948 cmd::SetBucketSize set_bucket_size1;
949 cmds::GetShaderSource get_shader_source;
950 cmd::GetBucketStart get_bucket_start;
951 cmd::SetToken set_token1;
952 cmd::SetBucketSize set_bucket_size2;
955 ExpectedMemoryInfo mem1 = GetExpectedMemory(MaxTransferBufferSize());
956 ExpectedMemoryInfo result1 = GetExpectedResultMemory(sizeof(uint32));
958 Cmds expected;
959 expected.set_bucket_size1.Init(kBucketId, 0);
960 expected.get_shader_source.Init(kShaderId, kBucketId);
961 expected.get_bucket_start.Init(
962 kBucketId, result1.id, result1.offset,
963 MaxTransferBufferSize(), mem1.id, mem1.offset);
964 expected.set_token1.Init(GetNextToken());
965 expected.set_bucket_size2.Init(kBucketId, 0);
966 char buf[sizeof(kString) + 1];
967 memset(buf, kBad, sizeof(buf));
969 EXPECT_CALL(*command_buffer(), OnFlush())
970 .WillOnce(DoAll(SetMemory(result1.ptr, uint32(sizeof(kString))),
971 SetMemory(mem1.ptr, kString)))
972 .RetiresOnSaturation();
974 GLsizei length = 0;
975 gl_->GetShaderSource(kShaderId, sizeof(buf), &length, buf);
976 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
977 EXPECT_EQ(sizeof(kString) - 1, static_cast<size_t>(length));
978 EXPECT_STREQ(kString.str, buf);
979 EXPECT_EQ(buf[sizeof(kString)], kBad);
982 #if defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS)
984 TEST_F(GLES2ImplementationTest, DrawArraysClientSideBuffers) {
985 static const float verts[][4] = {
986 { 12.0f, 23.0f, 34.0f, 45.0f, },
987 { 56.0f, 67.0f, 78.0f, 89.0f, },
988 { 13.0f, 24.0f, 35.0f, 46.0f, },
990 struct Cmds {
991 cmds::EnableVertexAttribArray enable1;
992 cmds::EnableVertexAttribArray enable2;
993 cmds::BindBuffer bind_to_emu;
994 cmds::BufferData set_size;
995 cmds::BufferSubData copy_data1;
996 cmd::SetToken set_token1;
997 cmds::VertexAttribPointer set_pointer1;
998 cmds::BufferSubData copy_data2;
999 cmd::SetToken set_token2;
1000 cmds::VertexAttribPointer set_pointer2;
1001 cmds::DrawArrays draw;
1002 cmds::BindBuffer restore;
1004 const GLuint kEmuBufferId = GLES2Implementation::kClientSideArrayId;
1005 const GLuint kAttribIndex1 = 1;
1006 const GLuint kAttribIndex2 = 3;
1007 const GLint kNumComponents1 = 3;
1008 const GLint kNumComponents2 = 2;
1009 const GLsizei kClientStride = sizeof(verts[0]);
1010 const GLint kFirst = 1;
1011 const GLsizei kCount = 2;
1012 const GLsizei kSize1 =
1013 arraysize(verts) * kNumComponents1 * sizeof(verts[0][0]);
1014 const GLsizei kSize2 =
1015 arraysize(verts) * kNumComponents2 * sizeof(verts[0][0]);
1016 const GLsizei kEmuOffset1 = 0;
1017 const GLsizei kEmuOffset2 = kSize1;
1018 const GLsizei kTotalSize = kSize1 + kSize2;
1020 ExpectedMemoryInfo mem1 = GetExpectedMemory(kSize1);
1021 ExpectedMemoryInfo mem2 = GetExpectedMemory(kSize2);
1023 Cmds expected;
1024 expected.enable1.Init(kAttribIndex1);
1025 expected.enable2.Init(kAttribIndex2);
1026 expected.bind_to_emu.Init(GL_ARRAY_BUFFER, kEmuBufferId);
1027 expected.set_size.Init(GL_ARRAY_BUFFER, kTotalSize, 0, 0, GL_DYNAMIC_DRAW);
1028 expected.copy_data1.Init(
1029 GL_ARRAY_BUFFER, kEmuOffset1, kSize1, mem1.id, mem1.offset);
1030 expected.set_token1.Init(GetNextToken());
1031 expected.set_pointer1.Init(
1032 kAttribIndex1, kNumComponents1, GL_FLOAT, GL_FALSE, 0, kEmuOffset1);
1033 expected.copy_data2.Init(
1034 GL_ARRAY_BUFFER, kEmuOffset2, kSize2, mem2.id, mem2.offset);
1035 expected.set_token2.Init(GetNextToken());
1036 expected.set_pointer2.Init(
1037 kAttribIndex2, kNumComponents2, GL_FLOAT, GL_FALSE, 0, kEmuOffset2);
1038 expected.draw.Init(GL_POINTS, kFirst, kCount);
1039 expected.restore.Init(GL_ARRAY_BUFFER, 0);
1040 gl_->EnableVertexAttribArray(kAttribIndex1);
1041 gl_->EnableVertexAttribArray(kAttribIndex2);
1042 gl_->VertexAttribPointer(
1043 kAttribIndex1, kNumComponents1, GL_FLOAT, GL_FALSE, kClientStride, verts);
1044 gl_->VertexAttribPointer(
1045 kAttribIndex2, kNumComponents2, GL_FLOAT, GL_FALSE, kClientStride, verts);
1046 gl_->DrawArrays(GL_POINTS, kFirst, kCount);
1047 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
1050 TEST_F(GLES2ImplementationTest, DrawArraysInstancedANGLEClientSideBuffers) {
1051 static const float verts[][4] = {
1052 { 12.0f, 23.0f, 34.0f, 45.0f, },
1053 { 56.0f, 67.0f, 78.0f, 89.0f, },
1054 { 13.0f, 24.0f, 35.0f, 46.0f, },
1056 struct Cmds {
1057 cmds::EnableVertexAttribArray enable1;
1058 cmds::EnableVertexAttribArray enable2;
1059 cmds::VertexAttribDivisorANGLE divisor;
1060 cmds::BindBuffer bind_to_emu;
1061 cmds::BufferData set_size;
1062 cmds::BufferSubData copy_data1;
1063 cmd::SetToken set_token1;
1064 cmds::VertexAttribPointer set_pointer1;
1065 cmds::BufferSubData copy_data2;
1066 cmd::SetToken set_token2;
1067 cmds::VertexAttribPointer set_pointer2;
1068 cmds::DrawArraysInstancedANGLE draw;
1069 cmds::BindBuffer restore;
1071 const GLuint kEmuBufferId = GLES2Implementation::kClientSideArrayId;
1072 const GLuint kAttribIndex1 = 1;
1073 const GLuint kAttribIndex2 = 3;
1074 const GLint kNumComponents1 = 3;
1075 const GLint kNumComponents2 = 2;
1076 const GLsizei kClientStride = sizeof(verts[0]);
1077 const GLint kFirst = 1;
1078 const GLsizei kCount = 2;
1079 const GLuint kDivisor = 1;
1080 const GLsizei kSize1 =
1081 arraysize(verts) * kNumComponents1 * sizeof(verts[0][0]);
1082 const GLsizei kSize2 =
1083 1 * kNumComponents2 * sizeof(verts[0][0]);
1084 const GLsizei kEmuOffset1 = 0;
1085 const GLsizei kEmuOffset2 = kSize1;
1086 const GLsizei kTotalSize = kSize1 + kSize2;
1088 ExpectedMemoryInfo mem1 = GetExpectedMemory(kSize1);
1089 ExpectedMemoryInfo mem2 = GetExpectedMemory(kSize2);
1091 Cmds expected;
1092 expected.enable1.Init(kAttribIndex1);
1093 expected.enable2.Init(kAttribIndex2);
1094 expected.divisor.Init(kAttribIndex2, kDivisor);
1095 expected.bind_to_emu.Init(GL_ARRAY_BUFFER, kEmuBufferId);
1096 expected.set_size.Init(GL_ARRAY_BUFFER, kTotalSize, 0, 0, GL_DYNAMIC_DRAW);
1097 expected.copy_data1.Init(
1098 GL_ARRAY_BUFFER, kEmuOffset1, kSize1, mem1.id, mem1.offset);
1099 expected.set_token1.Init(GetNextToken());
1100 expected.set_pointer1.Init(
1101 kAttribIndex1, kNumComponents1, GL_FLOAT, GL_FALSE, 0, kEmuOffset1);
1102 expected.copy_data2.Init(
1103 GL_ARRAY_BUFFER, kEmuOffset2, kSize2, mem2.id, mem2.offset);
1104 expected.set_token2.Init(GetNextToken());
1105 expected.set_pointer2.Init(
1106 kAttribIndex2, kNumComponents2, GL_FLOAT, GL_FALSE, 0, kEmuOffset2);
1107 expected.draw.Init(GL_POINTS, kFirst, kCount, 1);
1108 expected.restore.Init(GL_ARRAY_BUFFER, 0);
1109 gl_->EnableVertexAttribArray(kAttribIndex1);
1110 gl_->EnableVertexAttribArray(kAttribIndex2);
1111 gl_->VertexAttribPointer(
1112 kAttribIndex1, kNumComponents1, GL_FLOAT, GL_FALSE, kClientStride, verts);
1113 gl_->VertexAttribPointer(
1114 kAttribIndex2, kNumComponents2, GL_FLOAT, GL_FALSE, kClientStride, verts);
1115 gl_->VertexAttribDivisorANGLE(kAttribIndex2, kDivisor);
1116 gl_->DrawArraysInstancedANGLE(GL_POINTS, kFirst, kCount, 1);
1117 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
1120 TEST_F(GLES2ImplementationTest, DrawElementsClientSideBuffers) {
1121 static const float verts[][4] = {
1122 { 12.0f, 23.0f, 34.0f, 45.0f, },
1123 { 56.0f, 67.0f, 78.0f, 89.0f, },
1124 { 13.0f, 24.0f, 35.0f, 46.0f, },
1126 static const uint16 indices[] = {
1127 1, 2,
1129 struct Cmds {
1130 cmds::EnableVertexAttribArray enable1;
1131 cmds::EnableVertexAttribArray enable2;
1132 cmds::BindBuffer bind_to_index_emu;
1133 cmds::BufferData set_index_size;
1134 cmds::BufferSubData copy_data0;
1135 cmd::SetToken set_token0;
1136 cmds::BindBuffer bind_to_emu;
1137 cmds::BufferData set_size;
1138 cmds::BufferSubData copy_data1;
1139 cmd::SetToken set_token1;
1140 cmds::VertexAttribPointer set_pointer1;
1141 cmds::BufferSubData copy_data2;
1142 cmd::SetToken set_token2;
1143 cmds::VertexAttribPointer set_pointer2;
1144 cmds::DrawElements draw;
1145 cmds::BindBuffer restore;
1146 cmds::BindBuffer restore_element;
1148 const GLsizei kIndexSize = sizeof(indices);
1149 const GLuint kEmuBufferId = GLES2Implementation::kClientSideArrayId;
1150 const GLuint kEmuIndexBufferId =
1151 GLES2Implementation::kClientSideElementArrayId;
1152 const GLuint kAttribIndex1 = 1;
1153 const GLuint kAttribIndex2 = 3;
1154 const GLint kNumComponents1 = 3;
1155 const GLint kNumComponents2 = 2;
1156 const GLsizei kClientStride = sizeof(verts[0]);
1157 const GLsizei kCount = 2;
1158 const GLsizei kSize1 =
1159 arraysize(verts) * kNumComponents1 * sizeof(verts[0][0]);
1160 const GLsizei kSize2 =
1161 arraysize(verts) * kNumComponents2 * sizeof(verts[0][0]);
1162 const GLsizei kEmuOffset1 = 0;
1163 const GLsizei kEmuOffset2 = kSize1;
1164 const GLsizei kTotalSize = kSize1 + kSize2;
1166 ExpectedMemoryInfo mem1 = GetExpectedMemory(kIndexSize);
1167 ExpectedMemoryInfo mem2 = GetExpectedMemory(kSize1);
1168 ExpectedMemoryInfo mem3 = GetExpectedMemory(kSize2);
1170 Cmds expected;
1171 expected.enable1.Init(kAttribIndex1);
1172 expected.enable2.Init(kAttribIndex2);
1173 expected.bind_to_index_emu.Init(GL_ELEMENT_ARRAY_BUFFER, kEmuIndexBufferId);
1174 expected.set_index_size.Init(
1175 GL_ELEMENT_ARRAY_BUFFER, kIndexSize, 0, 0, GL_DYNAMIC_DRAW);
1176 expected.copy_data0.Init(
1177 GL_ELEMENT_ARRAY_BUFFER, 0, kIndexSize, mem1.id, mem1.offset);
1178 expected.set_token0.Init(GetNextToken());
1179 expected.bind_to_emu.Init(GL_ARRAY_BUFFER, kEmuBufferId);
1180 expected.set_size.Init(GL_ARRAY_BUFFER, kTotalSize, 0, 0, GL_DYNAMIC_DRAW);
1181 expected.copy_data1.Init(
1182 GL_ARRAY_BUFFER, kEmuOffset1, kSize1, mem2.id, mem2.offset);
1183 expected.set_token1.Init(GetNextToken());
1184 expected.set_pointer1.Init(
1185 kAttribIndex1, kNumComponents1, GL_FLOAT, GL_FALSE, 0, kEmuOffset1);
1186 expected.copy_data2.Init(
1187 GL_ARRAY_BUFFER, kEmuOffset2, kSize2, mem3.id, mem3.offset);
1188 expected.set_token2.Init(GetNextToken());
1189 expected.set_pointer2.Init(kAttribIndex2, kNumComponents2,
1190 GL_FLOAT, GL_FALSE, 0, kEmuOffset2);
1191 expected.draw.Init(GL_POINTS, kCount, GL_UNSIGNED_SHORT, 0);
1192 expected.restore.Init(GL_ARRAY_BUFFER, 0);
1193 expected.restore_element.Init(GL_ELEMENT_ARRAY_BUFFER, 0);
1194 gl_->EnableVertexAttribArray(kAttribIndex1);
1195 gl_->EnableVertexAttribArray(kAttribIndex2);
1196 gl_->VertexAttribPointer(kAttribIndex1, kNumComponents1,
1197 GL_FLOAT, GL_FALSE, kClientStride, verts);
1198 gl_->VertexAttribPointer(kAttribIndex2, kNumComponents2,
1199 GL_FLOAT, GL_FALSE, kClientStride, verts);
1200 gl_->DrawElements(GL_POINTS, kCount, GL_UNSIGNED_SHORT, indices);
1201 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
1204 TEST_F(GLES2ImplementationTest, DrawElementsClientSideBuffersIndexUint) {
1205 static const float verts[][4] = {
1206 { 12.0f, 23.0f, 34.0f, 45.0f, },
1207 { 56.0f, 67.0f, 78.0f, 89.0f, },
1208 { 13.0f, 24.0f, 35.0f, 46.0f, },
1210 static const uint32 indices[] = {
1211 1, 2,
1213 struct Cmds {
1214 cmds::EnableVertexAttribArray enable1;
1215 cmds::EnableVertexAttribArray enable2;
1216 cmds::BindBuffer bind_to_index_emu;
1217 cmds::BufferData set_index_size;
1218 cmds::BufferSubData copy_data0;
1219 cmd::SetToken set_token0;
1220 cmds::BindBuffer bind_to_emu;
1221 cmds::BufferData set_size;
1222 cmds::BufferSubData copy_data1;
1223 cmd::SetToken set_token1;
1224 cmds::VertexAttribPointer set_pointer1;
1225 cmds::BufferSubData copy_data2;
1226 cmd::SetToken set_token2;
1227 cmds::VertexAttribPointer set_pointer2;
1228 cmds::DrawElements draw;
1229 cmds::BindBuffer restore;
1230 cmds::BindBuffer restore_element;
1232 const GLsizei kIndexSize = sizeof(indices);
1233 const GLuint kEmuBufferId = GLES2Implementation::kClientSideArrayId;
1234 const GLuint kEmuIndexBufferId =
1235 GLES2Implementation::kClientSideElementArrayId;
1236 const GLuint kAttribIndex1 = 1;
1237 const GLuint kAttribIndex2 = 3;
1238 const GLint kNumComponents1 = 3;
1239 const GLint kNumComponents2 = 2;
1240 const GLsizei kClientStride = sizeof(verts[0]);
1241 const GLsizei kCount = 2;
1242 const GLsizei kSize1 =
1243 arraysize(verts) * kNumComponents1 * sizeof(verts[0][0]);
1244 const GLsizei kSize2 =
1245 arraysize(verts) * kNumComponents2 * sizeof(verts[0][0]);
1246 const GLsizei kEmuOffset1 = 0;
1247 const GLsizei kEmuOffset2 = kSize1;
1248 const GLsizei kTotalSize = kSize1 + kSize2;
1250 ExpectedMemoryInfo mem1 = GetExpectedMemory(kIndexSize);
1251 ExpectedMemoryInfo mem2 = GetExpectedMemory(kSize1);
1252 ExpectedMemoryInfo mem3 = GetExpectedMemory(kSize2);
1254 Cmds expected;
1255 expected.enable1.Init(kAttribIndex1);
1256 expected.enable2.Init(kAttribIndex2);
1257 expected.bind_to_index_emu.Init(GL_ELEMENT_ARRAY_BUFFER, kEmuIndexBufferId);
1258 expected.set_index_size.Init(
1259 GL_ELEMENT_ARRAY_BUFFER, kIndexSize, 0, 0, GL_DYNAMIC_DRAW);
1260 expected.copy_data0.Init(
1261 GL_ELEMENT_ARRAY_BUFFER, 0, kIndexSize, mem1.id, mem1.offset);
1262 expected.set_token0.Init(GetNextToken());
1263 expected.bind_to_emu.Init(GL_ARRAY_BUFFER, kEmuBufferId);
1264 expected.set_size.Init(GL_ARRAY_BUFFER, kTotalSize, 0, 0, GL_DYNAMIC_DRAW);
1265 expected.copy_data1.Init(
1266 GL_ARRAY_BUFFER, kEmuOffset1, kSize1, mem2.id, mem2.offset);
1267 expected.set_token1.Init(GetNextToken());
1268 expected.set_pointer1.Init(
1269 kAttribIndex1, kNumComponents1, GL_FLOAT, GL_FALSE, 0, kEmuOffset1);
1270 expected.copy_data2.Init(
1271 GL_ARRAY_BUFFER, kEmuOffset2, kSize2, mem3.id, mem3.offset);
1272 expected.set_token2.Init(GetNextToken());
1273 expected.set_pointer2.Init(kAttribIndex2, kNumComponents2,
1274 GL_FLOAT, GL_FALSE, 0, kEmuOffset2);
1275 expected.draw.Init(GL_POINTS, kCount, GL_UNSIGNED_INT, 0);
1276 expected.restore.Init(GL_ARRAY_BUFFER, 0);
1277 expected.restore_element.Init(GL_ELEMENT_ARRAY_BUFFER, 0);
1278 gl_->EnableVertexAttribArray(kAttribIndex1);
1279 gl_->EnableVertexAttribArray(kAttribIndex2);
1280 gl_->VertexAttribPointer(kAttribIndex1, kNumComponents1,
1281 GL_FLOAT, GL_FALSE, kClientStride, verts);
1282 gl_->VertexAttribPointer(kAttribIndex2, kNumComponents2,
1283 GL_FLOAT, GL_FALSE, kClientStride, verts);
1284 gl_->DrawElements(GL_POINTS, kCount, GL_UNSIGNED_INT, indices);
1285 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
1288 TEST_F(GLES2ImplementationTest, DrawElementsClientSideBuffersInvalidIndexUint) {
1289 static const float verts[][4] = {
1290 { 12.0f, 23.0f, 34.0f, 45.0f, },
1291 { 56.0f, 67.0f, 78.0f, 89.0f, },
1292 { 13.0f, 24.0f, 35.0f, 46.0f, },
1294 static const uint32 indices[] = {
1295 1, 0x90000000
1298 const GLuint kAttribIndex1 = 1;
1299 const GLuint kAttribIndex2 = 3;
1300 const GLint kNumComponents1 = 3;
1301 const GLint kNumComponents2 = 2;
1302 const GLsizei kClientStride = sizeof(verts[0]);
1303 const GLsizei kCount = 2;
1305 EXPECT_CALL(*command_buffer(), OnFlush())
1306 .Times(1)
1307 .RetiresOnSaturation();
1309 gl_->EnableVertexAttribArray(kAttribIndex1);
1310 gl_->EnableVertexAttribArray(kAttribIndex2);
1311 gl_->VertexAttribPointer(kAttribIndex1, kNumComponents1,
1312 GL_FLOAT, GL_FALSE, kClientStride, verts);
1313 gl_->VertexAttribPointer(kAttribIndex2, kNumComponents2,
1314 GL_FLOAT, GL_FALSE, kClientStride, verts);
1315 gl_->DrawElements(GL_POINTS, kCount, GL_UNSIGNED_INT, indices);
1317 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_OPERATION), gl_->GetError());
1320 TEST_F(GLES2ImplementationTest,
1321 DrawElementsClientSideBuffersServiceSideIndices) {
1322 static const float verts[][4] = {
1323 { 12.0f, 23.0f, 34.0f, 45.0f, },
1324 { 56.0f, 67.0f, 78.0f, 89.0f, },
1325 { 13.0f, 24.0f, 35.0f, 46.0f, },
1327 struct Cmds {
1328 cmds::EnableVertexAttribArray enable1;
1329 cmds::EnableVertexAttribArray enable2;
1330 cmds::BindBuffer bind_to_index;
1331 cmds::GetMaxValueInBufferCHROMIUM get_max;
1332 cmds::BindBuffer bind_to_emu;
1333 cmds::BufferData set_size;
1334 cmds::BufferSubData copy_data1;
1335 cmd::SetToken set_token1;
1336 cmds::VertexAttribPointer set_pointer1;
1337 cmds::BufferSubData copy_data2;
1338 cmd::SetToken set_token2;
1339 cmds::VertexAttribPointer set_pointer2;
1340 cmds::DrawElements draw;
1341 cmds::BindBuffer restore;
1343 const GLuint kEmuBufferId = GLES2Implementation::kClientSideArrayId;
1344 const GLuint kClientIndexBufferId = 0x789;
1345 const GLuint kIndexOffset = 0x40;
1346 const GLuint kMaxIndex = 2;
1347 const GLuint kAttribIndex1 = 1;
1348 const GLuint kAttribIndex2 = 3;
1349 const GLint kNumComponents1 = 3;
1350 const GLint kNumComponents2 = 2;
1351 const GLsizei kClientStride = sizeof(verts[0]);
1352 const GLsizei kCount = 2;
1353 const GLsizei kSize1 =
1354 arraysize(verts) * kNumComponents1 * sizeof(verts[0][0]);
1355 const GLsizei kSize2 =
1356 arraysize(verts) * kNumComponents2 * sizeof(verts[0][0]);
1357 const GLsizei kEmuOffset1 = 0;
1358 const GLsizei kEmuOffset2 = kSize1;
1359 const GLsizei kTotalSize = kSize1 + kSize2;
1361 ExpectedMemoryInfo mem1 = GetExpectedResultMemory(sizeof(uint32));
1362 ExpectedMemoryInfo mem2 = GetExpectedMemory(kSize1);
1363 ExpectedMemoryInfo mem3 = GetExpectedMemory(kSize2);
1366 Cmds expected;
1367 expected.enable1.Init(kAttribIndex1);
1368 expected.enable2.Init(kAttribIndex2);
1369 expected.bind_to_index.Init(GL_ELEMENT_ARRAY_BUFFER, kClientIndexBufferId);
1370 expected.get_max.Init(kClientIndexBufferId, kCount, GL_UNSIGNED_SHORT,
1371 kIndexOffset, mem1.id, mem1.offset);
1372 expected.bind_to_emu.Init(GL_ARRAY_BUFFER, kEmuBufferId);
1373 expected.set_size.Init(GL_ARRAY_BUFFER, kTotalSize, 0, 0, GL_DYNAMIC_DRAW);
1374 expected.copy_data1.Init(
1375 GL_ARRAY_BUFFER, kEmuOffset1, kSize1, mem2.id, mem2.offset);
1376 expected.set_token1.Init(GetNextToken());
1377 expected.set_pointer1.Init(kAttribIndex1, kNumComponents1,
1378 GL_FLOAT, GL_FALSE, 0, kEmuOffset1);
1379 expected.copy_data2.Init(
1380 GL_ARRAY_BUFFER, kEmuOffset2, kSize2, mem3.id, mem3.offset);
1381 expected.set_token2.Init(GetNextToken());
1382 expected.set_pointer2.Init(kAttribIndex2, kNumComponents2,
1383 GL_FLOAT, GL_FALSE, 0, kEmuOffset2);
1384 expected.draw.Init(GL_POINTS, kCount, GL_UNSIGNED_SHORT, kIndexOffset);
1385 expected.restore.Init(GL_ARRAY_BUFFER, 0);
1387 EXPECT_CALL(*command_buffer(), OnFlush())
1388 .WillOnce(SetMemory(mem1.ptr,kMaxIndex))
1389 .RetiresOnSaturation();
1391 gl_->EnableVertexAttribArray(kAttribIndex1);
1392 gl_->EnableVertexAttribArray(kAttribIndex2);
1393 gl_->BindBuffer(GL_ELEMENT_ARRAY_BUFFER, kClientIndexBufferId);
1394 gl_->VertexAttribPointer(kAttribIndex1, kNumComponents1,
1395 GL_FLOAT, GL_FALSE, kClientStride, verts);
1396 gl_->VertexAttribPointer(kAttribIndex2, kNumComponents2,
1397 GL_FLOAT, GL_FALSE, kClientStride, verts);
1398 gl_->DrawElements(GL_POINTS, kCount, GL_UNSIGNED_SHORT,
1399 reinterpret_cast<const void*>(kIndexOffset));
1400 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
1403 TEST_F(GLES2ImplementationTest, DrawElementsInstancedANGLEClientSideBuffers) {
1404 static const float verts[][4] = {
1405 { 12.0f, 23.0f, 34.0f, 45.0f, },
1406 { 56.0f, 67.0f, 78.0f, 89.0f, },
1407 { 13.0f, 24.0f, 35.0f, 46.0f, },
1409 static const uint16 indices[] = {
1410 1, 2,
1412 struct Cmds {
1413 cmds::EnableVertexAttribArray enable1;
1414 cmds::EnableVertexAttribArray enable2;
1415 cmds::VertexAttribDivisorANGLE divisor;
1416 cmds::BindBuffer bind_to_index_emu;
1417 cmds::BufferData set_index_size;
1418 cmds::BufferSubData copy_data0;
1419 cmd::SetToken set_token0;
1420 cmds::BindBuffer bind_to_emu;
1421 cmds::BufferData set_size;
1422 cmds::BufferSubData copy_data1;
1423 cmd::SetToken set_token1;
1424 cmds::VertexAttribPointer set_pointer1;
1425 cmds::BufferSubData copy_data2;
1426 cmd::SetToken set_token2;
1427 cmds::VertexAttribPointer set_pointer2;
1428 cmds::DrawElementsInstancedANGLE draw;
1429 cmds::BindBuffer restore;
1430 cmds::BindBuffer restore_element;
1432 const GLsizei kIndexSize = sizeof(indices);
1433 const GLuint kEmuBufferId = GLES2Implementation::kClientSideArrayId;
1434 const GLuint kEmuIndexBufferId =
1435 GLES2Implementation::kClientSideElementArrayId;
1436 const GLuint kAttribIndex1 = 1;
1437 const GLuint kAttribIndex2 = 3;
1438 const GLint kNumComponents1 = 3;
1439 const GLint kNumComponents2 = 2;
1440 const GLsizei kClientStride = sizeof(verts[0]);
1441 const GLsizei kCount = 2;
1442 const GLsizei kSize1 =
1443 arraysize(verts) * kNumComponents1 * sizeof(verts[0][0]);
1444 const GLsizei kSize2 =
1445 1 * kNumComponents2 * sizeof(verts[0][0]);
1446 const GLuint kDivisor = 1;
1447 const GLsizei kEmuOffset1 = 0;
1448 const GLsizei kEmuOffset2 = kSize1;
1449 const GLsizei kTotalSize = kSize1 + kSize2;
1451 ExpectedMemoryInfo mem1 = GetExpectedMemory(kIndexSize);
1452 ExpectedMemoryInfo mem2 = GetExpectedMemory(kSize1);
1453 ExpectedMemoryInfo mem3 = GetExpectedMemory(kSize2);
1455 Cmds expected;
1456 expected.enable1.Init(kAttribIndex1);
1457 expected.enable2.Init(kAttribIndex2);
1458 expected.divisor.Init(kAttribIndex2, kDivisor);
1459 expected.bind_to_index_emu.Init(GL_ELEMENT_ARRAY_BUFFER, kEmuIndexBufferId);
1460 expected.set_index_size.Init(
1461 GL_ELEMENT_ARRAY_BUFFER, kIndexSize, 0, 0, GL_DYNAMIC_DRAW);
1462 expected.copy_data0.Init(
1463 GL_ELEMENT_ARRAY_BUFFER, 0, kIndexSize, mem1.id, mem1.offset);
1464 expected.set_token0.Init(GetNextToken());
1465 expected.bind_to_emu.Init(GL_ARRAY_BUFFER, kEmuBufferId);
1466 expected.set_size.Init(GL_ARRAY_BUFFER, kTotalSize, 0, 0, GL_DYNAMIC_DRAW);
1467 expected.copy_data1.Init(
1468 GL_ARRAY_BUFFER, kEmuOffset1, kSize1, mem2.id, mem2.offset);
1469 expected.set_token1.Init(GetNextToken());
1470 expected.set_pointer1.Init(
1471 kAttribIndex1, kNumComponents1, GL_FLOAT, GL_FALSE, 0, kEmuOffset1);
1472 expected.copy_data2.Init(
1473 GL_ARRAY_BUFFER, kEmuOffset2, kSize2, mem3.id, mem3.offset);
1474 expected.set_token2.Init(GetNextToken());
1475 expected.set_pointer2.Init(kAttribIndex2, kNumComponents2,
1476 GL_FLOAT, GL_FALSE, 0, kEmuOffset2);
1477 expected.draw.Init(GL_POINTS, kCount, GL_UNSIGNED_SHORT, 0, 1);
1478 expected.restore.Init(GL_ARRAY_BUFFER, 0);
1479 expected.restore_element.Init(GL_ELEMENT_ARRAY_BUFFER, 0);
1480 gl_->EnableVertexAttribArray(kAttribIndex1);
1481 gl_->EnableVertexAttribArray(kAttribIndex2);
1482 gl_->VertexAttribPointer(kAttribIndex1, kNumComponents1,
1483 GL_FLOAT, GL_FALSE, kClientStride, verts);
1484 gl_->VertexAttribPointer(kAttribIndex2, kNumComponents2,
1485 GL_FLOAT, GL_FALSE, kClientStride, verts);
1486 gl_->VertexAttribDivisorANGLE(kAttribIndex2, kDivisor);
1487 gl_->DrawElementsInstancedANGLE(
1488 GL_POINTS, kCount, GL_UNSIGNED_SHORT, indices, 1);
1489 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
1492 TEST_F(GLES2ImplementationTest, GetVertexBufferPointerv) {
1493 static const float verts[1] = { 0.0f, };
1494 const GLuint kAttribIndex1 = 1;
1495 const GLuint kAttribIndex2 = 3;
1496 const GLint kNumComponents1 = 3;
1497 const GLint kNumComponents2 = 2;
1498 const GLsizei kStride1 = 12;
1499 const GLsizei kStride2 = 0;
1500 const GLuint kBufferId = 0x123;
1501 const GLint kOffset2 = 0x456;
1503 // It's all cached on the client side so no get commands are issued.
1504 struct Cmds {
1505 cmds::BindBuffer bind;
1506 cmds::VertexAttribPointer set_pointer;
1509 Cmds expected;
1510 expected.bind.Init(GL_ARRAY_BUFFER, kBufferId);
1511 expected.set_pointer.Init(kAttribIndex2, kNumComponents2, GL_FLOAT, GL_FALSE,
1512 kStride2, kOffset2);
1514 // Set one client side buffer.
1515 gl_->VertexAttribPointer(kAttribIndex1, kNumComponents1,
1516 GL_FLOAT, GL_FALSE, kStride1, verts);
1517 // Set one VBO
1518 gl_->BindBuffer(GL_ARRAY_BUFFER, kBufferId);
1519 gl_->VertexAttribPointer(kAttribIndex2, kNumComponents2,
1520 GL_FLOAT, GL_FALSE, kStride2,
1521 reinterpret_cast<const void*>(kOffset2));
1522 // now get them both.
1523 void* ptr1 = NULL;
1524 void* ptr2 = NULL;
1526 gl_->GetVertexAttribPointerv(
1527 kAttribIndex1, GL_VERTEX_ATTRIB_ARRAY_POINTER, &ptr1);
1528 gl_->GetVertexAttribPointerv(
1529 kAttribIndex2, GL_VERTEX_ATTRIB_ARRAY_POINTER, &ptr2);
1531 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
1532 EXPECT_TRUE(static_cast<const void*>(&verts) == ptr1);
1533 EXPECT_TRUE(ptr2 == reinterpret_cast<void*>(kOffset2));
1536 TEST_F(GLES2ImplementationTest, GetVertexAttrib) {
1537 static const float verts[1] = { 0.0f, };
1538 const GLuint kAttribIndex1 = 1;
1539 const GLuint kAttribIndex2 = 3;
1540 const GLint kNumComponents1 = 3;
1541 const GLint kNumComponents2 = 2;
1542 const GLsizei kStride1 = 12;
1543 const GLsizei kStride2 = 0;
1544 const GLuint kBufferId = 0x123;
1545 const GLint kOffset2 = 0x456;
1547 // Only one set and one get because the client side buffer's info is stored
1548 // on the client side.
1549 struct Cmds {
1550 cmds::EnableVertexAttribArray enable;
1551 cmds::BindBuffer bind;
1552 cmds::VertexAttribPointer set_pointer;
1553 cmds::GetVertexAttribfv get2; // for getting the value from attrib1
1556 ExpectedMemoryInfo mem2 = GetExpectedResultMemory(16);
1558 Cmds expected;
1559 expected.enable.Init(kAttribIndex1);
1560 expected.bind.Init(GL_ARRAY_BUFFER, kBufferId);
1561 expected.set_pointer.Init(kAttribIndex2, kNumComponents2, GL_FLOAT, GL_FALSE,
1562 kStride2, kOffset2);
1563 expected.get2.Init(kAttribIndex1,
1564 GL_CURRENT_VERTEX_ATTRIB,
1565 mem2.id, mem2.offset);
1567 FourFloats current_attrib(1.2f, 3.4f, 5.6f, 7.8f);
1569 // One call to flush to wait for last call to GetVertexAttribiv
1570 // as others are all cached.
1571 EXPECT_CALL(*command_buffer(), OnFlush())
1572 .WillOnce(SetMemory(
1573 mem2.ptr, SizedResultHelper<FourFloats>(current_attrib)))
1574 .RetiresOnSaturation();
1576 gl_->EnableVertexAttribArray(kAttribIndex1);
1577 // Set one client side buffer.
1578 gl_->VertexAttribPointer(kAttribIndex1, kNumComponents1,
1579 GL_FLOAT, GL_FALSE, kStride1, verts);
1580 // Set one VBO
1581 gl_->BindBuffer(GL_ARRAY_BUFFER, kBufferId);
1582 gl_->VertexAttribPointer(kAttribIndex2, kNumComponents2,
1583 GL_FLOAT, GL_FALSE, kStride2,
1584 reinterpret_cast<const void*>(kOffset2));
1585 // first get the service side once to see that we make a command
1586 GLint buffer_id = 0;
1587 GLint enabled = 0;
1588 GLint size = 0;
1589 GLint stride = 0;
1590 GLint type = 0;
1591 GLint normalized = 1;
1592 float current[4] = { 0.0f, };
1594 gl_->GetVertexAttribiv(
1595 kAttribIndex2, GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING, &buffer_id);
1596 EXPECT_EQ(kBufferId, static_cast<GLuint>(buffer_id));
1597 gl_->GetVertexAttribiv(
1598 kAttribIndex1, GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING, &buffer_id);
1599 gl_->GetVertexAttribiv(
1600 kAttribIndex1, GL_VERTEX_ATTRIB_ARRAY_ENABLED, &enabled);
1601 gl_->GetVertexAttribiv(
1602 kAttribIndex1, GL_VERTEX_ATTRIB_ARRAY_SIZE, &size);
1603 gl_->GetVertexAttribiv(
1604 kAttribIndex1, GL_VERTEX_ATTRIB_ARRAY_STRIDE, &stride);
1605 gl_->GetVertexAttribiv(
1606 kAttribIndex1, GL_VERTEX_ATTRIB_ARRAY_TYPE, &type);
1607 gl_->GetVertexAttribiv(
1608 kAttribIndex1, GL_VERTEX_ATTRIB_ARRAY_NORMALIZED, &normalized);
1609 gl_->GetVertexAttribfv(
1610 kAttribIndex1, GL_CURRENT_VERTEX_ATTRIB, &current[0]);
1612 EXPECT_EQ(0, buffer_id);
1613 EXPECT_EQ(GL_TRUE, enabled);
1614 EXPECT_EQ(kNumComponents1, size);
1615 EXPECT_EQ(kStride1, stride);
1616 EXPECT_EQ(GL_FLOAT, type);
1617 EXPECT_EQ(GL_FALSE, normalized);
1618 EXPECT_EQ(0, memcmp(&current_attrib, &current, sizeof(current_attrib)));
1620 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
1623 TEST_F(GLES2ImplementationTest, ReservedIds) {
1624 // Only the get error command should be issued.
1625 struct Cmds {
1626 cmds::GetError get;
1628 Cmds expected;
1630 ExpectedMemoryInfo mem1 = GetExpectedResultMemory(
1631 sizeof(cmds::GetError::Result));
1633 expected.get.Init(mem1.id, mem1.offset);
1635 // One call to flush to wait for GetError
1636 EXPECT_CALL(*command_buffer(), OnFlush())
1637 .WillOnce(SetMemory(mem1.ptr, GLuint(GL_NO_ERROR)))
1638 .RetiresOnSaturation();
1640 gl_->BindBuffer(
1641 GL_ARRAY_BUFFER,
1642 GLES2Implementation::kClientSideArrayId);
1643 gl_->BindBuffer(
1644 GL_ARRAY_BUFFER,
1645 GLES2Implementation::kClientSideElementArrayId);
1646 GLenum err = gl_->GetError();
1647 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_OPERATION), err);
1648 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
1651 #endif // defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS)
1653 TEST_F(GLES2ImplementationTest, ReadPixels2Reads) {
1654 struct Cmds {
1655 cmds::ReadPixels read1;
1656 cmd::SetToken set_token1;
1657 cmds::ReadPixels read2;
1658 cmd::SetToken set_token2;
1660 const GLint kBytesPerPixel = 4;
1661 const GLint kWidth =
1662 (kTransferBufferSize - GLES2Implementation::kStartingOffset) /
1663 kBytesPerPixel;
1664 const GLint kHeight = 2;
1665 const GLenum kFormat = GL_RGBA;
1666 const GLenum kType = GL_UNSIGNED_BYTE;
1668 ExpectedMemoryInfo mem1 =
1669 GetExpectedMemory(kWidth * kHeight / 2 * kBytesPerPixel);
1670 ExpectedMemoryInfo result1 =
1671 GetExpectedResultMemory(sizeof(cmds::ReadPixels::Result));
1672 ExpectedMemoryInfo mem2 =
1673 GetExpectedMemory(kWidth * kHeight / 2 * kBytesPerPixel);
1674 ExpectedMemoryInfo result2 =
1675 GetExpectedResultMemory(sizeof(cmds::ReadPixels::Result));
1677 Cmds expected;
1678 expected.read1.Init(
1679 0, 0, kWidth, kHeight / 2, kFormat, kType,
1680 mem1.id, mem1.offset, result1.id, result1.offset,
1681 false);
1682 expected.set_token1.Init(GetNextToken());
1683 expected.read2.Init(
1684 0, kHeight / 2, kWidth, kHeight / 2, kFormat, kType,
1685 mem2.id, mem2.offset, result2.id, result2.offset, false);
1686 expected.set_token2.Init(GetNextToken());
1687 scoped_ptr<int8[]> buffer(new int8[kWidth * kHeight * kBytesPerPixel]);
1689 EXPECT_CALL(*command_buffer(), OnFlush())
1690 .WillOnce(SetMemory(result1.ptr, static_cast<uint32>(1)))
1691 .WillOnce(SetMemory(result2.ptr, static_cast<uint32>(1)))
1692 .RetiresOnSaturation();
1694 gl_->ReadPixels(0, 0, kWidth, kHeight, kFormat, kType, buffer.get());
1695 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
1698 TEST_F(GLES2ImplementationTest, ReadPixelsBadFormatType) {
1699 struct Cmds {
1700 cmds::ReadPixels read;
1701 cmd::SetToken set_token;
1703 const GLint kBytesPerPixel = 4;
1704 const GLint kWidth = 2;
1705 const GLint kHeight = 2;
1706 const GLenum kFormat = 0;
1707 const GLenum kType = 0;
1709 ExpectedMemoryInfo mem1 =
1710 GetExpectedMemory(kWidth * kHeight * kBytesPerPixel);
1711 ExpectedMemoryInfo result1 =
1712 GetExpectedResultMemory(sizeof(cmds::ReadPixels::Result));
1714 Cmds expected;
1715 expected.read.Init(
1716 0, 0, kWidth, kHeight, kFormat, kType,
1717 mem1.id, mem1.offset, result1.id, result1.offset, false);
1718 expected.set_token.Init(GetNextToken());
1719 scoped_ptr<int8[]> buffer(new int8[kWidth * kHeight * kBytesPerPixel]);
1721 EXPECT_CALL(*command_buffer(), OnFlush())
1722 .Times(1)
1723 .RetiresOnSaturation();
1725 gl_->ReadPixels(0, 0, kWidth, kHeight, kFormat, kType, buffer.get());
1728 TEST_F(GLES2ImplementationTest, FreeUnusedSharedMemory) {
1729 struct Cmds {
1730 cmds::BufferSubData buf;
1731 cmd::SetToken set_token;
1733 const GLenum kTarget = GL_ELEMENT_ARRAY_BUFFER;
1734 const GLintptr kOffset = 15;
1735 const GLsizeiptr kSize = 16;
1737 ExpectedMemoryInfo mem1 = GetExpectedMemory(kSize);
1739 Cmds expected;
1740 expected.buf.Init(
1741 kTarget, kOffset, kSize, mem1.id, mem1.offset);
1742 expected.set_token.Init(GetNextToken());
1744 void* mem = gl_->MapBufferSubDataCHROMIUM(
1745 kTarget, kOffset, kSize, GL_WRITE_ONLY);
1746 ASSERT_TRUE(mem != NULL);
1747 gl_->UnmapBufferSubDataCHROMIUM(mem);
1748 EXPECT_CALL(*command_buffer(), DestroyTransferBuffer(_))
1749 .Times(1)
1750 .RetiresOnSaturation();
1751 gl_->FreeUnusedSharedMemory();
1754 TEST_F(GLES2ImplementationTest, MapUnmapBufferSubDataCHROMIUM) {
1755 struct Cmds {
1756 cmds::BufferSubData buf;
1757 cmd::SetToken set_token;
1759 const GLenum kTarget = GL_ELEMENT_ARRAY_BUFFER;
1760 const GLintptr kOffset = 15;
1761 const GLsizeiptr kSize = 16;
1763 uint32 offset = 0;
1764 Cmds expected;
1765 expected.buf.Init(
1766 kTarget, kOffset, kSize,
1767 command_buffer()->GetNextFreeTransferBufferId(), offset);
1768 expected.set_token.Init(GetNextToken());
1770 void* mem = gl_->MapBufferSubDataCHROMIUM(
1771 kTarget, kOffset, kSize, GL_WRITE_ONLY);
1772 ASSERT_TRUE(mem != NULL);
1773 gl_->UnmapBufferSubDataCHROMIUM(mem);
1774 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
1777 TEST_F(GLES2ImplementationTest, MapUnmapBufferSubDataCHROMIUMBadArgs) {
1778 const GLenum kTarget = GL_ELEMENT_ARRAY_BUFFER;
1779 const GLintptr kOffset = 15;
1780 const GLsizeiptr kSize = 16;
1782 ExpectedMemoryInfo result1 =
1783 GetExpectedResultMemory(sizeof(cmds::GetError::Result));
1784 ExpectedMemoryInfo result2 =
1785 GetExpectedResultMemory(sizeof(cmds::GetError::Result));
1786 ExpectedMemoryInfo result3 =
1787 GetExpectedResultMemory(sizeof(cmds::GetError::Result));
1788 ExpectedMemoryInfo result4 =
1789 GetExpectedResultMemory(sizeof(cmds::GetError::Result));
1791 // Calls to flush to wait for GetError
1792 EXPECT_CALL(*command_buffer(), OnFlush())
1793 .WillOnce(SetMemory(result1.ptr, GLuint(GL_NO_ERROR)))
1794 .WillOnce(SetMemory(result2.ptr, GLuint(GL_NO_ERROR)))
1795 .WillOnce(SetMemory(result3.ptr, GLuint(GL_NO_ERROR)))
1796 .WillOnce(SetMemory(result4.ptr, GLuint(GL_NO_ERROR)))
1797 .RetiresOnSaturation();
1799 void* mem;
1800 mem = gl_->MapBufferSubDataCHROMIUM(kTarget, -1, kSize, GL_WRITE_ONLY);
1801 ASSERT_TRUE(mem == NULL);
1802 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE), gl_->GetError());
1803 mem = gl_->MapBufferSubDataCHROMIUM(kTarget, kOffset, -1, GL_WRITE_ONLY);
1804 ASSERT_TRUE(mem == NULL);
1805 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE), gl_->GetError());
1806 mem = gl_->MapBufferSubDataCHROMIUM(kTarget, kOffset, kSize, GL_READ_ONLY);
1807 ASSERT_TRUE(mem == NULL);
1808 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_ENUM), gl_->GetError());
1809 const char* kPtr = "something";
1810 gl_->UnmapBufferSubDataCHROMIUM(kPtr);
1811 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE), gl_->GetError());
1814 TEST_F(GLES2ImplementationTest, MapUnmapTexSubImage2DCHROMIUM) {
1815 struct Cmds {
1816 cmds::TexSubImage2D tex;
1817 cmd::SetToken set_token;
1819 const GLint kLevel = 1;
1820 const GLint kXOffset = 2;
1821 const GLint kYOffset = 3;
1822 const GLint kWidth = 4;
1823 const GLint kHeight = 5;
1824 const GLenum kFormat = GL_RGBA;
1825 const GLenum kType = GL_UNSIGNED_BYTE;
1827 uint32 offset = 0;
1828 Cmds expected;
1829 expected.tex.Init(
1830 GL_TEXTURE_2D, kLevel, kXOffset, kYOffset, kWidth, kHeight, kFormat,
1831 kType,
1832 command_buffer()->GetNextFreeTransferBufferId(), offset, GL_FALSE);
1833 expected.set_token.Init(GetNextToken());
1835 void* mem = gl_->MapTexSubImage2DCHROMIUM(
1836 GL_TEXTURE_2D,
1837 kLevel,
1838 kXOffset,
1839 kYOffset,
1840 kWidth,
1841 kHeight,
1842 kFormat,
1843 kType,
1844 GL_WRITE_ONLY);
1845 ASSERT_TRUE(mem != NULL);
1846 gl_->UnmapTexSubImage2DCHROMIUM(mem);
1847 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
1850 TEST_F(GLES2ImplementationTest, MapUnmapTexSubImage2DCHROMIUMBadArgs) {
1851 const GLint kLevel = 1;
1852 const GLint kXOffset = 2;
1853 const GLint kYOffset = 3;
1854 const GLint kWidth = 4;
1855 const GLint kHeight = 5;
1856 const GLenum kFormat = GL_RGBA;
1857 const GLenum kType = GL_UNSIGNED_BYTE;
1859 ExpectedMemoryInfo result1 =
1860 GetExpectedResultMemory(sizeof(cmds::GetError::Result));
1861 ExpectedMemoryInfo result2 =
1862 GetExpectedResultMemory(sizeof(cmds::GetError::Result));
1863 ExpectedMemoryInfo result3 =
1864 GetExpectedResultMemory(sizeof(cmds::GetError::Result));
1865 ExpectedMemoryInfo result4 =
1866 GetExpectedResultMemory(sizeof(cmds::GetError::Result));
1867 ExpectedMemoryInfo result5 =
1868 GetExpectedResultMemory(sizeof(cmds::GetError::Result));
1869 ExpectedMemoryInfo result6 =
1870 GetExpectedResultMemory(sizeof(cmds::GetError::Result));
1871 ExpectedMemoryInfo result7 =
1872 GetExpectedResultMemory(sizeof(cmds::GetError::Result));
1874 // Calls to flush to wait for GetError
1875 EXPECT_CALL(*command_buffer(), OnFlush())
1876 .WillOnce(SetMemory(result1.ptr, GLuint(GL_NO_ERROR)))
1877 .WillOnce(SetMemory(result2.ptr, GLuint(GL_NO_ERROR)))
1878 .WillOnce(SetMemory(result3.ptr, GLuint(GL_NO_ERROR)))
1879 .WillOnce(SetMemory(result4.ptr, GLuint(GL_NO_ERROR)))
1880 .WillOnce(SetMemory(result5.ptr, GLuint(GL_NO_ERROR)))
1881 .WillOnce(SetMemory(result6.ptr, GLuint(GL_NO_ERROR)))
1882 .WillOnce(SetMemory(result7.ptr, GLuint(GL_NO_ERROR)))
1883 .RetiresOnSaturation();
1885 void* mem;
1886 mem = gl_->MapTexSubImage2DCHROMIUM(
1887 GL_TEXTURE_2D,
1889 kXOffset,
1890 kYOffset,
1891 kWidth,
1892 kHeight,
1893 kFormat,
1894 kType,
1895 GL_WRITE_ONLY);
1896 EXPECT_TRUE(mem == NULL);
1897 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE), gl_->GetError());
1898 mem = gl_->MapTexSubImage2DCHROMIUM(
1899 GL_TEXTURE_2D,
1900 kLevel,
1902 kYOffset,
1903 kWidth,
1904 kHeight,
1905 kFormat,
1906 kType,
1907 GL_WRITE_ONLY);
1908 EXPECT_TRUE(mem == NULL);
1909 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE), gl_->GetError());
1910 mem = gl_->MapTexSubImage2DCHROMIUM(
1911 GL_TEXTURE_2D,
1912 kLevel,
1913 kXOffset,
1915 kWidth,
1916 kHeight,
1917 kFormat,
1918 kType,
1919 GL_WRITE_ONLY);
1920 EXPECT_TRUE(mem == NULL);
1921 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE), gl_->GetError());
1922 mem = gl_->MapTexSubImage2DCHROMIUM(
1923 GL_TEXTURE_2D,
1924 kLevel,
1925 kXOffset,
1926 kYOffset,
1928 kHeight,
1929 kFormat,
1930 kType,
1931 GL_WRITE_ONLY);
1932 EXPECT_TRUE(mem == NULL);
1933 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE), gl_->GetError());
1934 mem = gl_->MapTexSubImage2DCHROMIUM(
1935 GL_TEXTURE_2D,
1936 kLevel,
1937 kXOffset,
1938 kYOffset,
1939 kWidth,
1941 kFormat,
1942 kType,
1943 GL_WRITE_ONLY);
1944 EXPECT_TRUE(mem == NULL);
1945 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE), gl_->GetError());
1946 mem = gl_->MapTexSubImage2DCHROMIUM(
1947 GL_TEXTURE_2D,
1948 kLevel,
1949 kXOffset,
1950 kYOffset,
1951 kWidth,
1952 kHeight,
1953 kFormat,
1954 kType,
1955 GL_READ_ONLY);
1956 EXPECT_TRUE(mem == NULL);
1957 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_ENUM), gl_->GetError());
1958 const char* kPtr = "something";
1959 gl_->UnmapTexSubImage2DCHROMIUM(kPtr);
1960 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE), gl_->GetError());
1963 TEST_F(GLES2ImplementationTest, GetProgramInfoCHROMIUMGoodArgs) {
1964 const uint32 kBucketId = GLES2Implementation::kResultBucketId;
1965 const GLuint kProgramId = 123;
1966 const char kBad = 0x12;
1967 GLsizei size = 0;
1968 const Str7 kString = {"foobar"};
1969 char buf[20];
1971 ExpectedMemoryInfo mem1 =
1972 GetExpectedMemory(MaxTransferBufferSize());
1973 ExpectedMemoryInfo result1 =
1974 GetExpectedResultMemory(sizeof(cmd::GetBucketStart::Result));
1975 ExpectedMemoryInfo result2 =
1976 GetExpectedResultMemory(sizeof(cmds::GetError::Result));
1978 memset(buf, kBad, sizeof(buf));
1979 EXPECT_CALL(*command_buffer(), OnFlush())
1980 .WillOnce(DoAll(SetMemory(result1.ptr, uint32(sizeof(kString))),
1981 SetMemory(mem1.ptr, kString)))
1982 .WillOnce(SetMemory(result2.ptr, GLuint(GL_NO_ERROR)))
1983 .RetiresOnSaturation();
1985 struct Cmds {
1986 cmd::SetBucketSize set_bucket_size1;
1987 cmds::GetProgramInfoCHROMIUM get_program_info;
1988 cmd::GetBucketStart get_bucket_start;
1989 cmd::SetToken set_token1;
1990 cmd::SetBucketSize set_bucket_size2;
1992 Cmds expected;
1993 expected.set_bucket_size1.Init(kBucketId, 0);
1994 expected.get_program_info.Init(kProgramId, kBucketId);
1995 expected.get_bucket_start.Init(
1996 kBucketId, result1.id, result1.offset,
1997 MaxTransferBufferSize(), mem1.id, mem1.offset);
1998 expected.set_token1.Init(GetNextToken());
1999 expected.set_bucket_size2.Init(kBucketId, 0);
2000 gl_->GetProgramInfoCHROMIUM(kProgramId, sizeof(buf), &size, &buf);
2001 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
2002 EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), gl_->GetError());
2003 EXPECT_EQ(sizeof(kString), static_cast<size_t>(size));
2004 EXPECT_STREQ(kString.str, buf);
2005 EXPECT_EQ(buf[sizeof(kString)], kBad);
2008 TEST_F(GLES2ImplementationTest, GetProgramInfoCHROMIUMBadArgs) {
2009 const uint32 kBucketId = GLES2Implementation::kResultBucketId;
2010 const GLuint kProgramId = 123;
2011 GLsizei size = 0;
2012 const Str7 kString = {"foobar"};
2013 char buf[20];
2015 ExpectedMemoryInfo mem1 = GetExpectedMemory(MaxTransferBufferSize());
2016 ExpectedMemoryInfo result1 =
2017 GetExpectedResultMemory(sizeof(cmd::GetBucketStart::Result));
2018 ExpectedMemoryInfo result2 =
2019 GetExpectedResultMemory(sizeof(cmds::GetError::Result));
2020 ExpectedMemoryInfo result3 =
2021 GetExpectedResultMemory(sizeof(cmds::GetError::Result));
2022 ExpectedMemoryInfo result4 =
2023 GetExpectedResultMemory(sizeof(cmds::GetError::Result));
2025 EXPECT_CALL(*command_buffer(), OnFlush())
2026 .WillOnce(DoAll(SetMemory(result1.ptr, uint32(sizeof(kString))),
2027 SetMemory(mem1.ptr, kString)))
2028 .WillOnce(SetMemory(result2.ptr, GLuint(GL_NO_ERROR)))
2029 .WillOnce(SetMemory(result3.ptr, GLuint(GL_NO_ERROR)))
2030 .WillOnce(SetMemory(result4.ptr, GLuint(GL_NO_ERROR)))
2031 .RetiresOnSaturation();
2033 // try bufsize not big enough.
2034 struct Cmds {
2035 cmd::SetBucketSize set_bucket_size1;
2036 cmds::GetProgramInfoCHROMIUM get_program_info;
2037 cmd::GetBucketStart get_bucket_start;
2038 cmd::SetToken set_token1;
2039 cmd::SetBucketSize set_bucket_size2;
2041 Cmds expected;
2042 expected.set_bucket_size1.Init(kBucketId, 0);
2043 expected.get_program_info.Init(kProgramId, kBucketId);
2044 expected.get_bucket_start.Init(
2045 kBucketId, result1.id, result1.offset,
2046 MaxTransferBufferSize(), mem1.id, mem1.offset);
2047 expected.set_token1.Init(GetNextToken());
2048 expected.set_bucket_size2.Init(kBucketId, 0);
2049 gl_->GetProgramInfoCHROMIUM(kProgramId, 6, &size, &buf);
2050 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
2051 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_OPERATION), gl_->GetError());
2052 ClearCommands();
2054 // try bad bufsize
2055 gl_->GetProgramInfoCHROMIUM(kProgramId, -1, &size, &buf);
2056 EXPECT_TRUE(NoCommandsWritten());
2057 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE), gl_->GetError());
2058 ClearCommands();
2059 // try no size ptr.
2060 gl_->GetProgramInfoCHROMIUM(kProgramId, sizeof(buf), NULL, &buf);
2061 EXPECT_TRUE(NoCommandsWritten());
2062 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE), gl_->GetError());
2065 TEST_F(GLES2ImplementationTest, GetUniformBlocksCHROMIUMGoodArgs) {
2066 const uint32 kBucketId = GLES2Implementation::kResultBucketId;
2067 const GLuint kProgramId = 123;
2068 const char kBad = 0x12;
2069 GLsizei size = 0;
2070 const Str7 kString = {"foobar"};
2071 char buf[20];
2073 ExpectedMemoryInfo mem1 =
2074 GetExpectedMemory(MaxTransferBufferSize());
2075 ExpectedMemoryInfo result1 =
2076 GetExpectedResultMemory(sizeof(cmd::GetBucketStart::Result));
2077 ExpectedMemoryInfo result2 =
2078 GetExpectedResultMemory(sizeof(cmds::GetError::Result));
2080 memset(buf, kBad, sizeof(buf));
2081 EXPECT_CALL(*command_buffer(), OnFlush())
2082 .WillOnce(DoAll(SetMemory(result1.ptr, uint32(sizeof(kString))),
2083 SetMemory(mem1.ptr, kString)))
2084 .WillOnce(SetMemory(result2.ptr, GLuint(GL_NO_ERROR)))
2085 .RetiresOnSaturation();
2087 struct Cmds {
2088 cmd::SetBucketSize set_bucket_size1;
2089 cmds::GetUniformBlocksCHROMIUM get_uniform_blocks;
2090 cmd::GetBucketStart get_bucket_start;
2091 cmd::SetToken set_token1;
2092 cmd::SetBucketSize set_bucket_size2;
2094 Cmds expected;
2095 expected.set_bucket_size1.Init(kBucketId, 0);
2096 expected.get_uniform_blocks.Init(kProgramId, kBucketId);
2097 expected.get_bucket_start.Init(
2098 kBucketId, result1.id, result1.offset,
2099 MaxTransferBufferSize(), mem1.id, mem1.offset);
2100 expected.set_token1.Init(GetNextToken());
2101 expected.set_bucket_size2.Init(kBucketId, 0);
2102 gl_->GetUniformBlocksCHROMIUM(kProgramId, sizeof(buf), &size, &buf);
2103 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
2104 EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), gl_->GetError());
2105 EXPECT_EQ(sizeof(kString), static_cast<size_t>(size));
2106 EXPECT_STREQ(kString.str, buf);
2107 EXPECT_EQ(buf[sizeof(kString)], kBad);
2110 TEST_F(GLES2ImplementationTest, GetUniformBlocksCHROMIUMBadArgs) {
2111 const uint32 kBucketId = GLES2Implementation::kResultBucketId;
2112 const GLuint kProgramId = 123;
2113 GLsizei size = 0;
2114 const Str7 kString = {"foobar"};
2115 char buf[20];
2117 ExpectedMemoryInfo mem1 = GetExpectedMemory(MaxTransferBufferSize());
2118 ExpectedMemoryInfo result1 =
2119 GetExpectedResultMemory(sizeof(cmd::GetBucketStart::Result));
2120 ExpectedMemoryInfo result2 =
2121 GetExpectedResultMemory(sizeof(cmds::GetError::Result));
2122 ExpectedMemoryInfo result3 =
2123 GetExpectedResultMemory(sizeof(cmds::GetError::Result));
2124 ExpectedMemoryInfo result4 =
2125 GetExpectedResultMemory(sizeof(cmds::GetError::Result));
2127 EXPECT_CALL(*command_buffer(), OnFlush())
2128 .WillOnce(DoAll(SetMemory(result1.ptr, uint32(sizeof(kString))),
2129 SetMemory(mem1.ptr, kString)))
2130 .WillOnce(SetMemory(result2.ptr, GLuint(GL_NO_ERROR)))
2131 .WillOnce(SetMemory(result3.ptr, GLuint(GL_NO_ERROR)))
2132 .WillOnce(SetMemory(result4.ptr, GLuint(GL_NO_ERROR)))
2133 .RetiresOnSaturation();
2135 // try bufsize not big enough.
2136 struct Cmds {
2137 cmd::SetBucketSize set_bucket_size1;
2138 cmds::GetUniformBlocksCHROMIUM get_uniform_blocks;
2139 cmd::GetBucketStart get_bucket_start;
2140 cmd::SetToken set_token1;
2141 cmd::SetBucketSize set_bucket_size2;
2143 Cmds expected;
2144 expected.set_bucket_size1.Init(kBucketId, 0);
2145 expected.get_uniform_blocks.Init(kProgramId, kBucketId);
2146 expected.get_bucket_start.Init(
2147 kBucketId, result1.id, result1.offset,
2148 MaxTransferBufferSize(), mem1.id, mem1.offset);
2149 expected.set_token1.Init(GetNextToken());
2150 expected.set_bucket_size2.Init(kBucketId, 0);
2151 gl_->GetUniformBlocksCHROMIUM(kProgramId, 6, &size, &buf);
2152 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
2153 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_OPERATION), gl_->GetError());
2154 ClearCommands();
2156 // try bad bufsize
2157 gl_->GetUniformBlocksCHROMIUM(kProgramId, -1, &size, &buf);
2158 EXPECT_TRUE(NoCommandsWritten());
2159 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE), gl_->GetError());
2160 ClearCommands();
2161 // try no size ptr.
2162 gl_->GetUniformBlocksCHROMIUM(kProgramId, sizeof(buf), NULL, &buf);
2163 EXPECT_TRUE(NoCommandsWritten());
2164 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE), gl_->GetError());
2167 // Test that things are cached
2168 TEST_F(GLES2ImplementationTest, GetIntegerCacheRead) {
2169 struct PNameValue {
2170 GLenum pname;
2171 GLint expected;
2173 const PNameValue pairs[] = {
2174 {GL_ACTIVE_TEXTURE, GL_TEXTURE0, },
2175 {GL_TEXTURE_BINDING_2D, 0, },
2176 {GL_TEXTURE_BINDING_CUBE_MAP, 0, },
2177 {GL_TEXTURE_BINDING_EXTERNAL_OES, 0, },
2178 {GL_FRAMEBUFFER_BINDING, 0, },
2179 {GL_RENDERBUFFER_BINDING, 0, },
2180 {GL_ARRAY_BUFFER_BINDING, 0, },
2181 {GL_ELEMENT_ARRAY_BUFFER_BINDING, 0, },
2182 {GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, kMaxCombinedTextureImageUnits, },
2183 {GL_MAX_CUBE_MAP_TEXTURE_SIZE, kMaxCubeMapTextureSize, },
2184 {GL_MAX_FRAGMENT_UNIFORM_VECTORS, kMaxFragmentUniformVectors, },
2185 {GL_MAX_RENDERBUFFER_SIZE, kMaxRenderbufferSize, },
2186 {GL_MAX_TEXTURE_IMAGE_UNITS, kMaxTextureImageUnits, },
2187 {GL_MAX_TEXTURE_SIZE, kMaxTextureSize, },
2188 {GL_MAX_VARYING_VECTORS, kMaxVaryingVectors, },
2189 {GL_MAX_VERTEX_ATTRIBS, kMaxVertexAttribs, },
2190 {GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, kMaxVertexTextureImageUnits, },
2191 {GL_MAX_VERTEX_UNIFORM_VECTORS, kMaxVertexUniformVectors, },
2192 {GL_NUM_COMPRESSED_TEXTURE_FORMATS, kNumCompressedTextureFormats, },
2193 {GL_NUM_SHADER_BINARY_FORMATS, kNumShaderBinaryFormats, }, };
2194 size_t num_pairs = sizeof(pairs) / sizeof(pairs[0]);
2195 for (size_t ii = 0; ii < num_pairs; ++ii) {
2196 const PNameValue& pv = pairs[ii];
2197 GLint v = -1;
2198 gl_->GetIntegerv(pv.pname, &v);
2199 EXPECT_TRUE(NoCommandsWritten());
2200 EXPECT_EQ(pv.expected, v);
2203 ExpectedMemoryInfo result1 =
2204 GetExpectedResultMemory(sizeof(cmds::GetError::Result));
2206 EXPECT_CALL(*command_buffer(), OnFlush())
2207 .WillOnce(SetMemory(result1.ptr, GLuint(GL_NO_ERROR)))
2208 .RetiresOnSaturation();
2209 EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), gl_->GetError());
2212 TEST_F(GLES2ImplementationTest, GetIntegerCacheWrite) {
2213 struct PNameValue {
2214 GLenum pname;
2215 GLint expected;
2217 gl_->ActiveTexture(GL_TEXTURE4);
2218 gl_->BindBuffer(GL_ARRAY_BUFFER, 2);
2219 gl_->BindBuffer(GL_ELEMENT_ARRAY_BUFFER, 3);
2220 gl_->BindFramebuffer(GL_FRAMEBUFFER, 4);
2221 gl_->BindRenderbuffer(GL_RENDERBUFFER, 5);
2222 gl_->BindTexture(GL_TEXTURE_2D, 6);
2223 gl_->BindTexture(GL_TEXTURE_CUBE_MAP, 7);
2224 gl_->BindTexture(GL_TEXTURE_EXTERNAL_OES, 8);
2226 const PNameValue pairs[] = {{GL_ACTIVE_TEXTURE, GL_TEXTURE4, },
2227 {GL_ARRAY_BUFFER_BINDING, 2, },
2228 {GL_ELEMENT_ARRAY_BUFFER_BINDING, 3, },
2229 {GL_FRAMEBUFFER_BINDING, 4, },
2230 {GL_RENDERBUFFER_BINDING, 5, },
2231 {GL_TEXTURE_BINDING_2D, 6, },
2232 {GL_TEXTURE_BINDING_CUBE_MAP, 7, },
2233 {GL_TEXTURE_BINDING_EXTERNAL_OES, 8, }, };
2234 size_t num_pairs = sizeof(pairs) / sizeof(pairs[0]);
2235 for (size_t ii = 0; ii < num_pairs; ++ii) {
2236 const PNameValue& pv = pairs[ii];
2237 GLint v = -1;
2238 gl_->GetIntegerv(pv.pname, &v);
2239 EXPECT_EQ(pv.expected, v);
2242 ExpectedMemoryInfo result1 =
2243 GetExpectedResultMemory(sizeof(cmds::GetError::Result));
2245 EXPECT_CALL(*command_buffer(), OnFlush())
2246 .WillOnce(SetMemory(result1.ptr, GLuint(GL_NO_ERROR)))
2247 .RetiresOnSaturation();
2248 EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), gl_->GetError());
2251 static bool CheckRect(
2252 int width, int height, GLenum format, GLenum type, int alignment,
2253 const uint8* r1, const uint8* r2) {
2254 uint32 size = 0;
2255 uint32 unpadded_row_size = 0;
2256 uint32 padded_row_size = 0;
2257 if (!GLES2Util::ComputeImageDataSizes(
2258 width, height, 1, format, type, alignment, &size, &unpadded_row_size,
2259 &padded_row_size)) {
2260 return false;
2263 int r2_stride = static_cast<int>(padded_row_size);
2265 for (int y = 0; y < height; ++y) {
2266 if (memcmp(r1, r2, unpadded_row_size) != 0) {
2267 return false;
2269 r1 += padded_row_size;
2270 r2 += r2_stride;
2272 return true;
2275 ACTION_P7(CheckRectAction, width, height, format, type, alignment, r1, r2) {
2276 EXPECT_TRUE(CheckRect(
2277 width, height, format, type, alignment, r1, r2));
2280 TEST_F(GLES2ImplementationTest, TexImage2D) {
2281 struct Cmds {
2282 cmds::TexImage2D tex_image_2d;
2283 cmd::SetToken set_token;
2285 struct Cmds2 {
2286 cmds::TexImage2D tex_image_2d;
2287 cmd::SetToken set_token;
2289 const GLenum kTarget = GL_TEXTURE_2D;
2290 const GLint kLevel = 0;
2291 const GLenum kFormat = GL_RGB;
2292 const GLsizei kWidth = 3;
2293 const GLsizei kHeight = 4;
2294 const GLint kBorder = 0;
2295 const GLenum kType = GL_UNSIGNED_BYTE;
2296 const GLint kPixelStoreUnpackAlignment = 4;
2297 static uint8 pixels[] = {
2298 11, 12, 13, 13, 14, 15, 15, 16, 17, 101, 102, 103,
2299 21, 22, 23, 23, 24, 25, 25, 26, 27, 201, 202, 203,
2300 31, 32, 33, 33, 34, 35, 35, 36, 37, 123, 124, 125,
2301 41, 42, 43, 43, 44, 45, 45, 46, 47,
2304 ExpectedMemoryInfo mem1 = GetExpectedMemory(sizeof(pixels));
2306 Cmds expected;
2307 expected.tex_image_2d.Init(
2308 kTarget, kLevel, kFormat, kWidth, kHeight, kFormat, kType,
2309 mem1.id, mem1.offset);
2310 expected.set_token.Init(GetNextToken());
2311 gl_->TexImage2D(
2312 kTarget, kLevel, kFormat, kWidth, kHeight, kBorder, kFormat, kType,
2313 pixels);
2314 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
2315 EXPECT_TRUE(CheckRect(
2316 kWidth, kHeight, kFormat, kType, kPixelStoreUnpackAlignment,
2317 pixels, mem1.ptr));
2320 TEST_F(GLES2ImplementationTest, TexImage2DViaMappedMem) {
2321 struct Cmds {
2322 cmds::TexImage2D tex_image_2d;
2323 cmd::SetToken set_token;
2325 const GLenum kTarget = GL_TEXTURE_2D;
2326 const GLint kLevel = 0;
2327 const GLenum kFormat = GL_RGB;
2328 const GLsizei kWidth = 3;
2329 const GLint kBorder = 0;
2330 const GLenum kType = GL_UNSIGNED_BYTE;
2331 const GLint kPixelStoreUnpackAlignment = 4;
2333 uint32 size = 0;
2334 uint32 unpadded_row_size = 0;
2335 uint32 padded_row_size = 0;
2336 ASSERT_TRUE(GLES2Util::ComputeImageDataSizes(
2337 kWidth, 2, 1, kFormat, kType, kPixelStoreUnpackAlignment,
2338 &size, &unpadded_row_size, &padded_row_size));
2339 const GLsizei kMaxHeight = (MaxTransferBufferSize() / padded_row_size) * 2;
2340 const GLsizei kHeight = kMaxHeight * 2;
2341 ASSERT_TRUE(GLES2Util::ComputeImageDataSizes(
2342 kWidth, kHeight, 1, kFormat, kType, kPixelStoreUnpackAlignment,
2343 &size, &unpadded_row_size, &padded_row_size));
2345 scoped_ptr<uint8[]> pixels(new uint8[size]);
2346 for (uint32 ii = 0; ii < size; ++ii) {
2347 pixels[ii] = static_cast<uint8>(ii);
2350 ExpectedMemoryInfo mem1 = GetExpectedMappedMemory(size);
2352 Cmds expected;
2353 expected.tex_image_2d.Init(
2354 kTarget, kLevel, kFormat, kWidth, kHeight, kFormat, kType,
2355 mem1.id, mem1.offset);
2356 expected.set_token.Init(GetNextToken());
2357 gl_->TexImage2D(
2358 kTarget, kLevel, kFormat, kWidth, kHeight, kBorder, kFormat, kType,
2359 pixels.get());
2360 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
2361 EXPECT_TRUE(CheckRect(
2362 kWidth, kHeight, kFormat, kType, kPixelStoreUnpackAlignment,
2363 pixels.get(), mem1.ptr));
2366 // Test TexImage2D with 2 writes
2367 TEST_F(GLES2ImplementationTest, TexImage2DViaTexSubImage2D) {
2368 // Set limit to 1 to effectively disable mapped memory.
2369 SetMappedMemoryLimit(1);
2371 struct Cmds {
2372 cmds::TexImage2D tex_image_2d;
2373 cmds::TexSubImage2D tex_sub_image_2d1;
2374 cmd::SetToken set_token1;
2375 cmds::TexSubImage2D tex_sub_image_2d2;
2376 cmd::SetToken set_token2;
2378 const GLenum kTarget = GL_TEXTURE_2D;
2379 const GLint kLevel = 0;
2380 const GLenum kFormat = GL_RGB;
2381 const GLint kBorder = 0;
2382 const GLenum kType = GL_UNSIGNED_BYTE;
2383 const GLint kPixelStoreUnpackAlignment = 4;
2384 const GLsizei kWidth = 3;
2386 uint32 size = 0;
2387 uint32 unpadded_row_size = 0;
2388 uint32 padded_row_size = 0;
2389 ASSERT_TRUE(GLES2Util::ComputeImageDataSizes(
2390 kWidth, 2, 1, kFormat, kType, kPixelStoreUnpackAlignment,
2391 &size, &unpadded_row_size, &padded_row_size));
2392 const GLsizei kHeight = (MaxTransferBufferSize() / padded_row_size) * 2;
2393 ASSERT_TRUE(GLES2Util::ComputeImageDataSizes(
2394 kWidth, kHeight, 1, kFormat, kType, kPixelStoreUnpackAlignment,
2395 &size, NULL, NULL));
2396 uint32 half_size = 0;
2397 ASSERT_TRUE(GLES2Util::ComputeImageDataSizes(
2398 kWidth, kHeight / 2, 1, kFormat, kType, kPixelStoreUnpackAlignment,
2399 &half_size, NULL, NULL));
2401 scoped_ptr<uint8[]> pixels(new uint8[size]);
2402 for (uint32 ii = 0; ii < size; ++ii) {
2403 pixels[ii] = static_cast<uint8>(ii);
2406 ExpectedMemoryInfo mem1 = GetExpectedMemory(half_size);
2407 ExpectedMemoryInfo mem2 = GetExpectedMemory(half_size);
2409 Cmds expected;
2410 expected.tex_image_2d.Init(
2411 kTarget, kLevel, kFormat, kWidth, kHeight, kFormat, kType,
2412 0, 0);
2413 expected.tex_sub_image_2d1.Init(
2414 kTarget, kLevel, 0, 0, kWidth, kHeight / 2, kFormat, kType,
2415 mem1.id, mem1.offset, true);
2416 expected.set_token1.Init(GetNextToken());
2417 expected.tex_sub_image_2d2.Init(
2418 kTarget, kLevel, 0, kHeight / 2, kWidth, kHeight / 2, kFormat, kType,
2419 mem2.id, mem2.offset, true);
2420 expected.set_token2.Init(GetNextToken());
2422 // TODO(gman): Make it possible to run this test
2423 // EXPECT_CALL(*command_buffer(), OnFlush())
2424 // .WillOnce(CheckRectAction(
2425 // kWidth, kHeight / 2, kFormat, kType, kPixelStoreUnpackAlignment,
2426 // false, pixels.get(),
2427 // GetExpectedTransferAddressFromOffsetAs<uint8>(offset1, half_size)))
2428 // .RetiresOnSaturation();
2430 gl_->TexImage2D(
2431 kTarget, kLevel, kFormat, kWidth, kHeight, kBorder, kFormat, kType,
2432 pixels.get());
2433 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
2434 EXPECT_TRUE(CheckRect(
2435 kWidth, kHeight / 2, kFormat, kType, kPixelStoreUnpackAlignment,
2436 pixels.get() + kHeight / 2 * padded_row_size, mem2.ptr));
2439 TEST_F(GLES2ImplementationTest, SubImageUnpack) {
2440 static const GLint unpack_alignments[] = { 1, 2, 4, 8 };
2442 static const GLenum kFormat = GL_RGB;
2443 static const GLenum kType = GL_UNSIGNED_BYTE;
2444 static const GLint kLevel = 0;
2445 static const GLint kBorder = 0;
2446 // We're testing using the unpack params to pull a subimage out of a larger
2447 // source of pixels. Here we specify the subimage by its border rows /
2448 // columns.
2449 static const GLint kSrcWidth = 33;
2450 static const GLint kSrcSubImageX0 = 11;
2451 static const GLint kSrcSubImageX1 = 20;
2452 static const GLint kSrcSubImageY0 = 18;
2453 static const GLint kSrcSubImageY1 = 23;
2454 static const GLint kSrcSubImageWidth = kSrcSubImageX1 - kSrcSubImageX0;
2455 static const GLint kSrcSubImageHeight = kSrcSubImageY1 - kSrcSubImageY0;
2457 // these are only used in the texsubimage tests
2458 static const GLint kTexWidth = 1023;
2459 static const GLint kTexHeight = 511;
2460 static const GLint kTexSubXOffset = 419;
2461 static const GLint kTexSubYOffset = 103;
2463 struct {
2464 cmds::PixelStorei pixel_store_i;
2465 cmds::TexImage2D tex_image_2d;
2466 } texImageExpected;
2468 struct {
2469 cmds::PixelStorei pixel_store_i;
2470 cmds::TexImage2D tex_image_2d;
2471 cmds::TexSubImage2D tex_sub_image_2d;
2472 } texSubImageExpected;
2474 uint32 src_size;
2475 ASSERT_TRUE(GLES2Util::ComputeImageDataSizes(
2476 kSrcWidth, kSrcSubImageY1, 1, kFormat, kType, 8, &src_size, NULL, NULL));
2477 scoped_ptr<uint8[]> src_pixels;
2478 src_pixels.reset(new uint8[src_size]);
2479 for (size_t i = 0; i < src_size; ++i) {
2480 src_pixels[i] = static_cast<int8>(i);
2483 for (int sub = 0; sub < 2; ++sub) {
2484 for (size_t a = 0; a < arraysize(unpack_alignments); ++a) {
2485 GLint alignment = unpack_alignments[a];
2486 uint32 size;
2487 uint32 unpadded_row_size;
2488 uint32 padded_row_size;
2489 ASSERT_TRUE(GLES2Util::ComputeImageDataSizes(
2490 kSrcSubImageWidth, kSrcSubImageHeight, 1, kFormat, kType, alignment,
2491 &size, &unpadded_row_size, &padded_row_size));
2492 ASSERT_TRUE(size <= MaxTransferBufferSize());
2493 ExpectedMemoryInfo mem = GetExpectedMemory(size);
2495 const void* commands = GetPut();
2496 gl_->PixelStorei(GL_UNPACK_ALIGNMENT, alignment);
2497 gl_->PixelStorei(GL_UNPACK_ROW_LENGTH_EXT, kSrcWidth);
2498 gl_->PixelStorei(GL_UNPACK_SKIP_PIXELS_EXT, kSrcSubImageX0);
2499 gl_->PixelStorei(GL_UNPACK_SKIP_ROWS_EXT, kSrcSubImageY0);
2500 if (sub) {
2501 gl_->TexImage2D(
2502 GL_TEXTURE_2D, kLevel, kFormat, kTexWidth, kTexHeight, kBorder,
2503 kFormat, kType, NULL);
2504 gl_->TexSubImage2D(
2505 GL_TEXTURE_2D, kLevel, kTexSubXOffset, kTexSubYOffset,
2506 kSrcSubImageWidth, kSrcSubImageHeight, kFormat, kType,
2507 src_pixels.get());
2508 texSubImageExpected.pixel_store_i.Init(
2509 GL_UNPACK_ALIGNMENT, alignment);
2510 texSubImageExpected.tex_image_2d.Init(
2511 GL_TEXTURE_2D, kLevel, kFormat, kTexWidth, kTexHeight,
2512 kFormat, kType, 0, 0);
2513 texSubImageExpected.tex_sub_image_2d.Init(
2514 GL_TEXTURE_2D, kLevel, kTexSubXOffset, kTexSubYOffset,
2515 kSrcSubImageWidth, kSrcSubImageHeight, kFormat, kType, mem.id,
2516 mem.offset, GL_FALSE);
2517 EXPECT_EQ(0, memcmp(
2518 &texSubImageExpected, commands, sizeof(texSubImageExpected)));
2519 } else {
2520 gl_->TexImage2D(
2521 GL_TEXTURE_2D, kLevel, kFormat,
2522 kSrcSubImageWidth, kSrcSubImageHeight, kBorder, kFormat, kType,
2523 src_pixels.get());
2524 texImageExpected.pixel_store_i.Init(GL_UNPACK_ALIGNMENT, alignment);
2525 texImageExpected.tex_image_2d.Init(
2526 GL_TEXTURE_2D, kLevel, kFormat, kSrcSubImageWidth,
2527 kSrcSubImageHeight, kFormat, kType, mem.id, mem.offset);
2528 EXPECT_EQ(0, memcmp(
2529 &texImageExpected, commands, sizeof(texImageExpected)));
2531 uint32 src_padded_row_size;
2532 ASSERT_TRUE(GLES2Util::ComputeImagePaddedRowSize(
2533 kSrcWidth, kFormat, kType, alignment, &src_padded_row_size));
2534 uint32 bytes_per_group = GLES2Util::ComputeImageGroupSize(
2535 kFormat, kType);
2536 for (int y = 0; y < kSrcSubImageHeight; ++y) {
2537 const uint8* src_row = src_pixels.get() +
2538 (kSrcSubImageY0 + y) * src_padded_row_size +
2539 bytes_per_group * kSrcSubImageX0;
2540 const uint8* dst_row = mem.ptr + y * padded_row_size;
2541 EXPECT_EQ(0, memcmp(src_row, dst_row, unpadded_row_size));
2543 ClearCommands();
2548 // Test texture related calls with invalid arguments.
2549 TEST_F(GLES2ImplementationTest, TextureInvalidArguments) {
2550 struct Cmds {
2551 cmds::TexImage2D tex_image_2d;
2552 cmd::SetToken set_token;
2554 const GLenum kTarget = GL_TEXTURE_2D;
2555 const GLint kLevel = 0;
2556 const GLenum kFormat = GL_RGB;
2557 const GLsizei kWidth = 3;
2558 const GLsizei kHeight = 4;
2559 const GLint kBorder = 0;
2560 const GLint kInvalidBorder = 1;
2561 const GLenum kType = GL_UNSIGNED_BYTE;
2562 const GLint kPixelStoreUnpackAlignment = 4;
2563 static uint8 pixels[] = {
2564 11, 12, 13, 13, 14, 15, 15, 16, 17, 101, 102, 103,
2565 21, 22, 23, 23, 24, 25, 25, 26, 27, 201, 202, 203,
2566 31, 32, 33, 33, 34, 35, 35, 36, 37, 123, 124, 125,
2567 41, 42, 43, 43, 44, 45, 45, 46, 47,
2570 // Verify that something works.
2572 ExpectedMemoryInfo mem1 = GetExpectedMemory(sizeof(pixels));
2574 Cmds expected;
2575 expected.tex_image_2d.Init(
2576 kTarget, kLevel, kFormat, kWidth, kHeight, kFormat, kType,
2577 mem1.id, mem1.offset);
2578 expected.set_token.Init(GetNextToken());
2579 gl_->TexImage2D(
2580 kTarget, kLevel, kFormat, kWidth, kHeight, kBorder, kFormat, kType,
2581 pixels);
2582 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
2583 EXPECT_TRUE(CheckRect(
2584 kWidth, kHeight, kFormat, kType, kPixelStoreUnpackAlignment,
2585 pixels, mem1.ptr));
2587 ClearCommands();
2589 // Use invalid border.
2590 gl_->TexImage2D(
2591 kTarget, kLevel, kFormat, kWidth, kHeight, kInvalidBorder, kFormat, kType,
2592 pixels);
2594 EXPECT_TRUE(NoCommandsWritten());
2595 EXPECT_EQ(GL_INVALID_VALUE, CheckError());
2597 ClearCommands();
2599 gl_->AsyncTexImage2DCHROMIUM(
2600 kTarget, kLevel, kFormat, kWidth, kHeight, kInvalidBorder, kFormat, kType,
2601 NULL);
2603 EXPECT_TRUE(NoCommandsWritten());
2604 EXPECT_EQ(GL_INVALID_VALUE, CheckError());
2606 ClearCommands();
2608 // Checking for CompressedTexImage2D argument validation is a bit tricky due
2609 // to (runtime-detected) compression formats. Try to infer the error with an
2610 // aux check.
2611 const GLenum kCompressedFormat = GL_ETC1_RGB8_OES;
2612 gl_->CompressedTexImage2D(
2613 kTarget, kLevel, kCompressedFormat, kWidth, kHeight, kBorder,
2614 arraysize(pixels), pixels);
2616 // In the above, kCompressedFormat and arraysize(pixels) are possibly wrong
2617 // values. First ensure that these do not cause failures at the client. If
2618 // this check ever fails, it probably means that client checks more than at
2619 // the time of writing of this test. In this case, more code needs to be
2620 // written for this test.
2621 EXPECT_FALSE(NoCommandsWritten());
2623 ClearCommands();
2625 // Changing border to invalid border should make the call fail at the client
2626 // checks.
2627 gl_->CompressedTexImage2D(
2628 kTarget, kLevel, kCompressedFormat, kWidth, kHeight, kInvalidBorder,
2629 arraysize(pixels), pixels);
2630 EXPECT_TRUE(NoCommandsWritten());
2631 EXPECT_EQ(GL_INVALID_VALUE, CheckError());
2634 TEST_F(GLES2ImplementationTest, TexImage3DSingleCommand) {
2635 struct Cmds {
2636 cmds::TexImage3D tex_image_3d;
2638 const GLenum kTarget = GL_TEXTURE_3D;
2639 const GLint kLevel = 0;
2640 const GLint kBorder = 0;
2641 const GLenum kFormat = GL_RGB;
2642 const GLenum kType = GL_UNSIGNED_BYTE;
2643 const GLint kPixelStoreUnpackAlignment = 4;
2644 const GLsizei kWidth = 3;
2645 const GLsizei kDepth = 2;
2647 uint32 size = 0;
2648 uint32 unpadded_row_size = 0;
2649 uint32 padded_row_size = 0;
2650 ASSERT_TRUE(GLES2Util::ComputeImageDataSizes(
2651 kWidth, 2, kDepth, kFormat, kType, kPixelStoreUnpackAlignment,
2652 &size, &unpadded_row_size, &padded_row_size));
2653 // Makes sure we can just send over the data in one command.
2654 const GLsizei kHeight = MaxTransferBufferSize() / padded_row_size / kDepth;
2655 ASSERT_TRUE(GLES2Util::ComputeImageDataSizes(
2656 kWidth, kHeight, kDepth, kFormat, kType, kPixelStoreUnpackAlignment,
2657 &size, NULL, NULL));
2659 scoped_ptr<uint8[]> pixels(new uint8[size]);
2660 for (uint32 ii = 0; ii < size; ++ii) {
2661 pixels[ii] = static_cast<uint8>(ii);
2664 ExpectedMemoryInfo mem = GetExpectedMemory(size);
2666 Cmds expected;
2667 expected.tex_image_3d.Init(
2668 kTarget, kLevel, kFormat, kWidth, kHeight, kDepth,
2669 kFormat, kType, mem.id, mem.offset);
2671 gl_->TexImage3D(
2672 kTarget, kLevel, kFormat, kWidth, kHeight, kDepth, kBorder,
2673 kFormat, kType, pixels.get());
2675 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
2676 EXPECT_TRUE(CheckRect(
2677 kWidth, kHeight * kDepth, kFormat, kType, kPixelStoreUnpackAlignment,
2678 reinterpret_cast<uint8*>(pixels.get()), mem.ptr));
2681 TEST_F(GLES2ImplementationTest, TexImage3DViaMappedMem) {
2682 struct Cmds {
2683 cmds::TexImage3D tex_image_3d;
2685 const GLenum kTarget = GL_TEXTURE_3D;
2686 const GLint kLevel = 0;
2687 const GLint kBorder = 0;
2688 const GLenum kFormat = GL_RGB;
2689 const GLenum kType = GL_UNSIGNED_BYTE;
2690 const GLint kPixelStoreUnpackAlignment = 4;
2691 const GLsizei kWidth = 3;
2692 const GLsizei kDepth = 2;
2694 uint32 size = 0;
2695 uint32 unpadded_row_size = 0;
2696 uint32 padded_row_size = 0;
2697 ASSERT_TRUE(GLES2Util::ComputeImageDataSizes(
2698 kWidth, 2, kDepth, kFormat, kType, kPixelStoreUnpackAlignment,
2699 &size, &unpadded_row_size, &padded_row_size));
2700 // Makes sure we can just send over the data in one command.
2701 const GLsizei kMaxHeight = MaxTransferBufferSize() / padded_row_size / kDepth;
2702 const GLsizei kHeight = kMaxHeight * 2;
2703 ASSERT_TRUE(GLES2Util::ComputeImageDataSizes(
2704 kWidth, kHeight, kDepth, kFormat, kType, kPixelStoreUnpackAlignment,
2705 &size, NULL, NULL));
2707 scoped_ptr<uint8[]> pixels(new uint8[size]);
2708 for (uint32 ii = 0; ii < size; ++ii) {
2709 pixels[ii] = static_cast<uint8>(ii);
2712 ExpectedMemoryInfo mem = GetExpectedMappedMemory(size);
2714 Cmds expected;
2715 expected.tex_image_3d.Init(
2716 kTarget, kLevel, kFormat, kWidth, kHeight, kDepth,
2717 kFormat, kType, mem.id, mem.offset);
2719 gl_->TexImage3D(
2720 kTarget, kLevel, kFormat, kWidth, kHeight, kDepth, kBorder,
2721 kFormat, kType, pixels.get());
2723 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
2724 EXPECT_TRUE(CheckRect(
2725 kWidth, kHeight * kDepth, kFormat, kType, kPixelStoreUnpackAlignment,
2726 reinterpret_cast<uint8*>(pixels.get()), mem.ptr));
2729 TEST_F(GLES2ImplementationTest, TexImage3DViaTexSubImage3D) {
2730 // Set limit to 1 to effectively disable mapped memory.
2731 SetMappedMemoryLimit(1);
2733 struct Cmds {
2734 cmds::TexImage3D tex_image_3d;
2735 cmds::TexSubImage3D tex_sub_image_3d1;
2736 cmd::SetToken set_token;
2737 cmds::TexSubImage3D tex_sub_image_3d2;
2739 const GLenum kTarget = GL_TEXTURE_3D;
2740 const GLint kLevel = 0;
2741 const GLint kBorder = 0;
2742 const GLenum kFormat = GL_RGB;
2743 const GLenum kType = GL_UNSIGNED_BYTE;
2744 const GLint kPixelStoreUnpackAlignment = 4;
2745 const GLsizei kWidth = 3;
2747 uint32 size = 0;
2748 uint32 unpadded_row_size = 0;
2749 uint32 padded_row_size = 0;
2750 ASSERT_TRUE(GLES2Util::ComputeImageDataSizes(
2751 kWidth, 2, 1, kFormat, kType, kPixelStoreUnpackAlignment,
2752 &size, &unpadded_row_size, &padded_row_size));
2753 // Makes sure the data is more than one command can hold.
2754 const GLsizei kHeight = MaxTransferBufferSize() / padded_row_size + 3;
2755 ASSERT_TRUE(GLES2Util::ComputeImageDataSizes(
2756 kWidth, kHeight, 1, kFormat, kType, kPixelStoreUnpackAlignment,
2757 &size, NULL, NULL));
2758 uint32 first_size = padded_row_size * (kHeight - 3);
2759 uint32 second_size =
2760 padded_row_size * 3 - (padded_row_size - unpadded_row_size);
2761 EXPECT_EQ(size, first_size + second_size);
2762 ExpectedMemoryInfo mem1 = GetExpectedMemory(first_size);
2763 ExpectedMemoryInfo mem2 = GetExpectedMemory(second_size);
2764 scoped_ptr<uint8[]> pixels(new uint8[size]);
2765 for (uint32 ii = 0; ii < size; ++ii) {
2766 pixels[ii] = static_cast<uint8>(ii);
2769 Cmds expected;
2770 expected.tex_image_3d.Init(
2771 kTarget, kLevel, kFormat, kWidth, kHeight, 1, kFormat, kType, 0, 0);
2772 expected.tex_sub_image_3d1.Init(
2773 kTarget, kLevel, 0, 0, 0, kWidth, kHeight - 3, 1, kFormat, kType,
2774 mem1.id, mem1.offset, GL_TRUE);
2775 expected.tex_sub_image_3d2.Init(
2776 kTarget, kLevel, 0, kHeight - 3, 0, kWidth, 3, 1, kFormat, kType,
2777 mem2.id, mem2.offset, GL_TRUE);
2778 expected.set_token.Init(GetNextToken());
2780 gl_->TexImage3D(
2781 kTarget, kLevel, kFormat, kWidth, kHeight, 1, kBorder,
2782 kFormat, kType, pixels.get());
2783 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
2786 // Test TexSubImage3D with 4 writes
2787 TEST_F(GLES2ImplementationTest, TexSubImage3D4Writes) {
2788 struct Cmds {
2789 cmds::TexSubImage3D tex_sub_image_3d1_1;
2790 cmd::SetToken set_token1;
2791 cmds::TexSubImage3D tex_sub_image_3d1_2;
2792 cmd::SetToken set_token2;
2793 cmds::TexSubImage3D tex_sub_image_3d2_1;
2794 cmd::SetToken set_token3;
2795 cmds::TexSubImage3D tex_sub_image_3d2_2;
2797 const GLenum kTarget = GL_TEXTURE_3D;
2798 const GLint kLevel = 0;
2799 const GLint kXOffset = 0;
2800 const GLint kYOffset = 0;
2801 const GLint kZOffset = 0;
2802 const GLenum kFormat = GL_RGB;
2803 const GLenum kType = GL_UNSIGNED_BYTE;
2804 const GLint kPixelStoreUnpackAlignment = 4;
2805 const GLsizei kWidth = 3;
2806 const GLsizei kDepth = 2;
2808 uint32 size = 0;
2809 uint32 unpadded_row_size = 0;
2810 uint32 padded_row_size = 0;
2811 ASSERT_TRUE(GLES2Util::ComputeImageDataSizes(
2812 kWidth, 2, 1, kFormat, kType, kPixelStoreUnpackAlignment,
2813 &size, &unpadded_row_size, &padded_row_size));
2814 const GLsizei kHeight = MaxTransferBufferSize() / padded_row_size + 2;
2815 ASSERT_TRUE(GLES2Util::ComputeImageDataSizes(
2816 kWidth, kHeight, kDepth, kFormat, kType, kPixelStoreUnpackAlignment,
2817 &size, NULL, NULL));
2818 uint32 first_size = (kHeight - 2) * padded_row_size;
2819 uint32 second_size = 2 * padded_row_size;
2820 uint32 third_size = first_size;
2821 uint32 fourth_size = second_size - (padded_row_size - unpadded_row_size);
2822 EXPECT_EQ(size, first_size + second_size + third_size + fourth_size);
2824 scoped_ptr<uint8[]> pixels(new uint8[size]);
2825 for (uint32 ii = 0; ii < size; ++ii) {
2826 pixels[ii] = static_cast<uint8>(ii);
2829 ExpectedMemoryInfo mem1_1 = GetExpectedMemory(first_size);
2830 ExpectedMemoryInfo mem1_2 = GetExpectedMemory(second_size);
2831 ExpectedMemoryInfo mem2_1 = GetExpectedMemory(third_size);
2832 ExpectedMemoryInfo mem2_2 = GetExpectedMemory(fourth_size);
2834 Cmds expected;
2835 expected.tex_sub_image_3d1_1.Init(
2836 kTarget, kLevel, kXOffset, kYOffset, kZOffset,
2837 kWidth, kHeight - 2, 1, kFormat, kType,
2838 mem1_1.id, mem1_1.offset, GL_FALSE);
2839 expected.tex_sub_image_3d1_2.Init(
2840 kTarget, kLevel, kXOffset, kYOffset + kHeight - 2, kZOffset,
2841 kWidth, 2, 1, kFormat, kType, mem1_2.id, mem1_2.offset, GL_FALSE);
2842 expected.tex_sub_image_3d2_1.Init(
2843 kTarget, kLevel, kXOffset, kYOffset, kZOffset + 1,
2844 kWidth, kHeight - 2, 1, kFormat, kType,
2845 mem2_1.id, mem2_1.offset, GL_FALSE);
2846 expected.tex_sub_image_3d2_2.Init(
2847 kTarget, kLevel, kXOffset, kYOffset + kHeight - 2, kZOffset + 1,
2848 kWidth, 2, 1, kFormat, kType, mem2_2.id, mem2_2.offset, GL_FALSE);
2849 expected.set_token1.Init(GetNextToken());
2850 expected.set_token2.Init(GetNextToken());
2851 expected.set_token3.Init(GetNextToken());
2853 gl_->TexSubImage3D(
2854 kTarget, kLevel, kXOffset, kYOffset, kZOffset, kWidth, kHeight, kDepth,
2855 kFormat, kType, pixels.get());
2857 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
2858 uint32 offset_to_last = first_size + second_size + third_size;
2859 EXPECT_TRUE(CheckRect(
2860 kWidth, 2, kFormat, kType, kPixelStoreUnpackAlignment,
2861 reinterpret_cast<uint8*>(pixels.get()) + offset_to_last, mem2_2.ptr));
2864 // glGen* Ids must not be reused until glDelete* commands have been
2865 // flushed by glFlush.
2866 TEST_F(GLES2ImplementationStrictSharedTest, FlushGenerationTestBuffers) {
2867 FlushGenerationTest<GenBuffersAPI>();
2869 TEST_F(GLES2ImplementationStrictSharedTest, FlushGenerationTestFramebuffers) {
2870 FlushGenerationTest<GenFramebuffersAPI>();
2872 TEST_F(GLES2ImplementationStrictSharedTest, FlushGenerationTestRenderbuffers) {
2873 FlushGenerationTest<GenRenderbuffersAPI>();
2875 TEST_F(GLES2ImplementationStrictSharedTest, FlushGenerationTestTextures) {
2876 FlushGenerationTest<GenTexturesAPI>();
2879 // glGen* Ids must not be reused cross-context until glDelete* commands are
2880 // flushed by glFlush, and the Ids are lazily freed after.
2881 TEST_F(GLES2ImplementationStrictSharedTest, CrossContextGenerationTestBuffers) {
2882 CrossContextGenerationTest<GenBuffersAPI>();
2884 TEST_F(GLES2ImplementationStrictSharedTest,
2885 CrossContextGenerationTestFramebuffers) {
2886 CrossContextGenerationTest<GenFramebuffersAPI>();
2888 TEST_F(GLES2ImplementationStrictSharedTest,
2889 CrossContextGenerationTestRenderbuffers) {
2890 CrossContextGenerationTest<GenRenderbuffersAPI>();
2892 TEST_F(GLES2ImplementationStrictSharedTest,
2893 CrossContextGenerationTestTextures) {
2894 CrossContextGenerationTest<GenTexturesAPI>();
2897 // Test Delete which causes auto flush. Tests a regression case that occurred
2898 // in testing.
2899 TEST_F(GLES2ImplementationStrictSharedTest,
2900 CrossContextGenerationAutoFlushTestBuffers) {
2901 CrossContextGenerationAutoFlushTest<GenBuffersAPI>();
2903 TEST_F(GLES2ImplementationStrictSharedTest,
2904 CrossContextGenerationAutoFlushTestFramebuffers) {
2905 CrossContextGenerationAutoFlushTest<GenFramebuffersAPI>();
2907 TEST_F(GLES2ImplementationStrictSharedTest,
2908 CrossContextGenerationAutoFlushTestRenderbuffers) {
2909 CrossContextGenerationAutoFlushTest<GenRenderbuffersAPI>();
2911 TEST_F(GLES2ImplementationStrictSharedTest,
2912 CrossContextGenerationAutoFlushTestTextures) {
2913 CrossContextGenerationAutoFlushTest<GenTexturesAPI>();
2916 TEST_F(GLES2ImplementationTest, GetString) {
2917 const uint32 kBucketId = GLES2Implementation::kResultBucketId;
2918 const Str7 kString = {"foobar"};
2919 // GL_CHROMIUM_map_sub is hard coded into GLES2Implementation.
2920 const char* expected_str =
2921 "foobar "
2922 "GL_EXT_unpack_subimage "
2923 "GL_CHROMIUM_map_sub";
2924 const char kBad = 0x12;
2925 struct Cmds {
2926 cmd::SetBucketSize set_bucket_size1;
2927 cmds::GetString get_string;
2928 cmd::GetBucketStart get_bucket_start;
2929 cmd::SetToken set_token1;
2930 cmd::SetBucketSize set_bucket_size2;
2932 ExpectedMemoryInfo mem1 = GetExpectedMemory(MaxTransferBufferSize());
2933 ExpectedMemoryInfo result1 =
2934 GetExpectedResultMemory(sizeof(cmd::GetBucketStart::Result));
2935 Cmds expected;
2936 expected.set_bucket_size1.Init(kBucketId, 0);
2937 expected.get_string.Init(GL_EXTENSIONS, kBucketId);
2938 expected.get_bucket_start.Init(
2939 kBucketId, result1.id, result1.offset,
2940 MaxTransferBufferSize(), mem1.id, mem1.offset);
2941 expected.set_token1.Init(GetNextToken());
2942 expected.set_bucket_size2.Init(kBucketId, 0);
2943 char buf[sizeof(kString) + 1];
2944 memset(buf, kBad, sizeof(buf));
2946 EXPECT_CALL(*command_buffer(), OnFlush())
2947 .WillOnce(DoAll(SetMemory(result1.ptr, uint32(sizeof(kString))),
2948 SetMemory(mem1.ptr, kString)))
2949 .RetiresOnSaturation();
2951 const GLubyte* result = gl_->GetString(GL_EXTENSIONS);
2952 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
2953 EXPECT_STREQ(expected_str, reinterpret_cast<const char*>(result));
2956 TEST_F(GLES2ImplementationTest, PixelStoreiGLPackReverseRowOrderANGLE) {
2957 const uint32 kBucketId = GLES2Implementation::kResultBucketId;
2958 const Str7 kString = {"foobar"};
2959 struct Cmds {
2960 cmd::SetBucketSize set_bucket_size1;
2961 cmds::GetString get_string;
2962 cmd::GetBucketStart get_bucket_start;
2963 cmd::SetToken set_token1;
2964 cmd::SetBucketSize set_bucket_size2;
2965 cmds::PixelStorei pixel_store;
2968 ExpectedMemoryInfo mem1 = GetExpectedMemory(MaxTransferBufferSize());
2969 ExpectedMemoryInfo result1 =
2970 GetExpectedResultMemory(sizeof(cmd::GetBucketStart::Result));
2972 Cmds expected;
2973 expected.set_bucket_size1.Init(kBucketId, 0);
2974 expected.get_string.Init(GL_EXTENSIONS, kBucketId);
2975 expected.get_bucket_start.Init(
2976 kBucketId, result1.id, result1.offset,
2977 MaxTransferBufferSize(), mem1.id, mem1.offset);
2978 expected.set_token1.Init(GetNextToken());
2979 expected.set_bucket_size2.Init(kBucketId, 0);
2980 expected.pixel_store.Init(GL_PACK_REVERSE_ROW_ORDER_ANGLE, 1);
2982 EXPECT_CALL(*command_buffer(), OnFlush())
2983 .WillOnce(DoAll(SetMemory(result1.ptr, uint32(sizeof(kString))),
2984 SetMemory(mem1.ptr, kString)))
2985 .RetiresOnSaturation();
2987 gl_->PixelStorei(GL_PACK_REVERSE_ROW_ORDER_ANGLE, 1);
2988 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
2991 TEST_F(GLES2ImplementationTest, CreateProgram) {
2992 struct Cmds {
2993 cmds::CreateProgram cmd;
2996 Cmds expected;
2997 expected.cmd.Init(kProgramsAndShadersStartId);
2998 GLuint id = gl_->CreateProgram();
2999 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
3000 EXPECT_EQ(kProgramsAndShadersStartId, id);
3003 TEST_F(GLES2ImplementationTest, BufferDataLargerThanTransferBuffer) {
3004 struct Cmds {
3005 cmds::BufferData set_size;
3006 cmds::BufferSubData copy_data1;
3007 cmd::SetToken set_token1;
3008 cmds::BufferSubData copy_data2;
3009 cmd::SetToken set_token2;
3011 const unsigned kUsableSize =
3012 kTransferBufferSize - GLES2Implementation::kStartingOffset;
3013 uint8 buf[kUsableSize * 2] = { 0, };
3015 ExpectedMemoryInfo mem1 = GetExpectedMemory(kUsableSize);
3016 ExpectedMemoryInfo mem2 = GetExpectedMemory(kUsableSize);
3018 Cmds expected;
3019 expected.set_size.Init(
3020 GL_ARRAY_BUFFER, arraysize(buf), 0, 0, GL_DYNAMIC_DRAW);
3021 expected.copy_data1.Init(
3022 GL_ARRAY_BUFFER, 0, kUsableSize, mem1.id, mem1.offset);
3023 expected.set_token1.Init(GetNextToken());
3024 expected.copy_data2.Init(
3025 GL_ARRAY_BUFFER, kUsableSize, kUsableSize, mem2.id, mem2.offset);
3026 expected.set_token2.Init(GetNextToken());
3027 gl_->BufferData(GL_ARRAY_BUFFER, arraysize(buf), buf, GL_DYNAMIC_DRAW);
3028 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
3031 TEST_F(GLES2ImplementationTest, CapabilitiesAreCached) {
3032 static const GLenum kStates[] = {
3033 GL_DITHER,
3034 GL_BLEND,
3035 GL_CULL_FACE,
3036 GL_DEPTH_TEST,
3037 GL_POLYGON_OFFSET_FILL,
3038 GL_SAMPLE_ALPHA_TO_COVERAGE,
3039 GL_SAMPLE_COVERAGE,
3040 GL_SCISSOR_TEST,
3041 GL_STENCIL_TEST,
3043 struct Cmds {
3044 cmds::Enable enable_cmd;
3046 Cmds expected;
3048 for (size_t ii = 0; ii < arraysize(kStates); ++ii) {
3049 GLenum state = kStates[ii];
3050 expected.enable_cmd.Init(state);
3051 GLboolean result = gl_->IsEnabled(state);
3052 EXPECT_EQ(static_cast<GLboolean>(ii == 0), result);
3053 EXPECT_TRUE(NoCommandsWritten());
3054 const void* commands = GetPut();
3055 if (!result) {
3056 gl_->Enable(state);
3057 EXPECT_EQ(0, memcmp(&expected, commands, sizeof(expected)));
3059 ClearCommands();
3060 result = gl_->IsEnabled(state);
3061 EXPECT_TRUE(result);
3062 EXPECT_TRUE(NoCommandsWritten());
3066 TEST_F(GLES2ImplementationTest, BindVertexArrayOES) {
3067 GLuint id = 0;
3068 gl_->GenVertexArraysOES(1, &id);
3069 ClearCommands();
3071 struct Cmds {
3072 cmds::BindVertexArrayOES cmd;
3074 Cmds expected;
3075 expected.cmd.Init(id);
3077 const void* commands = GetPut();
3078 gl_->BindVertexArrayOES(id);
3079 EXPECT_EQ(0, memcmp(&expected, commands, sizeof(expected)));
3080 ClearCommands();
3081 gl_->BindVertexArrayOES(id);
3082 EXPECT_TRUE(NoCommandsWritten());
3085 TEST_F(GLES2ImplementationTest, BeginEndQueryEXT) {
3086 // Test GetQueryivEXT returns 0 if no current query.
3087 GLint param = -1;
3088 gl_->GetQueryivEXT(GL_ANY_SAMPLES_PASSED_EXT, GL_CURRENT_QUERY_EXT, &param);
3089 EXPECT_EQ(0, param);
3091 GLuint expected_ids[2] = { 1, 2 }; // These must match what's actually genned.
3092 struct GenCmds {
3093 cmds::GenQueriesEXTImmediate gen;
3094 GLuint data[2];
3096 GenCmds expected_gen_cmds;
3097 expected_gen_cmds.gen.Init(arraysize(expected_ids), &expected_ids[0]);
3098 GLuint ids[arraysize(expected_ids)] = { 0, };
3099 gl_->GenQueriesEXT(arraysize(expected_ids), &ids[0]);
3100 EXPECT_EQ(0, memcmp(
3101 &expected_gen_cmds, commands_, sizeof(expected_gen_cmds)));
3102 GLuint id1 = ids[0];
3103 GLuint id2 = ids[1];
3104 ClearCommands();
3106 // Test BeginQueryEXT fails if id = 0.
3107 gl_->BeginQueryEXT(GL_ANY_SAMPLES_PASSED_EXT, 0);
3108 EXPECT_TRUE(NoCommandsWritten());
3109 EXPECT_EQ(GL_INVALID_OPERATION, CheckError());
3111 // Test BeginQueryEXT inserts command.
3112 struct BeginCmds {
3113 cmds::BeginQueryEXT begin_query;
3115 BeginCmds expected_begin_cmds;
3116 const void* commands = GetPut();
3117 gl_->BeginQueryEXT(GL_ANY_SAMPLES_PASSED_EXT, id1);
3118 QueryTracker::Query* query = GetQuery(id1);
3119 ASSERT_TRUE(query != NULL);
3120 expected_begin_cmds.begin_query.Init(
3121 GL_ANY_SAMPLES_PASSED_EXT, id1, query->shm_id(), query->shm_offset());
3122 EXPECT_EQ(0, memcmp(
3123 &expected_begin_cmds, commands, sizeof(expected_begin_cmds)));
3124 ClearCommands();
3126 // Test GetQueryivEXT returns id.
3127 param = -1;
3128 gl_->GetQueryivEXT(GL_ANY_SAMPLES_PASSED_EXT, GL_CURRENT_QUERY_EXT, &param);
3129 EXPECT_EQ(id1, static_cast<GLuint>(param));
3130 gl_->GetQueryivEXT(
3131 GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT, GL_CURRENT_QUERY_EXT, &param);
3132 EXPECT_EQ(0, param);
3134 // Test BeginQueryEXT fails if between Begin/End.
3135 gl_->BeginQueryEXT(GL_ANY_SAMPLES_PASSED_EXT, id2);
3136 EXPECT_TRUE(NoCommandsWritten());
3137 EXPECT_EQ(GL_INVALID_OPERATION, CheckError());
3139 // Test EndQueryEXT fails if target not same as current query.
3140 ClearCommands();
3141 gl_->EndQueryEXT(GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT);
3142 EXPECT_TRUE(NoCommandsWritten());
3143 EXPECT_EQ(GL_INVALID_OPERATION, CheckError());
3145 // Test EndQueryEXT sends command
3146 struct EndCmds {
3147 cmds::EndQueryEXT end_query;
3149 EndCmds expected_end_cmds;
3150 expected_end_cmds.end_query.Init(
3151 GL_ANY_SAMPLES_PASSED_EXT, query->submit_count());
3152 commands = GetPut();
3153 gl_->EndQueryEXT(GL_ANY_SAMPLES_PASSED_EXT);
3154 EXPECT_EQ(0, memcmp(
3155 &expected_end_cmds, commands, sizeof(expected_end_cmds)));
3157 // Test EndQueryEXT fails if no current query.
3158 ClearCommands();
3159 gl_->EndQueryEXT(GL_ANY_SAMPLES_PASSED_EXT);
3160 EXPECT_TRUE(NoCommandsWritten());
3161 EXPECT_EQ(GL_INVALID_OPERATION, CheckError());
3163 // Test 2nd Begin/End increments count.
3164 base::subtle::Atomic32 old_submit_count = query->submit_count();
3165 gl_->BeginQueryEXT(GL_ANY_SAMPLES_PASSED_EXT, id1);
3166 EXPECT_NE(old_submit_count, query->submit_count());
3167 expected_end_cmds.end_query.Init(
3168 GL_ANY_SAMPLES_PASSED_EXT, query->submit_count());
3169 commands = GetPut();
3170 gl_->EndQueryEXT(GL_ANY_SAMPLES_PASSED_EXT);
3171 EXPECT_EQ(0, memcmp(
3172 &expected_end_cmds, commands, sizeof(expected_end_cmds)));
3174 // Test BeginQueryEXT fails if target changed.
3175 ClearCommands();
3176 gl_->BeginQueryEXT(GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT, id1);
3177 EXPECT_TRUE(NoCommandsWritten());
3178 EXPECT_EQ(GL_INVALID_OPERATION, CheckError());
3180 // Test GetQueryObjectuivEXT fails if unused id
3181 GLuint available = 0xBDu;
3182 ClearCommands();
3183 gl_->GetQueryObjectuivEXT(id2, GL_QUERY_RESULT_AVAILABLE_EXT, &available);
3184 EXPECT_TRUE(NoCommandsWritten());
3185 EXPECT_EQ(0xBDu, available);
3186 EXPECT_EQ(GL_INVALID_OPERATION, CheckError());
3188 // Test GetQueryObjectuivEXT fails if bad id
3189 ClearCommands();
3190 gl_->GetQueryObjectuivEXT(4567, GL_QUERY_RESULT_AVAILABLE_EXT, &available);
3191 EXPECT_TRUE(NoCommandsWritten());
3192 EXPECT_EQ(0xBDu, available);
3193 EXPECT_EQ(GL_INVALID_OPERATION, CheckError());
3195 // Test GetQueryObjectuivEXT CheckResultsAvailable
3196 ClearCommands();
3197 gl_->GetQueryObjectuivEXT(id1, GL_QUERY_RESULT_AVAILABLE_EXT, &available);
3198 EXPECT_EQ(0u, available);
3200 // Test GetQueryObjectui64vEXT fails if unused id
3201 GLuint64 available2 = 0xBDu;
3202 ClearCommands();
3203 gl_->GetQueryObjectui64vEXT(id2, GL_QUERY_RESULT_AVAILABLE_EXT, &available2);
3204 EXPECT_TRUE(NoCommandsWritten());
3205 EXPECT_EQ(0xBDu, available2);
3206 EXPECT_EQ(GL_INVALID_OPERATION, CheckError());
3208 // Test GetQueryObjectui64vEXT fails if bad id
3209 ClearCommands();
3210 gl_->GetQueryObjectui64vEXT(4567, GL_QUERY_RESULT_AVAILABLE_EXT, &available2);
3211 EXPECT_TRUE(NoCommandsWritten());
3212 EXPECT_EQ(0xBDu, available2);
3213 EXPECT_EQ(GL_INVALID_OPERATION, CheckError());
3215 // Test GetQueryObjectui64vEXT CheckResultsAvailable
3216 ClearCommands();
3217 gl_->GetQueryObjectui64vEXT(id1, GL_QUERY_RESULT_AVAILABLE_EXT, &available2);
3218 EXPECT_EQ(0u, available2);
3221 TEST_F(GLES2ImplementationManualInitTest, BadQueryTargets) {
3222 ContextInitOptions init_options;
3223 init_options.sync_query = false;
3224 init_options.occlusion_query_boolean = false;
3225 init_options.timer_queries = false;
3226 ASSERT_TRUE(Initialize(init_options));
3228 GLuint id = 0;
3229 gl_->GenQueriesEXT(1, &id);
3230 ClearCommands();
3232 gl_->BeginQueryEXT(GL_COMMANDS_COMPLETED_CHROMIUM, id);
3233 EXPECT_EQ(GL_INVALID_OPERATION, CheckError());
3234 EXPECT_EQ(nullptr, GetQuery(id));
3236 gl_->BeginQueryEXT(GL_ANY_SAMPLES_PASSED, id);
3237 EXPECT_EQ(GL_INVALID_OPERATION, CheckError());
3238 EXPECT_EQ(nullptr, GetQuery(id));
3240 gl_->BeginQueryEXT(GL_ANY_SAMPLES_PASSED_CONSERVATIVE, id);
3241 EXPECT_EQ(GL_INVALID_OPERATION, CheckError());
3242 EXPECT_EQ(nullptr, GetQuery(id));
3244 gl_->BeginQueryEXT(GL_TIME_ELAPSED_EXT, id);
3245 EXPECT_EQ(GL_INVALID_OPERATION, CheckError());
3246 EXPECT_EQ(nullptr, GetQuery(id));
3248 gl_->BeginQueryEXT(0x123, id);
3249 EXPECT_EQ(GL_INVALID_ENUM, CheckError());
3250 EXPECT_EQ(nullptr, GetQuery(id));
3252 gl_->QueryCounterEXT(id, GL_TIMESTAMP_EXT);
3253 EXPECT_EQ(GL_INVALID_OPERATION, CheckError());
3254 EXPECT_EQ(nullptr, GetQuery(id));
3256 gl_->QueryCounterEXT(id, 0x123);
3257 EXPECT_EQ(GL_INVALID_ENUM, CheckError());
3258 EXPECT_EQ(nullptr, GetQuery(id));
3261 TEST_F(GLES2ImplementationTest, QueryCounterEXT) {
3262 GLuint expected_ids[2] = { 1, 2 }; // These must match what's actually genned.
3263 struct GenCmds {
3264 cmds::GenQueriesEXTImmediate gen;
3265 GLuint data[2];
3267 GenCmds expected_gen_cmds;
3268 expected_gen_cmds.gen.Init(arraysize(expected_ids), &expected_ids[0]);
3269 GLuint ids[arraysize(expected_ids)] = { 0, };
3270 gl_->GenQueriesEXT(arraysize(expected_ids), &ids[0]);
3271 EXPECT_EQ(0, memcmp(
3272 &expected_gen_cmds, commands_, sizeof(expected_gen_cmds)));
3273 GLuint id1 = ids[0];
3274 GLuint id2 = ids[1];
3275 ClearCommands();
3277 // Test QueryCounterEXT fails if id = 0.
3278 gl_->QueryCounterEXT(0, GL_TIMESTAMP_EXT);
3279 EXPECT_TRUE(NoCommandsWritten());
3280 EXPECT_EQ(GL_INVALID_OPERATION, CheckError());
3282 // Test QueryCounterEXT fails if target is unknown.
3283 ClearCommands();
3284 gl_->QueryCounterEXT(id1, GL_TIME_ELAPSED_EXT);
3285 EXPECT_TRUE(NoCommandsWritten());
3286 EXPECT_EQ(GL_INVALID_ENUM, CheckError());
3288 // Test QueryCounterEXT inserts command.
3289 struct QueryCounterCmds {
3290 cmds::QueryCounterEXT query_counter;
3292 QueryCounterCmds expected_query_counter_cmds;
3293 const void* commands = GetPut();
3294 gl_->QueryCounterEXT(id1, GL_TIMESTAMP_EXT);
3295 EXPECT_EQ(GL_NO_ERROR, CheckError());
3296 QueryTracker::Query* query = GetQuery(id1);
3297 ASSERT_TRUE(query != NULL);
3298 expected_query_counter_cmds.query_counter.Init(
3299 GL_TIMESTAMP_EXT, id1, query->shm_id(), query->shm_offset(),
3300 query->submit_count());
3301 EXPECT_EQ(0, memcmp(&expected_query_counter_cmds, commands,
3302 sizeof(expected_query_counter_cmds)));
3303 ClearCommands();
3305 // Test 2nd QueryCounterEXT succeeds.
3306 commands = GetPut();
3307 gl_->QueryCounterEXT(id2, GL_TIMESTAMP_EXT);
3308 EXPECT_EQ(GL_NO_ERROR, CheckError());
3309 QueryTracker::Query* query2 = GetQuery(id2);
3310 ASSERT_TRUE(query2 != NULL);
3311 expected_query_counter_cmds.query_counter.Init(
3312 GL_TIMESTAMP_EXT, id2, query2->shm_id(), query2->shm_offset(),
3313 query2->submit_count());
3314 EXPECT_EQ(0, memcmp(&expected_query_counter_cmds, commands,
3315 sizeof(expected_query_counter_cmds)));
3316 ClearCommands();
3318 // Test QueryCounterEXT increments count.
3319 base::subtle::Atomic32 old_submit_count = query->submit_count();
3320 commands = GetPut();
3321 gl_->QueryCounterEXT(id1, GL_TIMESTAMP_EXT);
3322 EXPECT_EQ(GL_NO_ERROR, CheckError());
3323 EXPECT_NE(old_submit_count, query->submit_count());
3324 expected_query_counter_cmds.query_counter.Init(
3325 GL_TIMESTAMP_EXT, id1, query->shm_id(), query->shm_offset(),
3326 query->submit_count());
3327 EXPECT_EQ(0, memcmp(&expected_query_counter_cmds, commands,
3328 sizeof(expected_query_counter_cmds)));
3329 ClearCommands();
3331 // Test GetQueryObjectuivEXT CheckResultsAvailable
3332 GLuint available = 0xBDu;
3333 ClearCommands();
3334 gl_->GetQueryObjectuivEXT(id1, GL_QUERY_RESULT_AVAILABLE_EXT, &available);
3335 EXPECT_EQ(0u, available);
3337 // Test GetQueryObjectui64vEXT CheckResultsAvailable
3338 GLuint64 available2 = 0xBDu;
3339 ClearCommands();
3340 gl_->GetQueryObjectui64vEXT(id1, GL_QUERY_RESULT_AVAILABLE_EXT, &available2);
3341 EXPECT_EQ(0u, available2);
3344 TEST_F(GLES2ImplementationTest, ErrorQuery) {
3345 GLuint id = 0;
3346 gl_->GenQueriesEXT(1, &id);
3347 ClearCommands();
3349 // Test BeginQueryEXT does NOT insert commands.
3350 gl_->BeginQueryEXT(GL_GET_ERROR_QUERY_CHROMIUM, id);
3351 EXPECT_TRUE(NoCommandsWritten());
3352 QueryTracker::Query* query = GetQuery(id);
3353 ASSERT_TRUE(query != NULL);
3355 // Test EndQueryEXT sends both begin and end command
3356 struct EndCmds {
3357 cmds::BeginQueryEXT begin_query;
3358 cmds::EndQueryEXT end_query;
3360 EndCmds expected_end_cmds;
3361 expected_end_cmds.begin_query.Init(
3362 GL_GET_ERROR_QUERY_CHROMIUM, id, query->shm_id(), query->shm_offset());
3363 expected_end_cmds.end_query.Init(
3364 GL_GET_ERROR_QUERY_CHROMIUM, query->submit_count());
3365 const void* commands = GetPut();
3366 gl_->EndQueryEXT(GL_GET_ERROR_QUERY_CHROMIUM);
3367 EXPECT_EQ(0, memcmp(
3368 &expected_end_cmds, commands, sizeof(expected_end_cmds)));
3369 ClearCommands();
3371 // Check result is not yet available.
3372 GLuint available = 0xBDu;
3373 gl_->GetQueryObjectuivEXT(id, GL_QUERY_RESULT_AVAILABLE_EXT, &available);
3374 EXPECT_TRUE(NoCommandsWritten());
3375 EXPECT_EQ(0u, available);
3377 // Test no commands are sent if there is a client side error.
3379 // Generate a client side error
3380 gl_->ActiveTexture(GL_TEXTURE0 - 1);
3382 gl_->BeginQueryEXT(GL_GET_ERROR_QUERY_CHROMIUM, id);
3383 gl_->EndQueryEXT(GL_GET_ERROR_QUERY_CHROMIUM);
3384 EXPECT_TRUE(NoCommandsWritten());
3386 // Check result is available.
3387 gl_->GetQueryObjectuivEXT(id, GL_QUERY_RESULT_AVAILABLE_EXT, &available);
3388 EXPECT_TRUE(NoCommandsWritten());
3389 EXPECT_NE(0u, available);
3391 // Check result.
3392 GLuint result = 0xBDu;
3393 gl_->GetQueryObjectuivEXT(id, GL_QUERY_RESULT_EXT, &result);
3394 EXPECT_TRUE(NoCommandsWritten());
3395 EXPECT_EQ(static_cast<GLuint>(GL_INVALID_ENUM), result);
3398 #if !defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS)
3399 TEST_F(GLES2ImplementationTest, VertexArrays) {
3400 const GLuint kAttribIndex1 = 1;
3401 const GLint kNumComponents1 = 3;
3402 const GLsizei kClientStride = 12;
3404 GLuint id = 0;
3405 gl_->GenVertexArraysOES(1, &id);
3406 ClearCommands();
3408 gl_->BindVertexArrayOES(id);
3410 // Test that VertexAttribPointer cannot be called with a bound buffer of 0
3411 // unless the offset is NULL
3412 gl_->BindBuffer(GL_ARRAY_BUFFER, 0);
3414 gl_->VertexAttribPointer(
3415 kAttribIndex1, kNumComponents1, GL_FLOAT, GL_FALSE, kClientStride,
3416 reinterpret_cast<const void*>(4));
3417 EXPECT_EQ(GL_INVALID_OPERATION, CheckError());
3419 gl_->VertexAttribPointer(
3420 kAttribIndex1, kNumComponents1, GL_FLOAT, GL_FALSE, kClientStride, NULL);
3421 EXPECT_EQ(GL_NO_ERROR, CheckError());
3423 #endif
3425 TEST_F(GLES2ImplementationTest, Disable) {
3426 struct Cmds {
3427 cmds::Disable cmd;
3429 Cmds expected;
3430 expected.cmd.Init(GL_DITHER); // Note: DITHER defaults to enabled.
3432 gl_->Disable(GL_DITHER);
3433 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
3434 // Check it's cached and not called again.
3435 ClearCommands();
3436 gl_->Disable(GL_DITHER);
3437 EXPECT_TRUE(NoCommandsWritten());
3440 TEST_F(GLES2ImplementationTest, Enable) {
3441 struct Cmds {
3442 cmds::Enable cmd;
3444 Cmds expected;
3445 expected.cmd.Init(GL_BLEND); // Note: BLEND defaults to disabled.
3447 gl_->Enable(GL_BLEND);
3448 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
3449 // Check it's cached and not called again.
3450 ClearCommands();
3451 gl_->Enable(GL_BLEND);
3452 EXPECT_TRUE(NoCommandsWritten());
3455 TEST_F(GLES2ImplementationTest, ConsumeTextureCHROMIUM) {
3456 struct Cmds {
3457 cmds::ConsumeTextureCHROMIUMImmediate cmd;
3458 GLbyte data[64];
3461 Mailbox mailbox = Mailbox::Generate();
3462 Cmds expected;
3463 expected.cmd.Init(GL_TEXTURE_2D, mailbox.name);
3464 gl_->ConsumeTextureCHROMIUM(GL_TEXTURE_2D, mailbox.name);
3465 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
3468 TEST_F(GLES2ImplementationTest, CreateAndConsumeTextureCHROMIUM) {
3469 struct Cmds {
3470 cmds::CreateAndConsumeTextureCHROMIUMImmediate cmd;
3471 GLbyte data[64];
3474 Mailbox mailbox = Mailbox::Generate();
3475 Cmds expected;
3476 expected.cmd.Init(GL_TEXTURE_2D, kTexturesStartId, mailbox.name);
3477 GLuint id = gl_->CreateAndConsumeTextureCHROMIUM(GL_TEXTURE_2D, mailbox.name);
3478 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
3479 EXPECT_EQ(kTexturesStartId, id);
3482 TEST_F(GLES2ImplementationTest, ProduceTextureCHROMIUM) {
3483 struct Cmds {
3484 cmds::ProduceTextureCHROMIUMImmediate cmd;
3485 GLbyte data[64];
3488 Mailbox mailbox = Mailbox::Generate();
3489 Cmds expected;
3490 expected.cmd.Init(GL_TEXTURE_2D, mailbox.name);
3491 gl_->ProduceTextureCHROMIUM(GL_TEXTURE_2D, mailbox.name);
3492 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
3495 TEST_F(GLES2ImplementationTest, ProduceTextureDirectCHROMIUM) {
3496 struct Cmds {
3497 cmds::ProduceTextureDirectCHROMIUMImmediate cmd;
3498 GLbyte data[64];
3501 Mailbox mailbox = Mailbox::Generate();
3502 Cmds expected;
3503 expected.cmd.Init(kTexturesStartId, GL_TEXTURE_2D, mailbox.name);
3504 gl_->ProduceTextureDirectCHROMIUM(
3505 kTexturesStartId, GL_TEXTURE_2D, mailbox.name);
3506 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
3509 TEST_F(GLES2ImplementationTest, LimitSizeAndOffsetTo32Bit) {
3510 GLsizeiptr size;
3511 GLintptr offset;
3512 if (sizeof(size) <= 4 || sizeof(offset) <= 4)
3513 return;
3514 // The below two casts should be no-op, as we return early if
3515 // it's 32-bit system.
3516 int64 value64 = 0x100000000;
3517 size = static_cast<GLsizeiptr>(value64);
3518 offset = static_cast<GLintptr>(value64);
3520 const char kSizeOverflowMessage[] = "size more than 32-bit";
3521 const char kOffsetOverflowMessage[] = "offset more than 32-bit";
3523 const GLfloat buf[] = { 1.0, 1.0, 1.0, 1.0 };
3524 const GLubyte indices[] = { 0 };
3526 const GLuint kClientArrayBufferId = 0x789;
3527 const GLuint kClientElementArrayBufferId = 0x790;
3528 gl_->BindBuffer(GL_ARRAY_BUFFER, kClientArrayBufferId);
3529 gl_->BindBuffer(GL_ELEMENT_ARRAY_BUFFER, kClientElementArrayBufferId);
3530 EXPECT_EQ(GL_NO_ERROR, CheckError());
3532 // Call BufferData() should succeed with legal paramaters.
3533 gl_->BufferData(GL_ARRAY_BUFFER, sizeof(buf), buf, GL_DYNAMIC_DRAW);
3534 gl_->BufferData(
3535 GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_DYNAMIC_DRAW);
3536 EXPECT_EQ(GL_NO_ERROR, CheckError());
3538 // BufferData: size
3539 gl_->BufferData(GL_ARRAY_BUFFER, size, buf, GL_DYNAMIC_DRAW);
3540 EXPECT_EQ(GL_INVALID_OPERATION, CheckError());
3541 EXPECT_STREQ(kSizeOverflowMessage, GetLastError().c_str());
3543 // Call BufferSubData() should succeed with legal paramaters.
3544 gl_->BufferSubData(GL_ARRAY_BUFFER, 0, sizeof(buf[0]), buf);
3545 EXPECT_EQ(GL_NO_ERROR, CheckError());
3547 // BufferSubData: offset
3548 gl_->BufferSubData(GL_ARRAY_BUFFER, offset, 1, buf);
3549 EXPECT_EQ(GL_INVALID_OPERATION, CheckError());
3550 EXPECT_STREQ(kOffsetOverflowMessage, GetLastError().c_str());
3552 // BufferSubData: size
3553 EXPECT_EQ(GL_NO_ERROR, CheckError());
3554 gl_->BufferSubData(GL_ARRAY_BUFFER, 0, size, buf);
3555 EXPECT_EQ(GL_INVALID_OPERATION, CheckError());
3556 EXPECT_STREQ(kSizeOverflowMessage, GetLastError().c_str());
3558 // Call MapBufferSubDataCHROMIUM() should succeed with legal paramaters.
3559 void* mem =
3560 gl_->MapBufferSubDataCHROMIUM(GL_ARRAY_BUFFER, 0, 1, GL_WRITE_ONLY);
3561 EXPECT_TRUE(NULL != mem);
3562 EXPECT_EQ(GL_NO_ERROR, CheckError());
3563 gl_->UnmapBufferSubDataCHROMIUM(mem);
3565 // MapBufferSubDataCHROMIUM: offset
3566 EXPECT_TRUE(NULL == gl_->MapBufferSubDataCHROMIUM(
3567 GL_ARRAY_BUFFER, offset, 1, GL_WRITE_ONLY));
3568 EXPECT_EQ(GL_INVALID_OPERATION, CheckError());
3569 EXPECT_STREQ(kOffsetOverflowMessage, GetLastError().c_str());
3571 // MapBufferSubDataCHROMIUM: size
3572 EXPECT_EQ(GL_NO_ERROR, CheckError());
3573 EXPECT_TRUE(NULL == gl_->MapBufferSubDataCHROMIUM(
3574 GL_ARRAY_BUFFER, 0, size, GL_WRITE_ONLY));
3575 EXPECT_EQ(GL_INVALID_OPERATION, CheckError());
3576 EXPECT_STREQ(kSizeOverflowMessage, GetLastError().c_str());
3578 // Call DrawElements() should succeed with legal paramaters.
3579 gl_->DrawElements(GL_POINTS, 1, GL_UNSIGNED_BYTE, NULL);
3580 EXPECT_EQ(GL_NO_ERROR, CheckError());
3582 // DrawElements: offset
3583 gl_->DrawElements(
3584 GL_POINTS, 1, GL_UNSIGNED_BYTE, reinterpret_cast<void*>(offset));
3585 EXPECT_EQ(GL_INVALID_OPERATION, CheckError());
3586 EXPECT_STREQ(kOffsetOverflowMessage, GetLastError().c_str());
3588 // Call DrawElementsInstancedANGLE() should succeed with legal paramaters.
3589 gl_->DrawElementsInstancedANGLE(GL_POINTS, 1, GL_UNSIGNED_BYTE, NULL, 1);
3590 EXPECT_EQ(GL_NO_ERROR, CheckError());
3592 // DrawElementsInstancedANGLE: offset
3593 gl_->DrawElementsInstancedANGLE(
3594 GL_POINTS, 1, GL_UNSIGNED_BYTE, reinterpret_cast<void*>(offset), 1);
3595 EXPECT_EQ(GL_INVALID_OPERATION, CheckError());
3596 EXPECT_STREQ(kOffsetOverflowMessage, GetLastError().c_str());
3598 // Call VertexAttribPointer() should succeed with legal paramaters.
3599 const GLuint kAttribIndex = 1;
3600 const GLsizei kStride = 4;
3601 gl_->VertexAttribPointer(
3602 kAttribIndex, 1, GL_FLOAT, GL_FALSE, kStride, NULL);
3603 EXPECT_EQ(GL_NO_ERROR, CheckError());
3605 // VertexAttribPointer: offset
3606 gl_->VertexAttribPointer(
3607 kAttribIndex, 1, GL_FLOAT, GL_FALSE, kStride,
3608 reinterpret_cast<void*>(offset));
3609 EXPECT_EQ(GL_INVALID_OPERATION, CheckError());
3610 EXPECT_STREQ(kOffsetOverflowMessage, GetLastError().c_str());
3613 TEST_F(GLES2ImplementationTest, TraceBeginCHROMIUM) {
3614 const uint32 kCategoryBucketId = GLES2Implementation::kResultBucketId;
3615 const uint32 kNameBucketId = GLES2Implementation::kResultBucketId + 1;
3616 const std::string category_name = "test category";
3617 const std::string trace_name = "test trace";
3618 const size_t kPaddedString1Size =
3619 transfer_buffer_->RoundToAlignment(category_name.size() + 1);
3620 const size_t kPaddedString2Size =
3621 transfer_buffer_->RoundToAlignment(trace_name.size() + 1);
3623 gl_->TraceBeginCHROMIUM(category_name.c_str(), trace_name.c_str());
3624 EXPECT_EQ(GL_NO_ERROR, CheckError());
3626 struct Cmds {
3627 cmd::SetBucketSize category_size1;
3628 cmd::SetBucketData category_data;
3629 cmd::SetToken set_token1;
3630 cmd::SetBucketSize name_size1;
3631 cmd::SetBucketData name_data;
3632 cmd::SetToken set_token2;
3633 cmds::TraceBeginCHROMIUM trace_call_begin;
3634 cmd::SetBucketSize category_size2;
3635 cmd::SetBucketSize name_size2;
3638 ExpectedMemoryInfo mem1 = GetExpectedMemory(kPaddedString1Size);
3639 ExpectedMemoryInfo mem2 = GetExpectedMemory(kPaddedString2Size);
3641 ASSERT_STREQ(category_name.c_str(), reinterpret_cast<char*>(mem1.ptr));
3642 ASSERT_STREQ(trace_name.c_str(), reinterpret_cast<char*>(mem2.ptr));
3644 Cmds expected;
3645 expected.category_size1.Init(kCategoryBucketId, category_name.size() + 1);
3646 expected.category_data.Init(
3647 kCategoryBucketId, 0, category_name.size() + 1, mem1.id, mem1.offset);
3648 expected.set_token1.Init(GetNextToken());
3649 expected.name_size1.Init(kNameBucketId, trace_name.size() + 1);
3650 expected.name_data.Init(
3651 kNameBucketId, 0, trace_name.size() + 1, mem2.id, mem2.offset);
3652 expected.set_token2.Init(GetNextToken());
3653 expected.trace_call_begin.Init(kCategoryBucketId, kNameBucketId);
3654 expected.category_size2.Init(kCategoryBucketId, 0);
3655 expected.name_size2.Init(kNameBucketId, 0);
3657 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
3660 TEST_F(GLES2ImplementationTest, AllowNestedTracesCHROMIUM) {
3661 const std::string category1_name = "test category 1";
3662 const std::string trace1_name = "test trace 1";
3663 const std::string category2_name = "test category 2";
3664 const std::string trace2_name = "test trace 2";
3666 gl_->TraceBeginCHROMIUM(category1_name.c_str(), trace1_name.c_str());
3667 EXPECT_EQ(GL_NO_ERROR, CheckError());
3669 gl_->TraceBeginCHROMIUM(category2_name.c_str(), trace2_name.c_str());
3670 EXPECT_EQ(GL_NO_ERROR, CheckError());
3672 gl_->TraceEndCHROMIUM();
3673 EXPECT_EQ(GL_NO_ERROR, CheckError());
3675 gl_->TraceEndCHROMIUM();
3676 EXPECT_EQ(GL_NO_ERROR, CheckError());
3678 // No more corresponding begin tracer marker should error.
3679 gl_->TraceEndCHROMIUM();
3680 EXPECT_EQ(GL_INVALID_OPERATION, CheckError());
3683 TEST_F(GLES2ImplementationTest, IsEnabled) {
3684 // If we use a valid enum, its state is cached on client side, so no command
3685 // is actually generated, and this test will fail.
3686 // TODO(zmo): it seems we never need the command. Maybe remove it.
3687 GLenum kCap = 1;
3688 struct Cmds {
3689 cmds::IsEnabled cmd;
3692 Cmds expected;
3693 ExpectedMemoryInfo result1 =
3694 GetExpectedResultMemory(sizeof(cmds::IsEnabled::Result));
3695 expected.cmd.Init(kCap, result1.id, result1.offset);
3697 EXPECT_CALL(*command_buffer(), OnFlush())
3698 .WillOnce(SetMemory(result1.ptr, uint32_t(GL_TRUE)))
3699 .RetiresOnSaturation();
3701 GLboolean result = gl_->IsEnabled(kCap);
3702 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
3703 EXPECT_TRUE(result);
3706 TEST_F(GLES2ImplementationTest, ClientWaitSync) {
3707 const GLuint client_sync_id = 36;
3708 struct Cmds {
3709 cmds::ClientWaitSync cmd;
3712 Cmds expected;
3713 ExpectedMemoryInfo result1 =
3714 GetExpectedResultMemory(sizeof(cmds::ClientWaitSync::Result));
3715 const GLuint64 kTimeout = 0xABCDEF0123456789;
3716 uint32_t v32_0 = 0, v32_1 = 0;
3717 GLES2Util::MapUint64ToTwoUint32(kTimeout, &v32_0, &v32_1);
3718 expected.cmd.Init(client_sync_id, GL_SYNC_FLUSH_COMMANDS_BIT,
3719 v32_0, v32_1, result1.id, result1.offset);
3721 EXPECT_CALL(*command_buffer(), OnFlush())
3722 .WillOnce(SetMemory(result1.ptr, uint32_t(GL_CONDITION_SATISFIED)))
3723 .RetiresOnSaturation();
3725 GLenum result = gl_->ClientWaitSync(
3726 reinterpret_cast<GLsync>(client_sync_id), GL_SYNC_FLUSH_COMMANDS_BIT,
3727 kTimeout);
3728 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
3729 EXPECT_EQ(static_cast<GLenum>(GL_CONDITION_SATISFIED), result);
3732 TEST_F(GLES2ImplementationTest, WaitSync) {
3733 const GLuint kClientSyncId = 36;
3734 struct Cmds {
3735 cmds::WaitSync cmd;
3737 Cmds expected;
3738 const GLuint64 kTimeout = GL_TIMEOUT_IGNORED;
3739 uint32_t v32_0 = 0, v32_1 = 0;
3740 GLES2Util::MapUint64ToTwoUint32(kTimeout, &v32_0, &v32_1);
3741 expected.cmd.Init(kClientSyncId, 0, v32_0, v32_1);
3743 gl_->WaitSync(reinterpret_cast<GLsync>(kClientSyncId), 0, kTimeout);
3744 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
3747 TEST_F(GLES2ImplementationTest, MapBufferRangeUnmapBufferWrite) {
3748 ExpectedMemoryInfo result =
3749 GetExpectedResultMemory(sizeof(cmds::MapBufferRange::Result));
3751 EXPECT_CALL(*command_buffer(), OnFlush())
3752 .WillOnce(SetMemory(result.ptr, uint32_t(1)))
3753 .RetiresOnSaturation();
3755 const GLuint kBufferId = 123;
3756 gl_->BindBuffer(GL_ARRAY_BUFFER, kBufferId);
3758 void* mem = gl_->MapBufferRange(GL_ARRAY_BUFFER, 10, 64, GL_MAP_WRITE_BIT);
3759 EXPECT_TRUE(mem != nullptr);
3761 EXPECT_TRUE(gl_->UnmapBuffer(GL_ARRAY_BUFFER));
3764 TEST_F(GLES2ImplementationTest, MapBufferRangeWriteWithInvalidateBit) {
3765 ExpectedMemoryInfo result =
3766 GetExpectedResultMemory(sizeof(cmds::MapBufferRange::Result));
3768 EXPECT_CALL(*command_buffer(), OnFlush())
3769 .WillOnce(SetMemory(result.ptr, uint32_t(1)))
3770 .RetiresOnSaturation();
3772 const GLuint kBufferId = 123;
3773 gl_->BindBuffer(GL_ARRAY_BUFFER, kBufferId);
3775 GLsizeiptr kSize = 64;
3776 void* mem = gl_->MapBufferRange(
3777 GL_ARRAY_BUFFER, 10, kSize,
3778 GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_RANGE_BIT);
3779 EXPECT_TRUE(mem != nullptr);
3780 std::vector<int8_t> zero(kSize);
3781 memset(&zero[0], 0, kSize);
3782 EXPECT_EQ(0, memcmp(mem, &zero[0], kSize));
3785 TEST_F(GLES2ImplementationTest, MapBufferRangeWriteWithGLError) {
3786 ExpectedMemoryInfo result =
3787 GetExpectedResultMemory(sizeof(cmds::MapBufferRange::Result));
3789 // Return a result of 0 to indicate an GL error.
3790 EXPECT_CALL(*command_buffer(), OnFlush())
3791 .WillOnce(SetMemory(result.ptr, uint32_t(0)))
3792 .RetiresOnSaturation();
3794 const GLuint kBufferId = 123;
3795 gl_->BindBuffer(GL_ARRAY_BUFFER, kBufferId);
3797 void* mem = gl_->MapBufferRange(GL_ARRAY_BUFFER, 10, 64, GL_MAP_WRITE_BIT);
3798 EXPECT_TRUE(mem == nullptr);
3801 TEST_F(GLES2ImplementationTest, MapBufferRangeUnmapBufferRead) {
3802 ExpectedMemoryInfo result =
3803 GetExpectedResultMemory(sizeof(cmds::MapBufferRange::Result));
3805 EXPECT_CALL(*command_buffer(), OnFlush())
3806 .WillOnce(SetMemory(result.ptr, uint32_t(1)))
3807 .RetiresOnSaturation();
3809 const GLuint kBufferId = 123;
3810 gl_->BindBuffer(GL_ARRAY_BUFFER, kBufferId);
3812 void* mem = gl_->MapBufferRange(GL_ARRAY_BUFFER, 10, 64, GL_MAP_READ_BIT);
3813 EXPECT_TRUE(mem != nullptr);
3815 EXPECT_TRUE(gl_->UnmapBuffer(GL_ARRAY_BUFFER));
3818 TEST_F(GLES2ImplementationTest, MapBufferRangeReadWithGLError) {
3819 ExpectedMemoryInfo result =
3820 GetExpectedResultMemory(sizeof(cmds::MapBufferRange::Result));
3822 // Return a result of 0 to indicate an GL error.
3823 EXPECT_CALL(*command_buffer(), OnFlush())
3824 .WillOnce(SetMemory(result.ptr, uint32_t(0)))
3825 .RetiresOnSaturation();
3827 const GLuint kBufferId = 123;
3828 gl_->BindBuffer(GL_ARRAY_BUFFER, kBufferId);
3830 void* mem = gl_->MapBufferRange(GL_ARRAY_BUFFER, 10, 64, GL_MAP_READ_BIT);
3831 EXPECT_TRUE(mem == nullptr);
3834 TEST_F(GLES2ImplementationTest, UnmapBufferFails) {
3835 // No bound buffer.
3836 EXPECT_FALSE(gl_->UnmapBuffer(GL_ARRAY_BUFFER));
3837 EXPECT_EQ(GL_INVALID_OPERATION, CheckError());
3839 const GLuint kBufferId = 123;
3840 gl_->BindBuffer(GL_ARRAY_BUFFER, kBufferId);
3842 // Buffer is unmapped.
3843 EXPECT_FALSE(gl_->UnmapBuffer(GL_ARRAY_BUFFER));
3844 EXPECT_EQ(GL_INVALID_OPERATION, CheckError());
3847 TEST_F(GLES2ImplementationTest, BufferDataUnmapsDataStore) {
3848 ExpectedMemoryInfo result =
3849 GetExpectedResultMemory(sizeof(cmds::MapBufferRange::Result));
3851 EXPECT_CALL(*command_buffer(), OnFlush())
3852 .WillOnce(SetMemory(result.ptr, uint32_t(1)))
3853 .RetiresOnSaturation();
3855 const GLuint kBufferId = 123;
3856 gl_->BindBuffer(GL_ARRAY_BUFFER, kBufferId);
3858 void* mem = gl_->MapBufferRange(GL_ARRAY_BUFFER, 10, 64, GL_MAP_WRITE_BIT);
3859 EXPECT_TRUE(mem != nullptr);
3861 std::vector<uint8_t> data(16);
3862 // BufferData unmaps the data store.
3863 gl_->BufferData(GL_ARRAY_BUFFER, 16, &data[0], GL_STREAM_DRAW);
3865 EXPECT_FALSE(gl_->UnmapBuffer(GL_ARRAY_BUFFER));
3866 EXPECT_EQ(GL_INVALID_OPERATION, CheckError());
3869 TEST_F(GLES2ImplementationTest, DeleteBuffersUnmapsDataStore) {
3870 ExpectedMemoryInfo result =
3871 GetExpectedResultMemory(sizeof(cmds::MapBufferRange::Result));
3873 EXPECT_CALL(*command_buffer(), OnFlush())
3874 .WillOnce(SetMemory(result.ptr, uint32_t(1)))
3875 .RetiresOnSaturation();
3877 const GLuint kBufferId = 123;
3878 gl_->BindBuffer(GL_ARRAY_BUFFER, kBufferId);
3880 void* mem = gl_->MapBufferRange(GL_ARRAY_BUFFER, 10, 64, GL_MAP_WRITE_BIT);
3881 EXPECT_TRUE(mem != nullptr);
3883 std::vector<uint8_t> data(16);
3884 // DeleteBuffers unmaps the data store.
3885 gl_->DeleteBuffers(1, &kBufferId);
3887 EXPECT_FALSE(gl_->UnmapBuffer(GL_ARRAY_BUFFER));
3888 EXPECT_EQ(GL_INVALID_OPERATION, CheckError());
3891 TEST_F(GLES2ImplementationTest, GetInternalformativ) {
3892 const GLint kNumSampleCounts = 8;
3893 struct Cmds {
3894 cmds::GetInternalformativ cmd;
3896 typedef cmds::GetInternalformativ::Result::Type ResultType;
3897 ResultType result = 0;
3898 Cmds expected;
3899 ExpectedMemoryInfo result1 =
3900 GetExpectedResultMemory(sizeof(uint32_t) + sizeof(ResultType));
3901 expected.cmd.Init(123, GL_RGBA8, GL_NUM_SAMPLE_COUNTS,
3902 result1.id, result1.offset);
3903 EXPECT_CALL(*command_buffer(), OnFlush())
3904 .WillOnce(SetMemory(result1.ptr,
3905 SizedResultHelper<ResultType>(kNumSampleCounts)))
3906 .RetiresOnSaturation();
3907 gl_->GetInternalformativ(123, GL_RGBA8, GL_NUM_SAMPLE_COUNTS, 1, &result);
3908 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
3909 EXPECT_EQ(static_cast<ResultType>(kNumSampleCounts), result);
3912 TEST_F(GLES2ImplementationManualInitTest, LoseContextOnOOM) {
3913 ContextInitOptions init_options;
3914 init_options.lose_context_when_out_of_memory = true;
3915 ASSERT_TRUE(Initialize(init_options));
3917 struct Cmds {
3918 cmds::LoseContextCHROMIUM cmd;
3921 GLsizei max = std::numeric_limits<GLsizei>::max();
3922 EXPECT_CALL(*gpu_control_, CreateGpuMemoryBufferImage(max, max, _, _))
3923 .WillOnce(Return(-1));
3924 gl_->CreateGpuMemoryBufferImageCHROMIUM(max, max, GL_RGBA, GL_MAP_CHROMIUM);
3925 // The context should be lost.
3926 Cmds expected;
3927 expected.cmd.Init(GL_GUILTY_CONTEXT_RESET_ARB, GL_UNKNOWN_CONTEXT_RESET_ARB);
3928 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
3931 TEST_F(GLES2ImplementationManualInitTest, NoLoseContextOnOOM) {
3932 ContextInitOptions init_options;
3933 ASSERT_TRUE(Initialize(init_options));
3935 struct Cmds {
3936 cmds::LoseContextCHROMIUM cmd;
3939 GLsizei max = std::numeric_limits<GLsizei>::max();
3940 EXPECT_CALL(*gpu_control_, CreateGpuMemoryBufferImage(max, max, _, _))
3941 .WillOnce(Return(-1));
3942 gl_->CreateGpuMemoryBufferImageCHROMIUM(max, max, GL_RGBA, GL_MAP_CHROMIUM);
3943 // The context should not be lost.
3944 EXPECT_TRUE(NoCommandsWritten());
3947 TEST_F(GLES2ImplementationManualInitTest, FailInitOnBGRMismatch1) {
3948 ContextInitOptions init_options;
3949 init_options.bind_generates_resource_client = false;
3950 init_options.bind_generates_resource_service = true;
3951 EXPECT_FALSE(Initialize(init_options));
3954 TEST_F(GLES2ImplementationManualInitTest, FailInitOnBGRMismatch2) {
3955 ContextInitOptions init_options;
3956 init_options.bind_generates_resource_client = true;
3957 init_options.bind_generates_resource_service = false;
3958 EXPECT_FALSE(Initialize(init_options));
3961 TEST_F(GLES2ImplementationManualInitTest, FailInitOnTransferBufferFail) {
3962 ContextInitOptions init_options;
3963 init_options.transfer_buffer_initialize_fail = true;
3964 EXPECT_FALSE(Initialize(init_options));
3967 #include "gpu/command_buffer/client/gles2_implementation_unittest_autogen.h"
3969 } // namespace gles2
3970 } // namespace gpu