Let the browser know about the renderer's page id assignments, even if the renderer...
[chromium-blink-merge.git] / gpu / command_buffer / client / gles2_implementation_unittest.cc
blobb4e266777f8ddfaebaa135fdc367fd4b4226adef
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 virtual ~MockTransferBuffer() { }
119 virtual bool Initialize(
120 unsigned int starting_buffer_size,
121 unsigned int result_size,
122 unsigned int /* min_buffer_size */,
123 unsigned int /* max_buffer_size */,
124 unsigned int alignment,
125 unsigned int size_to_flush) override;
126 virtual int GetShmId() override;
127 virtual void* GetResultBuffer() override;
128 virtual int GetResultOffset() override;
129 virtual void Free() override;
130 virtual bool HaveBuffer() const override;
131 virtual void* AllocUpTo(
132 unsigned int size, unsigned int* size_allocated) override;
133 virtual void* Alloc(unsigned int size) override;
134 virtual RingBuffer::Offset GetOffset(void* pointer) const override;
135 virtual void FreePendingToken(void* p, unsigned int /* token */) override;
137 size_t MaxTransferBufferSize() {
138 return size_ - result_size_;
141 unsigned int RoundToAlignment(unsigned int size) {
142 return (size + alignment_ - 1) & ~(alignment_ - 1);
145 bool InSync() {
146 return expected_buffer_index_ == actual_buffer_index_ &&
147 expected_offset_ == actual_offset_;
150 ExpectedMemoryInfo GetExpectedMemory(size_t size) {
151 ExpectedMemoryInfo mem;
152 mem.offset = AllocateExpectedTransferBuffer(size);
153 mem.id = GetExpectedTransferBufferId();
154 mem.ptr = static_cast<uint8*>(
155 GetExpectedTransferAddressFromOffset(mem.offset, size));
156 return mem;
159 ExpectedMemoryInfo GetExpectedResultMemory(size_t size) {
160 ExpectedMemoryInfo mem;
161 mem.offset = GetExpectedResultBufferOffset();
162 mem.id = GetExpectedResultBufferId();
163 mem.ptr = static_cast<uint8*>(
164 GetExpectedTransferAddressFromOffset(mem.offset, size));
165 return mem;
168 private:
169 static const int kNumBuffers = 2;
171 uint8* actual_buffer() const {
172 return static_cast<uint8*>(buffers_[actual_buffer_index_]->memory());
175 uint8* expected_buffer() const {
176 return static_cast<uint8*>(buffers_[expected_buffer_index_]->memory());
179 uint32 AllocateExpectedTransferBuffer(size_t size) {
180 EXPECT_LE(size, MaxTransferBufferSize());
182 // Toggle which buffer we get each time to simulate the buffer being
183 // reallocated.
184 expected_buffer_index_ = (expected_buffer_index_ + 1) % kNumBuffers;
186 if (expected_offset_ + size > size_) {
187 expected_offset_ = result_size_;
189 uint32 offset = expected_offset_;
190 expected_offset_ += RoundToAlignment(size);
192 // Make sure each buffer has a different offset.
193 return offset + expected_buffer_index_ * alignment_;
196 void* GetExpectedTransferAddressFromOffset(uint32 offset, size_t size) {
197 EXPECT_GE(offset, expected_buffer_index_ * alignment_);
198 EXPECT_LE(offset + size, size_ + expected_buffer_index_ * alignment_);
199 return expected_buffer() + offset;
202 int GetExpectedResultBufferId() {
203 return buffer_ids_[expected_buffer_index_];
206 uint32 GetExpectedResultBufferOffset() {
207 return expected_buffer_index_ * alignment_;
210 int GetExpectedTransferBufferId() {
211 return buffer_ids_[expected_buffer_index_];
214 CommandBuffer* command_buffer_;
215 size_t size_;
216 size_t result_size_;
217 uint32 alignment_;
218 int buffer_ids_[kNumBuffers];
219 scoped_refptr<Buffer> buffers_[kNumBuffers];
220 int actual_buffer_index_;
221 int expected_buffer_index_;
222 void* last_alloc_;
223 uint32 expected_offset_;
224 uint32 actual_offset_;
226 DISALLOW_COPY_AND_ASSIGN(MockTransferBuffer);
229 bool MockTransferBuffer::Initialize(
230 unsigned int starting_buffer_size,
231 unsigned int result_size,
232 unsigned int /* min_buffer_size */,
233 unsigned int /* max_buffer_size */,
234 unsigned int alignment,
235 unsigned int /* size_to_flush */) {
236 // Just check they match.
237 return size_ == starting_buffer_size &&
238 result_size_ == result_size &&
239 alignment_ == alignment;
242 int MockTransferBuffer::GetShmId() {
243 return buffer_ids_[actual_buffer_index_];
246 void* MockTransferBuffer::GetResultBuffer() {
247 return actual_buffer() + actual_buffer_index_ * alignment_;
250 int MockTransferBuffer::GetResultOffset() {
251 return actual_buffer_index_ * alignment_;
254 void MockTransferBuffer::Free() {
255 NOTREACHED();
258 bool MockTransferBuffer::HaveBuffer() const {
259 return true;
262 void* MockTransferBuffer::AllocUpTo(
263 unsigned int size, unsigned int* size_allocated) {
264 EXPECT_TRUE(size_allocated != NULL);
265 EXPECT_TRUE(last_alloc_ == NULL);
267 // Toggle which buffer we get each time to simulate the buffer being
268 // reallocated.
269 actual_buffer_index_ = (actual_buffer_index_ + 1) % kNumBuffers;
271 size = std::min(static_cast<size_t>(size), MaxTransferBufferSize());
272 if (actual_offset_ + size > size_) {
273 actual_offset_ = result_size_;
275 uint32 offset = actual_offset_;
276 actual_offset_ += RoundToAlignment(size);
277 *size_allocated = size;
279 // Make sure each buffer has a different offset.
280 last_alloc_ = actual_buffer() + offset + actual_buffer_index_ * alignment_;
281 return last_alloc_;
284 void* MockTransferBuffer::Alloc(unsigned int size) {
285 EXPECT_LE(size, MaxTransferBufferSize());
286 unsigned int temp = 0;
287 void* p = AllocUpTo(size, &temp);
288 EXPECT_EQ(temp, size);
289 return p;
292 RingBuffer::Offset MockTransferBuffer::GetOffset(void* pointer) const {
293 // Make sure each buffer has a different offset.
294 return static_cast<uint8*>(pointer) - actual_buffer();
297 void MockTransferBuffer::FreePendingToken(void* p, unsigned int /* token */) {
298 EXPECT_EQ(last_alloc_, p);
299 last_alloc_ = NULL;
302 // API wrapper for Buffers.
303 class GenBuffersAPI {
304 public:
305 static void Gen(GLES2Implementation* gl_impl, GLsizei n, GLuint* ids) {
306 gl_impl->GenBuffers(n, ids);
309 static void Delete(GLES2Implementation* gl_impl,
310 GLsizei n,
311 const GLuint* ids) {
312 gl_impl->DeleteBuffers(n, ids);
316 // API wrapper for Framebuffers.
317 class GenFramebuffersAPI {
318 public:
319 static void Gen(GLES2Implementation* gl_impl, GLsizei n, GLuint* ids) {
320 gl_impl->GenFramebuffers(n, ids);
323 static void Delete(GLES2Implementation* gl_impl,
324 GLsizei n,
325 const GLuint* ids) {
326 gl_impl->DeleteFramebuffers(n, ids);
330 // API wrapper for Renderbuffers.
331 class GenRenderbuffersAPI {
332 public:
333 static void Gen(GLES2Implementation* gl_impl, GLsizei n, GLuint* ids) {
334 gl_impl->GenRenderbuffers(n, ids);
337 static void Delete(GLES2Implementation* gl_impl,
338 GLsizei n,
339 const GLuint* ids) {
340 gl_impl->DeleteRenderbuffers(n, ids);
344 // API wrapper for Textures.
345 class GenTexturesAPI {
346 public:
347 static void Gen(GLES2Implementation* gl_impl, GLsizei n, GLuint* ids) {
348 gl_impl->GenTextures(n, ids);
351 static void Delete(GLES2Implementation* gl_impl,
352 GLsizei n,
353 const GLuint* ids) {
354 gl_impl->DeleteTextures(n, ids);
358 class GLES2ImplementationTest : public testing::Test {
359 protected:
360 static const int kNumTestContexts = 2;
361 static const uint8 kInitialValue = 0xBD;
362 static const int32 kNumCommandEntries = 500;
363 static const int32 kCommandBufferSizeBytes =
364 kNumCommandEntries * sizeof(CommandBufferEntry);
365 static const size_t kTransferBufferSize = 512;
367 static const GLint kMaxCombinedTextureImageUnits = 8;
368 static const GLint kMaxCubeMapTextureSize = 64;
369 static const GLint kMaxFragmentUniformVectors = 16;
370 static const GLint kMaxRenderbufferSize = 64;
371 static const GLint kMaxTextureImageUnits = 8;
372 static const GLint kMaxTextureSize = 128;
373 static const GLint kMaxVaryingVectors = 8;
374 static const GLint kMaxVertexAttribs = 8;
375 static const GLint kMaxVertexTextureImageUnits = 0;
376 static const GLint kMaxVertexUniformVectors = 128;
377 static const GLint kNumCompressedTextureFormats = 0;
378 static const GLint kNumShaderBinaryFormats = 0;
379 static const GLuint kStartId = 1024;
380 static const GLuint kBuffersStartId =
381 GLES2Implementation::kClientSideArrayId + 2 * kNumTestContexts;
382 static const GLuint kFramebuffersStartId = 1;
383 static const GLuint kProgramsAndShadersStartId = 1;
384 static const GLuint kRenderbuffersStartId = 1;
385 static const GLuint kTexturesStartId = 1;
386 static const GLuint kQueriesStartId = 1;
387 static const GLuint kVertexArraysStartId = 1;
389 typedef MockTransferBuffer::ExpectedMemoryInfo ExpectedMemoryInfo;
391 class TestContext {
392 public:
393 TestContext() : commands_(NULL), token_(0) {}
395 bool Initialize(ShareGroup* share_group,
396 bool bind_generates_resource_client,
397 bool bind_generates_resource_service,
398 bool lose_context_when_out_of_memory) {
399 command_buffer_.reset(new StrictMock<MockClientCommandBuffer>());
400 if (!command_buffer_->Initialize())
401 return false;
403 transfer_buffer_.reset(
404 new MockTransferBuffer(command_buffer_.get(),
405 kTransferBufferSize,
406 GLES2Implementation::kStartingOffset,
407 GLES2Implementation::kAlignment));
409 helper_.reset(new GLES2CmdHelper(command_buffer()));
410 helper_->Initialize(kCommandBufferSizeBytes);
412 gpu_control_.reset(new StrictMock<MockClientGpuControl>());
413 EXPECT_CALL(*gpu_control_, GetCapabilities())
414 .WillOnce(testing::Return(Capabilities()));
416 GLES2Implementation::GLStaticState state;
417 GLES2Implementation::GLStaticState::IntState& int_state = state.int_state;
418 int_state.max_combined_texture_image_units =
419 kMaxCombinedTextureImageUnits;
420 int_state.max_cube_map_texture_size = kMaxCubeMapTextureSize;
421 int_state.max_fragment_uniform_vectors = kMaxFragmentUniformVectors;
422 int_state.max_renderbuffer_size = kMaxRenderbufferSize;
423 int_state.max_texture_image_units = kMaxTextureImageUnits;
424 int_state.max_texture_size = kMaxTextureSize;
425 int_state.max_varying_vectors = kMaxVaryingVectors;
426 int_state.max_vertex_attribs = kMaxVertexAttribs;
427 int_state.max_vertex_texture_image_units = kMaxVertexTextureImageUnits;
428 int_state.max_vertex_uniform_vectors = kMaxVertexUniformVectors;
429 int_state.num_compressed_texture_formats = kNumCompressedTextureFormats;
430 int_state.num_shader_binary_formats = kNumShaderBinaryFormats;
431 int_state.bind_generates_resource_chromium =
432 bind_generates_resource_service ? 1 : 0;
434 // This just happens to work for now because IntState has 1 GLint per
435 // state.
436 // If IntState gets more complicated this code will need to get more
437 // complicated.
438 ExpectedMemoryInfo mem1 = transfer_buffer_->GetExpectedMemory(
439 sizeof(GLES2Implementation::GLStaticState::IntState) * 2 +
440 sizeof(cmds::GetShaderPrecisionFormat::Result) * 12);
443 InSequence sequence;
445 EXPECT_CALL(*command_buffer_, OnFlush())
446 .WillOnce(SetMemory(mem1.ptr + sizeof(int_state), int_state))
447 .RetiresOnSaturation();
448 GetNextToken(); // eat the token that starting up will use.
450 gl_.reset(new GLES2Implementation(helper_.get(),
451 share_group,
452 transfer_buffer_.get(),
453 bind_generates_resource_client,
454 lose_context_when_out_of_memory,
455 gpu_control_.get()));
457 if (!gl_->Initialize(kTransferBufferSize,
458 kTransferBufferSize,
459 kTransferBufferSize,
460 GLES2Implementation::kNoLimit))
461 return false;
464 EXPECT_CALL(*command_buffer_, OnFlush()).Times(1).RetiresOnSaturation();
465 helper_->CommandBufferHelper::Finish();
466 ::testing::Mock::VerifyAndClearExpectations(gl_.get());
468 scoped_refptr<Buffer> ring_buffer = helper_->get_ring_buffer();
469 commands_ = static_cast<CommandBufferEntry*>(ring_buffer->memory()) +
470 command_buffer()->GetLastState().put_offset;
471 ClearCommands();
472 EXPECT_TRUE(transfer_buffer_->InSync());
474 ::testing::Mock::VerifyAndClearExpectations(command_buffer());
475 return true;
478 void TearDown() {
479 Mock::VerifyAndClear(gl_.get());
480 EXPECT_CALL(*command_buffer(), OnFlush()).Times(AnyNumber());
481 // For command buffer.
482 EXPECT_CALL(*command_buffer(), DestroyTransferBuffer(_))
483 .Times(AtLeast(1));
484 gl_.reset();
487 MockClientCommandBuffer* command_buffer() const {
488 return command_buffer_.get();
491 int GetNextToken() { return ++token_; }
493 void ClearCommands() {
494 scoped_refptr<Buffer> ring_buffer = helper_->get_ring_buffer();
495 memset(ring_buffer->memory(), kInitialValue, ring_buffer->size());
498 scoped_ptr<MockClientCommandBuffer> command_buffer_;
499 scoped_ptr<MockClientGpuControl> gpu_control_;
500 scoped_ptr<GLES2CmdHelper> helper_;
501 scoped_ptr<MockTransferBuffer> transfer_buffer_;
502 scoped_ptr<GLES2Implementation> gl_;
503 CommandBufferEntry* commands_;
504 int token_;
507 GLES2ImplementationTest() : commands_(NULL) {}
509 virtual void SetUp() override;
510 virtual void TearDown() override;
512 bool NoCommandsWritten() {
513 scoped_refptr<Buffer> ring_buffer = helper_->get_ring_buffer();
514 const uint8* cmds = reinterpret_cast<const uint8*>(ring_buffer->memory());
515 const uint8* end = cmds + ring_buffer->size();
516 for (; cmds < end; ++cmds) {
517 if (*cmds != kInitialValue) {
518 return false;
521 return true;
524 QueryTracker::Query* GetQuery(GLuint id) {
525 return gl_->query_tracker_->GetQuery(id);
528 struct ContextInitOptions {
529 ContextInitOptions()
530 : bind_generates_resource_client(true),
531 bind_generates_resource_service(true),
532 lose_context_when_out_of_memory(false) {}
534 bool bind_generates_resource_client;
535 bool bind_generates_resource_service;
536 bool lose_context_when_out_of_memory;
539 bool Initialize(const ContextInitOptions& init_options) {
540 bool success = true;
541 share_group_ = new ShareGroup(init_options.bind_generates_resource_client);
543 for (int i = 0; i < kNumTestContexts; i++) {
544 if (!test_contexts_[i].Initialize(
545 share_group_.get(),
546 init_options.bind_generates_resource_client,
547 init_options.bind_generates_resource_service,
548 init_options.lose_context_when_out_of_memory))
549 success = false;
552 // Default to test context 0.
553 gpu_control_ = test_contexts_[0].gpu_control_.get();
554 helper_ = test_contexts_[0].helper_.get();
555 transfer_buffer_ = test_contexts_[0].transfer_buffer_.get();
556 gl_ = test_contexts_[0].gl_.get();
557 commands_ = test_contexts_[0].commands_;
558 return success;
561 MockClientCommandBuffer* command_buffer() const {
562 return test_contexts_[0].command_buffer_.get();
565 int GetNextToken() { return test_contexts_[0].GetNextToken(); }
567 const void* GetPut() {
568 return helper_->GetSpace(0);
571 void ClearCommands() {
572 scoped_refptr<Buffer> ring_buffer = helper_->get_ring_buffer();
573 memset(ring_buffer->memory(), kInitialValue, ring_buffer->size());
576 size_t MaxTransferBufferSize() {
577 return transfer_buffer_->MaxTransferBufferSize();
580 ExpectedMemoryInfo GetExpectedMemory(size_t size) {
581 return transfer_buffer_->GetExpectedMemory(size);
584 ExpectedMemoryInfo GetExpectedResultMemory(size_t size) {
585 return transfer_buffer_->GetExpectedResultMemory(size);
588 // Sets the ProgramInfoManager. The manager will be owned
589 // by the ShareGroup.
590 void SetProgramInfoManager(ProgramInfoManager* manager) {
591 gl_->share_group()->set_program_info_manager(manager);
594 int CheckError() {
595 ExpectedMemoryInfo result =
596 GetExpectedResultMemory(sizeof(cmds::GetError::Result));
597 EXPECT_CALL(*command_buffer(), OnFlush())
598 .WillOnce(SetMemory(result.ptr, GLuint(GL_NO_ERROR)))
599 .RetiresOnSaturation();
600 return gl_->GetError();
603 const std::string& GetLastError() {
604 return gl_->GetLastError();
607 bool GetBucketContents(uint32 bucket_id, std::vector<int8>* data) {
608 return gl_->GetBucketContents(bucket_id, data);
611 TestContext test_contexts_[kNumTestContexts];
613 scoped_refptr<ShareGroup> share_group_;
614 MockClientGpuControl* gpu_control_;
615 GLES2CmdHelper* helper_;
616 MockTransferBuffer* transfer_buffer_;
617 GLES2Implementation* gl_;
618 CommandBufferEntry* commands_;
621 void GLES2ImplementationTest::SetUp() {
622 ContextInitOptions init_options;
623 ASSERT_TRUE(Initialize(init_options));
626 void GLES2ImplementationTest::TearDown() {
627 for (int i = 0; i < kNumTestContexts; i++)
628 test_contexts_[i].TearDown();
631 class GLES2ImplementationManualInitTest : public GLES2ImplementationTest {
632 protected:
633 virtual void SetUp() override {}
636 class GLES2ImplementationStrictSharedTest : public GLES2ImplementationTest {
637 protected:
638 virtual void SetUp() override;
640 template <class ResApi>
641 void FlushGenerationTest() {
642 GLuint id1, id2, id3;
644 // Generate valid id.
645 ResApi::Gen(gl_, 1, &id1);
646 EXPECT_NE(id1, 0u);
648 // Delete id1 and generate id2. id1 should not be reused.
649 ResApi::Delete(gl_, 1, &id1);
650 ResApi::Gen(gl_, 1, &id2);
651 EXPECT_NE(id2, 0u);
652 EXPECT_NE(id2, id1);
654 // Expect id1 reuse after Flush.
655 gl_->Flush();
656 ResApi::Gen(gl_, 1, &id3);
657 EXPECT_EQ(id3, id1);
660 // Ids should not be reused unless the |Deleting| context does a Flush()
661 // AND triggers a lazy release after that.
662 template <class ResApi>
663 void CrossContextGenerationTest() {
664 GLES2Implementation* gl1 = test_contexts_[0].gl_.get();
665 GLES2Implementation* gl2 = test_contexts_[1].gl_.get();
666 GLuint id1, id2, id3;
668 // Delete, no flush on context 1. No reuse.
669 ResApi::Gen(gl1, 1, &id1);
670 ResApi::Delete(gl1, 1, &id1);
671 ResApi::Gen(gl1, 1, &id2);
672 EXPECT_NE(id1, id2);
674 // Flush context 2. Still no reuse.
675 gl2->Flush();
676 ResApi::Gen(gl2, 1, &id3);
677 EXPECT_NE(id1, id3);
678 EXPECT_NE(id2, id3);
680 // Flush on context 1, but no lazy release. Still no reuse.
681 gl1->Flush();
682 ResApi::Gen(gl2, 1, &id3);
683 EXPECT_NE(id1, id3);
685 // Lazy release triggered by another Delete. Should reuse id1.
686 ResApi::Delete(gl1, 1, &id2);
687 ResApi::Gen(gl2, 1, &id3);
688 EXPECT_EQ(id1, id3);
691 // Same as CrossContextGenerationTest(), but triggers an Auto Flush on
692 // the Delete(). Tests an edge case regression.
693 template <class ResApi>
694 void CrossContextGenerationAutoFlushTest() {
695 GLES2Implementation* gl1 = test_contexts_[0].gl_.get();
696 GLES2Implementation* gl2 = test_contexts_[1].gl_.get();
697 GLuint id1, id2, id3;
699 // Delete, no flush on context 1. No reuse.
700 // By half filling the buffer, an internal flush is forced on the Delete().
701 ResApi::Gen(gl1, 1, &id1);
702 gl1->helper()->Noop(kNumCommandEntries / 2);
703 ResApi::Delete(gl1, 1, &id1);
704 ResApi::Gen(gl1, 1, &id2);
705 EXPECT_NE(id1, id2);
707 // Flush context 2. Still no reuse.
708 gl2->Flush();
709 ResApi::Gen(gl2, 1, &id3);
710 EXPECT_NE(id1, id3);
711 EXPECT_NE(id2, id3);
713 // Flush on context 1, but no lazy release. Still no reuse.
714 gl1->Flush();
715 ResApi::Gen(gl2, 1, &id3);
716 EXPECT_NE(id1, id3);
718 // Lazy release triggered by another Delete. Should reuse id1.
719 ResApi::Delete(gl1, 1, &id2);
720 ResApi::Gen(gl2, 1, &id3);
721 EXPECT_EQ(id1, id3);
725 void GLES2ImplementationStrictSharedTest::SetUp() {
726 ContextInitOptions init_options;
727 init_options.bind_generates_resource_client = false;
728 init_options.bind_generates_resource_service = false;
729 ASSERT_TRUE(Initialize(init_options));
732 // GCC requires these declarations, but MSVC requires they not be present
733 #ifndef _MSC_VER
734 const uint8 GLES2ImplementationTest::kInitialValue;
735 const int32 GLES2ImplementationTest::kNumCommandEntries;
736 const int32 GLES2ImplementationTest::kCommandBufferSizeBytes;
737 const size_t GLES2ImplementationTest::kTransferBufferSize;
738 const GLint GLES2ImplementationTest::kMaxCombinedTextureImageUnits;
739 const GLint GLES2ImplementationTest::kMaxCubeMapTextureSize;
740 const GLint GLES2ImplementationTest::kMaxFragmentUniformVectors;
741 const GLint GLES2ImplementationTest::kMaxRenderbufferSize;
742 const GLint GLES2ImplementationTest::kMaxTextureImageUnits;
743 const GLint GLES2ImplementationTest::kMaxTextureSize;
744 const GLint GLES2ImplementationTest::kMaxVaryingVectors;
745 const GLint GLES2ImplementationTest::kMaxVertexAttribs;
746 const GLint GLES2ImplementationTest::kMaxVertexTextureImageUnits;
747 const GLint GLES2ImplementationTest::kMaxVertexUniformVectors;
748 const GLint GLES2ImplementationTest::kNumCompressedTextureFormats;
749 const GLint GLES2ImplementationTest::kNumShaderBinaryFormats;
750 const GLuint GLES2ImplementationTest::kStartId;
751 const GLuint GLES2ImplementationTest::kBuffersStartId;
752 const GLuint GLES2ImplementationTest::kFramebuffersStartId;
753 const GLuint GLES2ImplementationTest::kProgramsAndShadersStartId;
754 const GLuint GLES2ImplementationTest::kRenderbuffersStartId;
755 const GLuint GLES2ImplementationTest::kTexturesStartId;
756 const GLuint GLES2ImplementationTest::kQueriesStartId;
757 const GLuint GLES2ImplementationTest::kVertexArraysStartId;
758 #endif
760 TEST_F(GLES2ImplementationTest, Basic) {
761 EXPECT_TRUE(gl_->share_group() != NULL);
764 TEST_F(GLES2ImplementationTest, GetBucketContents) {
765 const uint32 kBucketId = GLES2Implementation::kResultBucketId;
766 const uint32 kTestSize = MaxTransferBufferSize() + 32;
768 scoped_ptr<uint8[]> buf(new uint8 [kTestSize]);
769 uint8* expected_data = buf.get();
770 for (uint32 ii = 0; ii < kTestSize; ++ii) {
771 expected_data[ii] = ii * 3;
774 struct Cmds {
775 cmd::GetBucketStart get_bucket_start;
776 cmd::SetToken set_token1;
777 cmd::GetBucketData get_bucket_data;
778 cmd::SetToken set_token2;
779 cmd::SetBucketSize set_bucket_size2;
782 ExpectedMemoryInfo mem1 = GetExpectedMemory(MaxTransferBufferSize());
783 ExpectedMemoryInfo result1 = GetExpectedResultMemory(sizeof(uint32));
784 ExpectedMemoryInfo mem2 = GetExpectedMemory(
785 kTestSize - MaxTransferBufferSize());
787 Cmds expected;
788 expected.get_bucket_start.Init(
789 kBucketId, result1.id, result1.offset,
790 MaxTransferBufferSize(), mem1.id, mem1.offset);
791 expected.set_token1.Init(GetNextToken());
792 expected.get_bucket_data.Init(
793 kBucketId, MaxTransferBufferSize(),
794 kTestSize - MaxTransferBufferSize(), mem2.id, mem2.offset);
795 expected.set_bucket_size2.Init(kBucketId, 0);
796 expected.set_token2.Init(GetNextToken());
798 EXPECT_CALL(*command_buffer(), OnFlush())
799 .WillOnce(DoAll(
800 SetMemory(result1.ptr, kTestSize),
801 SetMemoryFromArray(
802 mem1.ptr, expected_data, MaxTransferBufferSize())))
803 .WillOnce(SetMemoryFromArray(
804 mem2.ptr, expected_data + MaxTransferBufferSize(),
805 kTestSize - MaxTransferBufferSize()))
806 .RetiresOnSaturation();
808 std::vector<int8> data;
809 GetBucketContents(kBucketId, &data);
810 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
811 ASSERT_EQ(kTestSize, data.size());
812 EXPECT_EQ(0, memcmp(expected_data, &data[0], data.size()));
815 TEST_F(GLES2ImplementationTest, GetShaderPrecisionFormat) {
816 struct Cmds {
817 cmds::GetShaderPrecisionFormat cmd;
819 typedef cmds::GetShaderPrecisionFormat::Result Result;
821 // The first call for mediump should trigger a command buffer request.
822 GLint range1[2] = {0, 0};
823 GLint precision1 = 0;
824 Cmds expected1;
825 ExpectedMemoryInfo client_result1 = GetExpectedResultMemory(4);
826 expected1.cmd.Init(GL_FRAGMENT_SHADER, GL_MEDIUM_FLOAT,
827 client_result1.id, client_result1.offset);
828 Result server_result1 = {true, 14, 14, 10};
829 EXPECT_CALL(*command_buffer(), OnFlush())
830 .WillOnce(SetMemory(client_result1.ptr, server_result1))
831 .RetiresOnSaturation();
832 gl_->GetShaderPrecisionFormat(GL_FRAGMENT_SHADER, GL_MEDIUM_FLOAT,
833 range1, &precision1);
834 const void* commands2 = GetPut();
835 EXPECT_NE(commands_, commands2);
836 EXPECT_EQ(0, memcmp(&expected1, commands_, sizeof(expected1)));
837 EXPECT_EQ(range1[0], 14);
838 EXPECT_EQ(range1[1], 14);
839 EXPECT_EQ(precision1, 10);
841 // The second call for mediump should use the cached value and avoid
842 // triggering a command buffer request, so we do not expect a call to
843 // OnFlush() here. We do expect the results to be correct though.
844 GLint range2[2] = {0, 0};
845 GLint precision2 = 0;
846 gl_->GetShaderPrecisionFormat(GL_FRAGMENT_SHADER, GL_MEDIUM_FLOAT,
847 range2, &precision2);
848 const void* commands3 = GetPut();
849 EXPECT_EQ(commands2, commands3);
850 EXPECT_EQ(range2[0], 14);
851 EXPECT_EQ(range2[1], 14);
852 EXPECT_EQ(precision2, 10);
854 // If we then make a request for highp, we should get another command
855 // buffer request since it hasn't been cached yet.
856 GLint range3[2] = {0, 0};
857 GLint precision3 = 0;
858 Cmds expected3;
859 ExpectedMemoryInfo result3 = GetExpectedResultMemory(4);
860 expected3.cmd.Init(GL_FRAGMENT_SHADER, GL_HIGH_FLOAT,
861 result3.id, result3.offset);
862 Result result3_source = {true, 62, 62, 16};
863 EXPECT_CALL(*command_buffer(), OnFlush())
864 .WillOnce(SetMemory(result3.ptr, result3_source))
865 .RetiresOnSaturation();
866 gl_->GetShaderPrecisionFormat(GL_FRAGMENT_SHADER, GL_HIGH_FLOAT,
867 range3, &precision3);
868 const void* commands4 = GetPut();
869 EXPECT_NE(commands3, commands4);
870 EXPECT_EQ(0, memcmp(&expected3, commands3, sizeof(expected3)));
871 EXPECT_EQ(range3[0], 62);
872 EXPECT_EQ(range3[1], 62);
873 EXPECT_EQ(precision3, 16);
876 TEST_F(GLES2ImplementationTest, ShaderSource) {
877 const uint32 kBucketId = GLES2Implementation::kResultBucketId;
878 const GLuint kShaderId = 456;
879 const char* kString1 = "foobar";
880 const char* kString2 = "barfoo";
881 const size_t kString1Size = strlen(kString1);
882 const size_t kString2Size = strlen(kString2);
883 const size_t kString3Size = 1; // Want the NULL;
884 const size_t kSourceSize = kString1Size + kString2Size + kString3Size;
885 const size_t kPaddedString1Size =
886 transfer_buffer_->RoundToAlignment(kString1Size);
887 const size_t kPaddedString2Size =
888 transfer_buffer_->RoundToAlignment(kString2Size);
889 const size_t kPaddedString3Size =
890 transfer_buffer_->RoundToAlignment(kString3Size);
891 struct Cmds {
892 cmd::SetBucketSize set_bucket_size;
893 cmd::SetBucketData set_bucket_data1;
894 cmd::SetToken set_token1;
895 cmd::SetBucketData set_bucket_data2;
896 cmd::SetToken set_token2;
897 cmd::SetBucketData set_bucket_data3;
898 cmd::SetToken set_token3;
899 cmds::ShaderSourceBucket shader_source_bucket;
900 cmd::SetBucketSize clear_bucket_size;
903 ExpectedMemoryInfo mem1 = GetExpectedMemory(kPaddedString1Size);
904 ExpectedMemoryInfo mem2 = GetExpectedMemory(kPaddedString2Size);
905 ExpectedMemoryInfo mem3 = GetExpectedMemory(kPaddedString3Size);
907 Cmds expected;
908 expected.set_bucket_size.Init(kBucketId, kSourceSize);
909 expected.set_bucket_data1.Init(
910 kBucketId, 0, kString1Size, mem1.id, mem1.offset);
911 expected.set_token1.Init(GetNextToken());
912 expected.set_bucket_data2.Init(
913 kBucketId, kString1Size, kString2Size, mem2.id, mem2.offset);
914 expected.set_token2.Init(GetNextToken());
915 expected.set_bucket_data3.Init(
916 kBucketId, kString1Size + kString2Size,
917 kString3Size, mem3.id, mem3.offset);
918 expected.set_token3.Init(GetNextToken());
919 expected.shader_source_bucket.Init(kShaderId, kBucketId);
920 expected.clear_bucket_size.Init(kBucketId, 0);
921 const char* strings[] = {
922 kString1,
923 kString2,
925 gl_->ShaderSource(kShaderId, 2, strings, NULL);
926 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
929 TEST_F(GLES2ImplementationTest, GetShaderSource) {
930 const uint32 kBucketId = GLES2Implementation::kResultBucketId;
931 const GLuint kShaderId = 456;
932 const Str7 kString = {"foobar"};
933 const char kBad = 0x12;
934 struct Cmds {
935 cmd::SetBucketSize set_bucket_size1;
936 cmds::GetShaderSource get_shader_source;
937 cmd::GetBucketStart get_bucket_start;
938 cmd::SetToken set_token1;
939 cmd::SetBucketSize set_bucket_size2;
942 ExpectedMemoryInfo mem1 = GetExpectedMemory(MaxTransferBufferSize());
943 ExpectedMemoryInfo result1 = GetExpectedResultMemory(sizeof(uint32));
945 Cmds expected;
946 expected.set_bucket_size1.Init(kBucketId, 0);
947 expected.get_shader_source.Init(kShaderId, kBucketId);
948 expected.get_bucket_start.Init(
949 kBucketId, result1.id, result1.offset,
950 MaxTransferBufferSize(), mem1.id, mem1.offset);
951 expected.set_token1.Init(GetNextToken());
952 expected.set_bucket_size2.Init(kBucketId, 0);
953 char buf[sizeof(kString) + 1];
954 memset(buf, kBad, sizeof(buf));
956 EXPECT_CALL(*command_buffer(), OnFlush())
957 .WillOnce(DoAll(SetMemory(result1.ptr, uint32(sizeof(kString))),
958 SetMemory(mem1.ptr, kString)))
959 .RetiresOnSaturation();
961 GLsizei length = 0;
962 gl_->GetShaderSource(kShaderId, sizeof(buf), &length, buf);
963 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
964 EXPECT_EQ(sizeof(kString) - 1, static_cast<size_t>(length));
965 EXPECT_STREQ(kString.str, buf);
966 EXPECT_EQ(buf[sizeof(kString)], kBad);
969 #if defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS)
971 TEST_F(GLES2ImplementationTest, DrawArraysClientSideBuffers) {
972 static const float verts[][4] = {
973 { 12.0f, 23.0f, 34.0f, 45.0f, },
974 { 56.0f, 67.0f, 78.0f, 89.0f, },
975 { 13.0f, 24.0f, 35.0f, 46.0f, },
977 struct Cmds {
978 cmds::EnableVertexAttribArray enable1;
979 cmds::EnableVertexAttribArray enable2;
980 cmds::BindBuffer bind_to_emu;
981 cmds::BufferData set_size;
982 cmds::BufferSubData copy_data1;
983 cmd::SetToken set_token1;
984 cmds::VertexAttribPointer set_pointer1;
985 cmds::BufferSubData copy_data2;
986 cmd::SetToken set_token2;
987 cmds::VertexAttribPointer set_pointer2;
988 cmds::DrawArrays draw;
989 cmds::BindBuffer restore;
991 const GLuint kEmuBufferId = GLES2Implementation::kClientSideArrayId;
992 const GLuint kAttribIndex1 = 1;
993 const GLuint kAttribIndex2 = 3;
994 const GLint kNumComponents1 = 3;
995 const GLint kNumComponents2 = 2;
996 const GLsizei kClientStride = sizeof(verts[0]);
997 const GLint kFirst = 1;
998 const GLsizei kCount = 2;
999 const GLsizei kSize1 =
1000 arraysize(verts) * kNumComponents1 * sizeof(verts[0][0]);
1001 const GLsizei kSize2 =
1002 arraysize(verts) * kNumComponents2 * sizeof(verts[0][0]);
1003 const GLsizei kEmuOffset1 = 0;
1004 const GLsizei kEmuOffset2 = kSize1;
1005 const GLsizei kTotalSize = kSize1 + kSize2;
1007 ExpectedMemoryInfo mem1 = GetExpectedMemory(kSize1);
1008 ExpectedMemoryInfo mem2 = GetExpectedMemory(kSize2);
1010 Cmds expected;
1011 expected.enable1.Init(kAttribIndex1);
1012 expected.enable2.Init(kAttribIndex2);
1013 expected.bind_to_emu.Init(GL_ARRAY_BUFFER, kEmuBufferId);
1014 expected.set_size.Init(GL_ARRAY_BUFFER, kTotalSize, 0, 0, GL_DYNAMIC_DRAW);
1015 expected.copy_data1.Init(
1016 GL_ARRAY_BUFFER, kEmuOffset1, kSize1, mem1.id, mem1.offset);
1017 expected.set_token1.Init(GetNextToken());
1018 expected.set_pointer1.Init(
1019 kAttribIndex1, kNumComponents1, GL_FLOAT, GL_FALSE, 0, kEmuOffset1);
1020 expected.copy_data2.Init(
1021 GL_ARRAY_BUFFER, kEmuOffset2, kSize2, mem2.id, mem2.offset);
1022 expected.set_token2.Init(GetNextToken());
1023 expected.set_pointer2.Init(
1024 kAttribIndex2, kNumComponents2, GL_FLOAT, GL_FALSE, 0, kEmuOffset2);
1025 expected.draw.Init(GL_POINTS, kFirst, kCount);
1026 expected.restore.Init(GL_ARRAY_BUFFER, 0);
1027 gl_->EnableVertexAttribArray(kAttribIndex1);
1028 gl_->EnableVertexAttribArray(kAttribIndex2);
1029 gl_->VertexAttribPointer(
1030 kAttribIndex1, kNumComponents1, GL_FLOAT, GL_FALSE, kClientStride, verts);
1031 gl_->VertexAttribPointer(
1032 kAttribIndex2, kNumComponents2, GL_FLOAT, GL_FALSE, kClientStride, verts);
1033 gl_->DrawArrays(GL_POINTS, kFirst, kCount);
1034 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
1037 TEST_F(GLES2ImplementationTest, DrawArraysInstancedANGLEClientSideBuffers) {
1038 static const float verts[][4] = {
1039 { 12.0f, 23.0f, 34.0f, 45.0f, },
1040 { 56.0f, 67.0f, 78.0f, 89.0f, },
1041 { 13.0f, 24.0f, 35.0f, 46.0f, },
1043 struct Cmds {
1044 cmds::EnableVertexAttribArray enable1;
1045 cmds::EnableVertexAttribArray enable2;
1046 cmds::VertexAttribDivisorANGLE divisor;
1047 cmds::BindBuffer bind_to_emu;
1048 cmds::BufferData set_size;
1049 cmds::BufferSubData copy_data1;
1050 cmd::SetToken set_token1;
1051 cmds::VertexAttribPointer set_pointer1;
1052 cmds::BufferSubData copy_data2;
1053 cmd::SetToken set_token2;
1054 cmds::VertexAttribPointer set_pointer2;
1055 cmds::DrawArraysInstancedANGLE draw;
1056 cmds::BindBuffer restore;
1058 const GLuint kEmuBufferId = GLES2Implementation::kClientSideArrayId;
1059 const GLuint kAttribIndex1 = 1;
1060 const GLuint kAttribIndex2 = 3;
1061 const GLint kNumComponents1 = 3;
1062 const GLint kNumComponents2 = 2;
1063 const GLsizei kClientStride = sizeof(verts[0]);
1064 const GLint kFirst = 1;
1065 const GLsizei kCount = 2;
1066 const GLuint kDivisor = 1;
1067 const GLsizei kSize1 =
1068 arraysize(verts) * kNumComponents1 * sizeof(verts[0][0]);
1069 const GLsizei kSize2 =
1070 1 * kNumComponents2 * sizeof(verts[0][0]);
1071 const GLsizei kEmuOffset1 = 0;
1072 const GLsizei kEmuOffset2 = kSize1;
1073 const GLsizei kTotalSize = kSize1 + kSize2;
1075 ExpectedMemoryInfo mem1 = GetExpectedMemory(kSize1);
1076 ExpectedMemoryInfo mem2 = GetExpectedMemory(kSize2);
1078 Cmds expected;
1079 expected.enable1.Init(kAttribIndex1);
1080 expected.enable2.Init(kAttribIndex2);
1081 expected.divisor.Init(kAttribIndex2, kDivisor);
1082 expected.bind_to_emu.Init(GL_ARRAY_BUFFER, kEmuBufferId);
1083 expected.set_size.Init(GL_ARRAY_BUFFER, kTotalSize, 0, 0, GL_DYNAMIC_DRAW);
1084 expected.copy_data1.Init(
1085 GL_ARRAY_BUFFER, kEmuOffset1, kSize1, mem1.id, mem1.offset);
1086 expected.set_token1.Init(GetNextToken());
1087 expected.set_pointer1.Init(
1088 kAttribIndex1, kNumComponents1, GL_FLOAT, GL_FALSE, 0, kEmuOffset1);
1089 expected.copy_data2.Init(
1090 GL_ARRAY_BUFFER, kEmuOffset2, kSize2, mem2.id, mem2.offset);
1091 expected.set_token2.Init(GetNextToken());
1092 expected.set_pointer2.Init(
1093 kAttribIndex2, kNumComponents2, GL_FLOAT, GL_FALSE, 0, kEmuOffset2);
1094 expected.draw.Init(GL_POINTS, kFirst, kCount, 1);
1095 expected.restore.Init(GL_ARRAY_BUFFER, 0);
1096 gl_->EnableVertexAttribArray(kAttribIndex1);
1097 gl_->EnableVertexAttribArray(kAttribIndex2);
1098 gl_->VertexAttribPointer(
1099 kAttribIndex1, kNumComponents1, GL_FLOAT, GL_FALSE, kClientStride, verts);
1100 gl_->VertexAttribPointer(
1101 kAttribIndex2, kNumComponents2, GL_FLOAT, GL_FALSE, kClientStride, verts);
1102 gl_->VertexAttribDivisorANGLE(kAttribIndex2, kDivisor);
1103 gl_->DrawArraysInstancedANGLE(GL_POINTS, kFirst, kCount, 1);
1104 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
1107 TEST_F(GLES2ImplementationTest, DrawElementsClientSideBuffers) {
1108 static const float verts[][4] = {
1109 { 12.0f, 23.0f, 34.0f, 45.0f, },
1110 { 56.0f, 67.0f, 78.0f, 89.0f, },
1111 { 13.0f, 24.0f, 35.0f, 46.0f, },
1113 static const uint16 indices[] = {
1114 1, 2,
1116 struct Cmds {
1117 cmds::EnableVertexAttribArray enable1;
1118 cmds::EnableVertexAttribArray enable2;
1119 cmds::BindBuffer bind_to_index_emu;
1120 cmds::BufferData set_index_size;
1121 cmds::BufferSubData copy_data0;
1122 cmd::SetToken set_token0;
1123 cmds::BindBuffer bind_to_emu;
1124 cmds::BufferData set_size;
1125 cmds::BufferSubData copy_data1;
1126 cmd::SetToken set_token1;
1127 cmds::VertexAttribPointer set_pointer1;
1128 cmds::BufferSubData copy_data2;
1129 cmd::SetToken set_token2;
1130 cmds::VertexAttribPointer set_pointer2;
1131 cmds::DrawElements draw;
1132 cmds::BindBuffer restore;
1133 cmds::BindBuffer restore_element;
1135 const GLsizei kIndexSize = sizeof(indices);
1136 const GLuint kEmuBufferId = GLES2Implementation::kClientSideArrayId;
1137 const GLuint kEmuIndexBufferId =
1138 GLES2Implementation::kClientSideElementArrayId;
1139 const GLuint kAttribIndex1 = 1;
1140 const GLuint kAttribIndex2 = 3;
1141 const GLint kNumComponents1 = 3;
1142 const GLint kNumComponents2 = 2;
1143 const GLsizei kClientStride = sizeof(verts[0]);
1144 const GLsizei kCount = 2;
1145 const GLsizei kSize1 =
1146 arraysize(verts) * kNumComponents1 * sizeof(verts[0][0]);
1147 const GLsizei kSize2 =
1148 arraysize(verts) * kNumComponents2 * sizeof(verts[0][0]);
1149 const GLsizei kEmuOffset1 = 0;
1150 const GLsizei kEmuOffset2 = kSize1;
1151 const GLsizei kTotalSize = kSize1 + kSize2;
1153 ExpectedMemoryInfo mem1 = GetExpectedMemory(kIndexSize);
1154 ExpectedMemoryInfo mem2 = GetExpectedMemory(kSize1);
1155 ExpectedMemoryInfo mem3 = GetExpectedMemory(kSize2);
1157 Cmds expected;
1158 expected.enable1.Init(kAttribIndex1);
1159 expected.enable2.Init(kAttribIndex2);
1160 expected.bind_to_index_emu.Init(GL_ELEMENT_ARRAY_BUFFER, kEmuIndexBufferId);
1161 expected.set_index_size.Init(
1162 GL_ELEMENT_ARRAY_BUFFER, kIndexSize, 0, 0, GL_DYNAMIC_DRAW);
1163 expected.copy_data0.Init(
1164 GL_ELEMENT_ARRAY_BUFFER, 0, kIndexSize, mem1.id, mem1.offset);
1165 expected.set_token0.Init(GetNextToken());
1166 expected.bind_to_emu.Init(GL_ARRAY_BUFFER, kEmuBufferId);
1167 expected.set_size.Init(GL_ARRAY_BUFFER, kTotalSize, 0, 0, GL_DYNAMIC_DRAW);
1168 expected.copy_data1.Init(
1169 GL_ARRAY_BUFFER, kEmuOffset1, kSize1, mem2.id, mem2.offset);
1170 expected.set_token1.Init(GetNextToken());
1171 expected.set_pointer1.Init(
1172 kAttribIndex1, kNumComponents1, GL_FLOAT, GL_FALSE, 0, kEmuOffset1);
1173 expected.copy_data2.Init(
1174 GL_ARRAY_BUFFER, kEmuOffset2, kSize2, mem3.id, mem3.offset);
1175 expected.set_token2.Init(GetNextToken());
1176 expected.set_pointer2.Init(kAttribIndex2, kNumComponents2,
1177 GL_FLOAT, GL_FALSE, 0, kEmuOffset2);
1178 expected.draw.Init(GL_POINTS, kCount, GL_UNSIGNED_SHORT, 0);
1179 expected.restore.Init(GL_ARRAY_BUFFER, 0);
1180 expected.restore_element.Init(GL_ELEMENT_ARRAY_BUFFER, 0);
1181 gl_->EnableVertexAttribArray(kAttribIndex1);
1182 gl_->EnableVertexAttribArray(kAttribIndex2);
1183 gl_->VertexAttribPointer(kAttribIndex1, kNumComponents1,
1184 GL_FLOAT, GL_FALSE, kClientStride, verts);
1185 gl_->VertexAttribPointer(kAttribIndex2, kNumComponents2,
1186 GL_FLOAT, GL_FALSE, kClientStride, verts);
1187 gl_->DrawElements(GL_POINTS, kCount, GL_UNSIGNED_SHORT, indices);
1188 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
1191 TEST_F(GLES2ImplementationTest, DrawElementsClientSideBuffersIndexUint) {
1192 static const float verts[][4] = {
1193 { 12.0f, 23.0f, 34.0f, 45.0f, },
1194 { 56.0f, 67.0f, 78.0f, 89.0f, },
1195 { 13.0f, 24.0f, 35.0f, 46.0f, },
1197 static const uint32 indices[] = {
1198 1, 2,
1200 struct Cmds {
1201 cmds::EnableVertexAttribArray enable1;
1202 cmds::EnableVertexAttribArray enable2;
1203 cmds::BindBuffer bind_to_index_emu;
1204 cmds::BufferData set_index_size;
1205 cmds::BufferSubData copy_data0;
1206 cmd::SetToken set_token0;
1207 cmds::BindBuffer bind_to_emu;
1208 cmds::BufferData set_size;
1209 cmds::BufferSubData copy_data1;
1210 cmd::SetToken set_token1;
1211 cmds::VertexAttribPointer set_pointer1;
1212 cmds::BufferSubData copy_data2;
1213 cmd::SetToken set_token2;
1214 cmds::VertexAttribPointer set_pointer2;
1215 cmds::DrawElements draw;
1216 cmds::BindBuffer restore;
1217 cmds::BindBuffer restore_element;
1219 const GLsizei kIndexSize = sizeof(indices);
1220 const GLuint kEmuBufferId = GLES2Implementation::kClientSideArrayId;
1221 const GLuint kEmuIndexBufferId =
1222 GLES2Implementation::kClientSideElementArrayId;
1223 const GLuint kAttribIndex1 = 1;
1224 const GLuint kAttribIndex2 = 3;
1225 const GLint kNumComponents1 = 3;
1226 const GLint kNumComponents2 = 2;
1227 const GLsizei kClientStride = sizeof(verts[0]);
1228 const GLsizei kCount = 2;
1229 const GLsizei kSize1 =
1230 arraysize(verts) * kNumComponents1 * sizeof(verts[0][0]);
1231 const GLsizei kSize2 =
1232 arraysize(verts) * kNumComponents2 * sizeof(verts[0][0]);
1233 const GLsizei kEmuOffset1 = 0;
1234 const GLsizei kEmuOffset2 = kSize1;
1235 const GLsizei kTotalSize = kSize1 + kSize2;
1237 ExpectedMemoryInfo mem1 = GetExpectedMemory(kIndexSize);
1238 ExpectedMemoryInfo mem2 = GetExpectedMemory(kSize1);
1239 ExpectedMemoryInfo mem3 = GetExpectedMemory(kSize2);
1241 Cmds expected;
1242 expected.enable1.Init(kAttribIndex1);
1243 expected.enable2.Init(kAttribIndex2);
1244 expected.bind_to_index_emu.Init(GL_ELEMENT_ARRAY_BUFFER, kEmuIndexBufferId);
1245 expected.set_index_size.Init(
1246 GL_ELEMENT_ARRAY_BUFFER, kIndexSize, 0, 0, GL_DYNAMIC_DRAW);
1247 expected.copy_data0.Init(
1248 GL_ELEMENT_ARRAY_BUFFER, 0, kIndexSize, mem1.id, mem1.offset);
1249 expected.set_token0.Init(GetNextToken());
1250 expected.bind_to_emu.Init(GL_ARRAY_BUFFER, kEmuBufferId);
1251 expected.set_size.Init(GL_ARRAY_BUFFER, kTotalSize, 0, 0, GL_DYNAMIC_DRAW);
1252 expected.copy_data1.Init(
1253 GL_ARRAY_BUFFER, kEmuOffset1, kSize1, mem2.id, mem2.offset);
1254 expected.set_token1.Init(GetNextToken());
1255 expected.set_pointer1.Init(
1256 kAttribIndex1, kNumComponents1, GL_FLOAT, GL_FALSE, 0, kEmuOffset1);
1257 expected.copy_data2.Init(
1258 GL_ARRAY_BUFFER, kEmuOffset2, kSize2, mem3.id, mem3.offset);
1259 expected.set_token2.Init(GetNextToken());
1260 expected.set_pointer2.Init(kAttribIndex2, kNumComponents2,
1261 GL_FLOAT, GL_FALSE, 0, kEmuOffset2);
1262 expected.draw.Init(GL_POINTS, kCount, GL_UNSIGNED_INT, 0);
1263 expected.restore.Init(GL_ARRAY_BUFFER, 0);
1264 expected.restore_element.Init(GL_ELEMENT_ARRAY_BUFFER, 0);
1265 gl_->EnableVertexAttribArray(kAttribIndex1);
1266 gl_->EnableVertexAttribArray(kAttribIndex2);
1267 gl_->VertexAttribPointer(kAttribIndex1, kNumComponents1,
1268 GL_FLOAT, GL_FALSE, kClientStride, verts);
1269 gl_->VertexAttribPointer(kAttribIndex2, kNumComponents2,
1270 GL_FLOAT, GL_FALSE, kClientStride, verts);
1271 gl_->DrawElements(GL_POINTS, kCount, GL_UNSIGNED_INT, indices);
1272 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
1275 TEST_F(GLES2ImplementationTest, DrawElementsClientSideBuffersInvalidIndexUint) {
1276 static const float verts[][4] = {
1277 { 12.0f, 23.0f, 34.0f, 45.0f, },
1278 { 56.0f, 67.0f, 78.0f, 89.0f, },
1279 { 13.0f, 24.0f, 35.0f, 46.0f, },
1281 static const uint32 indices[] = {
1282 1, 0x90000000
1285 const GLuint kAttribIndex1 = 1;
1286 const GLuint kAttribIndex2 = 3;
1287 const GLint kNumComponents1 = 3;
1288 const GLint kNumComponents2 = 2;
1289 const GLsizei kClientStride = sizeof(verts[0]);
1290 const GLsizei kCount = 2;
1292 EXPECT_CALL(*command_buffer(), OnFlush())
1293 .Times(1)
1294 .RetiresOnSaturation();
1296 gl_->EnableVertexAttribArray(kAttribIndex1);
1297 gl_->EnableVertexAttribArray(kAttribIndex2);
1298 gl_->VertexAttribPointer(kAttribIndex1, kNumComponents1,
1299 GL_FLOAT, GL_FALSE, kClientStride, verts);
1300 gl_->VertexAttribPointer(kAttribIndex2, kNumComponents2,
1301 GL_FLOAT, GL_FALSE, kClientStride, verts);
1302 gl_->DrawElements(GL_POINTS, kCount, GL_UNSIGNED_INT, indices);
1304 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_OPERATION), gl_->GetError());
1307 TEST_F(GLES2ImplementationTest,
1308 DrawElementsClientSideBuffersServiceSideIndices) {
1309 static const float verts[][4] = {
1310 { 12.0f, 23.0f, 34.0f, 45.0f, },
1311 { 56.0f, 67.0f, 78.0f, 89.0f, },
1312 { 13.0f, 24.0f, 35.0f, 46.0f, },
1314 struct Cmds {
1315 cmds::EnableVertexAttribArray enable1;
1316 cmds::EnableVertexAttribArray enable2;
1317 cmds::BindBuffer bind_to_index;
1318 cmds::GetMaxValueInBufferCHROMIUM get_max;
1319 cmds::BindBuffer bind_to_emu;
1320 cmds::BufferData set_size;
1321 cmds::BufferSubData copy_data1;
1322 cmd::SetToken set_token1;
1323 cmds::VertexAttribPointer set_pointer1;
1324 cmds::BufferSubData copy_data2;
1325 cmd::SetToken set_token2;
1326 cmds::VertexAttribPointer set_pointer2;
1327 cmds::DrawElements draw;
1328 cmds::BindBuffer restore;
1330 const GLuint kEmuBufferId = GLES2Implementation::kClientSideArrayId;
1331 const GLuint kClientIndexBufferId = 0x789;
1332 const GLuint kIndexOffset = 0x40;
1333 const GLuint kMaxIndex = 2;
1334 const GLuint kAttribIndex1 = 1;
1335 const GLuint kAttribIndex2 = 3;
1336 const GLint kNumComponents1 = 3;
1337 const GLint kNumComponents2 = 2;
1338 const GLsizei kClientStride = sizeof(verts[0]);
1339 const GLsizei kCount = 2;
1340 const GLsizei kSize1 =
1341 arraysize(verts) * kNumComponents1 * sizeof(verts[0][0]);
1342 const GLsizei kSize2 =
1343 arraysize(verts) * kNumComponents2 * sizeof(verts[0][0]);
1344 const GLsizei kEmuOffset1 = 0;
1345 const GLsizei kEmuOffset2 = kSize1;
1346 const GLsizei kTotalSize = kSize1 + kSize2;
1348 ExpectedMemoryInfo mem1 = GetExpectedResultMemory(sizeof(uint32));
1349 ExpectedMemoryInfo mem2 = GetExpectedMemory(kSize1);
1350 ExpectedMemoryInfo mem3 = GetExpectedMemory(kSize2);
1353 Cmds expected;
1354 expected.enable1.Init(kAttribIndex1);
1355 expected.enable2.Init(kAttribIndex2);
1356 expected.bind_to_index.Init(GL_ELEMENT_ARRAY_BUFFER, kClientIndexBufferId);
1357 expected.get_max.Init(kClientIndexBufferId, kCount, GL_UNSIGNED_SHORT,
1358 kIndexOffset, mem1.id, mem1.offset);
1359 expected.bind_to_emu.Init(GL_ARRAY_BUFFER, kEmuBufferId);
1360 expected.set_size.Init(GL_ARRAY_BUFFER, kTotalSize, 0, 0, GL_DYNAMIC_DRAW);
1361 expected.copy_data1.Init(
1362 GL_ARRAY_BUFFER, kEmuOffset1, kSize1, mem2.id, mem2.offset);
1363 expected.set_token1.Init(GetNextToken());
1364 expected.set_pointer1.Init(kAttribIndex1, kNumComponents1,
1365 GL_FLOAT, GL_FALSE, 0, kEmuOffset1);
1366 expected.copy_data2.Init(
1367 GL_ARRAY_BUFFER, kEmuOffset2, kSize2, mem3.id, mem3.offset);
1368 expected.set_token2.Init(GetNextToken());
1369 expected.set_pointer2.Init(kAttribIndex2, kNumComponents2,
1370 GL_FLOAT, GL_FALSE, 0, kEmuOffset2);
1371 expected.draw.Init(GL_POINTS, kCount, GL_UNSIGNED_SHORT, kIndexOffset);
1372 expected.restore.Init(GL_ARRAY_BUFFER, 0);
1374 EXPECT_CALL(*command_buffer(), OnFlush())
1375 .WillOnce(SetMemory(mem1.ptr,kMaxIndex))
1376 .RetiresOnSaturation();
1378 gl_->EnableVertexAttribArray(kAttribIndex1);
1379 gl_->EnableVertexAttribArray(kAttribIndex2);
1380 gl_->BindBuffer(GL_ELEMENT_ARRAY_BUFFER, kClientIndexBufferId);
1381 gl_->VertexAttribPointer(kAttribIndex1, kNumComponents1,
1382 GL_FLOAT, GL_FALSE, kClientStride, verts);
1383 gl_->VertexAttribPointer(kAttribIndex2, kNumComponents2,
1384 GL_FLOAT, GL_FALSE, kClientStride, verts);
1385 gl_->DrawElements(GL_POINTS, kCount, GL_UNSIGNED_SHORT,
1386 reinterpret_cast<const void*>(kIndexOffset));
1387 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
1390 TEST_F(GLES2ImplementationTest, DrawElementsInstancedANGLEClientSideBuffers) {
1391 static const float verts[][4] = {
1392 { 12.0f, 23.0f, 34.0f, 45.0f, },
1393 { 56.0f, 67.0f, 78.0f, 89.0f, },
1394 { 13.0f, 24.0f, 35.0f, 46.0f, },
1396 static const uint16 indices[] = {
1397 1, 2,
1399 struct Cmds {
1400 cmds::EnableVertexAttribArray enable1;
1401 cmds::EnableVertexAttribArray enable2;
1402 cmds::VertexAttribDivisorANGLE divisor;
1403 cmds::BindBuffer bind_to_index_emu;
1404 cmds::BufferData set_index_size;
1405 cmds::BufferSubData copy_data0;
1406 cmd::SetToken set_token0;
1407 cmds::BindBuffer bind_to_emu;
1408 cmds::BufferData set_size;
1409 cmds::BufferSubData copy_data1;
1410 cmd::SetToken set_token1;
1411 cmds::VertexAttribPointer set_pointer1;
1412 cmds::BufferSubData copy_data2;
1413 cmd::SetToken set_token2;
1414 cmds::VertexAttribPointer set_pointer2;
1415 cmds::DrawElementsInstancedANGLE draw;
1416 cmds::BindBuffer restore;
1417 cmds::BindBuffer restore_element;
1419 const GLsizei kIndexSize = sizeof(indices);
1420 const GLuint kEmuBufferId = GLES2Implementation::kClientSideArrayId;
1421 const GLuint kEmuIndexBufferId =
1422 GLES2Implementation::kClientSideElementArrayId;
1423 const GLuint kAttribIndex1 = 1;
1424 const GLuint kAttribIndex2 = 3;
1425 const GLint kNumComponents1 = 3;
1426 const GLint kNumComponents2 = 2;
1427 const GLsizei kClientStride = sizeof(verts[0]);
1428 const GLsizei kCount = 2;
1429 const GLsizei kSize1 =
1430 arraysize(verts) * kNumComponents1 * sizeof(verts[0][0]);
1431 const GLsizei kSize2 =
1432 1 * kNumComponents2 * sizeof(verts[0][0]);
1433 const GLuint kDivisor = 1;
1434 const GLsizei kEmuOffset1 = 0;
1435 const GLsizei kEmuOffset2 = kSize1;
1436 const GLsizei kTotalSize = kSize1 + kSize2;
1438 ExpectedMemoryInfo mem1 = GetExpectedMemory(kIndexSize);
1439 ExpectedMemoryInfo mem2 = GetExpectedMemory(kSize1);
1440 ExpectedMemoryInfo mem3 = GetExpectedMemory(kSize2);
1442 Cmds expected;
1443 expected.enable1.Init(kAttribIndex1);
1444 expected.enable2.Init(kAttribIndex2);
1445 expected.divisor.Init(kAttribIndex2, kDivisor);
1446 expected.bind_to_index_emu.Init(GL_ELEMENT_ARRAY_BUFFER, kEmuIndexBufferId);
1447 expected.set_index_size.Init(
1448 GL_ELEMENT_ARRAY_BUFFER, kIndexSize, 0, 0, GL_DYNAMIC_DRAW);
1449 expected.copy_data0.Init(
1450 GL_ELEMENT_ARRAY_BUFFER, 0, kIndexSize, mem1.id, mem1.offset);
1451 expected.set_token0.Init(GetNextToken());
1452 expected.bind_to_emu.Init(GL_ARRAY_BUFFER, kEmuBufferId);
1453 expected.set_size.Init(GL_ARRAY_BUFFER, kTotalSize, 0, 0, GL_DYNAMIC_DRAW);
1454 expected.copy_data1.Init(
1455 GL_ARRAY_BUFFER, kEmuOffset1, kSize1, mem2.id, mem2.offset);
1456 expected.set_token1.Init(GetNextToken());
1457 expected.set_pointer1.Init(
1458 kAttribIndex1, kNumComponents1, GL_FLOAT, GL_FALSE, 0, kEmuOffset1);
1459 expected.copy_data2.Init(
1460 GL_ARRAY_BUFFER, kEmuOffset2, kSize2, mem3.id, mem3.offset);
1461 expected.set_token2.Init(GetNextToken());
1462 expected.set_pointer2.Init(kAttribIndex2, kNumComponents2,
1463 GL_FLOAT, GL_FALSE, 0, kEmuOffset2);
1464 expected.draw.Init(GL_POINTS, kCount, GL_UNSIGNED_SHORT, 0, 1);
1465 expected.restore.Init(GL_ARRAY_BUFFER, 0);
1466 expected.restore_element.Init(GL_ELEMENT_ARRAY_BUFFER, 0);
1467 gl_->EnableVertexAttribArray(kAttribIndex1);
1468 gl_->EnableVertexAttribArray(kAttribIndex2);
1469 gl_->VertexAttribPointer(kAttribIndex1, kNumComponents1,
1470 GL_FLOAT, GL_FALSE, kClientStride, verts);
1471 gl_->VertexAttribPointer(kAttribIndex2, kNumComponents2,
1472 GL_FLOAT, GL_FALSE, kClientStride, verts);
1473 gl_->VertexAttribDivisorANGLE(kAttribIndex2, kDivisor);
1474 gl_->DrawElementsInstancedANGLE(
1475 GL_POINTS, kCount, GL_UNSIGNED_SHORT, indices, 1);
1476 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
1479 TEST_F(GLES2ImplementationTest, GetVertexBufferPointerv) {
1480 static const float verts[1] = { 0.0f, };
1481 const GLuint kAttribIndex1 = 1;
1482 const GLuint kAttribIndex2 = 3;
1483 const GLint kNumComponents1 = 3;
1484 const GLint kNumComponents2 = 2;
1485 const GLsizei kStride1 = 12;
1486 const GLsizei kStride2 = 0;
1487 const GLuint kBufferId = 0x123;
1488 const GLint kOffset2 = 0x456;
1490 // It's all cached on the client side so no get commands are issued.
1491 struct Cmds {
1492 cmds::BindBuffer bind;
1493 cmds::VertexAttribPointer set_pointer;
1496 Cmds expected;
1497 expected.bind.Init(GL_ARRAY_BUFFER, kBufferId);
1498 expected.set_pointer.Init(kAttribIndex2, kNumComponents2, GL_FLOAT, GL_FALSE,
1499 kStride2, kOffset2);
1501 // Set one client side buffer.
1502 gl_->VertexAttribPointer(kAttribIndex1, kNumComponents1,
1503 GL_FLOAT, GL_FALSE, kStride1, verts);
1504 // Set one VBO
1505 gl_->BindBuffer(GL_ARRAY_BUFFER, kBufferId);
1506 gl_->VertexAttribPointer(kAttribIndex2, kNumComponents2,
1507 GL_FLOAT, GL_FALSE, kStride2,
1508 reinterpret_cast<const void*>(kOffset2));
1509 // now get them both.
1510 void* ptr1 = NULL;
1511 void* ptr2 = NULL;
1513 gl_->GetVertexAttribPointerv(
1514 kAttribIndex1, GL_VERTEX_ATTRIB_ARRAY_POINTER, &ptr1);
1515 gl_->GetVertexAttribPointerv(
1516 kAttribIndex2, GL_VERTEX_ATTRIB_ARRAY_POINTER, &ptr2);
1518 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
1519 EXPECT_TRUE(static_cast<const void*>(&verts) == ptr1);
1520 EXPECT_TRUE(ptr2 == reinterpret_cast<void*>(kOffset2));
1523 TEST_F(GLES2ImplementationTest, GetVertexAttrib) {
1524 static const float verts[1] = { 0.0f, };
1525 const GLuint kAttribIndex1 = 1;
1526 const GLuint kAttribIndex2 = 3;
1527 const GLint kNumComponents1 = 3;
1528 const GLint kNumComponents2 = 2;
1529 const GLsizei kStride1 = 12;
1530 const GLsizei kStride2 = 0;
1531 const GLuint kBufferId = 0x123;
1532 const GLint kOffset2 = 0x456;
1534 // Only one set and one get because the client side buffer's info is stored
1535 // on the client side.
1536 struct Cmds {
1537 cmds::EnableVertexAttribArray enable;
1538 cmds::BindBuffer bind;
1539 cmds::VertexAttribPointer set_pointer;
1540 cmds::GetVertexAttribfv get2; // for getting the value from attrib1
1543 ExpectedMemoryInfo mem2 = GetExpectedResultMemory(16);
1545 Cmds expected;
1546 expected.enable.Init(kAttribIndex1);
1547 expected.bind.Init(GL_ARRAY_BUFFER, kBufferId);
1548 expected.set_pointer.Init(kAttribIndex2, kNumComponents2, GL_FLOAT, GL_FALSE,
1549 kStride2, kOffset2);
1550 expected.get2.Init(kAttribIndex1,
1551 GL_CURRENT_VERTEX_ATTRIB,
1552 mem2.id, mem2.offset);
1554 FourFloats current_attrib(1.2f, 3.4f, 5.6f, 7.8f);
1556 // One call to flush to wait for last call to GetVertexAttribiv
1557 // as others are all cached.
1558 EXPECT_CALL(*command_buffer(), OnFlush())
1559 .WillOnce(SetMemory(
1560 mem2.ptr, SizedResultHelper<FourFloats>(current_attrib)))
1561 .RetiresOnSaturation();
1563 gl_->EnableVertexAttribArray(kAttribIndex1);
1564 // Set one client side buffer.
1565 gl_->VertexAttribPointer(kAttribIndex1, kNumComponents1,
1566 GL_FLOAT, GL_FALSE, kStride1, verts);
1567 // Set one VBO
1568 gl_->BindBuffer(GL_ARRAY_BUFFER, kBufferId);
1569 gl_->VertexAttribPointer(kAttribIndex2, kNumComponents2,
1570 GL_FLOAT, GL_FALSE, kStride2,
1571 reinterpret_cast<const void*>(kOffset2));
1572 // first get the service side once to see that we make a command
1573 GLint buffer_id = 0;
1574 GLint enabled = 0;
1575 GLint size = 0;
1576 GLint stride = 0;
1577 GLint type = 0;
1578 GLint normalized = 1;
1579 float current[4] = { 0.0f, };
1581 gl_->GetVertexAttribiv(
1582 kAttribIndex2, GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING, &buffer_id);
1583 EXPECT_EQ(kBufferId, static_cast<GLuint>(buffer_id));
1584 gl_->GetVertexAttribiv(
1585 kAttribIndex1, GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING, &buffer_id);
1586 gl_->GetVertexAttribiv(
1587 kAttribIndex1, GL_VERTEX_ATTRIB_ARRAY_ENABLED, &enabled);
1588 gl_->GetVertexAttribiv(
1589 kAttribIndex1, GL_VERTEX_ATTRIB_ARRAY_SIZE, &size);
1590 gl_->GetVertexAttribiv(
1591 kAttribIndex1, GL_VERTEX_ATTRIB_ARRAY_STRIDE, &stride);
1592 gl_->GetVertexAttribiv(
1593 kAttribIndex1, GL_VERTEX_ATTRIB_ARRAY_TYPE, &type);
1594 gl_->GetVertexAttribiv(
1595 kAttribIndex1, GL_VERTEX_ATTRIB_ARRAY_NORMALIZED, &normalized);
1596 gl_->GetVertexAttribfv(
1597 kAttribIndex1, GL_CURRENT_VERTEX_ATTRIB, &current[0]);
1599 EXPECT_EQ(0, buffer_id);
1600 EXPECT_EQ(GL_TRUE, enabled);
1601 EXPECT_EQ(kNumComponents1, size);
1602 EXPECT_EQ(kStride1, stride);
1603 EXPECT_EQ(GL_FLOAT, type);
1604 EXPECT_EQ(GL_FALSE, normalized);
1605 EXPECT_EQ(0, memcmp(&current_attrib, &current, sizeof(current_attrib)));
1607 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
1610 TEST_F(GLES2ImplementationTest, ReservedIds) {
1611 // Only the get error command should be issued.
1612 struct Cmds {
1613 cmds::GetError get;
1615 Cmds expected;
1617 ExpectedMemoryInfo mem1 = GetExpectedResultMemory(
1618 sizeof(cmds::GetError::Result));
1620 expected.get.Init(mem1.id, mem1.offset);
1622 // One call to flush to wait for GetError
1623 EXPECT_CALL(*command_buffer(), OnFlush())
1624 .WillOnce(SetMemory(mem1.ptr, GLuint(GL_NO_ERROR)))
1625 .RetiresOnSaturation();
1627 gl_->BindBuffer(
1628 GL_ARRAY_BUFFER,
1629 GLES2Implementation::kClientSideArrayId);
1630 gl_->BindBuffer(
1631 GL_ARRAY_BUFFER,
1632 GLES2Implementation::kClientSideElementArrayId);
1633 GLenum err = gl_->GetError();
1634 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_OPERATION), err);
1635 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
1638 #endif // defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS)
1640 TEST_F(GLES2ImplementationTest, ReadPixels2Reads) {
1641 struct Cmds {
1642 cmds::ReadPixels read1;
1643 cmd::SetToken set_token1;
1644 cmds::ReadPixels read2;
1645 cmd::SetToken set_token2;
1647 const GLint kBytesPerPixel = 4;
1648 const GLint kWidth =
1649 (kTransferBufferSize - GLES2Implementation::kStartingOffset) /
1650 kBytesPerPixel;
1651 const GLint kHeight = 2;
1652 const GLenum kFormat = GL_RGBA;
1653 const GLenum kType = GL_UNSIGNED_BYTE;
1655 ExpectedMemoryInfo mem1 =
1656 GetExpectedMemory(kWidth * kHeight / 2 * kBytesPerPixel);
1657 ExpectedMemoryInfo result1 =
1658 GetExpectedResultMemory(sizeof(cmds::ReadPixels::Result));
1659 ExpectedMemoryInfo mem2 =
1660 GetExpectedMemory(kWidth * kHeight / 2 * kBytesPerPixel);
1661 ExpectedMemoryInfo result2 =
1662 GetExpectedResultMemory(sizeof(cmds::ReadPixels::Result));
1664 Cmds expected;
1665 expected.read1.Init(
1666 0, 0, kWidth, kHeight / 2, kFormat, kType,
1667 mem1.id, mem1.offset, result1.id, result1.offset,
1668 false);
1669 expected.set_token1.Init(GetNextToken());
1670 expected.read2.Init(
1671 0, kHeight / 2, kWidth, kHeight / 2, kFormat, kType,
1672 mem2.id, mem2.offset, result2.id, result2.offset, false);
1673 expected.set_token2.Init(GetNextToken());
1674 scoped_ptr<int8[]> buffer(new int8[kWidth * kHeight * kBytesPerPixel]);
1676 EXPECT_CALL(*command_buffer(), OnFlush())
1677 .WillOnce(SetMemory(result1.ptr, static_cast<uint32>(1)))
1678 .WillOnce(SetMemory(result2.ptr, static_cast<uint32>(1)))
1679 .RetiresOnSaturation();
1681 gl_->ReadPixels(0, 0, kWidth, kHeight, kFormat, kType, buffer.get());
1682 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
1685 TEST_F(GLES2ImplementationTest, ReadPixelsBadFormatType) {
1686 struct Cmds {
1687 cmds::ReadPixels read;
1688 cmd::SetToken set_token;
1690 const GLint kBytesPerPixel = 4;
1691 const GLint kWidth = 2;
1692 const GLint kHeight = 2;
1693 const GLenum kFormat = 0;
1694 const GLenum kType = 0;
1696 ExpectedMemoryInfo mem1 =
1697 GetExpectedMemory(kWidth * kHeight * kBytesPerPixel);
1698 ExpectedMemoryInfo result1 =
1699 GetExpectedResultMemory(sizeof(cmds::ReadPixels::Result));
1701 Cmds expected;
1702 expected.read.Init(
1703 0, 0, kWidth, kHeight, kFormat, kType,
1704 mem1.id, mem1.offset, result1.id, result1.offset, false);
1705 expected.set_token.Init(GetNextToken());
1706 scoped_ptr<int8[]> buffer(new int8[kWidth * kHeight * kBytesPerPixel]);
1708 EXPECT_CALL(*command_buffer(), OnFlush())
1709 .Times(1)
1710 .RetiresOnSaturation();
1712 gl_->ReadPixels(0, 0, kWidth, kHeight, kFormat, kType, buffer.get());
1715 TEST_F(GLES2ImplementationTest, FreeUnusedSharedMemory) {
1716 struct Cmds {
1717 cmds::BufferSubData buf;
1718 cmd::SetToken set_token;
1720 const GLenum kTarget = GL_ELEMENT_ARRAY_BUFFER;
1721 const GLintptr kOffset = 15;
1722 const GLsizeiptr kSize = 16;
1724 ExpectedMemoryInfo mem1 = GetExpectedMemory(kSize);
1726 Cmds expected;
1727 expected.buf.Init(
1728 kTarget, kOffset, kSize, mem1.id, mem1.offset);
1729 expected.set_token.Init(GetNextToken());
1731 void* mem = gl_->MapBufferSubDataCHROMIUM(
1732 kTarget, kOffset, kSize, GL_WRITE_ONLY);
1733 ASSERT_TRUE(mem != NULL);
1734 gl_->UnmapBufferSubDataCHROMIUM(mem);
1735 EXPECT_CALL(*command_buffer(), DestroyTransferBuffer(_))
1736 .Times(1)
1737 .RetiresOnSaturation();
1738 gl_->FreeUnusedSharedMemory();
1741 TEST_F(GLES2ImplementationTest, MapUnmapBufferSubDataCHROMIUM) {
1742 struct Cmds {
1743 cmds::BufferSubData buf;
1744 cmd::SetToken set_token;
1746 const GLenum kTarget = GL_ELEMENT_ARRAY_BUFFER;
1747 const GLintptr kOffset = 15;
1748 const GLsizeiptr kSize = 16;
1750 uint32 offset = 0;
1751 Cmds expected;
1752 expected.buf.Init(
1753 kTarget, kOffset, kSize,
1754 command_buffer()->GetNextFreeTransferBufferId(), offset);
1755 expected.set_token.Init(GetNextToken());
1757 void* mem = gl_->MapBufferSubDataCHROMIUM(
1758 kTarget, kOffset, kSize, GL_WRITE_ONLY);
1759 ASSERT_TRUE(mem != NULL);
1760 gl_->UnmapBufferSubDataCHROMIUM(mem);
1761 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
1764 TEST_F(GLES2ImplementationTest, MapUnmapBufferSubDataCHROMIUMBadArgs) {
1765 const GLenum kTarget = GL_ELEMENT_ARRAY_BUFFER;
1766 const GLintptr kOffset = 15;
1767 const GLsizeiptr kSize = 16;
1769 ExpectedMemoryInfo result1 =
1770 GetExpectedResultMemory(sizeof(cmds::GetError::Result));
1771 ExpectedMemoryInfo result2 =
1772 GetExpectedResultMemory(sizeof(cmds::GetError::Result));
1773 ExpectedMemoryInfo result3 =
1774 GetExpectedResultMemory(sizeof(cmds::GetError::Result));
1775 ExpectedMemoryInfo result4 =
1776 GetExpectedResultMemory(sizeof(cmds::GetError::Result));
1778 // Calls to flush to wait for GetError
1779 EXPECT_CALL(*command_buffer(), OnFlush())
1780 .WillOnce(SetMemory(result1.ptr, GLuint(GL_NO_ERROR)))
1781 .WillOnce(SetMemory(result2.ptr, GLuint(GL_NO_ERROR)))
1782 .WillOnce(SetMemory(result3.ptr, GLuint(GL_NO_ERROR)))
1783 .WillOnce(SetMemory(result4.ptr, GLuint(GL_NO_ERROR)))
1784 .RetiresOnSaturation();
1786 void* mem;
1787 mem = gl_->MapBufferSubDataCHROMIUM(kTarget, -1, kSize, GL_WRITE_ONLY);
1788 ASSERT_TRUE(mem == NULL);
1789 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE), gl_->GetError());
1790 mem = gl_->MapBufferSubDataCHROMIUM(kTarget, kOffset, -1, GL_WRITE_ONLY);
1791 ASSERT_TRUE(mem == NULL);
1792 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE), gl_->GetError());
1793 mem = gl_->MapBufferSubDataCHROMIUM(kTarget, kOffset, kSize, GL_READ_ONLY);
1794 ASSERT_TRUE(mem == NULL);
1795 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_ENUM), gl_->GetError());
1796 const char* kPtr = "something";
1797 gl_->UnmapBufferSubDataCHROMIUM(kPtr);
1798 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE), gl_->GetError());
1801 TEST_F(GLES2ImplementationTest, MapUnmapTexSubImage2DCHROMIUM) {
1802 struct Cmds {
1803 cmds::TexSubImage2D tex;
1804 cmd::SetToken set_token;
1806 const GLint kLevel = 1;
1807 const GLint kXOffset = 2;
1808 const GLint kYOffset = 3;
1809 const GLint kWidth = 4;
1810 const GLint kHeight = 5;
1811 const GLenum kFormat = GL_RGBA;
1812 const GLenum kType = GL_UNSIGNED_BYTE;
1814 uint32 offset = 0;
1815 Cmds expected;
1816 expected.tex.Init(
1817 GL_TEXTURE_2D, kLevel, kXOffset, kYOffset, kWidth, kHeight, kFormat,
1818 kType,
1819 command_buffer()->GetNextFreeTransferBufferId(), offset, GL_FALSE);
1820 expected.set_token.Init(GetNextToken());
1822 void* mem = gl_->MapTexSubImage2DCHROMIUM(
1823 GL_TEXTURE_2D,
1824 kLevel,
1825 kXOffset,
1826 kYOffset,
1827 kWidth,
1828 kHeight,
1829 kFormat,
1830 kType,
1831 GL_WRITE_ONLY);
1832 ASSERT_TRUE(mem != NULL);
1833 gl_->UnmapTexSubImage2DCHROMIUM(mem);
1834 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
1837 TEST_F(GLES2ImplementationTest, MapUnmapTexSubImage2DCHROMIUMBadArgs) {
1838 const GLint kLevel = 1;
1839 const GLint kXOffset = 2;
1840 const GLint kYOffset = 3;
1841 const GLint kWidth = 4;
1842 const GLint kHeight = 5;
1843 const GLenum kFormat = GL_RGBA;
1844 const GLenum kType = GL_UNSIGNED_BYTE;
1846 ExpectedMemoryInfo result1 =
1847 GetExpectedResultMemory(sizeof(cmds::GetError::Result));
1848 ExpectedMemoryInfo result2 =
1849 GetExpectedResultMemory(sizeof(cmds::GetError::Result));
1850 ExpectedMemoryInfo result3 =
1851 GetExpectedResultMemory(sizeof(cmds::GetError::Result));
1852 ExpectedMemoryInfo result4 =
1853 GetExpectedResultMemory(sizeof(cmds::GetError::Result));
1854 ExpectedMemoryInfo result5 =
1855 GetExpectedResultMemory(sizeof(cmds::GetError::Result));
1856 ExpectedMemoryInfo result6 =
1857 GetExpectedResultMemory(sizeof(cmds::GetError::Result));
1858 ExpectedMemoryInfo result7 =
1859 GetExpectedResultMemory(sizeof(cmds::GetError::Result));
1861 // Calls to flush to wait for GetError
1862 EXPECT_CALL(*command_buffer(), OnFlush())
1863 .WillOnce(SetMemory(result1.ptr, GLuint(GL_NO_ERROR)))
1864 .WillOnce(SetMemory(result2.ptr, GLuint(GL_NO_ERROR)))
1865 .WillOnce(SetMemory(result3.ptr, GLuint(GL_NO_ERROR)))
1866 .WillOnce(SetMemory(result4.ptr, GLuint(GL_NO_ERROR)))
1867 .WillOnce(SetMemory(result5.ptr, GLuint(GL_NO_ERROR)))
1868 .WillOnce(SetMemory(result6.ptr, GLuint(GL_NO_ERROR)))
1869 .WillOnce(SetMemory(result7.ptr, GLuint(GL_NO_ERROR)))
1870 .RetiresOnSaturation();
1872 void* mem;
1873 mem = gl_->MapTexSubImage2DCHROMIUM(
1874 GL_TEXTURE_2D,
1876 kXOffset,
1877 kYOffset,
1878 kWidth,
1879 kHeight,
1880 kFormat,
1881 kType,
1882 GL_WRITE_ONLY);
1883 EXPECT_TRUE(mem == NULL);
1884 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE), gl_->GetError());
1885 mem = gl_->MapTexSubImage2DCHROMIUM(
1886 GL_TEXTURE_2D,
1887 kLevel,
1889 kYOffset,
1890 kWidth,
1891 kHeight,
1892 kFormat,
1893 kType,
1894 GL_WRITE_ONLY);
1895 EXPECT_TRUE(mem == NULL);
1896 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE), gl_->GetError());
1897 mem = gl_->MapTexSubImage2DCHROMIUM(
1898 GL_TEXTURE_2D,
1899 kLevel,
1900 kXOffset,
1902 kWidth,
1903 kHeight,
1904 kFormat,
1905 kType,
1906 GL_WRITE_ONLY);
1907 EXPECT_TRUE(mem == NULL);
1908 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE), gl_->GetError());
1909 mem = gl_->MapTexSubImage2DCHROMIUM(
1910 GL_TEXTURE_2D,
1911 kLevel,
1912 kXOffset,
1913 kYOffset,
1915 kHeight,
1916 kFormat,
1917 kType,
1918 GL_WRITE_ONLY);
1919 EXPECT_TRUE(mem == NULL);
1920 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE), gl_->GetError());
1921 mem = gl_->MapTexSubImage2DCHROMIUM(
1922 GL_TEXTURE_2D,
1923 kLevel,
1924 kXOffset,
1925 kYOffset,
1926 kWidth,
1928 kFormat,
1929 kType,
1930 GL_WRITE_ONLY);
1931 EXPECT_TRUE(mem == NULL);
1932 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE), gl_->GetError());
1933 mem = gl_->MapTexSubImage2DCHROMIUM(
1934 GL_TEXTURE_2D,
1935 kLevel,
1936 kXOffset,
1937 kYOffset,
1938 kWidth,
1939 kHeight,
1940 kFormat,
1941 kType,
1942 GL_READ_ONLY);
1943 EXPECT_TRUE(mem == NULL);
1944 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_ENUM), gl_->GetError());
1945 const char* kPtr = "something";
1946 gl_->UnmapTexSubImage2DCHROMIUM(kPtr);
1947 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE), gl_->GetError());
1950 TEST_F(GLES2ImplementationTest, GetMultipleIntegervCHROMIUMValidArgs) {
1951 const GLenum pnames[] = {
1952 GL_DEPTH_WRITEMASK,
1953 GL_COLOR_WRITEMASK,
1954 GL_STENCIL_WRITEMASK,
1956 const GLint num_results = 6;
1957 GLint results[num_results + 1];
1958 struct Cmds {
1959 cmds::GetMultipleIntegervCHROMIUM get_multiple;
1960 cmd::SetToken set_token;
1962 const GLsizei kNumPnames = arraysize(pnames);
1963 const GLsizeiptr kResultsSize = num_results * sizeof(results[0]);
1964 const size_t kPNamesSize = kNumPnames * sizeof(pnames[0]);
1966 ExpectedMemoryInfo mem1 = GetExpectedMemory(kPNamesSize + kResultsSize);
1967 ExpectedMemoryInfo result1 = GetExpectedResultMemory(
1968 sizeof(cmds::GetError::Result));
1970 const uint32 kPnamesOffset = mem1.offset;
1971 const uint32 kResultsOffset = mem1.offset + kPNamesSize;
1972 Cmds expected;
1973 expected.get_multiple.Init(
1974 mem1.id, kPnamesOffset, kNumPnames,
1975 mem1.id, kResultsOffset, kResultsSize);
1976 expected.set_token.Init(GetNextToken());
1978 const GLint kSentinel = 0x12345678;
1979 memset(results, 0, sizeof(results));
1980 results[num_results] = kSentinel;
1981 const GLint returned_results[] = {
1982 1, 0, 1, 0, 1, -1,
1984 // One call to flush to wait for results
1985 EXPECT_CALL(*command_buffer(), OnFlush())
1986 .WillOnce(SetMemoryFromArray(mem1.ptr + kPNamesSize,
1987 returned_results, sizeof(returned_results)))
1988 .WillOnce(SetMemory(result1.ptr, GLuint(GL_NO_ERROR)))
1989 .RetiresOnSaturation();
1991 gl_->GetMultipleIntegervCHROMIUM(
1992 &pnames[0], kNumPnames, &results[0], kResultsSize);
1993 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
1994 EXPECT_EQ(0, memcmp(&returned_results, results, sizeof(returned_results)));
1995 EXPECT_EQ(kSentinel, results[num_results]);
1996 EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), gl_->GetError());
1999 TEST_F(GLES2ImplementationTest, GetMultipleIntegervCHROMIUMBadArgs) {
2000 GLenum pnames[] = {
2001 GL_DEPTH_WRITEMASK,
2002 GL_COLOR_WRITEMASK,
2003 GL_STENCIL_WRITEMASK,
2005 const GLint num_results = 6;
2006 GLint results[num_results + 1];
2007 const GLsizei kNumPnames = arraysize(pnames);
2008 const GLsizeiptr kResultsSize = num_results * sizeof(results[0]);
2010 ExpectedMemoryInfo result1 =
2011 GetExpectedResultMemory(sizeof(cmds::GetError::Result));
2012 ExpectedMemoryInfo result2 =
2013 GetExpectedResultMemory(sizeof(cmds::GetError::Result));
2014 ExpectedMemoryInfo result3 =
2015 GetExpectedResultMemory(sizeof(cmds::GetError::Result));
2016 ExpectedMemoryInfo result4 =
2017 GetExpectedResultMemory(sizeof(cmds::GetError::Result));
2019 // Calls to flush to wait for GetError
2020 EXPECT_CALL(*command_buffer(), OnFlush())
2021 .WillOnce(SetMemory(result1.ptr, GLuint(GL_NO_ERROR)))
2022 .WillOnce(SetMemory(result2.ptr, GLuint(GL_NO_ERROR)))
2023 .WillOnce(SetMemory(result3.ptr, GLuint(GL_NO_ERROR)))
2024 .WillOnce(SetMemory(result4.ptr, GLuint(GL_NO_ERROR)))
2025 .RetiresOnSaturation();
2027 const GLint kSentinel = 0x12345678;
2028 memset(results, 0, sizeof(results));
2029 results[num_results] = kSentinel;
2030 // try bad size.
2031 gl_->GetMultipleIntegervCHROMIUM(
2032 &pnames[0], kNumPnames, &results[0], kResultsSize + 1);
2033 EXPECT_TRUE(NoCommandsWritten());
2034 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE), gl_->GetError());
2035 EXPECT_EQ(0, results[0]);
2036 EXPECT_EQ(kSentinel, results[num_results]);
2037 // try bad size.
2038 ClearCommands();
2039 gl_->GetMultipleIntegervCHROMIUM(
2040 &pnames[0], kNumPnames, &results[0], kResultsSize - 1);
2041 EXPECT_TRUE(NoCommandsWritten());
2042 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE), gl_->GetError());
2043 EXPECT_EQ(0, results[0]);
2044 EXPECT_EQ(kSentinel, results[num_results]);
2045 // try uncleared results.
2046 ClearCommands();
2047 results[2] = 1;
2048 gl_->GetMultipleIntegervCHROMIUM(
2049 &pnames[0], kNumPnames, &results[0], kResultsSize);
2050 EXPECT_TRUE(NoCommandsWritten());
2051 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE), gl_->GetError());
2052 EXPECT_EQ(0, results[0]);
2053 EXPECT_EQ(kSentinel, results[num_results]);
2054 // try bad enum results.
2055 ClearCommands();
2056 results[2] = 0;
2057 pnames[1] = GL_TRUE;
2058 gl_->GetMultipleIntegervCHROMIUM(
2059 &pnames[0], kNumPnames, &results[0], kResultsSize);
2060 EXPECT_TRUE(NoCommandsWritten());
2061 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_ENUM), gl_->GetError());
2062 EXPECT_EQ(0, results[0]);
2063 EXPECT_EQ(kSentinel, results[num_results]);
2066 TEST_F(GLES2ImplementationTest, GetProgramInfoCHROMIUMGoodArgs) {
2067 const uint32 kBucketId = GLES2Implementation::kResultBucketId;
2068 const GLuint kProgramId = 123;
2069 const char kBad = 0x12;
2070 GLsizei size = 0;
2071 const Str7 kString = {"foobar"};
2072 char buf[20];
2074 ExpectedMemoryInfo mem1 =
2075 GetExpectedMemory(MaxTransferBufferSize());
2076 ExpectedMemoryInfo result1 =
2077 GetExpectedResultMemory(sizeof(cmd::GetBucketStart::Result));
2078 ExpectedMemoryInfo result2 =
2079 GetExpectedResultMemory(sizeof(cmds::GetError::Result));
2081 memset(buf, kBad, sizeof(buf));
2082 EXPECT_CALL(*command_buffer(), OnFlush())
2083 .WillOnce(DoAll(SetMemory(result1.ptr, uint32(sizeof(kString))),
2084 SetMemory(mem1.ptr, kString)))
2085 .WillOnce(SetMemory(result2.ptr, GLuint(GL_NO_ERROR)))
2086 .RetiresOnSaturation();
2088 struct Cmds {
2089 cmd::SetBucketSize set_bucket_size1;
2090 cmds::GetProgramInfoCHROMIUM get_program_info;
2091 cmd::GetBucketStart get_bucket_start;
2092 cmd::SetToken set_token1;
2093 cmd::SetBucketSize set_bucket_size2;
2095 Cmds expected;
2096 expected.set_bucket_size1.Init(kBucketId, 0);
2097 expected.get_program_info.Init(kProgramId, kBucketId);
2098 expected.get_bucket_start.Init(
2099 kBucketId, result1.id, result1.offset,
2100 MaxTransferBufferSize(), mem1.id, mem1.offset);
2101 expected.set_token1.Init(GetNextToken());
2102 expected.set_bucket_size2.Init(kBucketId, 0);
2103 gl_->GetProgramInfoCHROMIUM(kProgramId, sizeof(buf), &size, &buf);
2104 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
2105 EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), gl_->GetError());
2106 EXPECT_EQ(sizeof(kString), static_cast<size_t>(size));
2107 EXPECT_STREQ(kString.str, buf);
2108 EXPECT_EQ(buf[sizeof(kString)], kBad);
2111 TEST_F(GLES2ImplementationTest, GetProgramInfoCHROMIUMBadArgs) {
2112 const uint32 kBucketId = GLES2Implementation::kResultBucketId;
2113 const GLuint kProgramId = 123;
2114 GLsizei size = 0;
2115 const Str7 kString = {"foobar"};
2116 char buf[20];
2118 ExpectedMemoryInfo mem1 = GetExpectedMemory(MaxTransferBufferSize());
2119 ExpectedMemoryInfo result1 =
2120 GetExpectedResultMemory(sizeof(cmd::GetBucketStart::Result));
2121 ExpectedMemoryInfo result2 =
2122 GetExpectedResultMemory(sizeof(cmds::GetError::Result));
2123 ExpectedMemoryInfo result3 =
2124 GetExpectedResultMemory(sizeof(cmds::GetError::Result));
2125 ExpectedMemoryInfo result4 =
2126 GetExpectedResultMemory(sizeof(cmds::GetError::Result));
2128 EXPECT_CALL(*command_buffer(), OnFlush())
2129 .WillOnce(DoAll(SetMemory(result1.ptr, uint32(sizeof(kString))),
2130 SetMemory(mem1.ptr, kString)))
2131 .WillOnce(SetMemory(result2.ptr, GLuint(GL_NO_ERROR)))
2132 .WillOnce(SetMemory(result3.ptr, GLuint(GL_NO_ERROR)))
2133 .WillOnce(SetMemory(result4.ptr, GLuint(GL_NO_ERROR)))
2134 .RetiresOnSaturation();
2136 // try bufsize not big enough.
2137 struct Cmds {
2138 cmd::SetBucketSize set_bucket_size1;
2139 cmds::GetProgramInfoCHROMIUM get_program_info;
2140 cmd::GetBucketStart get_bucket_start;
2141 cmd::SetToken set_token1;
2142 cmd::SetBucketSize set_bucket_size2;
2144 Cmds expected;
2145 expected.set_bucket_size1.Init(kBucketId, 0);
2146 expected.get_program_info.Init(kProgramId, kBucketId);
2147 expected.get_bucket_start.Init(
2148 kBucketId, result1.id, result1.offset,
2149 MaxTransferBufferSize(), mem1.id, mem1.offset);
2150 expected.set_token1.Init(GetNextToken());
2151 expected.set_bucket_size2.Init(kBucketId, 0);
2152 gl_->GetProgramInfoCHROMIUM(kProgramId, 6, &size, &buf);
2153 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
2154 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_OPERATION), gl_->GetError());
2155 ClearCommands();
2157 // try bad bufsize
2158 gl_->GetProgramInfoCHROMIUM(kProgramId, -1, &size, &buf);
2159 EXPECT_TRUE(NoCommandsWritten());
2160 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE), gl_->GetError());
2161 ClearCommands();
2162 // try no size ptr.
2163 gl_->GetProgramInfoCHROMIUM(kProgramId, sizeof(buf), NULL, &buf);
2164 EXPECT_TRUE(NoCommandsWritten());
2165 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE), gl_->GetError());
2168 // Test that things are cached
2169 TEST_F(GLES2ImplementationTest, GetIntegerCacheRead) {
2170 struct PNameValue {
2171 GLenum pname;
2172 GLint expected;
2174 const PNameValue pairs[] = {
2175 {GL_ACTIVE_TEXTURE, GL_TEXTURE0, },
2176 {GL_TEXTURE_BINDING_2D, 0, },
2177 {GL_TEXTURE_BINDING_CUBE_MAP, 0, },
2178 {GL_TEXTURE_BINDING_EXTERNAL_OES, 0, },
2179 {GL_FRAMEBUFFER_BINDING, 0, },
2180 {GL_RENDERBUFFER_BINDING, 0, },
2181 {GL_ARRAY_BUFFER_BINDING, 0, },
2182 {GL_ELEMENT_ARRAY_BUFFER_BINDING, 0, },
2183 {GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, kMaxCombinedTextureImageUnits, },
2184 {GL_MAX_CUBE_MAP_TEXTURE_SIZE, kMaxCubeMapTextureSize, },
2185 {GL_MAX_FRAGMENT_UNIFORM_VECTORS, kMaxFragmentUniformVectors, },
2186 {GL_MAX_RENDERBUFFER_SIZE, kMaxRenderbufferSize, },
2187 {GL_MAX_TEXTURE_IMAGE_UNITS, kMaxTextureImageUnits, },
2188 {GL_MAX_TEXTURE_SIZE, kMaxTextureSize, },
2189 {GL_MAX_VARYING_VECTORS, kMaxVaryingVectors, },
2190 {GL_MAX_VERTEX_ATTRIBS, kMaxVertexAttribs, },
2191 {GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, kMaxVertexTextureImageUnits, },
2192 {GL_MAX_VERTEX_UNIFORM_VECTORS, kMaxVertexUniformVectors, },
2193 {GL_NUM_COMPRESSED_TEXTURE_FORMATS, kNumCompressedTextureFormats, },
2194 {GL_NUM_SHADER_BINARY_FORMATS, kNumShaderBinaryFormats, }, };
2195 size_t num_pairs = sizeof(pairs) / sizeof(pairs[0]);
2196 for (size_t ii = 0; ii < num_pairs; ++ii) {
2197 const PNameValue& pv = pairs[ii];
2198 GLint v = -1;
2199 gl_->GetIntegerv(pv.pname, &v);
2200 EXPECT_TRUE(NoCommandsWritten());
2201 EXPECT_EQ(pv.expected, v);
2204 ExpectedMemoryInfo result1 =
2205 GetExpectedResultMemory(sizeof(cmds::GetError::Result));
2207 EXPECT_CALL(*command_buffer(), OnFlush())
2208 .WillOnce(SetMemory(result1.ptr, GLuint(GL_NO_ERROR)))
2209 .RetiresOnSaturation();
2210 EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), gl_->GetError());
2213 TEST_F(GLES2ImplementationTest, GetIntegerCacheWrite) {
2214 struct PNameValue {
2215 GLenum pname;
2216 GLint expected;
2218 gl_->ActiveTexture(GL_TEXTURE4);
2219 gl_->BindBuffer(GL_ARRAY_BUFFER, 2);
2220 gl_->BindBuffer(GL_ELEMENT_ARRAY_BUFFER, 3);
2221 gl_->BindFramebuffer(GL_FRAMEBUFFER, 4);
2222 gl_->BindRenderbuffer(GL_RENDERBUFFER, 5);
2223 gl_->BindTexture(GL_TEXTURE_2D, 6);
2224 gl_->BindTexture(GL_TEXTURE_CUBE_MAP, 7);
2225 gl_->BindTexture(GL_TEXTURE_EXTERNAL_OES, 8);
2227 const PNameValue pairs[] = {{GL_ACTIVE_TEXTURE, GL_TEXTURE4, },
2228 {GL_ARRAY_BUFFER_BINDING, 2, },
2229 {GL_ELEMENT_ARRAY_BUFFER_BINDING, 3, },
2230 {GL_FRAMEBUFFER_BINDING, 4, },
2231 {GL_RENDERBUFFER_BINDING, 5, },
2232 {GL_TEXTURE_BINDING_2D, 6, },
2233 {GL_TEXTURE_BINDING_CUBE_MAP, 7, },
2234 {GL_TEXTURE_BINDING_EXTERNAL_OES, 8, }, };
2235 size_t num_pairs = sizeof(pairs) / sizeof(pairs[0]);
2236 for (size_t ii = 0; ii < num_pairs; ++ii) {
2237 const PNameValue& pv = pairs[ii];
2238 GLint v = -1;
2239 gl_->GetIntegerv(pv.pname, &v);
2240 EXPECT_EQ(pv.expected, v);
2243 ExpectedMemoryInfo result1 =
2244 GetExpectedResultMemory(sizeof(cmds::GetError::Result));
2246 EXPECT_CALL(*command_buffer(), OnFlush())
2247 .WillOnce(SetMemory(result1.ptr, GLuint(GL_NO_ERROR)))
2248 .RetiresOnSaturation();
2249 EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), gl_->GetError());
2252 static bool CheckRect(
2253 int width, int height, GLenum format, GLenum type, int alignment,
2254 bool flip_y, const uint8* r1, const uint8* r2) {
2255 uint32 size = 0;
2256 uint32 unpadded_row_size = 0;
2257 uint32 padded_row_size = 0;
2258 if (!GLES2Util::ComputeImageDataSizes(
2259 width, height, format, type, alignment, &size, &unpadded_row_size,
2260 &padded_row_size)) {
2261 return false;
2264 int r2_stride = flip_y ?
2265 -static_cast<int>(padded_row_size) :
2266 static_cast<int>(padded_row_size);
2267 r2 = flip_y ? (r2 + (height - 1) * padded_row_size) : r2;
2269 for (int y = 0; y < height; ++y) {
2270 if (memcmp(r1, r2, unpadded_row_size) != 0) {
2271 return false;
2273 r1 += padded_row_size;
2274 r2 += r2_stride;
2276 return true;
2279 ACTION_P8(CheckRectAction, width, height, format, type, alignment, flip_y,
2280 r1, r2) {
2281 EXPECT_TRUE(CheckRect(
2282 width, height, format, type, alignment, flip_y, r1, r2));
2285 // Test TexImage2D with and without flip_y
2286 TEST_F(GLES2ImplementationTest, TexImage2D) {
2287 struct Cmds {
2288 cmds::TexImage2D tex_image_2d;
2289 cmd::SetToken set_token;
2291 struct Cmds2 {
2292 cmds::TexImage2D tex_image_2d;
2293 cmd::SetToken set_token;
2295 const GLenum kTarget = GL_TEXTURE_2D;
2296 const GLint kLevel = 0;
2297 const GLenum kFormat = GL_RGB;
2298 const GLsizei kWidth = 3;
2299 const GLsizei kHeight = 4;
2300 const GLint kBorder = 0;
2301 const GLenum kType = GL_UNSIGNED_BYTE;
2302 const GLint kPixelStoreUnpackAlignment = 4;
2303 static uint8 pixels[] = {
2304 11, 12, 13, 13, 14, 15, 15, 16, 17, 101, 102, 103,
2305 21, 22, 23, 23, 24, 25, 25, 26, 27, 201, 202, 203,
2306 31, 32, 33, 33, 34, 35, 35, 36, 37, 123, 124, 125,
2307 41, 42, 43, 43, 44, 45, 45, 46, 47,
2310 ExpectedMemoryInfo mem1 = GetExpectedMemory(sizeof(pixels));
2312 Cmds expected;
2313 expected.tex_image_2d.Init(
2314 kTarget, kLevel, kFormat, kWidth, kHeight, kFormat, kType,
2315 mem1.id, mem1.offset);
2316 expected.set_token.Init(GetNextToken());
2317 gl_->TexImage2D(
2318 kTarget, kLevel, kFormat, kWidth, kHeight, kBorder, kFormat, kType,
2319 pixels);
2320 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
2321 EXPECT_TRUE(CheckRect(
2322 kWidth, kHeight, kFormat, kType, kPixelStoreUnpackAlignment, false,
2323 pixels, mem1.ptr));
2325 ClearCommands();
2326 gl_->PixelStorei(GL_UNPACK_FLIP_Y_CHROMIUM, GL_TRUE);
2328 ExpectedMemoryInfo mem2 = GetExpectedMemory(sizeof(pixels));
2329 Cmds2 expected2;
2330 expected2.tex_image_2d.Init(
2331 kTarget, kLevel, kFormat, kWidth, kHeight, kFormat, kType,
2332 mem2.id, mem2.offset);
2333 expected2.set_token.Init(GetNextToken());
2334 const void* commands2 = GetPut();
2335 gl_->TexImage2D(
2336 kTarget, kLevel, kFormat, kWidth, kHeight, kBorder, kFormat, kType,
2337 pixels);
2338 EXPECT_EQ(0, memcmp(&expected2, commands2, sizeof(expected2)));
2339 EXPECT_TRUE(CheckRect(
2340 kWidth, kHeight, kFormat, kType, kPixelStoreUnpackAlignment, true,
2341 pixels, mem2.ptr));
2344 // Test TexImage2D with 2 writes
2345 TEST_F(GLES2ImplementationTest, TexImage2D2Writes) {
2346 struct Cmds {
2347 cmds::TexImage2D tex_image_2d;
2348 cmds::TexSubImage2D tex_sub_image_2d1;
2349 cmd::SetToken set_token1;
2350 cmds::TexSubImage2D tex_sub_image_2d2;
2351 cmd::SetToken set_token2;
2353 const GLenum kTarget = GL_TEXTURE_2D;
2354 const GLint kLevel = 0;
2355 const GLenum kFormat = GL_RGB;
2356 const GLint kBorder = 0;
2357 const GLenum kType = GL_UNSIGNED_BYTE;
2358 const GLint kPixelStoreUnpackAlignment = 4;
2359 const GLsizei kWidth = 3;
2361 uint32 size = 0;
2362 uint32 unpadded_row_size = 0;
2363 uint32 padded_row_size = 0;
2364 ASSERT_TRUE(GLES2Util::ComputeImageDataSizes(
2365 kWidth, 2, kFormat, kType, kPixelStoreUnpackAlignment,
2366 &size, &unpadded_row_size, &padded_row_size));
2367 const GLsizei kHeight = (MaxTransferBufferSize() / padded_row_size) * 2;
2368 ASSERT_TRUE(GLES2Util::ComputeImageDataSizes(
2369 kWidth, kHeight, kFormat, kType, kPixelStoreUnpackAlignment,
2370 &size, NULL, NULL));
2371 uint32 half_size = 0;
2372 ASSERT_TRUE(GLES2Util::ComputeImageDataSizes(
2373 kWidth, kHeight / 2, kFormat, kType, kPixelStoreUnpackAlignment,
2374 &half_size, NULL, NULL));
2376 scoped_ptr<uint8[]> pixels(new uint8[size]);
2377 for (uint32 ii = 0; ii < size; ++ii) {
2378 pixels[ii] = static_cast<uint8>(ii);
2381 ExpectedMemoryInfo mem1 = GetExpectedMemory(half_size);
2382 ExpectedMemoryInfo mem2 = GetExpectedMemory(half_size);
2384 Cmds expected;
2385 expected.tex_image_2d.Init(
2386 kTarget, kLevel, kFormat, kWidth, kHeight, kFormat, kType,
2387 0, 0);
2388 expected.tex_sub_image_2d1.Init(
2389 kTarget, kLevel, 0, 0, kWidth, kHeight / 2, kFormat, kType,
2390 mem1.id, mem1.offset, true);
2391 expected.set_token1.Init(GetNextToken());
2392 expected.tex_sub_image_2d2.Init(
2393 kTarget, kLevel, 0, kHeight / 2, kWidth, kHeight / 2, kFormat, kType,
2394 mem2.id, mem2.offset, true);
2395 expected.set_token2.Init(GetNextToken());
2397 // TODO(gman): Make it possible to run this test
2398 // EXPECT_CALL(*command_buffer(), OnFlush())
2399 // .WillOnce(CheckRectAction(
2400 // kWidth, kHeight / 2, kFormat, kType, kPixelStoreUnpackAlignment,
2401 // false, pixels.get(),
2402 // GetExpectedTransferAddressFromOffsetAs<uint8>(offset1, half_size)))
2403 // .RetiresOnSaturation();
2405 gl_->TexImage2D(
2406 kTarget, kLevel, kFormat, kWidth, kHeight, kBorder, kFormat, kType,
2407 pixels.get());
2408 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
2409 EXPECT_TRUE(CheckRect(
2410 kWidth, kHeight / 2, kFormat, kType, kPixelStoreUnpackAlignment, false,
2411 pixels.get() + kHeight / 2 * padded_row_size, mem2.ptr));
2413 ClearCommands();
2414 gl_->PixelStorei(GL_UNPACK_FLIP_Y_CHROMIUM, GL_TRUE);
2415 const void* commands2 = GetPut();
2416 ExpectedMemoryInfo mem3 = GetExpectedMemory(half_size);
2417 ExpectedMemoryInfo mem4 = GetExpectedMemory(half_size);
2418 expected.tex_image_2d.Init(
2419 kTarget, kLevel, kFormat, kWidth, kHeight, kFormat, kType,
2420 0, 0);
2421 expected.tex_sub_image_2d1.Init(
2422 kTarget, kLevel, 0, kHeight / 2, kWidth, kHeight / 2, kFormat, kType,
2423 mem3.id, mem3.offset, true);
2424 expected.set_token1.Init(GetNextToken());
2425 expected.tex_sub_image_2d2.Init(
2426 kTarget, kLevel, 0, 0, kWidth, kHeight / 2, kFormat, kType,
2427 mem4.id, mem4.offset, true);
2428 expected.set_token2.Init(GetNextToken());
2430 // TODO(gman): Make it possible to run this test
2431 // EXPECT_CALL(*command_buffer(), OnFlush())
2432 // .WillOnce(CheckRectAction(
2433 // kWidth, kHeight / 2, kFormat, kType, kPixelStoreUnpackAlignment,
2434 // true, pixels.get(),
2435 // GetExpectedTransferAddressFromOffsetAs<uint8>(offset3, half_size)))
2436 // .RetiresOnSaturation();
2438 gl_->TexImage2D(
2439 kTarget, kLevel, kFormat, kWidth, kHeight, kBorder, kFormat, kType,
2440 pixels.get());
2441 EXPECT_EQ(0, memcmp(&expected, commands2, sizeof(expected)));
2442 EXPECT_TRUE(CheckRect(
2443 kWidth, kHeight / 2, kFormat, kType, kPixelStoreUnpackAlignment, true,
2444 pixels.get() + kHeight / 2 * padded_row_size, mem4.ptr));
2447 // Test TexSubImage2D with GL_PACK_FLIP_Y set and partial multirow transfers
2448 TEST_F(GLES2ImplementationTest, TexSubImage2DFlipY) {
2449 const GLsizei kTextureWidth = MaxTransferBufferSize() / 4;
2450 const GLsizei kTextureHeight = 7;
2451 const GLsizei kSubImageWidth = MaxTransferBufferSize() / 8;
2452 const GLsizei kSubImageHeight = 4;
2453 const GLint kSubImageXOffset = 1;
2454 const GLint kSubImageYOffset = 2;
2455 const GLenum kFormat = GL_RGBA;
2456 const GLenum kType = GL_UNSIGNED_BYTE;
2457 const GLenum kTarget = GL_TEXTURE_2D;
2458 const GLint kLevel = 0;
2459 const GLint kBorder = 0;
2460 const GLint kPixelStoreUnpackAlignment = 4;
2462 struct Cmds {
2463 cmds::PixelStorei pixel_store_i1;
2464 cmds::TexImage2D tex_image_2d;
2465 cmds::PixelStorei pixel_store_i2;
2466 cmds::TexSubImage2D tex_sub_image_2d1;
2467 cmd::SetToken set_token1;
2468 cmds::TexSubImage2D tex_sub_image_2d2;
2469 cmd::SetToken set_token2;
2472 uint32 sub_2_high_size = 0;
2473 ASSERT_TRUE(GLES2Util::ComputeImageDataSizes(
2474 kSubImageWidth, 2, kFormat, kType, kPixelStoreUnpackAlignment,
2475 &sub_2_high_size, NULL, NULL));
2477 ExpectedMemoryInfo mem1 = GetExpectedMemory(sub_2_high_size);
2478 ExpectedMemoryInfo mem2 = GetExpectedMemory(sub_2_high_size);
2480 Cmds expected;
2481 expected.pixel_store_i1.Init(GL_UNPACK_ALIGNMENT, kPixelStoreUnpackAlignment);
2482 expected.tex_image_2d.Init(
2483 kTarget, kLevel, kFormat, kTextureWidth, kTextureHeight, kFormat,
2484 kType, 0, 0);
2485 expected.pixel_store_i2.Init(GL_UNPACK_FLIP_Y_CHROMIUM, GL_TRUE);
2486 expected.tex_sub_image_2d1.Init(kTarget, kLevel, kSubImageXOffset,
2487 kSubImageYOffset + 2, kSubImageWidth, 2, kFormat, kType,
2488 mem1.id, mem1.offset, false);
2489 expected.set_token1.Init(GetNextToken());
2490 expected.tex_sub_image_2d2.Init(kTarget, kLevel, kSubImageXOffset,
2491 kSubImageYOffset, kSubImageWidth , 2, kFormat, kType,
2492 mem2.id, mem2.offset, false);
2493 expected.set_token2.Init(GetNextToken());
2495 gl_->PixelStorei(GL_UNPACK_ALIGNMENT, kPixelStoreUnpackAlignment);
2496 gl_->TexImage2D(
2497 kTarget, kLevel, kFormat, kTextureWidth, kTextureHeight, kBorder, kFormat,
2498 kType, NULL);
2499 gl_->PixelStorei(GL_UNPACK_FLIP_Y_CHROMIUM, GL_TRUE);
2500 scoped_ptr<uint32[]> pixels(new uint32[kSubImageWidth * kSubImageHeight]);
2501 for (int y = 0; y < kSubImageHeight; ++y) {
2502 for (int x = 0; x < kSubImageWidth; ++x) {
2503 pixels.get()[kSubImageWidth * y + x] = x | (y << 16);
2506 gl_->TexSubImage2D(
2507 GL_TEXTURE_2D, 0, kSubImageXOffset, kSubImageYOffset, kSubImageWidth,
2508 kSubImageHeight, GL_RGBA, GL_UNSIGNED_BYTE, pixels.get());
2510 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
2511 EXPECT_TRUE(CheckRect(
2512 kSubImageWidth, 2, kFormat, kType, kPixelStoreUnpackAlignment, true,
2513 reinterpret_cast<uint8*>(pixels.get() + 2 * kSubImageWidth),
2514 mem2.ptr));
2517 TEST_F(GLES2ImplementationTest, SubImageUnpack) {
2518 static const GLint unpack_alignments[] = { 1, 2, 4, 8 };
2520 static const GLenum kFormat = GL_RGB;
2521 static const GLenum kType = GL_UNSIGNED_BYTE;
2522 static const GLint kLevel = 0;
2523 static const GLint kBorder = 0;
2524 // We're testing using the unpack params to pull a subimage out of a larger
2525 // source of pixels. Here we specify the subimage by its border rows /
2526 // columns.
2527 static const GLint kSrcWidth = 33;
2528 static const GLint kSrcSubImageX0 = 11;
2529 static const GLint kSrcSubImageX1 = 20;
2530 static const GLint kSrcSubImageY0 = 18;
2531 static const GLint kSrcSubImageY1 = 23;
2532 static const GLint kSrcSubImageWidth = kSrcSubImageX1 - kSrcSubImageX0;
2533 static const GLint kSrcSubImageHeight = kSrcSubImageY1 - kSrcSubImageY0;
2535 // these are only used in the texsubimage tests
2536 static const GLint kTexWidth = 1023;
2537 static const GLint kTexHeight = 511;
2538 static const GLint kTexSubXOffset = 419;
2539 static const GLint kTexSubYOffset = 103;
2541 struct {
2542 cmds::PixelStorei pixel_store_i;
2543 cmds::PixelStorei pixel_store_i2;
2544 cmds::TexImage2D tex_image_2d;
2545 } texImageExpected;
2547 struct {
2548 cmds::PixelStorei pixel_store_i;
2549 cmds::PixelStorei pixel_store_i2;
2550 cmds::TexImage2D tex_image_2d;
2551 cmds::TexSubImage2D tex_sub_image_2d;
2552 } texSubImageExpected;
2554 uint32 src_size;
2555 ASSERT_TRUE(GLES2Util::ComputeImageDataSizes(
2556 kSrcWidth, kSrcSubImageY1, kFormat, kType, 8, &src_size, NULL, NULL));
2557 scoped_ptr<uint8[]> src_pixels;
2558 src_pixels.reset(new uint8[src_size]);
2559 for (size_t i = 0; i < src_size; ++i) {
2560 src_pixels[i] = static_cast<int8>(i);
2563 for (int sub = 0; sub < 2; ++sub) {
2564 for (int flip_y = 0; flip_y < 2; ++flip_y) {
2565 for (size_t a = 0; a < arraysize(unpack_alignments); ++a) {
2566 GLint alignment = unpack_alignments[a];
2567 uint32 size;
2568 uint32 unpadded_row_size;
2569 uint32 padded_row_size;
2570 ASSERT_TRUE(GLES2Util::ComputeImageDataSizes(
2571 kSrcSubImageWidth, kSrcSubImageHeight, kFormat, kType, alignment,
2572 &size, &unpadded_row_size, &padded_row_size));
2573 ASSERT_TRUE(size <= MaxTransferBufferSize());
2574 ExpectedMemoryInfo mem = GetExpectedMemory(size);
2576 const void* commands = GetPut();
2577 gl_->PixelStorei(GL_UNPACK_ALIGNMENT, alignment);
2578 gl_->PixelStorei(GL_UNPACK_ROW_LENGTH_EXT, kSrcWidth);
2579 gl_->PixelStorei(GL_UNPACK_SKIP_PIXELS_EXT, kSrcSubImageX0);
2580 gl_->PixelStorei(GL_UNPACK_SKIP_ROWS_EXT, kSrcSubImageY0);
2581 gl_->PixelStorei(GL_UNPACK_FLIP_Y_CHROMIUM, flip_y);
2582 if (sub) {
2583 gl_->TexImage2D(
2584 GL_TEXTURE_2D, kLevel, kFormat, kTexWidth, kTexHeight, kBorder,
2585 kFormat, kType, NULL);
2586 gl_->TexSubImage2D(
2587 GL_TEXTURE_2D, kLevel, kTexSubXOffset, kTexSubYOffset,
2588 kSrcSubImageWidth, kSrcSubImageHeight, kFormat, kType,
2589 src_pixels.get());
2590 texSubImageExpected.pixel_store_i.Init(
2591 GL_UNPACK_ALIGNMENT, alignment);
2592 texSubImageExpected.pixel_store_i2.Init(
2593 GL_UNPACK_FLIP_Y_CHROMIUM, flip_y);
2594 texSubImageExpected.tex_image_2d.Init(
2595 GL_TEXTURE_2D, kLevel, kFormat, kTexWidth, kTexHeight,
2596 kFormat, kType, 0, 0);
2597 texSubImageExpected.tex_sub_image_2d.Init(
2598 GL_TEXTURE_2D, kLevel, kTexSubXOffset, kTexSubYOffset,
2599 kSrcSubImageWidth, kSrcSubImageHeight, kFormat, kType, mem.id,
2600 mem.offset, GL_FALSE);
2601 EXPECT_EQ(0, memcmp(
2602 &texSubImageExpected, commands, sizeof(texSubImageExpected)));
2603 } else {
2604 gl_->TexImage2D(
2605 GL_TEXTURE_2D, kLevel, kFormat,
2606 kSrcSubImageWidth, kSrcSubImageHeight, kBorder, kFormat, kType,
2607 src_pixels.get());
2608 texImageExpected.pixel_store_i.Init(GL_UNPACK_ALIGNMENT, alignment);
2609 texImageExpected.pixel_store_i2.Init(
2610 GL_UNPACK_FLIP_Y_CHROMIUM, flip_y);
2611 texImageExpected.tex_image_2d.Init(
2612 GL_TEXTURE_2D, kLevel, kFormat, kSrcSubImageWidth,
2613 kSrcSubImageHeight, kFormat, kType, mem.id, mem.offset);
2614 EXPECT_EQ(0, memcmp(
2615 &texImageExpected, commands, sizeof(texImageExpected)));
2617 uint32 src_padded_row_size;
2618 ASSERT_TRUE(GLES2Util::ComputeImagePaddedRowSize(
2619 kSrcWidth, kFormat, kType, alignment, &src_padded_row_size));
2620 uint32 bytes_per_group = GLES2Util::ComputeImageGroupSize(
2621 kFormat, kType);
2622 for (int y = 0; y < kSrcSubImageHeight; ++y) {
2623 GLint src_sub_y = flip_y ? kSrcSubImageHeight - y - 1 : y;
2624 const uint8* src_row = src_pixels.get() +
2625 (kSrcSubImageY0 + src_sub_y) * src_padded_row_size +
2626 bytes_per_group * kSrcSubImageX0;
2627 const uint8* dst_row = mem.ptr + y * padded_row_size;
2628 EXPECT_EQ(0, memcmp(src_row, dst_row, unpadded_row_size));
2630 ClearCommands();
2636 // Test texture related calls with invalid arguments.
2637 TEST_F(GLES2ImplementationTest, TextureInvalidArguments) {
2638 struct Cmds {
2639 cmds::TexImage2D tex_image_2d;
2640 cmd::SetToken set_token;
2642 const GLenum kTarget = GL_TEXTURE_2D;
2643 const GLint kLevel = 0;
2644 const GLenum kFormat = GL_RGB;
2645 const GLsizei kWidth = 3;
2646 const GLsizei kHeight = 4;
2647 const GLint kBorder = 0;
2648 const GLint kInvalidBorder = 1;
2649 const GLenum kType = GL_UNSIGNED_BYTE;
2650 const GLint kPixelStoreUnpackAlignment = 4;
2651 static uint8 pixels[] = {
2652 11, 12, 13, 13, 14, 15, 15, 16, 17, 101, 102, 103,
2653 21, 22, 23, 23, 24, 25, 25, 26, 27, 201, 202, 203,
2654 31, 32, 33, 33, 34, 35, 35, 36, 37, 123, 124, 125,
2655 41, 42, 43, 43, 44, 45, 45, 46, 47,
2658 // Verify that something works.
2660 ExpectedMemoryInfo mem1 = GetExpectedMemory(sizeof(pixels));
2662 Cmds expected;
2663 expected.tex_image_2d.Init(
2664 kTarget, kLevel, kFormat, kWidth, kHeight, kFormat, kType,
2665 mem1.id, mem1.offset);
2666 expected.set_token.Init(GetNextToken());
2667 gl_->TexImage2D(
2668 kTarget, kLevel, kFormat, kWidth, kHeight, kBorder, kFormat, kType,
2669 pixels);
2670 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
2671 EXPECT_TRUE(CheckRect(
2672 kWidth, kHeight, kFormat, kType, kPixelStoreUnpackAlignment, false,
2673 pixels, mem1.ptr));
2675 ClearCommands();
2677 // Use invalid border.
2678 gl_->TexImage2D(
2679 kTarget, kLevel, kFormat, kWidth, kHeight, kInvalidBorder, kFormat, kType,
2680 pixels);
2682 EXPECT_TRUE(NoCommandsWritten());
2683 EXPECT_EQ(GL_INVALID_VALUE, CheckError());
2685 ClearCommands();
2687 gl_->AsyncTexImage2DCHROMIUM(
2688 kTarget, kLevel, kFormat, kWidth, kHeight, kInvalidBorder, kFormat, kType,
2689 NULL);
2691 EXPECT_TRUE(NoCommandsWritten());
2692 EXPECT_EQ(GL_INVALID_VALUE, CheckError());
2694 ClearCommands();
2696 // Checking for CompressedTexImage2D argument validation is a bit tricky due
2697 // to (runtime-detected) compression formats. Try to infer the error with an
2698 // aux check.
2699 const GLenum kCompressedFormat = GL_ETC1_RGB8_OES;
2700 gl_->CompressedTexImage2D(
2701 kTarget, kLevel, kCompressedFormat, kWidth, kHeight, kBorder,
2702 arraysize(pixels), pixels);
2704 // In the above, kCompressedFormat and arraysize(pixels) are possibly wrong
2705 // values. First ensure that these do not cause failures at the client. If
2706 // this check ever fails, it probably means that client checks more than at
2707 // the time of writing of this test. In this case, more code needs to be
2708 // written for this test.
2709 EXPECT_FALSE(NoCommandsWritten());
2711 ClearCommands();
2713 // Changing border to invalid border should make the call fail at the client
2714 // checks.
2715 gl_->CompressedTexImage2D(
2716 kTarget, kLevel, kCompressedFormat, kWidth, kHeight, kInvalidBorder,
2717 arraysize(pixels), pixels);
2718 EXPECT_TRUE(NoCommandsWritten());
2719 EXPECT_EQ(GL_INVALID_VALUE, CheckError());
2723 // Binds can not be cached with bind_generates_resource = false because
2724 // our id might not be valid. More specifically if you bind on contextA then
2725 // delete on contextB the resource is still bound on contextA but GetInterger
2726 // won't return an id.
2727 TEST_F(GLES2ImplementationStrictSharedTest, BindsNotCached) {
2728 struct PNameValue {
2729 GLenum pname;
2730 GLint expected;
2732 const PNameValue pairs[] = {{GL_TEXTURE_BINDING_2D, 1, },
2733 {GL_TEXTURE_BINDING_CUBE_MAP, 2, },
2734 {GL_TEXTURE_BINDING_EXTERNAL_OES, 3, },
2735 {GL_FRAMEBUFFER_BINDING, 4, },
2736 {GL_RENDERBUFFER_BINDING, 5, },
2737 {GL_ARRAY_BUFFER_BINDING, 6, },
2738 {GL_ELEMENT_ARRAY_BUFFER_BINDING, 7, }, };
2739 size_t num_pairs = sizeof(pairs) / sizeof(pairs[0]);
2740 for (size_t ii = 0; ii < num_pairs; ++ii) {
2741 const PNameValue& pv = pairs[ii];
2742 GLint v = -1;
2743 ExpectedMemoryInfo result1 =
2744 GetExpectedResultMemory(sizeof(cmds::GetIntegerv::Result));
2745 EXPECT_CALL(*command_buffer(), OnFlush())
2746 .WillOnce(SetMemory(result1.ptr,
2747 SizedResultHelper<GLuint>(pv.expected)))
2748 .RetiresOnSaturation();
2749 gl_->GetIntegerv(pv.pname, &v);
2750 EXPECT_EQ(pv.expected, v);
2754 // glGen* Ids must not be reused until glDelete* commands have been
2755 // flushed by glFlush.
2756 TEST_F(GLES2ImplementationStrictSharedTest, FlushGenerationTestBuffers) {
2757 FlushGenerationTest<GenBuffersAPI>();
2759 TEST_F(GLES2ImplementationStrictSharedTest, FlushGenerationTestFramebuffers) {
2760 FlushGenerationTest<GenFramebuffersAPI>();
2762 TEST_F(GLES2ImplementationStrictSharedTest, FlushGenerationTestRenderbuffers) {
2763 FlushGenerationTest<GenRenderbuffersAPI>();
2765 TEST_F(GLES2ImplementationStrictSharedTest, FlushGenerationTestTextures) {
2766 FlushGenerationTest<GenTexturesAPI>();
2769 // glGen* Ids must not be reused cross-context until glDelete* commands are
2770 // flushed by glFlush, and the Ids are lazily freed after.
2771 TEST_F(GLES2ImplementationStrictSharedTest, CrossContextGenerationTestBuffers) {
2772 CrossContextGenerationTest<GenBuffersAPI>();
2774 TEST_F(GLES2ImplementationStrictSharedTest,
2775 CrossContextGenerationTestFramebuffers) {
2776 CrossContextGenerationTest<GenFramebuffersAPI>();
2778 TEST_F(GLES2ImplementationStrictSharedTest,
2779 CrossContextGenerationTestRenderbuffers) {
2780 CrossContextGenerationTest<GenRenderbuffersAPI>();
2782 TEST_F(GLES2ImplementationStrictSharedTest,
2783 CrossContextGenerationTestTextures) {
2784 CrossContextGenerationTest<GenTexturesAPI>();
2787 // Test Delete which causes auto flush. Tests a regression case that occurred
2788 // in testing.
2789 TEST_F(GLES2ImplementationStrictSharedTest,
2790 CrossContextGenerationAutoFlushTestBuffers) {
2791 CrossContextGenerationAutoFlushTest<GenBuffersAPI>();
2793 TEST_F(GLES2ImplementationStrictSharedTest,
2794 CrossContextGenerationAutoFlushTestFramebuffers) {
2795 CrossContextGenerationAutoFlushTest<GenFramebuffersAPI>();
2797 TEST_F(GLES2ImplementationStrictSharedTest,
2798 CrossContextGenerationAutoFlushTestRenderbuffers) {
2799 CrossContextGenerationAutoFlushTest<GenRenderbuffersAPI>();
2801 TEST_F(GLES2ImplementationStrictSharedTest,
2802 CrossContextGenerationAutoFlushTestTextures) {
2803 CrossContextGenerationAutoFlushTest<GenTexturesAPI>();
2806 TEST_F(GLES2ImplementationTest, GetString) {
2807 const uint32 kBucketId = GLES2Implementation::kResultBucketId;
2808 const Str7 kString = {"foobar"};
2809 // GL_CHROMIUM_map_sub GL_CHROMIUM_flipy are hard coded into
2810 // GLES2Implementation.
2811 const char* expected_str =
2812 "foobar "
2813 "GL_CHROMIUM_flipy "
2814 "GL_EXT_unpack_subimage "
2815 "GL_CHROMIUM_map_sub";
2816 const char kBad = 0x12;
2817 struct Cmds {
2818 cmd::SetBucketSize set_bucket_size1;
2819 cmds::GetString get_string;
2820 cmd::GetBucketStart get_bucket_start;
2821 cmd::SetToken set_token1;
2822 cmd::SetBucketSize set_bucket_size2;
2824 ExpectedMemoryInfo mem1 = GetExpectedMemory(MaxTransferBufferSize());
2825 ExpectedMemoryInfo result1 =
2826 GetExpectedResultMemory(sizeof(cmd::GetBucketStart::Result));
2827 Cmds expected;
2828 expected.set_bucket_size1.Init(kBucketId, 0);
2829 expected.get_string.Init(GL_EXTENSIONS, kBucketId);
2830 expected.get_bucket_start.Init(
2831 kBucketId, result1.id, result1.offset,
2832 MaxTransferBufferSize(), mem1.id, mem1.offset);
2833 expected.set_token1.Init(GetNextToken());
2834 expected.set_bucket_size2.Init(kBucketId, 0);
2835 char buf[sizeof(kString) + 1];
2836 memset(buf, kBad, sizeof(buf));
2838 EXPECT_CALL(*command_buffer(), OnFlush())
2839 .WillOnce(DoAll(SetMemory(result1.ptr, uint32(sizeof(kString))),
2840 SetMemory(mem1.ptr, kString)))
2841 .RetiresOnSaturation();
2843 const GLubyte* result = gl_->GetString(GL_EXTENSIONS);
2844 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
2845 EXPECT_STREQ(expected_str, reinterpret_cast<const char*>(result));
2848 TEST_F(GLES2ImplementationTest, PixelStoreiGLPackReverseRowOrderANGLE) {
2849 const uint32 kBucketId = GLES2Implementation::kResultBucketId;
2850 const Str7 kString = {"foobar"};
2851 struct Cmds {
2852 cmd::SetBucketSize set_bucket_size1;
2853 cmds::GetString get_string;
2854 cmd::GetBucketStart get_bucket_start;
2855 cmd::SetToken set_token1;
2856 cmd::SetBucketSize set_bucket_size2;
2857 cmds::PixelStorei pixel_store;
2860 ExpectedMemoryInfo mem1 = GetExpectedMemory(MaxTransferBufferSize());
2861 ExpectedMemoryInfo result1 =
2862 GetExpectedResultMemory(sizeof(cmd::GetBucketStart::Result));
2864 Cmds expected;
2865 expected.set_bucket_size1.Init(kBucketId, 0);
2866 expected.get_string.Init(GL_EXTENSIONS, kBucketId);
2867 expected.get_bucket_start.Init(
2868 kBucketId, result1.id, result1.offset,
2869 MaxTransferBufferSize(), mem1.id, mem1.offset);
2870 expected.set_token1.Init(GetNextToken());
2871 expected.set_bucket_size2.Init(kBucketId, 0);
2872 expected.pixel_store.Init(GL_PACK_REVERSE_ROW_ORDER_ANGLE, 1);
2874 EXPECT_CALL(*command_buffer(), OnFlush())
2875 .WillOnce(DoAll(SetMemory(result1.ptr, uint32(sizeof(kString))),
2876 SetMemory(mem1.ptr, kString)))
2877 .RetiresOnSaturation();
2879 gl_->PixelStorei(GL_PACK_REVERSE_ROW_ORDER_ANGLE, 1);
2880 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
2883 TEST_F(GLES2ImplementationTest, CreateProgram) {
2884 struct Cmds {
2885 cmds::CreateProgram cmd;
2888 Cmds expected;
2889 expected.cmd.Init(kProgramsAndShadersStartId);
2890 GLuint id = gl_->CreateProgram();
2891 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
2892 EXPECT_EQ(kProgramsAndShadersStartId, id);
2895 TEST_F(GLES2ImplementationTest, BufferDataLargerThanTransferBuffer) {
2896 struct Cmds {
2897 cmds::BufferData set_size;
2898 cmds::BufferSubData copy_data1;
2899 cmd::SetToken set_token1;
2900 cmds::BufferSubData copy_data2;
2901 cmd::SetToken set_token2;
2903 const unsigned kUsableSize =
2904 kTransferBufferSize - GLES2Implementation::kStartingOffset;
2905 uint8 buf[kUsableSize * 2] = { 0, };
2907 ExpectedMemoryInfo mem1 = GetExpectedMemory(kUsableSize);
2908 ExpectedMemoryInfo mem2 = GetExpectedMemory(kUsableSize);
2910 Cmds expected;
2911 expected.set_size.Init(
2912 GL_ARRAY_BUFFER, arraysize(buf), 0, 0, GL_DYNAMIC_DRAW);
2913 expected.copy_data1.Init(
2914 GL_ARRAY_BUFFER, 0, kUsableSize, mem1.id, mem1.offset);
2915 expected.set_token1.Init(GetNextToken());
2916 expected.copy_data2.Init(
2917 GL_ARRAY_BUFFER, kUsableSize, kUsableSize, mem2.id, mem2.offset);
2918 expected.set_token2.Init(GetNextToken());
2919 gl_->BufferData(GL_ARRAY_BUFFER, arraysize(buf), buf, GL_DYNAMIC_DRAW);
2920 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
2923 TEST_F(GLES2ImplementationTest, CapabilitiesAreCached) {
2924 static const GLenum kStates[] = {
2925 GL_DITHER,
2926 GL_BLEND,
2927 GL_CULL_FACE,
2928 GL_DEPTH_TEST,
2929 GL_POLYGON_OFFSET_FILL,
2930 GL_SAMPLE_ALPHA_TO_COVERAGE,
2931 GL_SAMPLE_COVERAGE,
2932 GL_SCISSOR_TEST,
2933 GL_STENCIL_TEST,
2935 struct Cmds {
2936 cmds::Enable enable_cmd;
2938 Cmds expected;
2940 for (size_t ii = 0; ii < arraysize(kStates); ++ii) {
2941 GLenum state = kStates[ii];
2942 expected.enable_cmd.Init(state);
2943 GLboolean result = gl_->IsEnabled(state);
2944 EXPECT_EQ(static_cast<GLboolean>(ii == 0), result);
2945 EXPECT_TRUE(NoCommandsWritten());
2946 const void* commands = GetPut();
2947 if (!result) {
2948 gl_->Enable(state);
2949 EXPECT_EQ(0, memcmp(&expected, commands, sizeof(expected)));
2951 ClearCommands();
2952 result = gl_->IsEnabled(state);
2953 EXPECT_TRUE(result);
2954 EXPECT_TRUE(NoCommandsWritten());
2958 TEST_F(GLES2ImplementationTest, BindVertexArrayOES) {
2959 GLuint id = 0;
2960 gl_->GenVertexArraysOES(1, &id);
2961 ClearCommands();
2963 struct Cmds {
2964 cmds::BindVertexArrayOES cmd;
2966 Cmds expected;
2967 expected.cmd.Init(id);
2969 const void* commands = GetPut();
2970 gl_->BindVertexArrayOES(id);
2971 EXPECT_EQ(0, memcmp(&expected, commands, sizeof(expected)));
2972 ClearCommands();
2973 gl_->BindVertexArrayOES(id);
2974 EXPECT_TRUE(NoCommandsWritten());
2977 TEST_F(GLES2ImplementationTest, BeginEndQueryEXT) {
2978 // Test GetQueryivEXT returns 0 if no current query.
2979 GLint param = -1;
2980 gl_->GetQueryivEXT(GL_ANY_SAMPLES_PASSED_EXT, GL_CURRENT_QUERY_EXT, &param);
2981 EXPECT_EQ(0, param);
2983 GLuint expected_ids[2] = { 1, 2 }; // These must match what's actually genned.
2984 struct GenCmds {
2985 cmds::GenQueriesEXTImmediate gen;
2986 GLuint data[2];
2988 GenCmds expected_gen_cmds;
2989 expected_gen_cmds.gen.Init(arraysize(expected_ids), &expected_ids[0]);
2990 GLuint ids[arraysize(expected_ids)] = { 0, };
2991 gl_->GenQueriesEXT(arraysize(expected_ids), &ids[0]);
2992 EXPECT_EQ(0, memcmp(
2993 &expected_gen_cmds, commands_, sizeof(expected_gen_cmds)));
2994 GLuint id1 = ids[0];
2995 GLuint id2 = ids[1];
2996 ClearCommands();
2998 // Test BeginQueryEXT fails if id = 0.
2999 gl_->BeginQueryEXT(GL_ANY_SAMPLES_PASSED_EXT, 0);
3000 EXPECT_TRUE(NoCommandsWritten());
3001 EXPECT_EQ(GL_INVALID_OPERATION, CheckError());
3003 // Test BeginQueryEXT inserts command.
3004 struct BeginCmds {
3005 cmds::BeginQueryEXT begin_query;
3007 BeginCmds expected_begin_cmds;
3008 const void* commands = GetPut();
3009 gl_->BeginQueryEXT(GL_ANY_SAMPLES_PASSED_EXT, id1);
3010 QueryTracker::Query* query = GetQuery(id1);
3011 ASSERT_TRUE(query != NULL);
3012 expected_begin_cmds.begin_query.Init(
3013 GL_ANY_SAMPLES_PASSED_EXT, id1, query->shm_id(), query->shm_offset());
3014 EXPECT_EQ(0, memcmp(
3015 &expected_begin_cmds, commands, sizeof(expected_begin_cmds)));
3016 ClearCommands();
3018 // Test GetQueryivEXT returns id.
3019 param = -1;
3020 gl_->GetQueryivEXT(GL_ANY_SAMPLES_PASSED_EXT, GL_CURRENT_QUERY_EXT, &param);
3021 EXPECT_EQ(id1, static_cast<GLuint>(param));
3022 gl_->GetQueryivEXT(
3023 GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT, GL_CURRENT_QUERY_EXT, &param);
3024 EXPECT_EQ(0, param);
3026 // Test BeginQueryEXT fails if between Begin/End.
3027 gl_->BeginQueryEXT(GL_ANY_SAMPLES_PASSED_EXT, id2);
3028 EXPECT_TRUE(NoCommandsWritten());
3029 EXPECT_EQ(GL_INVALID_OPERATION, CheckError());
3031 // Test EndQueryEXT fails if target not same as current query.
3032 ClearCommands();
3033 gl_->EndQueryEXT(GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT);
3034 EXPECT_TRUE(NoCommandsWritten());
3035 EXPECT_EQ(GL_INVALID_OPERATION, CheckError());
3037 // Test EndQueryEXT sends command
3038 struct EndCmds {
3039 cmds::EndQueryEXT end_query;
3041 EndCmds expected_end_cmds;
3042 expected_end_cmds.end_query.Init(
3043 GL_ANY_SAMPLES_PASSED_EXT, query->submit_count());
3044 commands = GetPut();
3045 gl_->EndQueryEXT(GL_ANY_SAMPLES_PASSED_EXT);
3046 EXPECT_EQ(0, memcmp(
3047 &expected_end_cmds, commands, sizeof(expected_end_cmds)));
3049 // Test EndQueryEXT fails if no current query.
3050 ClearCommands();
3051 gl_->EndQueryEXT(GL_ANY_SAMPLES_PASSED_EXT);
3052 EXPECT_TRUE(NoCommandsWritten());
3053 EXPECT_EQ(GL_INVALID_OPERATION, CheckError());
3055 // Test 2nd Begin/End increments count.
3056 base::subtle::Atomic32 old_submit_count = query->submit_count();
3057 gl_->BeginQueryEXT(GL_ANY_SAMPLES_PASSED_EXT, id1);
3058 EXPECT_NE(old_submit_count, query->submit_count());
3059 expected_end_cmds.end_query.Init(
3060 GL_ANY_SAMPLES_PASSED_EXT, query->submit_count());
3061 commands = GetPut();
3062 gl_->EndQueryEXT(GL_ANY_SAMPLES_PASSED_EXT);
3063 EXPECT_EQ(0, memcmp(
3064 &expected_end_cmds, commands, sizeof(expected_end_cmds)));
3066 // Test BeginQueryEXT fails if target changed.
3067 ClearCommands();
3068 gl_->BeginQueryEXT(GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT, id1);
3069 EXPECT_TRUE(NoCommandsWritten());
3070 EXPECT_EQ(GL_INVALID_OPERATION, CheckError());
3072 // Test GetQueryObjectuivEXT fails if unused id
3073 GLuint available = 0xBDu;
3074 ClearCommands();
3075 gl_->GetQueryObjectuivEXT(id2, GL_QUERY_RESULT_AVAILABLE_EXT, &available);
3076 EXPECT_TRUE(NoCommandsWritten());
3077 EXPECT_EQ(0xBDu, available);
3078 EXPECT_EQ(GL_INVALID_OPERATION, CheckError());
3080 // Test GetQueryObjectuivEXT fails if bad id
3081 ClearCommands();
3082 gl_->GetQueryObjectuivEXT(4567, GL_QUERY_RESULT_AVAILABLE_EXT, &available);
3083 EXPECT_TRUE(NoCommandsWritten());
3084 EXPECT_EQ(0xBDu, available);
3085 EXPECT_EQ(GL_INVALID_OPERATION, CheckError());
3087 // Test GetQueryObjectuivEXT CheckResultsAvailable
3088 ClearCommands();
3089 gl_->GetQueryObjectuivEXT(id1, GL_QUERY_RESULT_AVAILABLE_EXT, &available);
3090 EXPECT_EQ(0u, available);
3093 TEST_F(GLES2ImplementationTest, ErrorQuery) {
3094 GLuint id = 0;
3095 gl_->GenQueriesEXT(1, &id);
3096 ClearCommands();
3098 // Test BeginQueryEXT does NOT insert commands.
3099 gl_->BeginQueryEXT(GL_GET_ERROR_QUERY_CHROMIUM, id);
3100 EXPECT_TRUE(NoCommandsWritten());
3101 QueryTracker::Query* query = GetQuery(id);
3102 ASSERT_TRUE(query != NULL);
3104 // Test EndQueryEXT sends both begin and end command
3105 struct EndCmds {
3106 cmds::BeginQueryEXT begin_query;
3107 cmds::EndQueryEXT end_query;
3109 EndCmds expected_end_cmds;
3110 expected_end_cmds.begin_query.Init(
3111 GL_GET_ERROR_QUERY_CHROMIUM, id, query->shm_id(), query->shm_offset());
3112 expected_end_cmds.end_query.Init(
3113 GL_GET_ERROR_QUERY_CHROMIUM, query->submit_count());
3114 const void* commands = GetPut();
3115 gl_->EndQueryEXT(GL_GET_ERROR_QUERY_CHROMIUM);
3116 EXPECT_EQ(0, memcmp(
3117 &expected_end_cmds, commands, sizeof(expected_end_cmds)));
3118 ClearCommands();
3120 // Check result is not yet available.
3121 GLuint available = 0xBDu;
3122 gl_->GetQueryObjectuivEXT(id, GL_QUERY_RESULT_AVAILABLE_EXT, &available);
3123 EXPECT_TRUE(NoCommandsWritten());
3124 EXPECT_EQ(0u, available);
3126 // Test no commands are sent if there is a client side error.
3128 // Generate a client side error
3129 gl_->ActiveTexture(GL_TEXTURE0 - 1);
3131 gl_->BeginQueryEXT(GL_GET_ERROR_QUERY_CHROMIUM, id);
3132 gl_->EndQueryEXT(GL_GET_ERROR_QUERY_CHROMIUM);
3133 EXPECT_TRUE(NoCommandsWritten());
3135 // Check result is available.
3136 gl_->GetQueryObjectuivEXT(id, GL_QUERY_RESULT_AVAILABLE_EXT, &available);
3137 EXPECT_TRUE(NoCommandsWritten());
3138 EXPECT_NE(0u, available);
3140 // Check result.
3141 GLuint result = 0xBDu;
3142 gl_->GetQueryObjectuivEXT(id, GL_QUERY_RESULT_EXT, &result);
3143 EXPECT_TRUE(NoCommandsWritten());
3144 EXPECT_EQ(static_cast<GLuint>(GL_INVALID_ENUM), result);
3147 #if !defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS)
3148 TEST_F(GLES2ImplementationTest, VertexArrays) {
3149 const GLuint kAttribIndex1 = 1;
3150 const GLint kNumComponents1 = 3;
3151 const GLsizei kClientStride = 12;
3153 GLuint id = 0;
3154 gl_->GenVertexArraysOES(1, &id);
3155 ClearCommands();
3157 gl_->BindVertexArrayOES(id);
3159 // Test that VertexAttribPointer cannot be called with a bound buffer of 0
3160 // unless the offset is NULL
3161 gl_->BindBuffer(GL_ARRAY_BUFFER, 0);
3163 gl_->VertexAttribPointer(
3164 kAttribIndex1, kNumComponents1, GL_FLOAT, GL_FALSE, kClientStride,
3165 reinterpret_cast<const void*>(4));
3166 EXPECT_EQ(GL_INVALID_OPERATION, CheckError());
3168 gl_->VertexAttribPointer(
3169 kAttribIndex1, kNumComponents1, GL_FLOAT, GL_FALSE, kClientStride, NULL);
3170 EXPECT_EQ(GL_NO_ERROR, CheckError());
3172 #endif
3174 TEST_F(GLES2ImplementationTest, Disable) {
3175 struct Cmds {
3176 cmds::Disable cmd;
3178 Cmds expected;
3179 expected.cmd.Init(GL_DITHER); // Note: DITHER defaults to enabled.
3181 gl_->Disable(GL_DITHER);
3182 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
3183 // Check it's cached and not called again.
3184 ClearCommands();
3185 gl_->Disable(GL_DITHER);
3186 EXPECT_TRUE(NoCommandsWritten());
3189 TEST_F(GLES2ImplementationTest, Enable) {
3190 struct Cmds {
3191 cmds::Enable cmd;
3193 Cmds expected;
3194 expected.cmd.Init(GL_BLEND); // Note: BLEND defaults to disabled.
3196 gl_->Enable(GL_BLEND);
3197 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
3198 // Check it's cached and not called again.
3199 ClearCommands();
3200 gl_->Enable(GL_BLEND);
3201 EXPECT_TRUE(NoCommandsWritten());
3204 TEST_F(GLES2ImplementationTest, ConsumeTextureCHROMIUM) {
3205 struct Cmds {
3206 cmds::ConsumeTextureCHROMIUMImmediate cmd;
3207 GLbyte data[64];
3210 Mailbox mailbox = Mailbox::Generate();
3211 Cmds expected;
3212 expected.cmd.Init(GL_TEXTURE_2D, mailbox.name);
3213 gl_->ConsumeTextureCHROMIUM(GL_TEXTURE_2D, mailbox.name);
3214 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
3217 TEST_F(GLES2ImplementationTest, CreateAndConsumeTextureCHROMIUM) {
3218 struct Cmds {
3219 cmds::CreateAndConsumeTextureCHROMIUMImmediate cmd;
3220 GLbyte data[64];
3223 Mailbox mailbox = Mailbox::Generate();
3224 Cmds expected;
3225 expected.cmd.Init(GL_TEXTURE_2D, kTexturesStartId, mailbox.name);
3226 GLuint id = gl_->CreateAndConsumeTextureCHROMIUM(GL_TEXTURE_2D, mailbox.name);
3227 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
3228 EXPECT_EQ(kTexturesStartId, id);
3231 TEST_F(GLES2ImplementationTest, ProduceTextureCHROMIUM) {
3232 struct Cmds {
3233 cmds::ProduceTextureCHROMIUMImmediate cmd;
3234 GLbyte data[64];
3237 Mailbox mailbox = Mailbox::Generate();
3238 Cmds expected;
3239 expected.cmd.Init(GL_TEXTURE_2D, mailbox.name);
3240 gl_->ProduceTextureCHROMIUM(GL_TEXTURE_2D, mailbox.name);
3241 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
3244 TEST_F(GLES2ImplementationTest, ProduceTextureDirectCHROMIUM) {
3245 struct Cmds {
3246 cmds::ProduceTextureDirectCHROMIUMImmediate cmd;
3247 GLbyte data[64];
3250 Mailbox mailbox = Mailbox::Generate();
3251 Cmds expected;
3252 expected.cmd.Init(kTexturesStartId, GL_TEXTURE_2D, mailbox.name);
3253 gl_->ProduceTextureDirectCHROMIUM(
3254 kTexturesStartId, GL_TEXTURE_2D, mailbox.name);
3255 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
3258 TEST_F(GLES2ImplementationTest, LimitSizeAndOffsetTo32Bit) {
3259 GLsizeiptr size;
3260 GLintptr offset;
3261 if (sizeof(size) <= 4 || sizeof(offset) <= 4)
3262 return;
3263 // The below two casts should be no-op, as we return early if
3264 // it's 32-bit system.
3265 int64 value64 = 0x100000000;
3266 size = static_cast<GLsizeiptr>(value64);
3267 offset = static_cast<GLintptr>(value64);
3269 const char kSizeOverflowMessage[] = "size more than 32-bit";
3270 const char kOffsetOverflowMessage[] = "offset more than 32-bit";
3272 const GLfloat buf[] = { 1.0, 1.0, 1.0, 1.0 };
3273 const GLubyte indices[] = { 0 };
3275 const GLuint kClientArrayBufferId = 0x789;
3276 const GLuint kClientElementArrayBufferId = 0x790;
3277 gl_->BindBuffer(GL_ARRAY_BUFFER, kClientArrayBufferId);
3278 gl_->BindBuffer(GL_ELEMENT_ARRAY_BUFFER, kClientElementArrayBufferId);
3279 EXPECT_EQ(GL_NO_ERROR, CheckError());
3281 // Call BufferData() should succeed with legal paramaters.
3282 gl_->BufferData(GL_ARRAY_BUFFER, sizeof(buf), buf, GL_DYNAMIC_DRAW);
3283 gl_->BufferData(
3284 GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_DYNAMIC_DRAW);
3285 EXPECT_EQ(GL_NO_ERROR, CheckError());
3287 // BufferData: size
3288 gl_->BufferData(GL_ARRAY_BUFFER, size, buf, GL_DYNAMIC_DRAW);
3289 EXPECT_EQ(GL_INVALID_OPERATION, CheckError());
3290 EXPECT_STREQ(kSizeOverflowMessage, GetLastError().c_str());
3292 // Call BufferSubData() should succeed with legal paramaters.
3293 gl_->BufferSubData(GL_ARRAY_BUFFER, 0, sizeof(buf[0]), buf);
3294 EXPECT_EQ(GL_NO_ERROR, CheckError());
3296 // BufferSubData: offset
3297 gl_->BufferSubData(GL_ARRAY_BUFFER, offset, 1, buf);
3298 EXPECT_EQ(GL_INVALID_OPERATION, CheckError());
3299 EXPECT_STREQ(kOffsetOverflowMessage, GetLastError().c_str());
3301 // BufferSubData: size
3302 EXPECT_EQ(GL_NO_ERROR, CheckError());
3303 gl_->BufferSubData(GL_ARRAY_BUFFER, 0, size, buf);
3304 EXPECT_EQ(GL_INVALID_OPERATION, CheckError());
3305 EXPECT_STREQ(kSizeOverflowMessage, GetLastError().c_str());
3307 // Call MapBufferSubDataCHROMIUM() should succeed with legal paramaters.
3308 void* mem =
3309 gl_->MapBufferSubDataCHROMIUM(GL_ARRAY_BUFFER, 0, 1, GL_WRITE_ONLY);
3310 EXPECT_TRUE(NULL != mem);
3311 EXPECT_EQ(GL_NO_ERROR, CheckError());
3312 gl_->UnmapBufferSubDataCHROMIUM(mem);
3314 // MapBufferSubDataCHROMIUM: offset
3315 EXPECT_TRUE(NULL == gl_->MapBufferSubDataCHROMIUM(
3316 GL_ARRAY_BUFFER, offset, 1, GL_WRITE_ONLY));
3317 EXPECT_EQ(GL_INVALID_OPERATION, CheckError());
3318 EXPECT_STREQ(kOffsetOverflowMessage, GetLastError().c_str());
3320 // MapBufferSubDataCHROMIUM: size
3321 EXPECT_EQ(GL_NO_ERROR, CheckError());
3322 EXPECT_TRUE(NULL == gl_->MapBufferSubDataCHROMIUM(
3323 GL_ARRAY_BUFFER, 0, size, GL_WRITE_ONLY));
3324 EXPECT_EQ(GL_INVALID_OPERATION, CheckError());
3325 EXPECT_STREQ(kSizeOverflowMessage, GetLastError().c_str());
3327 // Call DrawElements() should succeed with legal paramaters.
3328 gl_->DrawElements(GL_POINTS, 1, GL_UNSIGNED_BYTE, NULL);
3329 EXPECT_EQ(GL_NO_ERROR, CheckError());
3331 // DrawElements: offset
3332 gl_->DrawElements(
3333 GL_POINTS, 1, GL_UNSIGNED_BYTE, reinterpret_cast<void*>(offset));
3334 EXPECT_EQ(GL_INVALID_OPERATION, CheckError());
3335 EXPECT_STREQ(kOffsetOverflowMessage, GetLastError().c_str());
3337 // Call DrawElementsInstancedANGLE() should succeed with legal paramaters.
3338 gl_->DrawElementsInstancedANGLE(GL_POINTS, 1, GL_UNSIGNED_BYTE, NULL, 1);
3339 EXPECT_EQ(GL_NO_ERROR, CheckError());
3341 // DrawElementsInstancedANGLE: offset
3342 gl_->DrawElementsInstancedANGLE(
3343 GL_POINTS, 1, GL_UNSIGNED_BYTE, reinterpret_cast<void*>(offset), 1);
3344 EXPECT_EQ(GL_INVALID_OPERATION, CheckError());
3345 EXPECT_STREQ(kOffsetOverflowMessage, GetLastError().c_str());
3347 // Call VertexAttribPointer() should succeed with legal paramaters.
3348 const GLuint kAttribIndex = 1;
3349 const GLsizei kStride = 4;
3350 gl_->VertexAttribPointer(
3351 kAttribIndex, 1, GL_FLOAT, GL_FALSE, kStride, NULL);
3352 EXPECT_EQ(GL_NO_ERROR, CheckError());
3354 // VertexAttribPointer: offset
3355 gl_->VertexAttribPointer(
3356 kAttribIndex, 1, GL_FLOAT, GL_FALSE, kStride,
3357 reinterpret_cast<void*>(offset));
3358 EXPECT_EQ(GL_INVALID_OPERATION, CheckError());
3359 EXPECT_STREQ(kOffsetOverflowMessage, GetLastError().c_str());
3362 TEST_F(GLES2ImplementationManualInitTest, LoseContextOnOOM) {
3363 ContextInitOptions init_options;
3364 init_options.lose_context_when_out_of_memory = true;
3365 ASSERT_TRUE(Initialize(init_options));
3367 struct Cmds {
3368 cmds::LoseContextCHROMIUM cmd;
3371 GLsizei max = std::numeric_limits<GLsizei>::max();
3372 EXPECT_CALL(*gpu_control_, CreateGpuMemoryBufferImage(max, max, _, _))
3373 .WillOnce(Return(-1));
3374 gl_->CreateGpuMemoryBufferImageCHROMIUM(max, max, GL_RGBA, GL_MAP_CHROMIUM);
3375 // The context should be lost.
3376 Cmds expected;
3377 expected.cmd.Init(GL_GUILTY_CONTEXT_RESET_ARB, GL_UNKNOWN_CONTEXT_RESET_ARB);
3378 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
3381 TEST_F(GLES2ImplementationManualInitTest, NoLoseContextOnOOM) {
3382 ContextInitOptions init_options;
3383 ASSERT_TRUE(Initialize(init_options));
3385 struct Cmds {
3386 cmds::LoseContextCHROMIUM cmd;
3389 GLsizei max = std::numeric_limits<GLsizei>::max();
3390 EXPECT_CALL(*gpu_control_, CreateGpuMemoryBufferImage(max, max, _, _))
3391 .WillOnce(Return(-1));
3392 gl_->CreateGpuMemoryBufferImageCHROMIUM(max, max, GL_RGBA, GL_MAP_CHROMIUM);
3393 // The context should not be lost.
3394 EXPECT_TRUE(NoCommandsWritten());
3397 TEST_F(GLES2ImplementationManualInitTest, FailInitOnBGRMismatch1) {
3398 ContextInitOptions init_options;
3399 init_options.bind_generates_resource_client = false;
3400 init_options.bind_generates_resource_service = true;
3401 EXPECT_FALSE(Initialize(init_options));
3404 TEST_F(GLES2ImplementationManualInitTest, FailInitOnBGRMismatch2) {
3405 ContextInitOptions init_options;
3406 init_options.bind_generates_resource_client = true;
3407 init_options.bind_generates_resource_service = false;
3408 EXPECT_FALSE(Initialize(init_options));
3411 #include "gpu/command_buffer/client/gles2_implementation_unittest_autogen.h"
3413 } // namespace gles2
3414 } // namespace gpu