Roll leveldb 3f7758:803d69 (v1.17 -> v1.18)
[chromium-blink-merge.git] / gpu / command_buffer / client / gles2_implementation_unittest.cc
blob5c944a873520c586a091e20533a75de75f076c1d
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 // Tests for GLES2Implementation.
7 #include "gpu/command_buffer/client/gles2_implementation.h"
9 #include <limits>
11 #include <GLES2/gl2ext.h>
12 #include <GLES2/gl2extchromium.h>
13 #include "base/compiler_specific.h"
14 #include "gpu/command_buffer/client/client_test_helper.h"
15 #include "gpu/command_buffer/client/program_info_manager.h"
16 #include "gpu/command_buffer/client/transfer_buffer.h"
17 #include "gpu/command_buffer/common/command_buffer.h"
18 #include "testing/gtest/include/gtest/gtest.h"
19 #include "testing/gmock/include/gmock/gmock.h"
21 #if !defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS)
22 #define GLES2_SUPPORT_CLIENT_SIDE_ARRAYS
23 #endif
25 using testing::_;
26 using testing::AtLeast;
27 using testing::AnyNumber;
28 using testing::DoAll;
29 using testing::InSequence;
30 using testing::Invoke;
31 using testing::Mock;
32 using testing::Sequence;
33 using testing::StrictMock;
34 using testing::Truly;
35 using testing::Return;
37 namespace gpu {
38 namespace gles2 {
40 ACTION_P2(SetMemory, dst, obj) {
41 memcpy(dst, &obj, sizeof(obj));
44 ACTION_P3(SetMemoryFromArray, dst, array, size) {
45 memcpy(dst, array, size);
48 // Used to help set the transfer buffer result to SizedResult of a single value.
49 template <typename T>
50 class SizedResultHelper {
51 public:
52 explicit SizedResultHelper(T result)
53 : size_(sizeof(result)),
54 result_(result) {
57 private:
58 uint32 size_;
59 T result_;
62 // Struct to make it easy to pass a vec4 worth of floats.
63 struct FourFloats {
64 FourFloats(float _x, float _y, float _z, float _w)
65 : x(_x),
66 y(_y),
67 z(_z),
68 w(_w) {
71 float x;
72 float y;
73 float z;
74 float w;
77 #pragma pack(push, 1)
78 // Struct that holds 7 characters.
79 struct Str7 {
80 char str[7];
82 #pragma pack(pop)
84 class MockTransferBuffer : public TransferBufferInterface {
85 public:
86 struct ExpectedMemoryInfo {
87 uint32 offset;
88 int32 id;
89 uint8* ptr;
92 MockTransferBuffer(
93 CommandBuffer* command_buffer,
94 unsigned int size,
95 unsigned int result_size,
96 unsigned int alignment)
97 : command_buffer_(command_buffer),
98 size_(size),
99 result_size_(result_size),
100 alignment_(alignment),
101 actual_buffer_index_(0),
102 expected_buffer_index_(0),
103 last_alloc_(NULL),
104 expected_offset_(result_size),
105 actual_offset_(result_size) {
106 // We have to allocate the buffers here because
107 // we need to know their address before GLES2Implementation::Initialize
108 // is called.
109 for (int ii = 0; ii < kNumBuffers; ++ii) {
110 buffers_[ii] = command_buffer_->CreateTransferBuffer(
111 size_ + ii * alignment_,
112 &buffer_ids_[ii]);
113 EXPECT_NE(-1, buffer_ids_[ii]);
117 ~MockTransferBuffer() override {}
119 bool Initialize(unsigned int starting_buffer_size,
120 unsigned int result_size,
121 unsigned int /* min_buffer_size */,
122 unsigned int /* max_buffer_size */,
123 unsigned int alignment,
124 unsigned int size_to_flush) override;
125 int GetShmId() override;
126 void* GetResultBuffer() override;
127 int GetResultOffset() override;
128 void Free() override;
129 bool HaveBuffer() const override;
130 void* AllocUpTo(unsigned int size, unsigned int* size_allocated) override;
131 void* Alloc(unsigned int size) override;
132 RingBuffer::Offset GetOffset(void* pointer) const override;
133 void FreePendingToken(void* p, unsigned int /* token */) override;
135 size_t MaxTransferBufferSize() {
136 return size_ - result_size_;
139 unsigned int RoundToAlignment(unsigned int size) {
140 return (size + alignment_ - 1) & ~(alignment_ - 1);
143 bool InSync() {
144 return expected_buffer_index_ == actual_buffer_index_ &&
145 expected_offset_ == actual_offset_;
148 ExpectedMemoryInfo GetExpectedMemory(size_t size) {
149 ExpectedMemoryInfo mem;
150 mem.offset = AllocateExpectedTransferBuffer(size);
151 mem.id = GetExpectedTransferBufferId();
152 mem.ptr = static_cast<uint8*>(
153 GetExpectedTransferAddressFromOffset(mem.offset, size));
154 return mem;
157 ExpectedMemoryInfo GetExpectedResultMemory(size_t size) {
158 ExpectedMemoryInfo mem;
159 mem.offset = GetExpectedResultBufferOffset();
160 mem.id = GetExpectedResultBufferId();
161 mem.ptr = static_cast<uint8*>(
162 GetExpectedTransferAddressFromOffset(mem.offset, size));
163 return mem;
166 private:
167 static const int kNumBuffers = 2;
169 uint8* actual_buffer() const {
170 return static_cast<uint8*>(buffers_[actual_buffer_index_]->memory());
173 uint8* expected_buffer() const {
174 return static_cast<uint8*>(buffers_[expected_buffer_index_]->memory());
177 uint32 AllocateExpectedTransferBuffer(size_t size) {
178 EXPECT_LE(size, MaxTransferBufferSize());
180 // Toggle which buffer we get each time to simulate the buffer being
181 // reallocated.
182 expected_buffer_index_ = (expected_buffer_index_ + 1) % kNumBuffers;
184 if (expected_offset_ + size > size_) {
185 expected_offset_ = result_size_;
187 uint32 offset = expected_offset_;
188 expected_offset_ += RoundToAlignment(size);
190 // Make sure each buffer has a different offset.
191 return offset + expected_buffer_index_ * alignment_;
194 void* GetExpectedTransferAddressFromOffset(uint32 offset, size_t size) {
195 EXPECT_GE(offset, expected_buffer_index_ * alignment_);
196 EXPECT_LE(offset + size, size_ + expected_buffer_index_ * alignment_);
197 return expected_buffer() + offset;
200 int GetExpectedResultBufferId() {
201 return buffer_ids_[expected_buffer_index_];
204 uint32 GetExpectedResultBufferOffset() {
205 return expected_buffer_index_ * alignment_;
208 int GetExpectedTransferBufferId() {
209 return buffer_ids_[expected_buffer_index_];
212 CommandBuffer* command_buffer_;
213 size_t size_;
214 size_t result_size_;
215 uint32 alignment_;
216 int buffer_ids_[kNumBuffers];
217 scoped_refptr<Buffer> buffers_[kNumBuffers];
218 int actual_buffer_index_;
219 int expected_buffer_index_;
220 void* last_alloc_;
221 uint32 expected_offset_;
222 uint32 actual_offset_;
224 DISALLOW_COPY_AND_ASSIGN(MockTransferBuffer);
227 bool MockTransferBuffer::Initialize(
228 unsigned int starting_buffer_size,
229 unsigned int result_size,
230 unsigned int /* min_buffer_size */,
231 unsigned int /* max_buffer_size */,
232 unsigned int alignment,
233 unsigned int /* size_to_flush */) {
234 // Just check they match.
235 return size_ == starting_buffer_size &&
236 result_size_ == result_size &&
237 alignment_ == alignment;
240 int MockTransferBuffer::GetShmId() {
241 return buffer_ids_[actual_buffer_index_];
244 void* MockTransferBuffer::GetResultBuffer() {
245 return actual_buffer() + actual_buffer_index_ * alignment_;
248 int MockTransferBuffer::GetResultOffset() {
249 return actual_buffer_index_ * alignment_;
252 void MockTransferBuffer::Free() {
253 NOTREACHED();
256 bool MockTransferBuffer::HaveBuffer() const {
257 return true;
260 void* MockTransferBuffer::AllocUpTo(
261 unsigned int size, unsigned int* size_allocated) {
262 EXPECT_TRUE(size_allocated != NULL);
263 EXPECT_TRUE(last_alloc_ == NULL);
265 // Toggle which buffer we get each time to simulate the buffer being
266 // reallocated.
267 actual_buffer_index_ = (actual_buffer_index_ + 1) % kNumBuffers;
269 size = std::min(static_cast<size_t>(size), MaxTransferBufferSize());
270 if (actual_offset_ + size > size_) {
271 actual_offset_ = result_size_;
273 uint32 offset = actual_offset_;
274 actual_offset_ += RoundToAlignment(size);
275 *size_allocated = size;
277 // Make sure each buffer has a different offset.
278 last_alloc_ = actual_buffer() + offset + actual_buffer_index_ * alignment_;
279 return last_alloc_;
282 void* MockTransferBuffer::Alloc(unsigned int size) {
283 EXPECT_LE(size, MaxTransferBufferSize());
284 unsigned int temp = 0;
285 void* p = AllocUpTo(size, &temp);
286 EXPECT_EQ(temp, size);
287 return p;
290 RingBuffer::Offset MockTransferBuffer::GetOffset(void* pointer) const {
291 // Make sure each buffer has a different offset.
292 return static_cast<uint8*>(pointer) - actual_buffer();
295 void MockTransferBuffer::FreePendingToken(void* p, unsigned int /* token */) {
296 EXPECT_EQ(last_alloc_, p);
297 last_alloc_ = NULL;
300 // API wrapper for Buffers.
301 class GenBuffersAPI {
302 public:
303 static void Gen(GLES2Implementation* gl_impl, GLsizei n, GLuint* ids) {
304 gl_impl->GenBuffers(n, ids);
307 static void Delete(GLES2Implementation* gl_impl,
308 GLsizei n,
309 const GLuint* ids) {
310 gl_impl->DeleteBuffers(n, ids);
314 // API wrapper for Framebuffers.
315 class GenFramebuffersAPI {
316 public:
317 static void Gen(GLES2Implementation* gl_impl, GLsizei n, GLuint* ids) {
318 gl_impl->GenFramebuffers(n, ids);
321 static void Delete(GLES2Implementation* gl_impl,
322 GLsizei n,
323 const GLuint* ids) {
324 gl_impl->DeleteFramebuffers(n, ids);
328 // API wrapper for Renderbuffers.
329 class GenRenderbuffersAPI {
330 public:
331 static void Gen(GLES2Implementation* gl_impl, GLsizei n, GLuint* ids) {
332 gl_impl->GenRenderbuffers(n, ids);
335 static void Delete(GLES2Implementation* gl_impl,
336 GLsizei n,
337 const GLuint* ids) {
338 gl_impl->DeleteRenderbuffers(n, ids);
342 // API wrapper for Textures.
343 class GenTexturesAPI {
344 public:
345 static void Gen(GLES2Implementation* gl_impl, GLsizei n, GLuint* ids) {
346 gl_impl->GenTextures(n, ids);
349 static void Delete(GLES2Implementation* gl_impl,
350 GLsizei n,
351 const GLuint* ids) {
352 gl_impl->DeleteTextures(n, ids);
356 class GLES2ImplementationTest : public testing::Test {
357 protected:
358 static const int kNumTestContexts = 2;
359 static const uint8 kInitialValue = 0xBD;
360 static const int32 kNumCommandEntries = 500;
361 static const int32 kCommandBufferSizeBytes =
362 kNumCommandEntries * sizeof(CommandBufferEntry);
363 static const size_t kTransferBufferSize = 512;
365 static const GLint kMaxCombinedTextureImageUnits = 8;
366 static const GLint kMaxCubeMapTextureSize = 64;
367 static const GLint kMaxFragmentUniformVectors = 16;
368 static const GLint kMaxRenderbufferSize = 64;
369 static const GLint kMaxTextureImageUnits = 8;
370 static const GLint kMaxTextureSize = 128;
371 static const GLint kMaxVaryingVectors = 8;
372 static const GLint kMaxVertexAttribs = 8;
373 static const GLint kMaxVertexTextureImageUnits = 0;
374 static const GLint kMaxVertexUniformVectors = 128;
375 static const GLint kNumCompressedTextureFormats = 0;
376 static const GLint kNumShaderBinaryFormats = 0;
377 static const GLuint kStartId = 1024;
378 static const GLuint kBuffersStartId =
379 GLES2Implementation::kClientSideArrayId + 2 * kNumTestContexts;
380 static const GLuint kFramebuffersStartId = 1;
381 static const GLuint kProgramsAndShadersStartId = 1;
382 static const GLuint kRenderbuffersStartId = 1;
383 static const GLuint kTexturesStartId = 1;
384 static const GLuint kQueriesStartId = 1;
385 static const GLuint kVertexArraysStartId = 1;
386 static const GLuint kValuebuffersStartId = 1;
388 typedef MockTransferBuffer::ExpectedMemoryInfo ExpectedMemoryInfo;
390 class TestContext {
391 public:
392 TestContext() : commands_(NULL), token_(0) {}
394 bool Initialize(ShareGroup* share_group,
395 bool bind_generates_resource_client,
396 bool bind_generates_resource_service,
397 bool lose_context_when_out_of_memory) {
398 command_buffer_.reset(new StrictMock<MockClientCommandBuffer>());
399 if (!command_buffer_->Initialize())
400 return false;
402 transfer_buffer_.reset(
403 new MockTransferBuffer(command_buffer_.get(),
404 kTransferBufferSize,
405 GLES2Implementation::kStartingOffset,
406 GLES2Implementation::kAlignment));
408 helper_.reset(new GLES2CmdHelper(command_buffer()));
409 helper_->Initialize(kCommandBufferSizeBytes);
411 gpu_control_.reset(new StrictMock<MockClientGpuControl>());
412 Capabilities capabilities;
413 capabilities.VisitPrecisions(
414 [](GLenum shader, GLenum type,
415 Capabilities::ShaderPrecision* precision) {
416 precision->min_range = 3;
417 precision->max_range = 5;
418 precision->precision = 7;
420 capabilities.max_combined_texture_image_units =
421 kMaxCombinedTextureImageUnits;
422 capabilities.max_cube_map_texture_size = kMaxCubeMapTextureSize;
423 capabilities.max_fragment_uniform_vectors = kMaxFragmentUniformVectors;
424 capabilities.max_renderbuffer_size = kMaxRenderbufferSize;
425 capabilities.max_texture_image_units = kMaxTextureImageUnits;
426 capabilities.max_texture_size = kMaxTextureSize;
427 capabilities.max_varying_vectors = kMaxVaryingVectors;
428 capabilities.max_vertex_attribs = kMaxVertexAttribs;
429 capabilities.max_vertex_texture_image_units = kMaxVertexTextureImageUnits;
430 capabilities.max_vertex_uniform_vectors = kMaxVertexUniformVectors;
431 capabilities.num_compressed_texture_formats =
432 kNumCompressedTextureFormats;
433 capabilities.num_shader_binary_formats = kNumShaderBinaryFormats;
434 capabilities.bind_generates_resource_chromium =
435 bind_generates_resource_service ? 1 : 0;
436 EXPECT_CALL(*gpu_control_, GetCapabilities())
437 .WillOnce(testing::Return(capabilities));
440 InSequence sequence;
442 const bool support_client_side_arrays = true;
443 gl_.reset(new GLES2Implementation(helper_.get(),
444 share_group,
445 transfer_buffer_.get(),
446 bind_generates_resource_client,
447 lose_context_when_out_of_memory,
448 support_client_side_arrays,
449 gpu_control_.get()));
451 if (!gl_->Initialize(kTransferBufferSize,
452 kTransferBufferSize,
453 kTransferBufferSize,
454 GLES2Implementation::kNoLimit))
455 return false;
458 helper_->CommandBufferHelper::Finish();
459 ::testing::Mock::VerifyAndClearExpectations(gl_.get());
461 scoped_refptr<Buffer> ring_buffer = helper_->get_ring_buffer();
462 commands_ = static_cast<CommandBufferEntry*>(ring_buffer->memory()) +
463 command_buffer()->GetPutOffset();
464 ClearCommands();
465 EXPECT_TRUE(transfer_buffer_->InSync());
467 ::testing::Mock::VerifyAndClearExpectations(command_buffer());
468 return true;
471 void TearDown() {
472 Mock::VerifyAndClear(gl_.get());
473 EXPECT_CALL(*command_buffer(), OnFlush()).Times(AnyNumber());
474 // For command buffer.
475 EXPECT_CALL(*command_buffer(), DestroyTransferBuffer(_))
476 .Times(AtLeast(1));
477 gl_.reset();
480 MockClientCommandBuffer* command_buffer() const {
481 return command_buffer_.get();
484 int GetNextToken() { return ++token_; }
486 void ClearCommands() {
487 scoped_refptr<Buffer> ring_buffer = helper_->get_ring_buffer();
488 memset(ring_buffer->memory(), kInitialValue, ring_buffer->size());
491 scoped_ptr<MockClientCommandBuffer> command_buffer_;
492 scoped_ptr<MockClientGpuControl> gpu_control_;
493 scoped_ptr<GLES2CmdHelper> helper_;
494 scoped_ptr<MockTransferBuffer> transfer_buffer_;
495 scoped_ptr<GLES2Implementation> gl_;
496 CommandBufferEntry* commands_;
497 int token_;
500 GLES2ImplementationTest() : commands_(NULL) {}
502 void SetUp() override;
503 void TearDown() override;
505 bool NoCommandsWritten() {
506 scoped_refptr<Buffer> ring_buffer = helper_->get_ring_buffer();
507 const uint8* cmds = reinterpret_cast<const uint8*>(ring_buffer->memory());
508 const uint8* end = cmds + ring_buffer->size();
509 for (; cmds < end; ++cmds) {
510 if (*cmds != kInitialValue) {
511 return false;
514 return true;
517 QueryTracker::Query* GetQuery(GLuint id) {
518 return gl_->query_tracker_->GetQuery(id);
521 struct ContextInitOptions {
522 ContextInitOptions()
523 : bind_generates_resource_client(true),
524 bind_generates_resource_service(true),
525 lose_context_when_out_of_memory(false) {}
527 bool bind_generates_resource_client;
528 bool bind_generates_resource_service;
529 bool lose_context_when_out_of_memory;
532 bool Initialize(const ContextInitOptions& init_options) {
533 bool success = true;
534 share_group_ = new ShareGroup(init_options.bind_generates_resource_client);
536 for (int i = 0; i < kNumTestContexts; i++) {
537 if (!test_contexts_[i].Initialize(
538 share_group_.get(),
539 init_options.bind_generates_resource_client,
540 init_options.bind_generates_resource_service,
541 init_options.lose_context_when_out_of_memory))
542 success = false;
545 // Default to test context 0.
546 gpu_control_ = test_contexts_[0].gpu_control_.get();
547 helper_ = test_contexts_[0].helper_.get();
548 transfer_buffer_ = test_contexts_[0].transfer_buffer_.get();
549 gl_ = test_contexts_[0].gl_.get();
550 commands_ = test_contexts_[0].commands_;
551 return success;
554 MockClientCommandBuffer* command_buffer() const {
555 return test_contexts_[0].command_buffer_.get();
558 int GetNextToken() { return test_contexts_[0].GetNextToken(); }
560 const void* GetPut() {
561 return helper_->GetSpace(0);
564 void ClearCommands() {
565 scoped_refptr<Buffer> ring_buffer = helper_->get_ring_buffer();
566 memset(ring_buffer->memory(), kInitialValue, ring_buffer->size());
569 size_t MaxTransferBufferSize() {
570 return transfer_buffer_->MaxTransferBufferSize();
573 ExpectedMemoryInfo GetExpectedMemory(size_t size) {
574 return transfer_buffer_->GetExpectedMemory(size);
577 ExpectedMemoryInfo GetExpectedResultMemory(size_t size) {
578 return transfer_buffer_->GetExpectedResultMemory(size);
581 // Sets the ProgramInfoManager. The manager will be owned
582 // by the ShareGroup.
583 void SetProgramInfoManager(ProgramInfoManager* manager) {
584 gl_->share_group()->set_program_info_manager(manager);
587 int CheckError() {
588 ExpectedMemoryInfo result =
589 GetExpectedResultMemory(sizeof(cmds::GetError::Result));
590 EXPECT_CALL(*command_buffer(), OnFlush())
591 .WillOnce(SetMemory(result.ptr, GLuint(GL_NO_ERROR)))
592 .RetiresOnSaturation();
593 return gl_->GetError();
596 const std::string& GetLastError() {
597 return gl_->GetLastError();
600 bool GetBucketContents(uint32 bucket_id, std::vector<int8>* data) {
601 return gl_->GetBucketContents(bucket_id, data);
604 TestContext test_contexts_[kNumTestContexts];
606 scoped_refptr<ShareGroup> share_group_;
607 MockClientGpuControl* gpu_control_;
608 GLES2CmdHelper* helper_;
609 MockTransferBuffer* transfer_buffer_;
610 GLES2Implementation* gl_;
611 CommandBufferEntry* commands_;
614 void GLES2ImplementationTest::SetUp() {
615 ContextInitOptions init_options;
616 ASSERT_TRUE(Initialize(init_options));
619 void GLES2ImplementationTest::TearDown() {
620 for (int i = 0; i < kNumTestContexts; i++)
621 test_contexts_[i].TearDown();
624 class GLES2ImplementationManualInitTest : public GLES2ImplementationTest {
625 protected:
626 void SetUp() override {}
629 class GLES2ImplementationStrictSharedTest : public GLES2ImplementationTest {
630 protected:
631 void SetUp() override;
633 template <class ResApi>
634 void FlushGenerationTest() {
635 GLuint id1, id2, id3;
637 // Generate valid id.
638 ResApi::Gen(gl_, 1, &id1);
639 EXPECT_NE(id1, 0u);
641 // Delete id1 and generate id2. id1 should not be reused.
642 ResApi::Delete(gl_, 1, &id1);
643 ResApi::Gen(gl_, 1, &id2);
644 EXPECT_NE(id2, 0u);
645 EXPECT_NE(id2, id1);
647 // Expect id1 reuse after Flush.
648 gl_->Flush();
649 ResApi::Gen(gl_, 1, &id3);
650 EXPECT_EQ(id3, id1);
653 // Ids should not be reused unless the |Deleting| context does a Flush()
654 // AND triggers a lazy release after that.
655 template <class ResApi>
656 void CrossContextGenerationTest() {
657 GLES2Implementation* gl1 = test_contexts_[0].gl_.get();
658 GLES2Implementation* gl2 = test_contexts_[1].gl_.get();
659 GLuint id1, id2, id3;
661 // Delete, no flush on context 1. No reuse.
662 ResApi::Gen(gl1, 1, &id1);
663 ResApi::Delete(gl1, 1, &id1);
664 ResApi::Gen(gl1, 1, &id2);
665 EXPECT_NE(id1, id2);
667 // Flush context 2. Still no reuse.
668 gl2->Flush();
669 ResApi::Gen(gl2, 1, &id3);
670 EXPECT_NE(id1, id3);
671 EXPECT_NE(id2, id3);
673 // Flush on context 1, but no lazy release. Still no reuse.
674 gl1->Flush();
675 ResApi::Gen(gl2, 1, &id3);
676 EXPECT_NE(id1, id3);
678 // Lazy release triggered by another Delete. Should reuse id1.
679 ResApi::Delete(gl1, 1, &id2);
680 ResApi::Gen(gl2, 1, &id3);
681 EXPECT_EQ(id1, id3);
684 // Same as CrossContextGenerationTest(), but triggers an Auto Flush on
685 // the Delete(). Tests an edge case regression.
686 template <class ResApi>
687 void CrossContextGenerationAutoFlushTest() {
688 GLES2Implementation* gl1 = test_contexts_[0].gl_.get();
689 GLES2Implementation* gl2 = test_contexts_[1].gl_.get();
690 GLuint id1, id2, id3;
692 // Delete, no flush on context 1. No reuse.
693 // By half filling the buffer, an internal flush is forced on the Delete().
694 ResApi::Gen(gl1, 1, &id1);
695 gl1->helper()->Noop(kNumCommandEntries / 2);
696 ResApi::Delete(gl1, 1, &id1);
697 ResApi::Gen(gl1, 1, &id2);
698 EXPECT_NE(id1, id2);
700 // Flush context 2. Still no reuse.
701 gl2->Flush();
702 ResApi::Gen(gl2, 1, &id3);
703 EXPECT_NE(id1, id3);
704 EXPECT_NE(id2, id3);
706 // Flush on context 1, but no lazy release. Still no reuse.
707 gl1->Flush();
708 ResApi::Gen(gl2, 1, &id3);
709 EXPECT_NE(id1, id3);
711 // Lazy release triggered by another Delete. Should reuse id1.
712 ResApi::Delete(gl1, 1, &id2);
713 ResApi::Gen(gl2, 1, &id3);
714 EXPECT_EQ(id1, id3);
718 void GLES2ImplementationStrictSharedTest::SetUp() {
719 ContextInitOptions init_options;
720 init_options.bind_generates_resource_client = false;
721 init_options.bind_generates_resource_service = false;
722 ASSERT_TRUE(Initialize(init_options));
725 // GCC requires these declarations, but MSVC requires they not be present
726 #ifndef _MSC_VER
727 const uint8 GLES2ImplementationTest::kInitialValue;
728 const int32 GLES2ImplementationTest::kNumCommandEntries;
729 const int32 GLES2ImplementationTest::kCommandBufferSizeBytes;
730 const size_t GLES2ImplementationTest::kTransferBufferSize;
731 const GLint GLES2ImplementationTest::kMaxCombinedTextureImageUnits;
732 const GLint GLES2ImplementationTest::kMaxCubeMapTextureSize;
733 const GLint GLES2ImplementationTest::kMaxFragmentUniformVectors;
734 const GLint GLES2ImplementationTest::kMaxRenderbufferSize;
735 const GLint GLES2ImplementationTest::kMaxTextureImageUnits;
736 const GLint GLES2ImplementationTest::kMaxTextureSize;
737 const GLint GLES2ImplementationTest::kMaxVaryingVectors;
738 const GLint GLES2ImplementationTest::kMaxVertexAttribs;
739 const GLint GLES2ImplementationTest::kMaxVertexTextureImageUnits;
740 const GLint GLES2ImplementationTest::kMaxVertexUniformVectors;
741 const GLint GLES2ImplementationTest::kNumCompressedTextureFormats;
742 const GLint GLES2ImplementationTest::kNumShaderBinaryFormats;
743 const GLuint GLES2ImplementationTest::kStartId;
744 const GLuint GLES2ImplementationTest::kBuffersStartId;
745 const GLuint GLES2ImplementationTest::kFramebuffersStartId;
746 const GLuint GLES2ImplementationTest::kProgramsAndShadersStartId;
747 const GLuint GLES2ImplementationTest::kRenderbuffersStartId;
748 const GLuint GLES2ImplementationTest::kTexturesStartId;
749 const GLuint GLES2ImplementationTest::kQueriesStartId;
750 const GLuint GLES2ImplementationTest::kVertexArraysStartId;
751 const GLuint GLES2ImplementationTest::kValuebuffersStartId;
752 #endif
754 TEST_F(GLES2ImplementationTest, Basic) {
755 EXPECT_TRUE(gl_->share_group() != NULL);
758 TEST_F(GLES2ImplementationTest, GetBucketContents) {
759 const uint32 kBucketId = GLES2Implementation::kResultBucketId;
760 const uint32 kTestSize = MaxTransferBufferSize() + 32;
762 scoped_ptr<uint8[]> buf(new uint8 [kTestSize]);
763 uint8* expected_data = buf.get();
764 for (uint32 ii = 0; ii < kTestSize; ++ii) {
765 expected_data[ii] = ii * 3;
768 struct Cmds {
769 cmd::GetBucketStart get_bucket_start;
770 cmd::SetToken set_token1;
771 cmd::GetBucketData get_bucket_data;
772 cmd::SetToken set_token2;
773 cmd::SetBucketSize set_bucket_size2;
776 ExpectedMemoryInfo mem1 = GetExpectedMemory(MaxTransferBufferSize());
777 ExpectedMemoryInfo result1 = GetExpectedResultMemory(sizeof(uint32));
778 ExpectedMemoryInfo mem2 = GetExpectedMemory(
779 kTestSize - MaxTransferBufferSize());
781 Cmds expected;
782 expected.get_bucket_start.Init(
783 kBucketId, result1.id, result1.offset,
784 MaxTransferBufferSize(), mem1.id, mem1.offset);
785 expected.set_token1.Init(GetNextToken());
786 expected.get_bucket_data.Init(
787 kBucketId, MaxTransferBufferSize(),
788 kTestSize - MaxTransferBufferSize(), mem2.id, mem2.offset);
789 expected.set_bucket_size2.Init(kBucketId, 0);
790 expected.set_token2.Init(GetNextToken());
792 EXPECT_CALL(*command_buffer(), OnFlush())
793 .WillOnce(DoAll(
794 SetMemory(result1.ptr, kTestSize),
795 SetMemoryFromArray(
796 mem1.ptr, expected_data, MaxTransferBufferSize())))
797 .WillOnce(SetMemoryFromArray(
798 mem2.ptr, expected_data + MaxTransferBufferSize(),
799 kTestSize - MaxTransferBufferSize()))
800 .RetiresOnSaturation();
802 std::vector<int8> data;
803 GetBucketContents(kBucketId, &data);
804 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
805 ASSERT_EQ(kTestSize, data.size());
806 EXPECT_EQ(0, memcmp(expected_data, &data[0], data.size()));
809 TEST_F(GLES2ImplementationTest, GetShaderPrecisionFormat) {
810 struct Cmds {
811 cmds::GetShaderPrecisionFormat cmd;
813 typedef cmds::GetShaderPrecisionFormat::Result Result;
814 const unsigned kDummyType1 = 3;
815 const unsigned kDummyType2 = 4;
817 // The first call for dummy type 1 should trigger a command buffer request.
818 GLint range1[2] = {0, 0};
819 GLint precision1 = 0;
820 Cmds expected1;
821 ExpectedMemoryInfo client_result1 = GetExpectedResultMemory(4);
822 expected1.cmd.Init(GL_FRAGMENT_SHADER, kDummyType1, client_result1.id,
823 client_result1.offset);
824 Result server_result1 = {true, 14, 14, 10};
825 EXPECT_CALL(*command_buffer(), OnFlush())
826 .WillOnce(SetMemory(client_result1.ptr, server_result1))
827 .RetiresOnSaturation();
828 gl_->GetShaderPrecisionFormat(GL_FRAGMENT_SHADER, kDummyType1, range1,
829 &precision1);
830 const void* commands2 = GetPut();
831 EXPECT_NE(commands_, commands2);
832 EXPECT_EQ(0, memcmp(&expected1, commands_, sizeof(expected1)));
833 EXPECT_EQ(range1[0], 14);
834 EXPECT_EQ(range1[1], 14);
835 EXPECT_EQ(precision1, 10);
837 // The second call for dummy type 1 should use the cached value and avoid
838 // triggering a command buffer request, so we do not expect a call to
839 // OnFlush() here. We do expect the results to be correct though.
840 GLint range2[2] = {0, 0};
841 GLint precision2 = 0;
842 gl_->GetShaderPrecisionFormat(GL_FRAGMENT_SHADER, kDummyType1, range2,
843 &precision2);
844 const void* commands3 = GetPut();
845 EXPECT_EQ(commands2, commands3);
846 EXPECT_EQ(range2[0], 14);
847 EXPECT_EQ(range2[1], 14);
848 EXPECT_EQ(precision2, 10);
850 // If we then make a request for dummy type 2, we should get another command
851 // buffer request since it hasn't been cached yet.
852 GLint range3[2] = {0, 0};
853 GLint precision3 = 0;
854 Cmds expected3;
855 ExpectedMemoryInfo result3 = GetExpectedResultMemory(4);
856 expected3.cmd.Init(GL_FRAGMENT_SHADER, kDummyType2, result3.id,
857 result3.offset);
858 Result result3_source = {true, 62, 62, 16};
859 EXPECT_CALL(*command_buffer(), OnFlush())
860 .WillOnce(SetMemory(result3.ptr, result3_source))
861 .RetiresOnSaturation();
862 gl_->GetShaderPrecisionFormat(GL_FRAGMENT_SHADER, kDummyType2, range3,
863 &precision3);
864 const void* commands4 = GetPut();
865 EXPECT_NE(commands3, commands4);
866 EXPECT_EQ(0, memcmp(&expected3, commands3, sizeof(expected3)));
867 EXPECT_EQ(range3[0], 62);
868 EXPECT_EQ(range3[1], 62);
869 EXPECT_EQ(precision3, 16);
871 // Any call for predefined types should use the cached value from the
872 // Capabilities and avoid triggering a command buffer request, so we do not
873 // expect a call to OnFlush() here. We do expect the results to be correct
874 // though.
875 GLint range4[2] = {0, 0};
876 GLint precision4 = 0;
877 gl_->GetShaderPrecisionFormat(GL_FRAGMENT_SHADER, GL_MEDIUM_FLOAT, range4,
878 &precision4);
879 const void* commands5 = GetPut();
880 EXPECT_EQ(commands4, commands5);
881 EXPECT_EQ(range4[0], 3);
882 EXPECT_EQ(range4[1], 5);
883 EXPECT_EQ(precision4, 7);
886 TEST_F(GLES2ImplementationTest, ShaderSource) {
887 const uint32 kBucketId = GLES2Implementation::kResultBucketId;
888 const GLuint kShaderId = 456;
889 const char* kString1 = "foobar";
890 const char* kString2 = "barfoo";
891 const size_t kString1Size = strlen(kString1);
892 const size_t kString2Size = strlen(kString2);
893 const size_t kString3Size = 1; // Want the NULL;
894 const size_t kSourceSize = kString1Size + kString2Size + kString3Size;
895 const size_t kPaddedString1Size =
896 transfer_buffer_->RoundToAlignment(kString1Size);
897 const size_t kPaddedString2Size =
898 transfer_buffer_->RoundToAlignment(kString2Size);
899 const size_t kPaddedString3Size =
900 transfer_buffer_->RoundToAlignment(kString3Size);
901 struct Cmds {
902 cmd::SetBucketSize set_bucket_size;
903 cmd::SetBucketData set_bucket_data1;
904 cmd::SetToken set_token1;
905 cmd::SetBucketData set_bucket_data2;
906 cmd::SetToken set_token2;
907 cmd::SetBucketData set_bucket_data3;
908 cmd::SetToken set_token3;
909 cmds::ShaderSourceBucket shader_source_bucket;
910 cmd::SetBucketSize clear_bucket_size;
913 ExpectedMemoryInfo mem1 = GetExpectedMemory(kPaddedString1Size);
914 ExpectedMemoryInfo mem2 = GetExpectedMemory(kPaddedString2Size);
915 ExpectedMemoryInfo mem3 = GetExpectedMemory(kPaddedString3Size);
917 Cmds expected;
918 expected.set_bucket_size.Init(kBucketId, kSourceSize);
919 expected.set_bucket_data1.Init(
920 kBucketId, 0, kString1Size, mem1.id, mem1.offset);
921 expected.set_token1.Init(GetNextToken());
922 expected.set_bucket_data2.Init(
923 kBucketId, kString1Size, kString2Size, mem2.id, mem2.offset);
924 expected.set_token2.Init(GetNextToken());
925 expected.set_bucket_data3.Init(
926 kBucketId, kString1Size + kString2Size,
927 kString3Size, mem3.id, mem3.offset);
928 expected.set_token3.Init(GetNextToken());
929 expected.shader_source_bucket.Init(kShaderId, kBucketId);
930 expected.clear_bucket_size.Init(kBucketId, 0);
931 const char* strings[] = {
932 kString1,
933 kString2,
935 gl_->ShaderSource(kShaderId, 2, strings, NULL);
936 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
939 TEST_F(GLES2ImplementationTest, GetShaderSource) {
940 const uint32 kBucketId = GLES2Implementation::kResultBucketId;
941 const GLuint kShaderId = 456;
942 const Str7 kString = {"foobar"};
943 const char kBad = 0x12;
944 struct Cmds {
945 cmd::SetBucketSize set_bucket_size1;
946 cmds::GetShaderSource get_shader_source;
947 cmd::GetBucketStart get_bucket_start;
948 cmd::SetToken set_token1;
949 cmd::SetBucketSize set_bucket_size2;
952 ExpectedMemoryInfo mem1 = GetExpectedMemory(MaxTransferBufferSize());
953 ExpectedMemoryInfo result1 = GetExpectedResultMemory(sizeof(uint32));
955 Cmds expected;
956 expected.set_bucket_size1.Init(kBucketId, 0);
957 expected.get_shader_source.Init(kShaderId, kBucketId);
958 expected.get_bucket_start.Init(
959 kBucketId, result1.id, result1.offset,
960 MaxTransferBufferSize(), mem1.id, mem1.offset);
961 expected.set_token1.Init(GetNextToken());
962 expected.set_bucket_size2.Init(kBucketId, 0);
963 char buf[sizeof(kString) + 1];
964 memset(buf, kBad, sizeof(buf));
966 EXPECT_CALL(*command_buffer(), OnFlush())
967 .WillOnce(DoAll(SetMemory(result1.ptr, uint32(sizeof(kString))),
968 SetMemory(mem1.ptr, kString)))
969 .RetiresOnSaturation();
971 GLsizei length = 0;
972 gl_->GetShaderSource(kShaderId, sizeof(buf), &length, buf);
973 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
974 EXPECT_EQ(sizeof(kString) - 1, static_cast<size_t>(length));
975 EXPECT_STREQ(kString.str, buf);
976 EXPECT_EQ(buf[sizeof(kString)], kBad);
979 #if defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS)
981 TEST_F(GLES2ImplementationTest, DrawArraysClientSideBuffers) {
982 static const float verts[][4] = {
983 { 12.0f, 23.0f, 34.0f, 45.0f, },
984 { 56.0f, 67.0f, 78.0f, 89.0f, },
985 { 13.0f, 24.0f, 35.0f, 46.0f, },
987 struct Cmds {
988 cmds::EnableVertexAttribArray enable1;
989 cmds::EnableVertexAttribArray enable2;
990 cmds::BindBuffer bind_to_emu;
991 cmds::BufferData set_size;
992 cmds::BufferSubData copy_data1;
993 cmd::SetToken set_token1;
994 cmds::VertexAttribPointer set_pointer1;
995 cmds::BufferSubData copy_data2;
996 cmd::SetToken set_token2;
997 cmds::VertexAttribPointer set_pointer2;
998 cmds::DrawArrays draw;
999 cmds::BindBuffer restore;
1001 const GLuint kEmuBufferId = GLES2Implementation::kClientSideArrayId;
1002 const GLuint kAttribIndex1 = 1;
1003 const GLuint kAttribIndex2 = 3;
1004 const GLint kNumComponents1 = 3;
1005 const GLint kNumComponents2 = 2;
1006 const GLsizei kClientStride = sizeof(verts[0]);
1007 const GLint kFirst = 1;
1008 const GLsizei kCount = 2;
1009 const GLsizei kSize1 =
1010 arraysize(verts) * kNumComponents1 * sizeof(verts[0][0]);
1011 const GLsizei kSize2 =
1012 arraysize(verts) * kNumComponents2 * sizeof(verts[0][0]);
1013 const GLsizei kEmuOffset1 = 0;
1014 const GLsizei kEmuOffset2 = kSize1;
1015 const GLsizei kTotalSize = kSize1 + kSize2;
1017 ExpectedMemoryInfo mem1 = GetExpectedMemory(kSize1);
1018 ExpectedMemoryInfo mem2 = GetExpectedMemory(kSize2);
1020 Cmds expected;
1021 expected.enable1.Init(kAttribIndex1);
1022 expected.enable2.Init(kAttribIndex2);
1023 expected.bind_to_emu.Init(GL_ARRAY_BUFFER, kEmuBufferId);
1024 expected.set_size.Init(GL_ARRAY_BUFFER, kTotalSize, 0, 0, GL_DYNAMIC_DRAW);
1025 expected.copy_data1.Init(
1026 GL_ARRAY_BUFFER, kEmuOffset1, kSize1, mem1.id, mem1.offset);
1027 expected.set_token1.Init(GetNextToken());
1028 expected.set_pointer1.Init(
1029 kAttribIndex1, kNumComponents1, GL_FLOAT, GL_FALSE, 0, kEmuOffset1);
1030 expected.copy_data2.Init(
1031 GL_ARRAY_BUFFER, kEmuOffset2, kSize2, mem2.id, mem2.offset);
1032 expected.set_token2.Init(GetNextToken());
1033 expected.set_pointer2.Init(
1034 kAttribIndex2, kNumComponents2, GL_FLOAT, GL_FALSE, 0, kEmuOffset2);
1035 expected.draw.Init(GL_POINTS, kFirst, kCount);
1036 expected.restore.Init(GL_ARRAY_BUFFER, 0);
1037 gl_->EnableVertexAttribArray(kAttribIndex1);
1038 gl_->EnableVertexAttribArray(kAttribIndex2);
1039 gl_->VertexAttribPointer(
1040 kAttribIndex1, kNumComponents1, GL_FLOAT, GL_FALSE, kClientStride, verts);
1041 gl_->VertexAttribPointer(
1042 kAttribIndex2, kNumComponents2, GL_FLOAT, GL_FALSE, kClientStride, verts);
1043 gl_->DrawArrays(GL_POINTS, kFirst, kCount);
1044 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
1047 TEST_F(GLES2ImplementationTest, DrawArraysInstancedANGLEClientSideBuffers) {
1048 static const float verts[][4] = {
1049 { 12.0f, 23.0f, 34.0f, 45.0f, },
1050 { 56.0f, 67.0f, 78.0f, 89.0f, },
1051 { 13.0f, 24.0f, 35.0f, 46.0f, },
1053 struct Cmds {
1054 cmds::EnableVertexAttribArray enable1;
1055 cmds::EnableVertexAttribArray enable2;
1056 cmds::VertexAttribDivisorANGLE divisor;
1057 cmds::BindBuffer bind_to_emu;
1058 cmds::BufferData set_size;
1059 cmds::BufferSubData copy_data1;
1060 cmd::SetToken set_token1;
1061 cmds::VertexAttribPointer set_pointer1;
1062 cmds::BufferSubData copy_data2;
1063 cmd::SetToken set_token2;
1064 cmds::VertexAttribPointer set_pointer2;
1065 cmds::DrawArraysInstancedANGLE draw;
1066 cmds::BindBuffer restore;
1068 const GLuint kEmuBufferId = GLES2Implementation::kClientSideArrayId;
1069 const GLuint kAttribIndex1 = 1;
1070 const GLuint kAttribIndex2 = 3;
1071 const GLint kNumComponents1 = 3;
1072 const GLint kNumComponents2 = 2;
1073 const GLsizei kClientStride = sizeof(verts[0]);
1074 const GLint kFirst = 1;
1075 const GLsizei kCount = 2;
1076 const GLuint kDivisor = 1;
1077 const GLsizei kSize1 =
1078 arraysize(verts) * kNumComponents1 * sizeof(verts[0][0]);
1079 const GLsizei kSize2 =
1080 1 * kNumComponents2 * sizeof(verts[0][0]);
1081 const GLsizei kEmuOffset1 = 0;
1082 const GLsizei kEmuOffset2 = kSize1;
1083 const GLsizei kTotalSize = kSize1 + kSize2;
1085 ExpectedMemoryInfo mem1 = GetExpectedMemory(kSize1);
1086 ExpectedMemoryInfo mem2 = GetExpectedMemory(kSize2);
1088 Cmds expected;
1089 expected.enable1.Init(kAttribIndex1);
1090 expected.enable2.Init(kAttribIndex2);
1091 expected.divisor.Init(kAttribIndex2, kDivisor);
1092 expected.bind_to_emu.Init(GL_ARRAY_BUFFER, kEmuBufferId);
1093 expected.set_size.Init(GL_ARRAY_BUFFER, kTotalSize, 0, 0, GL_DYNAMIC_DRAW);
1094 expected.copy_data1.Init(
1095 GL_ARRAY_BUFFER, kEmuOffset1, kSize1, mem1.id, mem1.offset);
1096 expected.set_token1.Init(GetNextToken());
1097 expected.set_pointer1.Init(
1098 kAttribIndex1, kNumComponents1, GL_FLOAT, GL_FALSE, 0, kEmuOffset1);
1099 expected.copy_data2.Init(
1100 GL_ARRAY_BUFFER, kEmuOffset2, kSize2, mem2.id, mem2.offset);
1101 expected.set_token2.Init(GetNextToken());
1102 expected.set_pointer2.Init(
1103 kAttribIndex2, kNumComponents2, GL_FLOAT, GL_FALSE, 0, kEmuOffset2);
1104 expected.draw.Init(GL_POINTS, kFirst, kCount, 1);
1105 expected.restore.Init(GL_ARRAY_BUFFER, 0);
1106 gl_->EnableVertexAttribArray(kAttribIndex1);
1107 gl_->EnableVertexAttribArray(kAttribIndex2);
1108 gl_->VertexAttribPointer(
1109 kAttribIndex1, kNumComponents1, GL_FLOAT, GL_FALSE, kClientStride, verts);
1110 gl_->VertexAttribPointer(
1111 kAttribIndex2, kNumComponents2, GL_FLOAT, GL_FALSE, kClientStride, verts);
1112 gl_->VertexAttribDivisorANGLE(kAttribIndex2, kDivisor);
1113 gl_->DrawArraysInstancedANGLE(GL_POINTS, kFirst, kCount, 1);
1114 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
1117 TEST_F(GLES2ImplementationTest, DrawElementsClientSideBuffers) {
1118 static const float verts[][4] = {
1119 { 12.0f, 23.0f, 34.0f, 45.0f, },
1120 { 56.0f, 67.0f, 78.0f, 89.0f, },
1121 { 13.0f, 24.0f, 35.0f, 46.0f, },
1123 static const uint16 indices[] = {
1124 1, 2,
1126 struct Cmds {
1127 cmds::EnableVertexAttribArray enable1;
1128 cmds::EnableVertexAttribArray enable2;
1129 cmds::BindBuffer bind_to_index_emu;
1130 cmds::BufferData set_index_size;
1131 cmds::BufferSubData copy_data0;
1132 cmd::SetToken set_token0;
1133 cmds::BindBuffer bind_to_emu;
1134 cmds::BufferData set_size;
1135 cmds::BufferSubData copy_data1;
1136 cmd::SetToken set_token1;
1137 cmds::VertexAttribPointer set_pointer1;
1138 cmds::BufferSubData copy_data2;
1139 cmd::SetToken set_token2;
1140 cmds::VertexAttribPointer set_pointer2;
1141 cmds::DrawElements draw;
1142 cmds::BindBuffer restore;
1143 cmds::BindBuffer restore_element;
1145 const GLsizei kIndexSize = sizeof(indices);
1146 const GLuint kEmuBufferId = GLES2Implementation::kClientSideArrayId;
1147 const GLuint kEmuIndexBufferId =
1148 GLES2Implementation::kClientSideElementArrayId;
1149 const GLuint kAttribIndex1 = 1;
1150 const GLuint kAttribIndex2 = 3;
1151 const GLint kNumComponents1 = 3;
1152 const GLint kNumComponents2 = 2;
1153 const GLsizei kClientStride = sizeof(verts[0]);
1154 const GLsizei kCount = 2;
1155 const GLsizei kSize1 =
1156 arraysize(verts) * kNumComponents1 * sizeof(verts[0][0]);
1157 const GLsizei kSize2 =
1158 arraysize(verts) * kNumComponents2 * sizeof(verts[0][0]);
1159 const GLsizei kEmuOffset1 = 0;
1160 const GLsizei kEmuOffset2 = kSize1;
1161 const GLsizei kTotalSize = kSize1 + kSize2;
1163 ExpectedMemoryInfo mem1 = GetExpectedMemory(kIndexSize);
1164 ExpectedMemoryInfo mem2 = GetExpectedMemory(kSize1);
1165 ExpectedMemoryInfo mem3 = GetExpectedMemory(kSize2);
1167 Cmds expected;
1168 expected.enable1.Init(kAttribIndex1);
1169 expected.enable2.Init(kAttribIndex2);
1170 expected.bind_to_index_emu.Init(GL_ELEMENT_ARRAY_BUFFER, kEmuIndexBufferId);
1171 expected.set_index_size.Init(
1172 GL_ELEMENT_ARRAY_BUFFER, kIndexSize, 0, 0, GL_DYNAMIC_DRAW);
1173 expected.copy_data0.Init(
1174 GL_ELEMENT_ARRAY_BUFFER, 0, kIndexSize, mem1.id, mem1.offset);
1175 expected.set_token0.Init(GetNextToken());
1176 expected.bind_to_emu.Init(GL_ARRAY_BUFFER, kEmuBufferId);
1177 expected.set_size.Init(GL_ARRAY_BUFFER, kTotalSize, 0, 0, GL_DYNAMIC_DRAW);
1178 expected.copy_data1.Init(
1179 GL_ARRAY_BUFFER, kEmuOffset1, kSize1, mem2.id, mem2.offset);
1180 expected.set_token1.Init(GetNextToken());
1181 expected.set_pointer1.Init(
1182 kAttribIndex1, kNumComponents1, GL_FLOAT, GL_FALSE, 0, kEmuOffset1);
1183 expected.copy_data2.Init(
1184 GL_ARRAY_BUFFER, kEmuOffset2, kSize2, mem3.id, mem3.offset);
1185 expected.set_token2.Init(GetNextToken());
1186 expected.set_pointer2.Init(kAttribIndex2, kNumComponents2,
1187 GL_FLOAT, GL_FALSE, 0, kEmuOffset2);
1188 expected.draw.Init(GL_POINTS, kCount, GL_UNSIGNED_SHORT, 0);
1189 expected.restore.Init(GL_ARRAY_BUFFER, 0);
1190 expected.restore_element.Init(GL_ELEMENT_ARRAY_BUFFER, 0);
1191 gl_->EnableVertexAttribArray(kAttribIndex1);
1192 gl_->EnableVertexAttribArray(kAttribIndex2);
1193 gl_->VertexAttribPointer(kAttribIndex1, kNumComponents1,
1194 GL_FLOAT, GL_FALSE, kClientStride, verts);
1195 gl_->VertexAttribPointer(kAttribIndex2, kNumComponents2,
1196 GL_FLOAT, GL_FALSE, kClientStride, verts);
1197 gl_->DrawElements(GL_POINTS, kCount, GL_UNSIGNED_SHORT, indices);
1198 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
1201 TEST_F(GLES2ImplementationTest, DrawElementsClientSideBuffersIndexUint) {
1202 static const float verts[][4] = {
1203 { 12.0f, 23.0f, 34.0f, 45.0f, },
1204 { 56.0f, 67.0f, 78.0f, 89.0f, },
1205 { 13.0f, 24.0f, 35.0f, 46.0f, },
1207 static const uint32 indices[] = {
1208 1, 2,
1210 struct Cmds {
1211 cmds::EnableVertexAttribArray enable1;
1212 cmds::EnableVertexAttribArray enable2;
1213 cmds::BindBuffer bind_to_index_emu;
1214 cmds::BufferData set_index_size;
1215 cmds::BufferSubData copy_data0;
1216 cmd::SetToken set_token0;
1217 cmds::BindBuffer bind_to_emu;
1218 cmds::BufferData set_size;
1219 cmds::BufferSubData copy_data1;
1220 cmd::SetToken set_token1;
1221 cmds::VertexAttribPointer set_pointer1;
1222 cmds::BufferSubData copy_data2;
1223 cmd::SetToken set_token2;
1224 cmds::VertexAttribPointer set_pointer2;
1225 cmds::DrawElements draw;
1226 cmds::BindBuffer restore;
1227 cmds::BindBuffer restore_element;
1229 const GLsizei kIndexSize = sizeof(indices);
1230 const GLuint kEmuBufferId = GLES2Implementation::kClientSideArrayId;
1231 const GLuint kEmuIndexBufferId =
1232 GLES2Implementation::kClientSideElementArrayId;
1233 const GLuint kAttribIndex1 = 1;
1234 const GLuint kAttribIndex2 = 3;
1235 const GLint kNumComponents1 = 3;
1236 const GLint kNumComponents2 = 2;
1237 const GLsizei kClientStride = sizeof(verts[0]);
1238 const GLsizei kCount = 2;
1239 const GLsizei kSize1 =
1240 arraysize(verts) * kNumComponents1 * sizeof(verts[0][0]);
1241 const GLsizei kSize2 =
1242 arraysize(verts) * kNumComponents2 * sizeof(verts[0][0]);
1243 const GLsizei kEmuOffset1 = 0;
1244 const GLsizei kEmuOffset2 = kSize1;
1245 const GLsizei kTotalSize = kSize1 + kSize2;
1247 ExpectedMemoryInfo mem1 = GetExpectedMemory(kIndexSize);
1248 ExpectedMemoryInfo mem2 = GetExpectedMemory(kSize1);
1249 ExpectedMemoryInfo mem3 = GetExpectedMemory(kSize2);
1251 Cmds expected;
1252 expected.enable1.Init(kAttribIndex1);
1253 expected.enable2.Init(kAttribIndex2);
1254 expected.bind_to_index_emu.Init(GL_ELEMENT_ARRAY_BUFFER, kEmuIndexBufferId);
1255 expected.set_index_size.Init(
1256 GL_ELEMENT_ARRAY_BUFFER, kIndexSize, 0, 0, GL_DYNAMIC_DRAW);
1257 expected.copy_data0.Init(
1258 GL_ELEMENT_ARRAY_BUFFER, 0, kIndexSize, mem1.id, mem1.offset);
1259 expected.set_token0.Init(GetNextToken());
1260 expected.bind_to_emu.Init(GL_ARRAY_BUFFER, kEmuBufferId);
1261 expected.set_size.Init(GL_ARRAY_BUFFER, kTotalSize, 0, 0, GL_DYNAMIC_DRAW);
1262 expected.copy_data1.Init(
1263 GL_ARRAY_BUFFER, kEmuOffset1, kSize1, mem2.id, mem2.offset);
1264 expected.set_token1.Init(GetNextToken());
1265 expected.set_pointer1.Init(
1266 kAttribIndex1, kNumComponents1, GL_FLOAT, GL_FALSE, 0, kEmuOffset1);
1267 expected.copy_data2.Init(
1268 GL_ARRAY_BUFFER, kEmuOffset2, kSize2, mem3.id, mem3.offset);
1269 expected.set_token2.Init(GetNextToken());
1270 expected.set_pointer2.Init(kAttribIndex2, kNumComponents2,
1271 GL_FLOAT, GL_FALSE, 0, kEmuOffset2);
1272 expected.draw.Init(GL_POINTS, kCount, GL_UNSIGNED_INT, 0);
1273 expected.restore.Init(GL_ARRAY_BUFFER, 0);
1274 expected.restore_element.Init(GL_ELEMENT_ARRAY_BUFFER, 0);
1275 gl_->EnableVertexAttribArray(kAttribIndex1);
1276 gl_->EnableVertexAttribArray(kAttribIndex2);
1277 gl_->VertexAttribPointer(kAttribIndex1, kNumComponents1,
1278 GL_FLOAT, GL_FALSE, kClientStride, verts);
1279 gl_->VertexAttribPointer(kAttribIndex2, kNumComponents2,
1280 GL_FLOAT, GL_FALSE, kClientStride, verts);
1281 gl_->DrawElements(GL_POINTS, kCount, GL_UNSIGNED_INT, indices);
1282 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
1285 TEST_F(GLES2ImplementationTest, DrawElementsClientSideBuffersInvalidIndexUint) {
1286 static const float verts[][4] = {
1287 { 12.0f, 23.0f, 34.0f, 45.0f, },
1288 { 56.0f, 67.0f, 78.0f, 89.0f, },
1289 { 13.0f, 24.0f, 35.0f, 46.0f, },
1291 static const uint32 indices[] = {
1292 1, 0x90000000
1295 const GLuint kAttribIndex1 = 1;
1296 const GLuint kAttribIndex2 = 3;
1297 const GLint kNumComponents1 = 3;
1298 const GLint kNumComponents2 = 2;
1299 const GLsizei kClientStride = sizeof(verts[0]);
1300 const GLsizei kCount = 2;
1302 EXPECT_CALL(*command_buffer(), OnFlush())
1303 .Times(1)
1304 .RetiresOnSaturation();
1306 gl_->EnableVertexAttribArray(kAttribIndex1);
1307 gl_->EnableVertexAttribArray(kAttribIndex2);
1308 gl_->VertexAttribPointer(kAttribIndex1, kNumComponents1,
1309 GL_FLOAT, GL_FALSE, kClientStride, verts);
1310 gl_->VertexAttribPointer(kAttribIndex2, kNumComponents2,
1311 GL_FLOAT, GL_FALSE, kClientStride, verts);
1312 gl_->DrawElements(GL_POINTS, kCount, GL_UNSIGNED_INT, indices);
1314 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_OPERATION), gl_->GetError());
1317 TEST_F(GLES2ImplementationTest,
1318 DrawElementsClientSideBuffersServiceSideIndices) {
1319 static const float verts[][4] = {
1320 { 12.0f, 23.0f, 34.0f, 45.0f, },
1321 { 56.0f, 67.0f, 78.0f, 89.0f, },
1322 { 13.0f, 24.0f, 35.0f, 46.0f, },
1324 struct Cmds {
1325 cmds::EnableVertexAttribArray enable1;
1326 cmds::EnableVertexAttribArray enable2;
1327 cmds::BindBuffer bind_to_index;
1328 cmds::GetMaxValueInBufferCHROMIUM get_max;
1329 cmds::BindBuffer bind_to_emu;
1330 cmds::BufferData set_size;
1331 cmds::BufferSubData copy_data1;
1332 cmd::SetToken set_token1;
1333 cmds::VertexAttribPointer set_pointer1;
1334 cmds::BufferSubData copy_data2;
1335 cmd::SetToken set_token2;
1336 cmds::VertexAttribPointer set_pointer2;
1337 cmds::DrawElements draw;
1338 cmds::BindBuffer restore;
1340 const GLuint kEmuBufferId = GLES2Implementation::kClientSideArrayId;
1341 const GLuint kClientIndexBufferId = 0x789;
1342 const GLuint kIndexOffset = 0x40;
1343 const GLuint kMaxIndex = 2;
1344 const GLuint kAttribIndex1 = 1;
1345 const GLuint kAttribIndex2 = 3;
1346 const GLint kNumComponents1 = 3;
1347 const GLint kNumComponents2 = 2;
1348 const GLsizei kClientStride = sizeof(verts[0]);
1349 const GLsizei kCount = 2;
1350 const GLsizei kSize1 =
1351 arraysize(verts) * kNumComponents1 * sizeof(verts[0][0]);
1352 const GLsizei kSize2 =
1353 arraysize(verts) * kNumComponents2 * sizeof(verts[0][0]);
1354 const GLsizei kEmuOffset1 = 0;
1355 const GLsizei kEmuOffset2 = kSize1;
1356 const GLsizei kTotalSize = kSize1 + kSize2;
1358 ExpectedMemoryInfo mem1 = GetExpectedResultMemory(sizeof(uint32));
1359 ExpectedMemoryInfo mem2 = GetExpectedMemory(kSize1);
1360 ExpectedMemoryInfo mem3 = GetExpectedMemory(kSize2);
1363 Cmds expected;
1364 expected.enable1.Init(kAttribIndex1);
1365 expected.enable2.Init(kAttribIndex2);
1366 expected.bind_to_index.Init(GL_ELEMENT_ARRAY_BUFFER, kClientIndexBufferId);
1367 expected.get_max.Init(kClientIndexBufferId, kCount, GL_UNSIGNED_SHORT,
1368 kIndexOffset, mem1.id, mem1.offset);
1369 expected.bind_to_emu.Init(GL_ARRAY_BUFFER, kEmuBufferId);
1370 expected.set_size.Init(GL_ARRAY_BUFFER, kTotalSize, 0, 0, GL_DYNAMIC_DRAW);
1371 expected.copy_data1.Init(
1372 GL_ARRAY_BUFFER, kEmuOffset1, kSize1, mem2.id, mem2.offset);
1373 expected.set_token1.Init(GetNextToken());
1374 expected.set_pointer1.Init(kAttribIndex1, kNumComponents1,
1375 GL_FLOAT, GL_FALSE, 0, kEmuOffset1);
1376 expected.copy_data2.Init(
1377 GL_ARRAY_BUFFER, kEmuOffset2, kSize2, mem3.id, mem3.offset);
1378 expected.set_token2.Init(GetNextToken());
1379 expected.set_pointer2.Init(kAttribIndex2, kNumComponents2,
1380 GL_FLOAT, GL_FALSE, 0, kEmuOffset2);
1381 expected.draw.Init(GL_POINTS, kCount, GL_UNSIGNED_SHORT, kIndexOffset);
1382 expected.restore.Init(GL_ARRAY_BUFFER, 0);
1384 EXPECT_CALL(*command_buffer(), OnFlush())
1385 .WillOnce(SetMemory(mem1.ptr,kMaxIndex))
1386 .RetiresOnSaturation();
1388 gl_->EnableVertexAttribArray(kAttribIndex1);
1389 gl_->EnableVertexAttribArray(kAttribIndex2);
1390 gl_->BindBuffer(GL_ELEMENT_ARRAY_BUFFER, kClientIndexBufferId);
1391 gl_->VertexAttribPointer(kAttribIndex1, kNumComponents1,
1392 GL_FLOAT, GL_FALSE, kClientStride, verts);
1393 gl_->VertexAttribPointer(kAttribIndex2, kNumComponents2,
1394 GL_FLOAT, GL_FALSE, kClientStride, verts);
1395 gl_->DrawElements(GL_POINTS, kCount, GL_UNSIGNED_SHORT,
1396 reinterpret_cast<const void*>(kIndexOffset));
1397 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
1400 TEST_F(GLES2ImplementationTest, DrawElementsInstancedANGLEClientSideBuffers) {
1401 static const float verts[][4] = {
1402 { 12.0f, 23.0f, 34.0f, 45.0f, },
1403 { 56.0f, 67.0f, 78.0f, 89.0f, },
1404 { 13.0f, 24.0f, 35.0f, 46.0f, },
1406 static const uint16 indices[] = {
1407 1, 2,
1409 struct Cmds {
1410 cmds::EnableVertexAttribArray enable1;
1411 cmds::EnableVertexAttribArray enable2;
1412 cmds::VertexAttribDivisorANGLE divisor;
1413 cmds::BindBuffer bind_to_index_emu;
1414 cmds::BufferData set_index_size;
1415 cmds::BufferSubData copy_data0;
1416 cmd::SetToken set_token0;
1417 cmds::BindBuffer bind_to_emu;
1418 cmds::BufferData set_size;
1419 cmds::BufferSubData copy_data1;
1420 cmd::SetToken set_token1;
1421 cmds::VertexAttribPointer set_pointer1;
1422 cmds::BufferSubData copy_data2;
1423 cmd::SetToken set_token2;
1424 cmds::VertexAttribPointer set_pointer2;
1425 cmds::DrawElementsInstancedANGLE draw;
1426 cmds::BindBuffer restore;
1427 cmds::BindBuffer restore_element;
1429 const GLsizei kIndexSize = sizeof(indices);
1430 const GLuint kEmuBufferId = GLES2Implementation::kClientSideArrayId;
1431 const GLuint kEmuIndexBufferId =
1432 GLES2Implementation::kClientSideElementArrayId;
1433 const GLuint kAttribIndex1 = 1;
1434 const GLuint kAttribIndex2 = 3;
1435 const GLint kNumComponents1 = 3;
1436 const GLint kNumComponents2 = 2;
1437 const GLsizei kClientStride = sizeof(verts[0]);
1438 const GLsizei kCount = 2;
1439 const GLsizei kSize1 =
1440 arraysize(verts) * kNumComponents1 * sizeof(verts[0][0]);
1441 const GLsizei kSize2 =
1442 1 * kNumComponents2 * sizeof(verts[0][0]);
1443 const GLuint kDivisor = 1;
1444 const GLsizei kEmuOffset1 = 0;
1445 const GLsizei kEmuOffset2 = kSize1;
1446 const GLsizei kTotalSize = kSize1 + kSize2;
1448 ExpectedMemoryInfo mem1 = GetExpectedMemory(kIndexSize);
1449 ExpectedMemoryInfo mem2 = GetExpectedMemory(kSize1);
1450 ExpectedMemoryInfo mem3 = GetExpectedMemory(kSize2);
1452 Cmds expected;
1453 expected.enable1.Init(kAttribIndex1);
1454 expected.enable2.Init(kAttribIndex2);
1455 expected.divisor.Init(kAttribIndex2, kDivisor);
1456 expected.bind_to_index_emu.Init(GL_ELEMENT_ARRAY_BUFFER, kEmuIndexBufferId);
1457 expected.set_index_size.Init(
1458 GL_ELEMENT_ARRAY_BUFFER, kIndexSize, 0, 0, GL_DYNAMIC_DRAW);
1459 expected.copy_data0.Init(
1460 GL_ELEMENT_ARRAY_BUFFER, 0, kIndexSize, mem1.id, mem1.offset);
1461 expected.set_token0.Init(GetNextToken());
1462 expected.bind_to_emu.Init(GL_ARRAY_BUFFER, kEmuBufferId);
1463 expected.set_size.Init(GL_ARRAY_BUFFER, kTotalSize, 0, 0, GL_DYNAMIC_DRAW);
1464 expected.copy_data1.Init(
1465 GL_ARRAY_BUFFER, kEmuOffset1, kSize1, mem2.id, mem2.offset);
1466 expected.set_token1.Init(GetNextToken());
1467 expected.set_pointer1.Init(
1468 kAttribIndex1, kNumComponents1, GL_FLOAT, GL_FALSE, 0, kEmuOffset1);
1469 expected.copy_data2.Init(
1470 GL_ARRAY_BUFFER, kEmuOffset2, kSize2, mem3.id, mem3.offset);
1471 expected.set_token2.Init(GetNextToken());
1472 expected.set_pointer2.Init(kAttribIndex2, kNumComponents2,
1473 GL_FLOAT, GL_FALSE, 0, kEmuOffset2);
1474 expected.draw.Init(GL_POINTS, kCount, GL_UNSIGNED_SHORT, 0, 1);
1475 expected.restore.Init(GL_ARRAY_BUFFER, 0);
1476 expected.restore_element.Init(GL_ELEMENT_ARRAY_BUFFER, 0);
1477 gl_->EnableVertexAttribArray(kAttribIndex1);
1478 gl_->EnableVertexAttribArray(kAttribIndex2);
1479 gl_->VertexAttribPointer(kAttribIndex1, kNumComponents1,
1480 GL_FLOAT, GL_FALSE, kClientStride, verts);
1481 gl_->VertexAttribPointer(kAttribIndex2, kNumComponents2,
1482 GL_FLOAT, GL_FALSE, kClientStride, verts);
1483 gl_->VertexAttribDivisorANGLE(kAttribIndex2, kDivisor);
1484 gl_->DrawElementsInstancedANGLE(
1485 GL_POINTS, kCount, GL_UNSIGNED_SHORT, indices, 1);
1486 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
1489 TEST_F(GLES2ImplementationTest, GetVertexBufferPointerv) {
1490 static const float verts[1] = { 0.0f, };
1491 const GLuint kAttribIndex1 = 1;
1492 const GLuint kAttribIndex2 = 3;
1493 const GLint kNumComponents1 = 3;
1494 const GLint kNumComponents2 = 2;
1495 const GLsizei kStride1 = 12;
1496 const GLsizei kStride2 = 0;
1497 const GLuint kBufferId = 0x123;
1498 const GLint kOffset2 = 0x456;
1500 // It's all cached on the client side so no get commands are issued.
1501 struct Cmds {
1502 cmds::BindBuffer bind;
1503 cmds::VertexAttribPointer set_pointer;
1506 Cmds expected;
1507 expected.bind.Init(GL_ARRAY_BUFFER, kBufferId);
1508 expected.set_pointer.Init(kAttribIndex2, kNumComponents2, GL_FLOAT, GL_FALSE,
1509 kStride2, kOffset2);
1511 // Set one client side buffer.
1512 gl_->VertexAttribPointer(kAttribIndex1, kNumComponents1,
1513 GL_FLOAT, GL_FALSE, kStride1, verts);
1514 // Set one VBO
1515 gl_->BindBuffer(GL_ARRAY_BUFFER, kBufferId);
1516 gl_->VertexAttribPointer(kAttribIndex2, kNumComponents2,
1517 GL_FLOAT, GL_FALSE, kStride2,
1518 reinterpret_cast<const void*>(kOffset2));
1519 // now get them both.
1520 void* ptr1 = NULL;
1521 void* ptr2 = NULL;
1523 gl_->GetVertexAttribPointerv(
1524 kAttribIndex1, GL_VERTEX_ATTRIB_ARRAY_POINTER, &ptr1);
1525 gl_->GetVertexAttribPointerv(
1526 kAttribIndex2, GL_VERTEX_ATTRIB_ARRAY_POINTER, &ptr2);
1528 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
1529 EXPECT_TRUE(static_cast<const void*>(&verts) == ptr1);
1530 EXPECT_TRUE(ptr2 == reinterpret_cast<void*>(kOffset2));
1533 TEST_F(GLES2ImplementationTest, GetVertexAttrib) {
1534 static const float verts[1] = { 0.0f, };
1535 const GLuint kAttribIndex1 = 1;
1536 const GLuint kAttribIndex2 = 3;
1537 const GLint kNumComponents1 = 3;
1538 const GLint kNumComponents2 = 2;
1539 const GLsizei kStride1 = 12;
1540 const GLsizei kStride2 = 0;
1541 const GLuint kBufferId = 0x123;
1542 const GLint kOffset2 = 0x456;
1544 // Only one set and one get because the client side buffer's info is stored
1545 // on the client side.
1546 struct Cmds {
1547 cmds::EnableVertexAttribArray enable;
1548 cmds::BindBuffer bind;
1549 cmds::VertexAttribPointer set_pointer;
1550 cmds::GetVertexAttribfv get2; // for getting the value from attrib1
1553 ExpectedMemoryInfo mem2 = GetExpectedResultMemory(16);
1555 Cmds expected;
1556 expected.enable.Init(kAttribIndex1);
1557 expected.bind.Init(GL_ARRAY_BUFFER, kBufferId);
1558 expected.set_pointer.Init(kAttribIndex2, kNumComponents2, GL_FLOAT, GL_FALSE,
1559 kStride2, kOffset2);
1560 expected.get2.Init(kAttribIndex1,
1561 GL_CURRENT_VERTEX_ATTRIB,
1562 mem2.id, mem2.offset);
1564 FourFloats current_attrib(1.2f, 3.4f, 5.6f, 7.8f);
1566 // One call to flush to wait for last call to GetVertexAttribiv
1567 // as others are all cached.
1568 EXPECT_CALL(*command_buffer(), OnFlush())
1569 .WillOnce(SetMemory(
1570 mem2.ptr, SizedResultHelper<FourFloats>(current_attrib)))
1571 .RetiresOnSaturation();
1573 gl_->EnableVertexAttribArray(kAttribIndex1);
1574 // Set one client side buffer.
1575 gl_->VertexAttribPointer(kAttribIndex1, kNumComponents1,
1576 GL_FLOAT, GL_FALSE, kStride1, verts);
1577 // Set one VBO
1578 gl_->BindBuffer(GL_ARRAY_BUFFER, kBufferId);
1579 gl_->VertexAttribPointer(kAttribIndex2, kNumComponents2,
1580 GL_FLOAT, GL_FALSE, kStride2,
1581 reinterpret_cast<const void*>(kOffset2));
1582 // first get the service side once to see that we make a command
1583 GLint buffer_id = 0;
1584 GLint enabled = 0;
1585 GLint size = 0;
1586 GLint stride = 0;
1587 GLint type = 0;
1588 GLint normalized = 1;
1589 float current[4] = { 0.0f, };
1591 gl_->GetVertexAttribiv(
1592 kAttribIndex2, GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING, &buffer_id);
1593 EXPECT_EQ(kBufferId, static_cast<GLuint>(buffer_id));
1594 gl_->GetVertexAttribiv(
1595 kAttribIndex1, GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING, &buffer_id);
1596 gl_->GetVertexAttribiv(
1597 kAttribIndex1, GL_VERTEX_ATTRIB_ARRAY_ENABLED, &enabled);
1598 gl_->GetVertexAttribiv(
1599 kAttribIndex1, GL_VERTEX_ATTRIB_ARRAY_SIZE, &size);
1600 gl_->GetVertexAttribiv(
1601 kAttribIndex1, GL_VERTEX_ATTRIB_ARRAY_STRIDE, &stride);
1602 gl_->GetVertexAttribiv(
1603 kAttribIndex1, GL_VERTEX_ATTRIB_ARRAY_TYPE, &type);
1604 gl_->GetVertexAttribiv(
1605 kAttribIndex1, GL_VERTEX_ATTRIB_ARRAY_NORMALIZED, &normalized);
1606 gl_->GetVertexAttribfv(
1607 kAttribIndex1, GL_CURRENT_VERTEX_ATTRIB, &current[0]);
1609 EXPECT_EQ(0, buffer_id);
1610 EXPECT_EQ(GL_TRUE, enabled);
1611 EXPECT_EQ(kNumComponents1, size);
1612 EXPECT_EQ(kStride1, stride);
1613 EXPECT_EQ(GL_FLOAT, type);
1614 EXPECT_EQ(GL_FALSE, normalized);
1615 EXPECT_EQ(0, memcmp(&current_attrib, &current, sizeof(current_attrib)));
1617 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
1620 TEST_F(GLES2ImplementationTest, ReservedIds) {
1621 // Only the get error command should be issued.
1622 struct Cmds {
1623 cmds::GetError get;
1625 Cmds expected;
1627 ExpectedMemoryInfo mem1 = GetExpectedResultMemory(
1628 sizeof(cmds::GetError::Result));
1630 expected.get.Init(mem1.id, mem1.offset);
1632 // One call to flush to wait for GetError
1633 EXPECT_CALL(*command_buffer(), OnFlush())
1634 .WillOnce(SetMemory(mem1.ptr, GLuint(GL_NO_ERROR)))
1635 .RetiresOnSaturation();
1637 gl_->BindBuffer(
1638 GL_ARRAY_BUFFER,
1639 GLES2Implementation::kClientSideArrayId);
1640 gl_->BindBuffer(
1641 GL_ARRAY_BUFFER,
1642 GLES2Implementation::kClientSideElementArrayId);
1643 GLenum err = gl_->GetError();
1644 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_OPERATION), err);
1645 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
1648 #endif // defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS)
1650 TEST_F(GLES2ImplementationTest, ReadPixels2Reads) {
1651 struct Cmds {
1652 cmds::ReadPixels read1;
1653 cmd::SetToken set_token1;
1654 cmds::ReadPixels read2;
1655 cmd::SetToken set_token2;
1657 const GLint kBytesPerPixel = 4;
1658 const GLint kWidth =
1659 (kTransferBufferSize - GLES2Implementation::kStartingOffset) /
1660 kBytesPerPixel;
1661 const GLint kHeight = 2;
1662 const GLenum kFormat = GL_RGBA;
1663 const GLenum kType = GL_UNSIGNED_BYTE;
1665 ExpectedMemoryInfo mem1 =
1666 GetExpectedMemory(kWidth * kHeight / 2 * kBytesPerPixel);
1667 ExpectedMemoryInfo result1 =
1668 GetExpectedResultMemory(sizeof(cmds::ReadPixels::Result));
1669 ExpectedMemoryInfo mem2 =
1670 GetExpectedMemory(kWidth * kHeight / 2 * kBytesPerPixel);
1671 ExpectedMemoryInfo result2 =
1672 GetExpectedResultMemory(sizeof(cmds::ReadPixels::Result));
1674 Cmds expected;
1675 expected.read1.Init(
1676 0, 0, kWidth, kHeight / 2, kFormat, kType,
1677 mem1.id, mem1.offset, result1.id, result1.offset,
1678 false);
1679 expected.set_token1.Init(GetNextToken());
1680 expected.read2.Init(
1681 0, kHeight / 2, kWidth, kHeight / 2, kFormat, kType,
1682 mem2.id, mem2.offset, result2.id, result2.offset, false);
1683 expected.set_token2.Init(GetNextToken());
1684 scoped_ptr<int8[]> buffer(new int8[kWidth * kHeight * kBytesPerPixel]);
1686 EXPECT_CALL(*command_buffer(), OnFlush())
1687 .WillOnce(SetMemory(result1.ptr, static_cast<uint32>(1)))
1688 .WillOnce(SetMemory(result2.ptr, static_cast<uint32>(1)))
1689 .RetiresOnSaturation();
1691 gl_->ReadPixels(0, 0, kWidth, kHeight, kFormat, kType, buffer.get());
1692 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
1695 TEST_F(GLES2ImplementationTest, ReadPixelsBadFormatType) {
1696 struct Cmds {
1697 cmds::ReadPixels read;
1698 cmd::SetToken set_token;
1700 const GLint kBytesPerPixel = 4;
1701 const GLint kWidth = 2;
1702 const GLint kHeight = 2;
1703 const GLenum kFormat = 0;
1704 const GLenum kType = 0;
1706 ExpectedMemoryInfo mem1 =
1707 GetExpectedMemory(kWidth * kHeight * kBytesPerPixel);
1708 ExpectedMemoryInfo result1 =
1709 GetExpectedResultMemory(sizeof(cmds::ReadPixels::Result));
1711 Cmds expected;
1712 expected.read.Init(
1713 0, 0, kWidth, kHeight, kFormat, kType,
1714 mem1.id, mem1.offset, result1.id, result1.offset, false);
1715 expected.set_token.Init(GetNextToken());
1716 scoped_ptr<int8[]> buffer(new int8[kWidth * kHeight * kBytesPerPixel]);
1718 EXPECT_CALL(*command_buffer(), OnFlush())
1719 .Times(1)
1720 .RetiresOnSaturation();
1722 gl_->ReadPixels(0, 0, kWidth, kHeight, kFormat, kType, buffer.get());
1725 TEST_F(GLES2ImplementationTest, FreeUnusedSharedMemory) {
1726 struct Cmds {
1727 cmds::BufferSubData buf;
1728 cmd::SetToken set_token;
1730 const GLenum kTarget = GL_ELEMENT_ARRAY_BUFFER;
1731 const GLintptr kOffset = 15;
1732 const GLsizeiptr kSize = 16;
1734 ExpectedMemoryInfo mem1 = GetExpectedMemory(kSize);
1736 Cmds expected;
1737 expected.buf.Init(
1738 kTarget, kOffset, kSize, mem1.id, mem1.offset);
1739 expected.set_token.Init(GetNextToken());
1741 void* mem = gl_->MapBufferSubDataCHROMIUM(
1742 kTarget, kOffset, kSize, GL_WRITE_ONLY);
1743 ASSERT_TRUE(mem != NULL);
1744 gl_->UnmapBufferSubDataCHROMIUM(mem);
1745 EXPECT_CALL(*command_buffer(), DestroyTransferBuffer(_))
1746 .Times(1)
1747 .RetiresOnSaturation();
1748 gl_->FreeUnusedSharedMemory();
1751 TEST_F(GLES2ImplementationTest, MapUnmapBufferSubDataCHROMIUM) {
1752 struct Cmds {
1753 cmds::BufferSubData buf;
1754 cmd::SetToken set_token;
1756 const GLenum kTarget = GL_ELEMENT_ARRAY_BUFFER;
1757 const GLintptr kOffset = 15;
1758 const GLsizeiptr kSize = 16;
1760 uint32 offset = 0;
1761 Cmds expected;
1762 expected.buf.Init(
1763 kTarget, kOffset, kSize,
1764 command_buffer()->GetNextFreeTransferBufferId(), offset);
1765 expected.set_token.Init(GetNextToken());
1767 void* mem = gl_->MapBufferSubDataCHROMIUM(
1768 kTarget, kOffset, kSize, GL_WRITE_ONLY);
1769 ASSERT_TRUE(mem != NULL);
1770 gl_->UnmapBufferSubDataCHROMIUM(mem);
1771 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
1774 TEST_F(GLES2ImplementationTest, MapUnmapBufferSubDataCHROMIUMBadArgs) {
1775 const GLenum kTarget = GL_ELEMENT_ARRAY_BUFFER;
1776 const GLintptr kOffset = 15;
1777 const GLsizeiptr kSize = 16;
1779 ExpectedMemoryInfo result1 =
1780 GetExpectedResultMemory(sizeof(cmds::GetError::Result));
1781 ExpectedMemoryInfo result2 =
1782 GetExpectedResultMemory(sizeof(cmds::GetError::Result));
1783 ExpectedMemoryInfo result3 =
1784 GetExpectedResultMemory(sizeof(cmds::GetError::Result));
1785 ExpectedMemoryInfo result4 =
1786 GetExpectedResultMemory(sizeof(cmds::GetError::Result));
1788 // Calls to flush to wait for GetError
1789 EXPECT_CALL(*command_buffer(), OnFlush())
1790 .WillOnce(SetMemory(result1.ptr, GLuint(GL_NO_ERROR)))
1791 .WillOnce(SetMemory(result2.ptr, GLuint(GL_NO_ERROR)))
1792 .WillOnce(SetMemory(result3.ptr, GLuint(GL_NO_ERROR)))
1793 .WillOnce(SetMemory(result4.ptr, GLuint(GL_NO_ERROR)))
1794 .RetiresOnSaturation();
1796 void* mem;
1797 mem = gl_->MapBufferSubDataCHROMIUM(kTarget, -1, kSize, GL_WRITE_ONLY);
1798 ASSERT_TRUE(mem == NULL);
1799 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE), gl_->GetError());
1800 mem = gl_->MapBufferSubDataCHROMIUM(kTarget, kOffset, -1, 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, kSize, GL_READ_ONLY);
1804 ASSERT_TRUE(mem == NULL);
1805 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_ENUM), gl_->GetError());
1806 const char* kPtr = "something";
1807 gl_->UnmapBufferSubDataCHROMIUM(kPtr);
1808 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE), gl_->GetError());
1811 TEST_F(GLES2ImplementationTest, MapUnmapTexSubImage2DCHROMIUM) {
1812 struct Cmds {
1813 cmds::TexSubImage2D tex;
1814 cmd::SetToken set_token;
1816 const GLint kLevel = 1;
1817 const GLint kXOffset = 2;
1818 const GLint kYOffset = 3;
1819 const GLint kWidth = 4;
1820 const GLint kHeight = 5;
1821 const GLenum kFormat = GL_RGBA;
1822 const GLenum kType = GL_UNSIGNED_BYTE;
1824 uint32 offset = 0;
1825 Cmds expected;
1826 expected.tex.Init(
1827 GL_TEXTURE_2D, kLevel, kXOffset, kYOffset, kWidth, kHeight, kFormat,
1828 kType,
1829 command_buffer()->GetNextFreeTransferBufferId(), offset, GL_FALSE);
1830 expected.set_token.Init(GetNextToken());
1832 void* mem = gl_->MapTexSubImage2DCHROMIUM(
1833 GL_TEXTURE_2D,
1834 kLevel,
1835 kXOffset,
1836 kYOffset,
1837 kWidth,
1838 kHeight,
1839 kFormat,
1840 kType,
1841 GL_WRITE_ONLY);
1842 ASSERT_TRUE(mem != NULL);
1843 gl_->UnmapTexSubImage2DCHROMIUM(mem);
1844 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
1847 TEST_F(GLES2ImplementationTest, MapUnmapTexSubImage2DCHROMIUMBadArgs) {
1848 const GLint kLevel = 1;
1849 const GLint kXOffset = 2;
1850 const GLint kYOffset = 3;
1851 const GLint kWidth = 4;
1852 const GLint kHeight = 5;
1853 const GLenum kFormat = GL_RGBA;
1854 const GLenum kType = GL_UNSIGNED_BYTE;
1856 ExpectedMemoryInfo result1 =
1857 GetExpectedResultMemory(sizeof(cmds::GetError::Result));
1858 ExpectedMemoryInfo result2 =
1859 GetExpectedResultMemory(sizeof(cmds::GetError::Result));
1860 ExpectedMemoryInfo result3 =
1861 GetExpectedResultMemory(sizeof(cmds::GetError::Result));
1862 ExpectedMemoryInfo result4 =
1863 GetExpectedResultMemory(sizeof(cmds::GetError::Result));
1864 ExpectedMemoryInfo result5 =
1865 GetExpectedResultMemory(sizeof(cmds::GetError::Result));
1866 ExpectedMemoryInfo result6 =
1867 GetExpectedResultMemory(sizeof(cmds::GetError::Result));
1868 ExpectedMemoryInfo result7 =
1869 GetExpectedResultMemory(sizeof(cmds::GetError::Result));
1871 // Calls to flush to wait for GetError
1872 EXPECT_CALL(*command_buffer(), OnFlush())
1873 .WillOnce(SetMemory(result1.ptr, GLuint(GL_NO_ERROR)))
1874 .WillOnce(SetMemory(result2.ptr, GLuint(GL_NO_ERROR)))
1875 .WillOnce(SetMemory(result3.ptr, GLuint(GL_NO_ERROR)))
1876 .WillOnce(SetMemory(result4.ptr, GLuint(GL_NO_ERROR)))
1877 .WillOnce(SetMemory(result5.ptr, GLuint(GL_NO_ERROR)))
1878 .WillOnce(SetMemory(result6.ptr, GLuint(GL_NO_ERROR)))
1879 .WillOnce(SetMemory(result7.ptr, GLuint(GL_NO_ERROR)))
1880 .RetiresOnSaturation();
1882 void* mem;
1883 mem = gl_->MapTexSubImage2DCHROMIUM(
1884 GL_TEXTURE_2D,
1886 kXOffset,
1887 kYOffset,
1888 kWidth,
1889 kHeight,
1890 kFormat,
1891 kType,
1892 GL_WRITE_ONLY);
1893 EXPECT_TRUE(mem == NULL);
1894 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE), gl_->GetError());
1895 mem = gl_->MapTexSubImage2DCHROMIUM(
1896 GL_TEXTURE_2D,
1897 kLevel,
1899 kYOffset,
1900 kWidth,
1901 kHeight,
1902 kFormat,
1903 kType,
1904 GL_WRITE_ONLY);
1905 EXPECT_TRUE(mem == NULL);
1906 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE), gl_->GetError());
1907 mem = gl_->MapTexSubImage2DCHROMIUM(
1908 GL_TEXTURE_2D,
1909 kLevel,
1910 kXOffset,
1912 kWidth,
1913 kHeight,
1914 kFormat,
1915 kType,
1916 GL_WRITE_ONLY);
1917 EXPECT_TRUE(mem == NULL);
1918 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE), gl_->GetError());
1919 mem = gl_->MapTexSubImage2DCHROMIUM(
1920 GL_TEXTURE_2D,
1921 kLevel,
1922 kXOffset,
1923 kYOffset,
1925 kHeight,
1926 kFormat,
1927 kType,
1928 GL_WRITE_ONLY);
1929 EXPECT_TRUE(mem == NULL);
1930 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE), gl_->GetError());
1931 mem = gl_->MapTexSubImage2DCHROMIUM(
1932 GL_TEXTURE_2D,
1933 kLevel,
1934 kXOffset,
1935 kYOffset,
1936 kWidth,
1938 kFormat,
1939 kType,
1940 GL_WRITE_ONLY);
1941 EXPECT_TRUE(mem == NULL);
1942 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE), gl_->GetError());
1943 mem = gl_->MapTexSubImage2DCHROMIUM(
1944 GL_TEXTURE_2D,
1945 kLevel,
1946 kXOffset,
1947 kYOffset,
1948 kWidth,
1949 kHeight,
1950 kFormat,
1951 kType,
1952 GL_READ_ONLY);
1953 EXPECT_TRUE(mem == NULL);
1954 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_ENUM), gl_->GetError());
1955 const char* kPtr = "something";
1956 gl_->UnmapTexSubImage2DCHROMIUM(kPtr);
1957 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE), gl_->GetError());
1960 TEST_F(GLES2ImplementationTest, GetProgramInfoCHROMIUMGoodArgs) {
1961 const uint32 kBucketId = GLES2Implementation::kResultBucketId;
1962 const GLuint kProgramId = 123;
1963 const char kBad = 0x12;
1964 GLsizei size = 0;
1965 const Str7 kString = {"foobar"};
1966 char buf[20];
1968 ExpectedMemoryInfo mem1 =
1969 GetExpectedMemory(MaxTransferBufferSize());
1970 ExpectedMemoryInfo result1 =
1971 GetExpectedResultMemory(sizeof(cmd::GetBucketStart::Result));
1972 ExpectedMemoryInfo result2 =
1973 GetExpectedResultMemory(sizeof(cmds::GetError::Result));
1975 memset(buf, kBad, sizeof(buf));
1976 EXPECT_CALL(*command_buffer(), OnFlush())
1977 .WillOnce(DoAll(SetMemory(result1.ptr, uint32(sizeof(kString))),
1978 SetMemory(mem1.ptr, kString)))
1979 .WillOnce(SetMemory(result2.ptr, GLuint(GL_NO_ERROR)))
1980 .RetiresOnSaturation();
1982 struct Cmds {
1983 cmd::SetBucketSize set_bucket_size1;
1984 cmds::GetProgramInfoCHROMIUM get_program_info;
1985 cmd::GetBucketStart get_bucket_start;
1986 cmd::SetToken set_token1;
1987 cmd::SetBucketSize set_bucket_size2;
1989 Cmds expected;
1990 expected.set_bucket_size1.Init(kBucketId, 0);
1991 expected.get_program_info.Init(kProgramId, kBucketId);
1992 expected.get_bucket_start.Init(
1993 kBucketId, result1.id, result1.offset,
1994 MaxTransferBufferSize(), mem1.id, mem1.offset);
1995 expected.set_token1.Init(GetNextToken());
1996 expected.set_bucket_size2.Init(kBucketId, 0);
1997 gl_->GetProgramInfoCHROMIUM(kProgramId, sizeof(buf), &size, &buf);
1998 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
1999 EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), gl_->GetError());
2000 EXPECT_EQ(sizeof(kString), static_cast<size_t>(size));
2001 EXPECT_STREQ(kString.str, buf);
2002 EXPECT_EQ(buf[sizeof(kString)], kBad);
2005 TEST_F(GLES2ImplementationTest, GetProgramInfoCHROMIUMBadArgs) {
2006 const uint32 kBucketId = GLES2Implementation::kResultBucketId;
2007 const GLuint kProgramId = 123;
2008 GLsizei size = 0;
2009 const Str7 kString = {"foobar"};
2010 char buf[20];
2012 ExpectedMemoryInfo mem1 = GetExpectedMemory(MaxTransferBufferSize());
2013 ExpectedMemoryInfo result1 =
2014 GetExpectedResultMemory(sizeof(cmd::GetBucketStart::Result));
2015 ExpectedMemoryInfo result2 =
2016 GetExpectedResultMemory(sizeof(cmds::GetError::Result));
2017 ExpectedMemoryInfo result3 =
2018 GetExpectedResultMemory(sizeof(cmds::GetError::Result));
2019 ExpectedMemoryInfo result4 =
2020 GetExpectedResultMemory(sizeof(cmds::GetError::Result));
2022 EXPECT_CALL(*command_buffer(), OnFlush())
2023 .WillOnce(DoAll(SetMemory(result1.ptr, uint32(sizeof(kString))),
2024 SetMemory(mem1.ptr, kString)))
2025 .WillOnce(SetMemory(result2.ptr, GLuint(GL_NO_ERROR)))
2026 .WillOnce(SetMemory(result3.ptr, GLuint(GL_NO_ERROR)))
2027 .WillOnce(SetMemory(result4.ptr, GLuint(GL_NO_ERROR)))
2028 .RetiresOnSaturation();
2030 // try bufsize not big enough.
2031 struct Cmds {
2032 cmd::SetBucketSize set_bucket_size1;
2033 cmds::GetProgramInfoCHROMIUM get_program_info;
2034 cmd::GetBucketStart get_bucket_start;
2035 cmd::SetToken set_token1;
2036 cmd::SetBucketSize set_bucket_size2;
2038 Cmds expected;
2039 expected.set_bucket_size1.Init(kBucketId, 0);
2040 expected.get_program_info.Init(kProgramId, kBucketId);
2041 expected.get_bucket_start.Init(
2042 kBucketId, result1.id, result1.offset,
2043 MaxTransferBufferSize(), mem1.id, mem1.offset);
2044 expected.set_token1.Init(GetNextToken());
2045 expected.set_bucket_size2.Init(kBucketId, 0);
2046 gl_->GetProgramInfoCHROMIUM(kProgramId, 6, &size, &buf);
2047 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
2048 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_OPERATION), gl_->GetError());
2049 ClearCommands();
2051 // try bad bufsize
2052 gl_->GetProgramInfoCHROMIUM(kProgramId, -1, &size, &buf);
2053 EXPECT_TRUE(NoCommandsWritten());
2054 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE), gl_->GetError());
2055 ClearCommands();
2056 // try no size ptr.
2057 gl_->GetProgramInfoCHROMIUM(kProgramId, sizeof(buf), NULL, &buf);
2058 EXPECT_TRUE(NoCommandsWritten());
2059 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE), gl_->GetError());
2062 // Test that things are cached
2063 TEST_F(GLES2ImplementationTest, GetIntegerCacheRead) {
2064 struct PNameValue {
2065 GLenum pname;
2066 GLint expected;
2068 const PNameValue pairs[] = {
2069 {GL_ACTIVE_TEXTURE, GL_TEXTURE0, },
2070 {GL_TEXTURE_BINDING_2D, 0, },
2071 {GL_TEXTURE_BINDING_CUBE_MAP, 0, },
2072 {GL_TEXTURE_BINDING_EXTERNAL_OES, 0, },
2073 {GL_FRAMEBUFFER_BINDING, 0, },
2074 {GL_RENDERBUFFER_BINDING, 0, },
2075 {GL_ARRAY_BUFFER_BINDING, 0, },
2076 {GL_ELEMENT_ARRAY_BUFFER_BINDING, 0, },
2077 {GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, kMaxCombinedTextureImageUnits, },
2078 {GL_MAX_CUBE_MAP_TEXTURE_SIZE, kMaxCubeMapTextureSize, },
2079 {GL_MAX_FRAGMENT_UNIFORM_VECTORS, kMaxFragmentUniformVectors, },
2080 {GL_MAX_RENDERBUFFER_SIZE, kMaxRenderbufferSize, },
2081 {GL_MAX_TEXTURE_IMAGE_UNITS, kMaxTextureImageUnits, },
2082 {GL_MAX_TEXTURE_SIZE, kMaxTextureSize, },
2083 {GL_MAX_VARYING_VECTORS, kMaxVaryingVectors, },
2084 {GL_MAX_VERTEX_ATTRIBS, kMaxVertexAttribs, },
2085 {GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, kMaxVertexTextureImageUnits, },
2086 {GL_MAX_VERTEX_UNIFORM_VECTORS, kMaxVertexUniformVectors, },
2087 {GL_NUM_COMPRESSED_TEXTURE_FORMATS, kNumCompressedTextureFormats, },
2088 {GL_NUM_SHADER_BINARY_FORMATS, kNumShaderBinaryFormats, }, };
2089 size_t num_pairs = sizeof(pairs) / sizeof(pairs[0]);
2090 for (size_t ii = 0; ii < num_pairs; ++ii) {
2091 const PNameValue& pv = pairs[ii];
2092 GLint v = -1;
2093 gl_->GetIntegerv(pv.pname, &v);
2094 EXPECT_TRUE(NoCommandsWritten());
2095 EXPECT_EQ(pv.expected, v);
2098 ExpectedMemoryInfo result1 =
2099 GetExpectedResultMemory(sizeof(cmds::GetError::Result));
2101 EXPECT_CALL(*command_buffer(), OnFlush())
2102 .WillOnce(SetMemory(result1.ptr, GLuint(GL_NO_ERROR)))
2103 .RetiresOnSaturation();
2104 EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), gl_->GetError());
2107 TEST_F(GLES2ImplementationTest, GetIntegerCacheWrite) {
2108 struct PNameValue {
2109 GLenum pname;
2110 GLint expected;
2112 gl_->ActiveTexture(GL_TEXTURE4);
2113 gl_->BindBuffer(GL_ARRAY_BUFFER, 2);
2114 gl_->BindBuffer(GL_ELEMENT_ARRAY_BUFFER, 3);
2115 gl_->BindFramebuffer(GL_FRAMEBUFFER, 4);
2116 gl_->BindRenderbuffer(GL_RENDERBUFFER, 5);
2117 gl_->BindTexture(GL_TEXTURE_2D, 6);
2118 gl_->BindTexture(GL_TEXTURE_CUBE_MAP, 7);
2119 gl_->BindTexture(GL_TEXTURE_EXTERNAL_OES, 8);
2121 const PNameValue pairs[] = {{GL_ACTIVE_TEXTURE, GL_TEXTURE4, },
2122 {GL_ARRAY_BUFFER_BINDING, 2, },
2123 {GL_ELEMENT_ARRAY_BUFFER_BINDING, 3, },
2124 {GL_FRAMEBUFFER_BINDING, 4, },
2125 {GL_RENDERBUFFER_BINDING, 5, },
2126 {GL_TEXTURE_BINDING_2D, 6, },
2127 {GL_TEXTURE_BINDING_CUBE_MAP, 7, },
2128 {GL_TEXTURE_BINDING_EXTERNAL_OES, 8, }, };
2129 size_t num_pairs = sizeof(pairs) / sizeof(pairs[0]);
2130 for (size_t ii = 0; ii < num_pairs; ++ii) {
2131 const PNameValue& pv = pairs[ii];
2132 GLint v = -1;
2133 gl_->GetIntegerv(pv.pname, &v);
2134 EXPECT_EQ(pv.expected, v);
2137 ExpectedMemoryInfo result1 =
2138 GetExpectedResultMemory(sizeof(cmds::GetError::Result));
2140 EXPECT_CALL(*command_buffer(), OnFlush())
2141 .WillOnce(SetMemory(result1.ptr, GLuint(GL_NO_ERROR)))
2142 .RetiresOnSaturation();
2143 EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), gl_->GetError());
2146 static bool CheckRect(
2147 int width, int height, GLenum format, GLenum type, int alignment,
2148 bool flip_y, const uint8* r1, const uint8* r2) {
2149 uint32 size = 0;
2150 uint32 unpadded_row_size = 0;
2151 uint32 padded_row_size = 0;
2152 if (!GLES2Util::ComputeImageDataSizes(
2153 width, height, format, type, alignment, &size, &unpadded_row_size,
2154 &padded_row_size)) {
2155 return false;
2158 int r2_stride = flip_y ?
2159 -static_cast<int>(padded_row_size) :
2160 static_cast<int>(padded_row_size);
2161 r2 = flip_y ? (r2 + (height - 1) * padded_row_size) : r2;
2163 for (int y = 0; y < height; ++y) {
2164 if (memcmp(r1, r2, unpadded_row_size) != 0) {
2165 return false;
2167 r1 += padded_row_size;
2168 r2 += r2_stride;
2170 return true;
2173 ACTION_P8(CheckRectAction, width, height, format, type, alignment, flip_y,
2174 r1, r2) {
2175 EXPECT_TRUE(CheckRect(
2176 width, height, format, type, alignment, flip_y, r1, r2));
2179 // Test TexImage2D with and without flip_y
2180 TEST_F(GLES2ImplementationTest, TexImage2D) {
2181 struct Cmds {
2182 cmds::TexImage2D tex_image_2d;
2183 cmd::SetToken set_token;
2185 struct Cmds2 {
2186 cmds::TexImage2D tex_image_2d;
2187 cmd::SetToken set_token;
2189 const GLenum kTarget = GL_TEXTURE_2D;
2190 const GLint kLevel = 0;
2191 const GLenum kFormat = GL_RGB;
2192 const GLsizei kWidth = 3;
2193 const GLsizei kHeight = 4;
2194 const GLint kBorder = 0;
2195 const GLenum kType = GL_UNSIGNED_BYTE;
2196 const GLint kPixelStoreUnpackAlignment = 4;
2197 static uint8 pixels[] = {
2198 11, 12, 13, 13, 14, 15, 15, 16, 17, 101, 102, 103,
2199 21, 22, 23, 23, 24, 25, 25, 26, 27, 201, 202, 203,
2200 31, 32, 33, 33, 34, 35, 35, 36, 37, 123, 124, 125,
2201 41, 42, 43, 43, 44, 45, 45, 46, 47,
2204 ExpectedMemoryInfo mem1 = GetExpectedMemory(sizeof(pixels));
2206 Cmds expected;
2207 expected.tex_image_2d.Init(
2208 kTarget, kLevel, kFormat, kWidth, kHeight, kFormat, kType,
2209 mem1.id, mem1.offset);
2210 expected.set_token.Init(GetNextToken());
2211 gl_->TexImage2D(
2212 kTarget, kLevel, kFormat, kWidth, kHeight, kBorder, kFormat, kType,
2213 pixels);
2214 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
2215 EXPECT_TRUE(CheckRect(
2216 kWidth, kHeight, kFormat, kType, kPixelStoreUnpackAlignment, false,
2217 pixels, mem1.ptr));
2219 ClearCommands();
2220 gl_->PixelStorei(GL_UNPACK_FLIP_Y_CHROMIUM, GL_TRUE);
2222 ExpectedMemoryInfo mem2 = GetExpectedMemory(sizeof(pixels));
2223 Cmds2 expected2;
2224 expected2.tex_image_2d.Init(
2225 kTarget, kLevel, kFormat, kWidth, kHeight, kFormat, kType,
2226 mem2.id, mem2.offset);
2227 expected2.set_token.Init(GetNextToken());
2228 const void* commands2 = GetPut();
2229 gl_->TexImage2D(
2230 kTarget, kLevel, kFormat, kWidth, kHeight, kBorder, kFormat, kType,
2231 pixels);
2232 EXPECT_EQ(0, memcmp(&expected2, commands2, sizeof(expected2)));
2233 EXPECT_TRUE(CheckRect(
2234 kWidth, kHeight, kFormat, kType, kPixelStoreUnpackAlignment, true,
2235 pixels, mem2.ptr));
2238 // Test TexImage2D with 2 writes
2239 TEST_F(GLES2ImplementationTest, TexImage2D2Writes) {
2240 struct Cmds {
2241 cmds::TexImage2D tex_image_2d;
2242 cmds::TexSubImage2D tex_sub_image_2d1;
2243 cmd::SetToken set_token1;
2244 cmds::TexSubImage2D tex_sub_image_2d2;
2245 cmd::SetToken set_token2;
2247 const GLenum kTarget = GL_TEXTURE_2D;
2248 const GLint kLevel = 0;
2249 const GLenum kFormat = GL_RGB;
2250 const GLint kBorder = 0;
2251 const GLenum kType = GL_UNSIGNED_BYTE;
2252 const GLint kPixelStoreUnpackAlignment = 4;
2253 const GLsizei kWidth = 3;
2255 uint32 size = 0;
2256 uint32 unpadded_row_size = 0;
2257 uint32 padded_row_size = 0;
2258 ASSERT_TRUE(GLES2Util::ComputeImageDataSizes(
2259 kWidth, 2, kFormat, kType, kPixelStoreUnpackAlignment,
2260 &size, &unpadded_row_size, &padded_row_size));
2261 const GLsizei kHeight = (MaxTransferBufferSize() / padded_row_size) * 2;
2262 ASSERT_TRUE(GLES2Util::ComputeImageDataSizes(
2263 kWidth, kHeight, kFormat, kType, kPixelStoreUnpackAlignment,
2264 &size, NULL, NULL));
2265 uint32 half_size = 0;
2266 ASSERT_TRUE(GLES2Util::ComputeImageDataSizes(
2267 kWidth, kHeight / 2, kFormat, kType, kPixelStoreUnpackAlignment,
2268 &half_size, NULL, NULL));
2270 scoped_ptr<uint8[]> pixels(new uint8[size]);
2271 for (uint32 ii = 0; ii < size; ++ii) {
2272 pixels[ii] = static_cast<uint8>(ii);
2275 ExpectedMemoryInfo mem1 = GetExpectedMemory(half_size);
2276 ExpectedMemoryInfo mem2 = GetExpectedMemory(half_size);
2278 Cmds expected;
2279 expected.tex_image_2d.Init(
2280 kTarget, kLevel, kFormat, kWidth, kHeight, kFormat, kType,
2281 0, 0);
2282 expected.tex_sub_image_2d1.Init(
2283 kTarget, kLevel, 0, 0, kWidth, kHeight / 2, kFormat, kType,
2284 mem1.id, mem1.offset, true);
2285 expected.set_token1.Init(GetNextToken());
2286 expected.tex_sub_image_2d2.Init(
2287 kTarget, kLevel, 0, kHeight / 2, kWidth, kHeight / 2, kFormat, kType,
2288 mem2.id, mem2.offset, true);
2289 expected.set_token2.Init(GetNextToken());
2291 // TODO(gman): Make it possible to run this test
2292 // EXPECT_CALL(*command_buffer(), OnFlush())
2293 // .WillOnce(CheckRectAction(
2294 // kWidth, kHeight / 2, kFormat, kType, kPixelStoreUnpackAlignment,
2295 // false, pixels.get(),
2296 // GetExpectedTransferAddressFromOffsetAs<uint8>(offset1, half_size)))
2297 // .RetiresOnSaturation();
2299 gl_->TexImage2D(
2300 kTarget, kLevel, kFormat, kWidth, kHeight, kBorder, kFormat, kType,
2301 pixels.get());
2302 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
2303 EXPECT_TRUE(CheckRect(
2304 kWidth, kHeight / 2, kFormat, kType, kPixelStoreUnpackAlignment, false,
2305 pixels.get() + kHeight / 2 * padded_row_size, mem2.ptr));
2307 ClearCommands();
2308 gl_->PixelStorei(GL_UNPACK_FLIP_Y_CHROMIUM, GL_TRUE);
2309 const void* commands2 = GetPut();
2310 ExpectedMemoryInfo mem3 = GetExpectedMemory(half_size);
2311 ExpectedMemoryInfo mem4 = GetExpectedMemory(half_size);
2312 expected.tex_image_2d.Init(
2313 kTarget, kLevel, kFormat, kWidth, kHeight, kFormat, kType,
2314 0, 0);
2315 expected.tex_sub_image_2d1.Init(
2316 kTarget, kLevel, 0, kHeight / 2, kWidth, kHeight / 2, kFormat, kType,
2317 mem3.id, mem3.offset, true);
2318 expected.set_token1.Init(GetNextToken());
2319 expected.tex_sub_image_2d2.Init(
2320 kTarget, kLevel, 0, 0, kWidth, kHeight / 2, kFormat, kType,
2321 mem4.id, mem4.offset, true);
2322 expected.set_token2.Init(GetNextToken());
2324 // TODO(gman): Make it possible to run this test
2325 // EXPECT_CALL(*command_buffer(), OnFlush())
2326 // .WillOnce(CheckRectAction(
2327 // kWidth, kHeight / 2, kFormat, kType, kPixelStoreUnpackAlignment,
2328 // true, pixels.get(),
2329 // GetExpectedTransferAddressFromOffsetAs<uint8>(offset3, half_size)))
2330 // .RetiresOnSaturation();
2332 gl_->TexImage2D(
2333 kTarget, kLevel, kFormat, kWidth, kHeight, kBorder, kFormat, kType,
2334 pixels.get());
2335 EXPECT_EQ(0, memcmp(&expected, commands2, sizeof(expected)));
2336 EXPECT_TRUE(CheckRect(
2337 kWidth, kHeight / 2, kFormat, kType, kPixelStoreUnpackAlignment, true,
2338 pixels.get() + kHeight / 2 * padded_row_size, mem4.ptr));
2341 // Test TexSubImage2D with GL_PACK_FLIP_Y set and partial multirow transfers
2342 TEST_F(GLES2ImplementationTest, TexSubImage2DFlipY) {
2343 const GLsizei kTextureWidth = MaxTransferBufferSize() / 4;
2344 const GLsizei kTextureHeight = 7;
2345 const GLsizei kSubImageWidth = MaxTransferBufferSize() / 8;
2346 const GLsizei kSubImageHeight = 4;
2347 const GLint kSubImageXOffset = 1;
2348 const GLint kSubImageYOffset = 2;
2349 const GLenum kFormat = GL_RGBA;
2350 const GLenum kType = GL_UNSIGNED_BYTE;
2351 const GLenum kTarget = GL_TEXTURE_2D;
2352 const GLint kLevel = 0;
2353 const GLint kBorder = 0;
2354 const GLint kPixelStoreUnpackAlignment = 4;
2356 struct Cmds {
2357 cmds::PixelStorei pixel_store_i1;
2358 cmds::TexImage2D tex_image_2d;
2359 cmds::PixelStorei pixel_store_i2;
2360 cmds::TexSubImage2D tex_sub_image_2d1;
2361 cmd::SetToken set_token1;
2362 cmds::TexSubImage2D tex_sub_image_2d2;
2363 cmd::SetToken set_token2;
2366 uint32 sub_2_high_size = 0;
2367 ASSERT_TRUE(GLES2Util::ComputeImageDataSizes(
2368 kSubImageWidth, 2, kFormat, kType, kPixelStoreUnpackAlignment,
2369 &sub_2_high_size, NULL, NULL));
2371 ExpectedMemoryInfo mem1 = GetExpectedMemory(sub_2_high_size);
2372 ExpectedMemoryInfo mem2 = GetExpectedMemory(sub_2_high_size);
2374 Cmds expected;
2375 expected.pixel_store_i1.Init(GL_UNPACK_ALIGNMENT, kPixelStoreUnpackAlignment);
2376 expected.tex_image_2d.Init(
2377 kTarget, kLevel, kFormat, kTextureWidth, kTextureHeight, kFormat,
2378 kType, 0, 0);
2379 expected.pixel_store_i2.Init(GL_UNPACK_FLIP_Y_CHROMIUM, GL_TRUE);
2380 expected.tex_sub_image_2d1.Init(kTarget, kLevel, kSubImageXOffset,
2381 kSubImageYOffset + 2, kSubImageWidth, 2, kFormat, kType,
2382 mem1.id, mem1.offset, false);
2383 expected.set_token1.Init(GetNextToken());
2384 expected.tex_sub_image_2d2.Init(kTarget, kLevel, kSubImageXOffset,
2385 kSubImageYOffset, kSubImageWidth , 2, kFormat, kType,
2386 mem2.id, mem2.offset, false);
2387 expected.set_token2.Init(GetNextToken());
2389 gl_->PixelStorei(GL_UNPACK_ALIGNMENT, kPixelStoreUnpackAlignment);
2390 gl_->TexImage2D(
2391 kTarget, kLevel, kFormat, kTextureWidth, kTextureHeight, kBorder, kFormat,
2392 kType, NULL);
2393 gl_->PixelStorei(GL_UNPACK_FLIP_Y_CHROMIUM, GL_TRUE);
2394 scoped_ptr<uint32[]> pixels(new uint32[kSubImageWidth * kSubImageHeight]);
2395 for (int y = 0; y < kSubImageHeight; ++y) {
2396 for (int x = 0; x < kSubImageWidth; ++x) {
2397 pixels.get()[kSubImageWidth * y + x] = x | (y << 16);
2400 gl_->TexSubImage2D(
2401 GL_TEXTURE_2D, 0, kSubImageXOffset, kSubImageYOffset, kSubImageWidth,
2402 kSubImageHeight, GL_RGBA, GL_UNSIGNED_BYTE, pixels.get());
2404 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
2405 EXPECT_TRUE(CheckRect(
2406 kSubImageWidth, 2, kFormat, kType, kPixelStoreUnpackAlignment, true,
2407 reinterpret_cast<uint8*>(pixels.get() + 2 * kSubImageWidth),
2408 mem2.ptr));
2411 TEST_F(GLES2ImplementationTest, SubImageUnpack) {
2412 static const GLint unpack_alignments[] = { 1, 2, 4, 8 };
2414 static const GLenum kFormat = GL_RGB;
2415 static const GLenum kType = GL_UNSIGNED_BYTE;
2416 static const GLint kLevel = 0;
2417 static const GLint kBorder = 0;
2418 // We're testing using the unpack params to pull a subimage out of a larger
2419 // source of pixels. Here we specify the subimage by its border rows /
2420 // columns.
2421 static const GLint kSrcWidth = 33;
2422 static const GLint kSrcSubImageX0 = 11;
2423 static const GLint kSrcSubImageX1 = 20;
2424 static const GLint kSrcSubImageY0 = 18;
2425 static const GLint kSrcSubImageY1 = 23;
2426 static const GLint kSrcSubImageWidth = kSrcSubImageX1 - kSrcSubImageX0;
2427 static const GLint kSrcSubImageHeight = kSrcSubImageY1 - kSrcSubImageY0;
2429 // these are only used in the texsubimage tests
2430 static const GLint kTexWidth = 1023;
2431 static const GLint kTexHeight = 511;
2432 static const GLint kTexSubXOffset = 419;
2433 static const GLint kTexSubYOffset = 103;
2435 struct {
2436 cmds::PixelStorei pixel_store_i;
2437 cmds::PixelStorei pixel_store_i2;
2438 cmds::TexImage2D tex_image_2d;
2439 } texImageExpected;
2441 struct {
2442 cmds::PixelStorei pixel_store_i;
2443 cmds::PixelStorei pixel_store_i2;
2444 cmds::TexImage2D tex_image_2d;
2445 cmds::TexSubImage2D tex_sub_image_2d;
2446 } texSubImageExpected;
2448 uint32 src_size;
2449 ASSERT_TRUE(GLES2Util::ComputeImageDataSizes(
2450 kSrcWidth, kSrcSubImageY1, kFormat, kType, 8, &src_size, NULL, NULL));
2451 scoped_ptr<uint8[]> src_pixels;
2452 src_pixels.reset(new uint8[src_size]);
2453 for (size_t i = 0; i < src_size; ++i) {
2454 src_pixels[i] = static_cast<int8>(i);
2457 for (int sub = 0; sub < 2; ++sub) {
2458 for (int flip_y = 0; flip_y < 2; ++flip_y) {
2459 for (size_t a = 0; a < arraysize(unpack_alignments); ++a) {
2460 GLint alignment = unpack_alignments[a];
2461 uint32 size;
2462 uint32 unpadded_row_size;
2463 uint32 padded_row_size;
2464 ASSERT_TRUE(GLES2Util::ComputeImageDataSizes(
2465 kSrcSubImageWidth, kSrcSubImageHeight, kFormat, kType, alignment,
2466 &size, &unpadded_row_size, &padded_row_size));
2467 ASSERT_TRUE(size <= MaxTransferBufferSize());
2468 ExpectedMemoryInfo mem = GetExpectedMemory(size);
2470 const void* commands = GetPut();
2471 gl_->PixelStorei(GL_UNPACK_ALIGNMENT, alignment);
2472 gl_->PixelStorei(GL_UNPACK_ROW_LENGTH_EXT, kSrcWidth);
2473 gl_->PixelStorei(GL_UNPACK_SKIP_PIXELS_EXT, kSrcSubImageX0);
2474 gl_->PixelStorei(GL_UNPACK_SKIP_ROWS_EXT, kSrcSubImageY0);
2475 gl_->PixelStorei(GL_UNPACK_FLIP_Y_CHROMIUM, flip_y);
2476 if (sub) {
2477 gl_->TexImage2D(
2478 GL_TEXTURE_2D, kLevel, kFormat, kTexWidth, kTexHeight, kBorder,
2479 kFormat, kType, NULL);
2480 gl_->TexSubImage2D(
2481 GL_TEXTURE_2D, kLevel, kTexSubXOffset, kTexSubYOffset,
2482 kSrcSubImageWidth, kSrcSubImageHeight, kFormat, kType,
2483 src_pixels.get());
2484 texSubImageExpected.pixel_store_i.Init(
2485 GL_UNPACK_ALIGNMENT, alignment);
2486 texSubImageExpected.pixel_store_i2.Init(
2487 GL_UNPACK_FLIP_Y_CHROMIUM, flip_y);
2488 texSubImageExpected.tex_image_2d.Init(
2489 GL_TEXTURE_2D, kLevel, kFormat, kTexWidth, kTexHeight,
2490 kFormat, kType, 0, 0);
2491 texSubImageExpected.tex_sub_image_2d.Init(
2492 GL_TEXTURE_2D, kLevel, kTexSubXOffset, kTexSubYOffset,
2493 kSrcSubImageWidth, kSrcSubImageHeight, kFormat, kType, mem.id,
2494 mem.offset, GL_FALSE);
2495 EXPECT_EQ(0, memcmp(
2496 &texSubImageExpected, commands, sizeof(texSubImageExpected)));
2497 } else {
2498 gl_->TexImage2D(
2499 GL_TEXTURE_2D, kLevel, kFormat,
2500 kSrcSubImageWidth, kSrcSubImageHeight, kBorder, kFormat, kType,
2501 src_pixels.get());
2502 texImageExpected.pixel_store_i.Init(GL_UNPACK_ALIGNMENT, alignment);
2503 texImageExpected.pixel_store_i2.Init(
2504 GL_UNPACK_FLIP_Y_CHROMIUM, flip_y);
2505 texImageExpected.tex_image_2d.Init(
2506 GL_TEXTURE_2D, kLevel, kFormat, kSrcSubImageWidth,
2507 kSrcSubImageHeight, kFormat, kType, mem.id, mem.offset);
2508 EXPECT_EQ(0, memcmp(
2509 &texImageExpected, commands, sizeof(texImageExpected)));
2511 uint32 src_padded_row_size;
2512 ASSERT_TRUE(GLES2Util::ComputeImagePaddedRowSize(
2513 kSrcWidth, kFormat, kType, alignment, &src_padded_row_size));
2514 uint32 bytes_per_group = GLES2Util::ComputeImageGroupSize(
2515 kFormat, kType);
2516 for (int y = 0; y < kSrcSubImageHeight; ++y) {
2517 GLint src_sub_y = flip_y ? kSrcSubImageHeight - y - 1 : y;
2518 const uint8* src_row = src_pixels.get() +
2519 (kSrcSubImageY0 + src_sub_y) * src_padded_row_size +
2520 bytes_per_group * kSrcSubImageX0;
2521 const uint8* dst_row = mem.ptr + y * padded_row_size;
2522 EXPECT_EQ(0, memcmp(src_row, dst_row, unpadded_row_size));
2524 ClearCommands();
2530 // Test texture related calls with invalid arguments.
2531 TEST_F(GLES2ImplementationTest, TextureInvalidArguments) {
2532 struct Cmds {
2533 cmds::TexImage2D tex_image_2d;
2534 cmd::SetToken set_token;
2536 const GLenum kTarget = GL_TEXTURE_2D;
2537 const GLint kLevel = 0;
2538 const GLenum kFormat = GL_RGB;
2539 const GLsizei kWidth = 3;
2540 const GLsizei kHeight = 4;
2541 const GLint kBorder = 0;
2542 const GLint kInvalidBorder = 1;
2543 const GLenum kType = GL_UNSIGNED_BYTE;
2544 const GLint kPixelStoreUnpackAlignment = 4;
2545 static uint8 pixels[] = {
2546 11, 12, 13, 13, 14, 15, 15, 16, 17, 101, 102, 103,
2547 21, 22, 23, 23, 24, 25, 25, 26, 27, 201, 202, 203,
2548 31, 32, 33, 33, 34, 35, 35, 36, 37, 123, 124, 125,
2549 41, 42, 43, 43, 44, 45, 45, 46, 47,
2552 // Verify that something works.
2554 ExpectedMemoryInfo mem1 = GetExpectedMemory(sizeof(pixels));
2556 Cmds expected;
2557 expected.tex_image_2d.Init(
2558 kTarget, kLevel, kFormat, kWidth, kHeight, kFormat, kType,
2559 mem1.id, mem1.offset);
2560 expected.set_token.Init(GetNextToken());
2561 gl_->TexImage2D(
2562 kTarget, kLevel, kFormat, kWidth, kHeight, kBorder, kFormat, kType,
2563 pixels);
2564 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
2565 EXPECT_TRUE(CheckRect(
2566 kWidth, kHeight, kFormat, kType, kPixelStoreUnpackAlignment, false,
2567 pixels, mem1.ptr));
2569 ClearCommands();
2571 // Use invalid border.
2572 gl_->TexImage2D(
2573 kTarget, kLevel, kFormat, kWidth, kHeight, kInvalidBorder, kFormat, kType,
2574 pixels);
2576 EXPECT_TRUE(NoCommandsWritten());
2577 EXPECT_EQ(GL_INVALID_VALUE, CheckError());
2579 ClearCommands();
2581 gl_->AsyncTexImage2DCHROMIUM(
2582 kTarget, kLevel, kFormat, kWidth, kHeight, kInvalidBorder, kFormat, kType,
2583 NULL);
2585 EXPECT_TRUE(NoCommandsWritten());
2586 EXPECT_EQ(GL_INVALID_VALUE, CheckError());
2588 ClearCommands();
2590 // Checking for CompressedTexImage2D argument validation is a bit tricky due
2591 // to (runtime-detected) compression formats. Try to infer the error with an
2592 // aux check.
2593 const GLenum kCompressedFormat = GL_ETC1_RGB8_OES;
2594 gl_->CompressedTexImage2D(
2595 kTarget, kLevel, kCompressedFormat, kWidth, kHeight, kBorder,
2596 arraysize(pixels), pixels);
2598 // In the above, kCompressedFormat and arraysize(pixels) are possibly wrong
2599 // values. First ensure that these do not cause failures at the client. If
2600 // this check ever fails, it probably means that client checks more than at
2601 // the time of writing of this test. In this case, more code needs to be
2602 // written for this test.
2603 EXPECT_FALSE(NoCommandsWritten());
2605 ClearCommands();
2607 // Changing border to invalid border should make the call fail at the client
2608 // checks.
2609 gl_->CompressedTexImage2D(
2610 kTarget, kLevel, kCompressedFormat, kWidth, kHeight, kInvalidBorder,
2611 arraysize(pixels), pixels);
2612 EXPECT_TRUE(NoCommandsWritten());
2613 EXPECT_EQ(GL_INVALID_VALUE, CheckError());
2617 // Binds can not be cached with bind_generates_resource = false because
2618 // our id might not be valid. More specifically if you bind on contextA then
2619 // delete on contextB the resource is still bound on contextA but GetInterger
2620 // won't return an id.
2621 TEST_F(GLES2ImplementationStrictSharedTest, BindsNotCached) {
2622 struct PNameValue {
2623 GLenum pname;
2624 GLint expected;
2626 const PNameValue pairs[] = {{GL_TEXTURE_BINDING_2D, 1, },
2627 {GL_TEXTURE_BINDING_CUBE_MAP, 2, },
2628 {GL_TEXTURE_BINDING_EXTERNAL_OES, 3, },
2629 {GL_FRAMEBUFFER_BINDING, 4, },
2630 {GL_RENDERBUFFER_BINDING, 5, },
2631 {GL_ARRAY_BUFFER_BINDING, 6, },
2632 {GL_ELEMENT_ARRAY_BUFFER_BINDING, 7, }, };
2633 size_t num_pairs = sizeof(pairs) / sizeof(pairs[0]);
2634 for (size_t ii = 0; ii < num_pairs; ++ii) {
2635 const PNameValue& pv = pairs[ii];
2636 GLint v = -1;
2637 ExpectedMemoryInfo result1 =
2638 GetExpectedResultMemory(sizeof(cmds::GetIntegerv::Result));
2639 EXPECT_CALL(*command_buffer(), OnFlush())
2640 .WillOnce(SetMemory(result1.ptr,
2641 SizedResultHelper<GLuint>(pv.expected)))
2642 .RetiresOnSaturation();
2643 gl_->GetIntegerv(pv.pname, &v);
2644 EXPECT_EQ(pv.expected, v);
2648 // glGen* Ids must not be reused until glDelete* commands have been
2649 // flushed by glFlush.
2650 TEST_F(GLES2ImplementationStrictSharedTest, FlushGenerationTestBuffers) {
2651 FlushGenerationTest<GenBuffersAPI>();
2653 TEST_F(GLES2ImplementationStrictSharedTest, FlushGenerationTestFramebuffers) {
2654 FlushGenerationTest<GenFramebuffersAPI>();
2656 TEST_F(GLES2ImplementationStrictSharedTest, FlushGenerationTestRenderbuffers) {
2657 FlushGenerationTest<GenRenderbuffersAPI>();
2659 TEST_F(GLES2ImplementationStrictSharedTest, FlushGenerationTestTextures) {
2660 FlushGenerationTest<GenTexturesAPI>();
2663 // glGen* Ids must not be reused cross-context until glDelete* commands are
2664 // flushed by glFlush, and the Ids are lazily freed after.
2665 TEST_F(GLES2ImplementationStrictSharedTest, CrossContextGenerationTestBuffers) {
2666 CrossContextGenerationTest<GenBuffersAPI>();
2668 TEST_F(GLES2ImplementationStrictSharedTest,
2669 CrossContextGenerationTestFramebuffers) {
2670 CrossContextGenerationTest<GenFramebuffersAPI>();
2672 TEST_F(GLES2ImplementationStrictSharedTest,
2673 CrossContextGenerationTestRenderbuffers) {
2674 CrossContextGenerationTest<GenRenderbuffersAPI>();
2676 TEST_F(GLES2ImplementationStrictSharedTest,
2677 CrossContextGenerationTestTextures) {
2678 CrossContextGenerationTest<GenTexturesAPI>();
2681 // Test Delete which causes auto flush. Tests a regression case that occurred
2682 // in testing.
2683 TEST_F(GLES2ImplementationStrictSharedTest,
2684 CrossContextGenerationAutoFlushTestBuffers) {
2685 CrossContextGenerationAutoFlushTest<GenBuffersAPI>();
2687 TEST_F(GLES2ImplementationStrictSharedTest,
2688 CrossContextGenerationAutoFlushTestFramebuffers) {
2689 CrossContextGenerationAutoFlushTest<GenFramebuffersAPI>();
2691 TEST_F(GLES2ImplementationStrictSharedTest,
2692 CrossContextGenerationAutoFlushTestRenderbuffers) {
2693 CrossContextGenerationAutoFlushTest<GenRenderbuffersAPI>();
2695 TEST_F(GLES2ImplementationStrictSharedTest,
2696 CrossContextGenerationAutoFlushTestTextures) {
2697 CrossContextGenerationAutoFlushTest<GenTexturesAPI>();
2700 TEST_F(GLES2ImplementationTest, GetString) {
2701 const uint32 kBucketId = GLES2Implementation::kResultBucketId;
2702 const Str7 kString = {"foobar"};
2703 // GL_CHROMIUM_map_sub GL_CHROMIUM_flipy are hard coded into
2704 // GLES2Implementation.
2705 const char* expected_str =
2706 "foobar "
2707 "GL_CHROMIUM_flipy "
2708 "GL_EXT_unpack_subimage "
2709 "GL_CHROMIUM_map_sub";
2710 const char kBad = 0x12;
2711 struct Cmds {
2712 cmd::SetBucketSize set_bucket_size1;
2713 cmds::GetString get_string;
2714 cmd::GetBucketStart get_bucket_start;
2715 cmd::SetToken set_token1;
2716 cmd::SetBucketSize set_bucket_size2;
2718 ExpectedMemoryInfo mem1 = GetExpectedMemory(MaxTransferBufferSize());
2719 ExpectedMemoryInfo result1 =
2720 GetExpectedResultMemory(sizeof(cmd::GetBucketStart::Result));
2721 Cmds expected;
2722 expected.set_bucket_size1.Init(kBucketId, 0);
2723 expected.get_string.Init(GL_EXTENSIONS, kBucketId);
2724 expected.get_bucket_start.Init(
2725 kBucketId, result1.id, result1.offset,
2726 MaxTransferBufferSize(), mem1.id, mem1.offset);
2727 expected.set_token1.Init(GetNextToken());
2728 expected.set_bucket_size2.Init(kBucketId, 0);
2729 char buf[sizeof(kString) + 1];
2730 memset(buf, kBad, sizeof(buf));
2732 EXPECT_CALL(*command_buffer(), OnFlush())
2733 .WillOnce(DoAll(SetMemory(result1.ptr, uint32(sizeof(kString))),
2734 SetMemory(mem1.ptr, kString)))
2735 .RetiresOnSaturation();
2737 const GLubyte* result = gl_->GetString(GL_EXTENSIONS);
2738 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
2739 EXPECT_STREQ(expected_str, reinterpret_cast<const char*>(result));
2742 TEST_F(GLES2ImplementationTest, PixelStoreiGLPackReverseRowOrderANGLE) {
2743 const uint32 kBucketId = GLES2Implementation::kResultBucketId;
2744 const Str7 kString = {"foobar"};
2745 struct Cmds {
2746 cmd::SetBucketSize set_bucket_size1;
2747 cmds::GetString get_string;
2748 cmd::GetBucketStart get_bucket_start;
2749 cmd::SetToken set_token1;
2750 cmd::SetBucketSize set_bucket_size2;
2751 cmds::PixelStorei pixel_store;
2754 ExpectedMemoryInfo mem1 = GetExpectedMemory(MaxTransferBufferSize());
2755 ExpectedMemoryInfo result1 =
2756 GetExpectedResultMemory(sizeof(cmd::GetBucketStart::Result));
2758 Cmds expected;
2759 expected.set_bucket_size1.Init(kBucketId, 0);
2760 expected.get_string.Init(GL_EXTENSIONS, kBucketId);
2761 expected.get_bucket_start.Init(
2762 kBucketId, result1.id, result1.offset,
2763 MaxTransferBufferSize(), mem1.id, mem1.offset);
2764 expected.set_token1.Init(GetNextToken());
2765 expected.set_bucket_size2.Init(kBucketId, 0);
2766 expected.pixel_store.Init(GL_PACK_REVERSE_ROW_ORDER_ANGLE, 1);
2768 EXPECT_CALL(*command_buffer(), OnFlush())
2769 .WillOnce(DoAll(SetMemory(result1.ptr, uint32(sizeof(kString))),
2770 SetMemory(mem1.ptr, kString)))
2771 .RetiresOnSaturation();
2773 gl_->PixelStorei(GL_PACK_REVERSE_ROW_ORDER_ANGLE, 1);
2774 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
2777 TEST_F(GLES2ImplementationTest, CreateProgram) {
2778 struct Cmds {
2779 cmds::CreateProgram cmd;
2782 Cmds expected;
2783 expected.cmd.Init(kProgramsAndShadersStartId);
2784 GLuint id = gl_->CreateProgram();
2785 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
2786 EXPECT_EQ(kProgramsAndShadersStartId, id);
2789 TEST_F(GLES2ImplementationTest, BufferDataLargerThanTransferBuffer) {
2790 struct Cmds {
2791 cmds::BufferData set_size;
2792 cmds::BufferSubData copy_data1;
2793 cmd::SetToken set_token1;
2794 cmds::BufferSubData copy_data2;
2795 cmd::SetToken set_token2;
2797 const unsigned kUsableSize =
2798 kTransferBufferSize - GLES2Implementation::kStartingOffset;
2799 uint8 buf[kUsableSize * 2] = { 0, };
2801 ExpectedMemoryInfo mem1 = GetExpectedMemory(kUsableSize);
2802 ExpectedMemoryInfo mem2 = GetExpectedMemory(kUsableSize);
2804 Cmds expected;
2805 expected.set_size.Init(
2806 GL_ARRAY_BUFFER, arraysize(buf), 0, 0, GL_DYNAMIC_DRAW);
2807 expected.copy_data1.Init(
2808 GL_ARRAY_BUFFER, 0, kUsableSize, mem1.id, mem1.offset);
2809 expected.set_token1.Init(GetNextToken());
2810 expected.copy_data2.Init(
2811 GL_ARRAY_BUFFER, kUsableSize, kUsableSize, mem2.id, mem2.offset);
2812 expected.set_token2.Init(GetNextToken());
2813 gl_->BufferData(GL_ARRAY_BUFFER, arraysize(buf), buf, GL_DYNAMIC_DRAW);
2814 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
2817 TEST_F(GLES2ImplementationTest, CapabilitiesAreCached) {
2818 static const GLenum kStates[] = {
2819 GL_DITHER,
2820 GL_BLEND,
2821 GL_CULL_FACE,
2822 GL_DEPTH_TEST,
2823 GL_POLYGON_OFFSET_FILL,
2824 GL_SAMPLE_ALPHA_TO_COVERAGE,
2825 GL_SAMPLE_COVERAGE,
2826 GL_SCISSOR_TEST,
2827 GL_STENCIL_TEST,
2829 struct Cmds {
2830 cmds::Enable enable_cmd;
2832 Cmds expected;
2834 for (size_t ii = 0; ii < arraysize(kStates); ++ii) {
2835 GLenum state = kStates[ii];
2836 expected.enable_cmd.Init(state);
2837 GLboolean result = gl_->IsEnabled(state);
2838 EXPECT_EQ(static_cast<GLboolean>(ii == 0), result);
2839 EXPECT_TRUE(NoCommandsWritten());
2840 const void* commands = GetPut();
2841 if (!result) {
2842 gl_->Enable(state);
2843 EXPECT_EQ(0, memcmp(&expected, commands, sizeof(expected)));
2845 ClearCommands();
2846 result = gl_->IsEnabled(state);
2847 EXPECT_TRUE(result);
2848 EXPECT_TRUE(NoCommandsWritten());
2852 TEST_F(GLES2ImplementationTest, BindVertexArrayOES) {
2853 GLuint id = 0;
2854 gl_->GenVertexArraysOES(1, &id);
2855 ClearCommands();
2857 struct Cmds {
2858 cmds::BindVertexArrayOES cmd;
2860 Cmds expected;
2861 expected.cmd.Init(id);
2863 const void* commands = GetPut();
2864 gl_->BindVertexArrayOES(id);
2865 EXPECT_EQ(0, memcmp(&expected, commands, sizeof(expected)));
2866 ClearCommands();
2867 gl_->BindVertexArrayOES(id);
2868 EXPECT_TRUE(NoCommandsWritten());
2871 TEST_F(GLES2ImplementationTest, BeginEndQueryEXT) {
2872 // Test GetQueryivEXT returns 0 if no current query.
2873 GLint param = -1;
2874 gl_->GetQueryivEXT(GL_ANY_SAMPLES_PASSED_EXT, GL_CURRENT_QUERY_EXT, &param);
2875 EXPECT_EQ(0, param);
2877 GLuint expected_ids[2] = { 1, 2 }; // These must match what's actually genned.
2878 struct GenCmds {
2879 cmds::GenQueriesEXTImmediate gen;
2880 GLuint data[2];
2882 GenCmds expected_gen_cmds;
2883 expected_gen_cmds.gen.Init(arraysize(expected_ids), &expected_ids[0]);
2884 GLuint ids[arraysize(expected_ids)] = { 0, };
2885 gl_->GenQueriesEXT(arraysize(expected_ids), &ids[0]);
2886 EXPECT_EQ(0, memcmp(
2887 &expected_gen_cmds, commands_, sizeof(expected_gen_cmds)));
2888 GLuint id1 = ids[0];
2889 GLuint id2 = ids[1];
2890 ClearCommands();
2892 // Test BeginQueryEXT fails if id = 0.
2893 gl_->BeginQueryEXT(GL_ANY_SAMPLES_PASSED_EXT, 0);
2894 EXPECT_TRUE(NoCommandsWritten());
2895 EXPECT_EQ(GL_INVALID_OPERATION, CheckError());
2897 // Test BeginQueryEXT inserts command.
2898 struct BeginCmds {
2899 cmds::BeginQueryEXT begin_query;
2901 BeginCmds expected_begin_cmds;
2902 const void* commands = GetPut();
2903 gl_->BeginQueryEXT(GL_ANY_SAMPLES_PASSED_EXT, id1);
2904 QueryTracker::Query* query = GetQuery(id1);
2905 ASSERT_TRUE(query != NULL);
2906 expected_begin_cmds.begin_query.Init(
2907 GL_ANY_SAMPLES_PASSED_EXT, id1, query->shm_id(), query->shm_offset());
2908 EXPECT_EQ(0, memcmp(
2909 &expected_begin_cmds, commands, sizeof(expected_begin_cmds)));
2910 ClearCommands();
2912 // Test GetQueryivEXT returns id.
2913 param = -1;
2914 gl_->GetQueryivEXT(GL_ANY_SAMPLES_PASSED_EXT, GL_CURRENT_QUERY_EXT, &param);
2915 EXPECT_EQ(id1, static_cast<GLuint>(param));
2916 gl_->GetQueryivEXT(
2917 GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT, GL_CURRENT_QUERY_EXT, &param);
2918 EXPECT_EQ(0, param);
2920 // Test BeginQueryEXT fails if between Begin/End.
2921 gl_->BeginQueryEXT(GL_ANY_SAMPLES_PASSED_EXT, id2);
2922 EXPECT_TRUE(NoCommandsWritten());
2923 EXPECT_EQ(GL_INVALID_OPERATION, CheckError());
2925 // Test EndQueryEXT fails if target not same as current query.
2926 ClearCommands();
2927 gl_->EndQueryEXT(GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT);
2928 EXPECT_TRUE(NoCommandsWritten());
2929 EXPECT_EQ(GL_INVALID_OPERATION, CheckError());
2931 // Test EndQueryEXT sends command
2932 struct EndCmds {
2933 cmds::EndQueryEXT end_query;
2935 EndCmds expected_end_cmds;
2936 expected_end_cmds.end_query.Init(
2937 GL_ANY_SAMPLES_PASSED_EXT, query->submit_count());
2938 commands = GetPut();
2939 gl_->EndQueryEXT(GL_ANY_SAMPLES_PASSED_EXT);
2940 EXPECT_EQ(0, memcmp(
2941 &expected_end_cmds, commands, sizeof(expected_end_cmds)));
2943 // Test EndQueryEXT fails if no current query.
2944 ClearCommands();
2945 gl_->EndQueryEXT(GL_ANY_SAMPLES_PASSED_EXT);
2946 EXPECT_TRUE(NoCommandsWritten());
2947 EXPECT_EQ(GL_INVALID_OPERATION, CheckError());
2949 // Test 2nd Begin/End increments count.
2950 base::subtle::Atomic32 old_submit_count = query->submit_count();
2951 gl_->BeginQueryEXT(GL_ANY_SAMPLES_PASSED_EXT, id1);
2952 EXPECT_NE(old_submit_count, query->submit_count());
2953 expected_end_cmds.end_query.Init(
2954 GL_ANY_SAMPLES_PASSED_EXT, query->submit_count());
2955 commands = GetPut();
2956 gl_->EndQueryEXT(GL_ANY_SAMPLES_PASSED_EXT);
2957 EXPECT_EQ(0, memcmp(
2958 &expected_end_cmds, commands, sizeof(expected_end_cmds)));
2960 // Test BeginQueryEXT fails if target changed.
2961 ClearCommands();
2962 gl_->BeginQueryEXT(GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT, id1);
2963 EXPECT_TRUE(NoCommandsWritten());
2964 EXPECT_EQ(GL_INVALID_OPERATION, CheckError());
2966 // Test GetQueryObjectuivEXT fails if unused id
2967 GLuint available = 0xBDu;
2968 ClearCommands();
2969 gl_->GetQueryObjectuivEXT(id2, GL_QUERY_RESULT_AVAILABLE_EXT, &available);
2970 EXPECT_TRUE(NoCommandsWritten());
2971 EXPECT_EQ(0xBDu, available);
2972 EXPECT_EQ(GL_INVALID_OPERATION, CheckError());
2974 // Test GetQueryObjectuivEXT fails if bad id
2975 ClearCommands();
2976 gl_->GetQueryObjectuivEXT(4567, GL_QUERY_RESULT_AVAILABLE_EXT, &available);
2977 EXPECT_TRUE(NoCommandsWritten());
2978 EXPECT_EQ(0xBDu, available);
2979 EXPECT_EQ(GL_INVALID_OPERATION, CheckError());
2981 // Test GetQueryObjectuivEXT CheckResultsAvailable
2982 ClearCommands();
2983 gl_->GetQueryObjectuivEXT(id1, GL_QUERY_RESULT_AVAILABLE_EXT, &available);
2984 EXPECT_EQ(0u, available);
2987 TEST_F(GLES2ImplementationTest, ErrorQuery) {
2988 GLuint id = 0;
2989 gl_->GenQueriesEXT(1, &id);
2990 ClearCommands();
2992 // Test BeginQueryEXT does NOT insert commands.
2993 gl_->BeginQueryEXT(GL_GET_ERROR_QUERY_CHROMIUM, id);
2994 EXPECT_TRUE(NoCommandsWritten());
2995 QueryTracker::Query* query = GetQuery(id);
2996 ASSERT_TRUE(query != NULL);
2998 // Test EndQueryEXT sends both begin and end command
2999 struct EndCmds {
3000 cmds::BeginQueryEXT begin_query;
3001 cmds::EndQueryEXT end_query;
3003 EndCmds expected_end_cmds;
3004 expected_end_cmds.begin_query.Init(
3005 GL_GET_ERROR_QUERY_CHROMIUM, id, query->shm_id(), query->shm_offset());
3006 expected_end_cmds.end_query.Init(
3007 GL_GET_ERROR_QUERY_CHROMIUM, query->submit_count());
3008 const void* commands = GetPut();
3009 gl_->EndQueryEXT(GL_GET_ERROR_QUERY_CHROMIUM);
3010 EXPECT_EQ(0, memcmp(
3011 &expected_end_cmds, commands, sizeof(expected_end_cmds)));
3012 ClearCommands();
3014 // Check result is not yet available.
3015 GLuint available = 0xBDu;
3016 gl_->GetQueryObjectuivEXT(id, GL_QUERY_RESULT_AVAILABLE_EXT, &available);
3017 EXPECT_TRUE(NoCommandsWritten());
3018 EXPECT_EQ(0u, available);
3020 // Test no commands are sent if there is a client side error.
3022 // Generate a client side error
3023 gl_->ActiveTexture(GL_TEXTURE0 - 1);
3025 gl_->BeginQueryEXT(GL_GET_ERROR_QUERY_CHROMIUM, id);
3026 gl_->EndQueryEXT(GL_GET_ERROR_QUERY_CHROMIUM);
3027 EXPECT_TRUE(NoCommandsWritten());
3029 // Check result is available.
3030 gl_->GetQueryObjectuivEXT(id, GL_QUERY_RESULT_AVAILABLE_EXT, &available);
3031 EXPECT_TRUE(NoCommandsWritten());
3032 EXPECT_NE(0u, available);
3034 // Check result.
3035 GLuint result = 0xBDu;
3036 gl_->GetQueryObjectuivEXT(id, GL_QUERY_RESULT_EXT, &result);
3037 EXPECT_TRUE(NoCommandsWritten());
3038 EXPECT_EQ(static_cast<GLuint>(GL_INVALID_ENUM), result);
3041 #if !defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS)
3042 TEST_F(GLES2ImplementationTest, VertexArrays) {
3043 const GLuint kAttribIndex1 = 1;
3044 const GLint kNumComponents1 = 3;
3045 const GLsizei kClientStride = 12;
3047 GLuint id = 0;
3048 gl_->GenVertexArraysOES(1, &id);
3049 ClearCommands();
3051 gl_->BindVertexArrayOES(id);
3053 // Test that VertexAttribPointer cannot be called with a bound buffer of 0
3054 // unless the offset is NULL
3055 gl_->BindBuffer(GL_ARRAY_BUFFER, 0);
3057 gl_->VertexAttribPointer(
3058 kAttribIndex1, kNumComponents1, GL_FLOAT, GL_FALSE, kClientStride,
3059 reinterpret_cast<const void*>(4));
3060 EXPECT_EQ(GL_INVALID_OPERATION, CheckError());
3062 gl_->VertexAttribPointer(
3063 kAttribIndex1, kNumComponents1, GL_FLOAT, GL_FALSE, kClientStride, NULL);
3064 EXPECT_EQ(GL_NO_ERROR, CheckError());
3066 #endif
3068 TEST_F(GLES2ImplementationTest, Disable) {
3069 struct Cmds {
3070 cmds::Disable cmd;
3072 Cmds expected;
3073 expected.cmd.Init(GL_DITHER); // Note: DITHER defaults to enabled.
3075 gl_->Disable(GL_DITHER);
3076 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
3077 // Check it's cached and not called again.
3078 ClearCommands();
3079 gl_->Disable(GL_DITHER);
3080 EXPECT_TRUE(NoCommandsWritten());
3083 TEST_F(GLES2ImplementationTest, Enable) {
3084 struct Cmds {
3085 cmds::Enable cmd;
3087 Cmds expected;
3088 expected.cmd.Init(GL_BLEND); // Note: BLEND defaults to disabled.
3090 gl_->Enable(GL_BLEND);
3091 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
3092 // Check it's cached and not called again.
3093 ClearCommands();
3094 gl_->Enable(GL_BLEND);
3095 EXPECT_TRUE(NoCommandsWritten());
3098 TEST_F(GLES2ImplementationTest, ConsumeTextureCHROMIUM) {
3099 struct Cmds {
3100 cmds::ConsumeTextureCHROMIUMImmediate cmd;
3101 GLbyte data[64];
3104 Mailbox mailbox = Mailbox::Generate();
3105 Cmds expected;
3106 expected.cmd.Init(GL_TEXTURE_2D, mailbox.name);
3107 gl_->ConsumeTextureCHROMIUM(GL_TEXTURE_2D, mailbox.name);
3108 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
3111 TEST_F(GLES2ImplementationTest, CreateAndConsumeTextureCHROMIUM) {
3112 struct Cmds {
3113 cmds::CreateAndConsumeTextureCHROMIUMImmediate cmd;
3114 GLbyte data[64];
3117 Mailbox mailbox = Mailbox::Generate();
3118 Cmds expected;
3119 expected.cmd.Init(GL_TEXTURE_2D, kTexturesStartId, mailbox.name);
3120 GLuint id = gl_->CreateAndConsumeTextureCHROMIUM(GL_TEXTURE_2D, mailbox.name);
3121 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
3122 EXPECT_EQ(kTexturesStartId, id);
3125 TEST_F(GLES2ImplementationTest, ProduceTextureCHROMIUM) {
3126 struct Cmds {
3127 cmds::ProduceTextureCHROMIUMImmediate cmd;
3128 GLbyte data[64];
3131 Mailbox mailbox = Mailbox::Generate();
3132 Cmds expected;
3133 expected.cmd.Init(GL_TEXTURE_2D, mailbox.name);
3134 gl_->ProduceTextureCHROMIUM(GL_TEXTURE_2D, mailbox.name);
3135 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
3138 TEST_F(GLES2ImplementationTest, ProduceTextureDirectCHROMIUM) {
3139 struct Cmds {
3140 cmds::ProduceTextureDirectCHROMIUMImmediate cmd;
3141 GLbyte data[64];
3144 Mailbox mailbox = Mailbox::Generate();
3145 Cmds expected;
3146 expected.cmd.Init(kTexturesStartId, GL_TEXTURE_2D, mailbox.name);
3147 gl_->ProduceTextureDirectCHROMIUM(
3148 kTexturesStartId, GL_TEXTURE_2D, mailbox.name);
3149 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
3152 TEST_F(GLES2ImplementationTest, LimitSizeAndOffsetTo32Bit) {
3153 GLsizeiptr size;
3154 GLintptr offset;
3155 if (sizeof(size) <= 4 || sizeof(offset) <= 4)
3156 return;
3157 // The below two casts should be no-op, as we return early if
3158 // it's 32-bit system.
3159 int64 value64 = 0x100000000;
3160 size = static_cast<GLsizeiptr>(value64);
3161 offset = static_cast<GLintptr>(value64);
3163 const char kSizeOverflowMessage[] = "size more than 32-bit";
3164 const char kOffsetOverflowMessage[] = "offset more than 32-bit";
3166 const GLfloat buf[] = { 1.0, 1.0, 1.0, 1.0 };
3167 const GLubyte indices[] = { 0 };
3169 const GLuint kClientArrayBufferId = 0x789;
3170 const GLuint kClientElementArrayBufferId = 0x790;
3171 gl_->BindBuffer(GL_ARRAY_BUFFER, kClientArrayBufferId);
3172 gl_->BindBuffer(GL_ELEMENT_ARRAY_BUFFER, kClientElementArrayBufferId);
3173 EXPECT_EQ(GL_NO_ERROR, CheckError());
3175 // Call BufferData() should succeed with legal paramaters.
3176 gl_->BufferData(GL_ARRAY_BUFFER, sizeof(buf), buf, GL_DYNAMIC_DRAW);
3177 gl_->BufferData(
3178 GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_DYNAMIC_DRAW);
3179 EXPECT_EQ(GL_NO_ERROR, CheckError());
3181 // BufferData: size
3182 gl_->BufferData(GL_ARRAY_BUFFER, size, buf, GL_DYNAMIC_DRAW);
3183 EXPECT_EQ(GL_INVALID_OPERATION, CheckError());
3184 EXPECT_STREQ(kSizeOverflowMessage, GetLastError().c_str());
3186 // Call BufferSubData() should succeed with legal paramaters.
3187 gl_->BufferSubData(GL_ARRAY_BUFFER, 0, sizeof(buf[0]), buf);
3188 EXPECT_EQ(GL_NO_ERROR, CheckError());
3190 // BufferSubData: offset
3191 gl_->BufferSubData(GL_ARRAY_BUFFER, offset, 1, buf);
3192 EXPECT_EQ(GL_INVALID_OPERATION, CheckError());
3193 EXPECT_STREQ(kOffsetOverflowMessage, GetLastError().c_str());
3195 // BufferSubData: size
3196 EXPECT_EQ(GL_NO_ERROR, CheckError());
3197 gl_->BufferSubData(GL_ARRAY_BUFFER, 0, size, buf);
3198 EXPECT_EQ(GL_INVALID_OPERATION, CheckError());
3199 EXPECT_STREQ(kSizeOverflowMessage, GetLastError().c_str());
3201 // Call MapBufferSubDataCHROMIUM() should succeed with legal paramaters.
3202 void* mem =
3203 gl_->MapBufferSubDataCHROMIUM(GL_ARRAY_BUFFER, 0, 1, GL_WRITE_ONLY);
3204 EXPECT_TRUE(NULL != mem);
3205 EXPECT_EQ(GL_NO_ERROR, CheckError());
3206 gl_->UnmapBufferSubDataCHROMIUM(mem);
3208 // MapBufferSubDataCHROMIUM: offset
3209 EXPECT_TRUE(NULL == gl_->MapBufferSubDataCHROMIUM(
3210 GL_ARRAY_BUFFER, offset, 1, GL_WRITE_ONLY));
3211 EXPECT_EQ(GL_INVALID_OPERATION, CheckError());
3212 EXPECT_STREQ(kOffsetOverflowMessage, GetLastError().c_str());
3214 // MapBufferSubDataCHROMIUM: size
3215 EXPECT_EQ(GL_NO_ERROR, CheckError());
3216 EXPECT_TRUE(NULL == gl_->MapBufferSubDataCHROMIUM(
3217 GL_ARRAY_BUFFER, 0, size, GL_WRITE_ONLY));
3218 EXPECT_EQ(GL_INVALID_OPERATION, CheckError());
3219 EXPECT_STREQ(kSizeOverflowMessage, GetLastError().c_str());
3221 // Call DrawElements() should succeed with legal paramaters.
3222 gl_->DrawElements(GL_POINTS, 1, GL_UNSIGNED_BYTE, NULL);
3223 EXPECT_EQ(GL_NO_ERROR, CheckError());
3225 // DrawElements: offset
3226 gl_->DrawElements(
3227 GL_POINTS, 1, GL_UNSIGNED_BYTE, reinterpret_cast<void*>(offset));
3228 EXPECT_EQ(GL_INVALID_OPERATION, CheckError());
3229 EXPECT_STREQ(kOffsetOverflowMessage, GetLastError().c_str());
3231 // Call DrawElementsInstancedANGLE() should succeed with legal paramaters.
3232 gl_->DrawElementsInstancedANGLE(GL_POINTS, 1, GL_UNSIGNED_BYTE, NULL, 1);
3233 EXPECT_EQ(GL_NO_ERROR, CheckError());
3235 // DrawElementsInstancedANGLE: offset
3236 gl_->DrawElementsInstancedANGLE(
3237 GL_POINTS, 1, GL_UNSIGNED_BYTE, reinterpret_cast<void*>(offset), 1);
3238 EXPECT_EQ(GL_INVALID_OPERATION, CheckError());
3239 EXPECT_STREQ(kOffsetOverflowMessage, GetLastError().c_str());
3241 // Call VertexAttribPointer() should succeed with legal paramaters.
3242 const GLuint kAttribIndex = 1;
3243 const GLsizei kStride = 4;
3244 gl_->VertexAttribPointer(
3245 kAttribIndex, 1, GL_FLOAT, GL_FALSE, kStride, NULL);
3246 EXPECT_EQ(GL_NO_ERROR, CheckError());
3248 // VertexAttribPointer: offset
3249 gl_->VertexAttribPointer(
3250 kAttribIndex, 1, GL_FLOAT, GL_FALSE, kStride,
3251 reinterpret_cast<void*>(offset));
3252 EXPECT_EQ(GL_INVALID_OPERATION, CheckError());
3253 EXPECT_STREQ(kOffsetOverflowMessage, GetLastError().c_str());
3256 TEST_F(GLES2ImplementationManualInitTest, LoseContextOnOOM) {
3257 ContextInitOptions init_options;
3258 init_options.lose_context_when_out_of_memory = true;
3259 ASSERT_TRUE(Initialize(init_options));
3261 struct Cmds {
3262 cmds::LoseContextCHROMIUM cmd;
3265 GLsizei max = std::numeric_limits<GLsizei>::max();
3266 EXPECT_CALL(*gpu_control_, CreateGpuMemoryBufferImage(max, max, _, _))
3267 .WillOnce(Return(-1));
3268 gl_->CreateGpuMemoryBufferImageCHROMIUM(max, max, GL_RGBA, GL_MAP_CHROMIUM);
3269 // The context should be lost.
3270 Cmds expected;
3271 expected.cmd.Init(GL_GUILTY_CONTEXT_RESET_ARB, GL_UNKNOWN_CONTEXT_RESET_ARB);
3272 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
3275 TEST_F(GLES2ImplementationManualInitTest, NoLoseContextOnOOM) {
3276 ContextInitOptions init_options;
3277 ASSERT_TRUE(Initialize(init_options));
3279 struct Cmds {
3280 cmds::LoseContextCHROMIUM cmd;
3283 GLsizei max = std::numeric_limits<GLsizei>::max();
3284 EXPECT_CALL(*gpu_control_, CreateGpuMemoryBufferImage(max, max, _, _))
3285 .WillOnce(Return(-1));
3286 gl_->CreateGpuMemoryBufferImageCHROMIUM(max, max, GL_RGBA, GL_MAP_CHROMIUM);
3287 // The context should not be lost.
3288 EXPECT_TRUE(NoCommandsWritten());
3291 TEST_F(GLES2ImplementationManualInitTest, FailInitOnBGRMismatch1) {
3292 ContextInitOptions init_options;
3293 init_options.bind_generates_resource_client = false;
3294 init_options.bind_generates_resource_service = true;
3295 EXPECT_FALSE(Initialize(init_options));
3298 TEST_F(GLES2ImplementationManualInitTest, FailInitOnBGRMismatch2) {
3299 ContextInitOptions init_options;
3300 init_options.bind_generates_resource_client = true;
3301 init_options.bind_generates_resource_service = false;
3302 EXPECT_FALSE(Initialize(init_options));
3305 #include "gpu/command_buffer/client/gles2_implementation_unittest_autogen.h"
3307 } // namespace gles2
3308 } // namespace gpu