Don't show supervised user as "already on this device" while they're being imported.
[chromium-blink-merge.git] / gpu / command_buffer / client / gles2_implementation_unittest.cc
blob0b02f94897a5ed4bd92528bbfe12291bc924fb2e
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 <GLES3/gl3.h>
14 #include "base/compiler_specific.h"
15 #include "gpu/command_buffer/client/client_test_helper.h"
16 #include "gpu/command_buffer/client/program_info_manager.h"
17 #include "gpu/command_buffer/client/transfer_buffer.h"
18 #include "gpu/command_buffer/common/command_buffer.h"
19 #include "testing/gtest/include/gtest/gtest.h"
20 #include "testing/gmock/include/gmock/gmock.h"
22 #if !defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS)
23 #define GLES2_SUPPORT_CLIENT_SIDE_ARRAYS
24 #endif
26 using testing::_;
27 using testing::AtLeast;
28 using testing::AnyNumber;
29 using testing::DoAll;
30 using testing::InSequence;
31 using testing::Invoke;
32 using testing::Mock;
33 using testing::Sequence;
34 using testing::StrictMock;
35 using testing::Truly;
36 using testing::Return;
38 namespace gpu {
39 namespace gles2 {
41 ACTION_P2(SetMemory, dst, obj) {
42 memcpy(dst, &obj, sizeof(obj));
45 ACTION_P3(SetMemoryFromArray, dst, array, size) {
46 memcpy(dst, array, size);
49 // Used to help set the transfer buffer result to SizedResult of a single value.
50 template <typename T>
51 class SizedResultHelper {
52 public:
53 explicit SizedResultHelper(T result)
54 : size_(sizeof(result)) {
55 memcpy(result_, &result, sizeof(T));
58 private:
59 uint32 size_;
60 char result_[sizeof(T)];
63 // Struct to make it easy to pass a vec4 worth of floats.
64 struct FourFloats {
65 FourFloats(float _x, float _y, float _z, float _w)
66 : x(_x),
67 y(_y),
68 z(_z),
69 w(_w) {
72 float x;
73 float y;
74 float z;
75 float w;
78 #pragma pack(push, 1)
79 // Struct that holds 7 characters.
80 struct Str7 {
81 char str[7];
83 #pragma pack(pop)
85 class MockTransferBuffer : public TransferBufferInterface {
86 public:
87 struct ExpectedMemoryInfo {
88 uint32 offset;
89 int32 id;
90 uint8* ptr;
93 MockTransferBuffer(
94 CommandBuffer* command_buffer,
95 unsigned int size,
96 unsigned int result_size,
97 unsigned int alignment,
98 bool initialize_fail)
99 : command_buffer_(command_buffer),
100 size_(size),
101 result_size_(result_size),
102 alignment_(alignment),
103 actual_buffer_index_(0),
104 expected_buffer_index_(0),
105 last_alloc_(NULL),
106 expected_offset_(result_size),
107 actual_offset_(result_size),
108 initialize_fail_(initialize_fail) {
109 // We have to allocate the buffers here because
110 // we need to know their address before GLES2Implementation::Initialize
111 // is called.
112 for (int ii = 0; ii < kNumBuffers; ++ii) {
113 buffers_[ii] = command_buffer_->CreateTransferBuffer(
114 size_ + ii * alignment_,
115 &buffer_ids_[ii]);
116 EXPECT_NE(-1, buffer_ids_[ii]);
120 ~MockTransferBuffer() override {}
122 bool Initialize(unsigned int starting_buffer_size,
123 unsigned int result_size,
124 unsigned int /* min_buffer_size */,
125 unsigned int /* max_buffer_size */,
126 unsigned int alignment,
127 unsigned int size_to_flush) override;
128 int GetShmId() override;
129 void* GetResultBuffer() override;
130 int GetResultOffset() override;
131 void Free() override;
132 bool HaveBuffer() const override;
133 void* AllocUpTo(unsigned int size, unsigned int* size_allocated) override;
134 void* Alloc(unsigned int size) override;
135 RingBuffer::Offset GetOffset(void* pointer) const override;
136 void FreePendingToken(void* p, unsigned int /* token */) override;
138 size_t MaxTransferBufferSize() {
139 return size_ - result_size_;
142 unsigned int RoundToAlignment(unsigned int size) {
143 return (size + alignment_ - 1) & ~(alignment_ - 1);
146 bool InSync() {
147 return expected_buffer_index_ == actual_buffer_index_ &&
148 expected_offset_ == actual_offset_;
151 ExpectedMemoryInfo GetExpectedMemory(size_t size) {
152 ExpectedMemoryInfo mem;
153 mem.offset = AllocateExpectedTransferBuffer(size);
154 mem.id = GetExpectedTransferBufferId();
155 mem.ptr = static_cast<uint8*>(
156 GetExpectedTransferAddressFromOffset(mem.offset, size));
157 return mem;
160 ExpectedMemoryInfo GetExpectedResultMemory(size_t size) {
161 ExpectedMemoryInfo mem;
162 mem.offset = GetExpectedResultBufferOffset();
163 mem.id = GetExpectedResultBufferId();
164 mem.ptr = static_cast<uint8*>(
165 GetExpectedTransferAddressFromOffset(mem.offset, size));
166 return mem;
169 private:
170 static const int kNumBuffers = 2;
172 uint8* actual_buffer() const {
173 return static_cast<uint8*>(buffers_[actual_buffer_index_]->memory());
176 uint8* expected_buffer() const {
177 return static_cast<uint8*>(buffers_[expected_buffer_index_]->memory());
180 uint32 AllocateExpectedTransferBuffer(size_t size) {
181 EXPECT_LE(size, MaxTransferBufferSize());
183 // Toggle which buffer we get each time to simulate the buffer being
184 // reallocated.
185 expected_buffer_index_ = (expected_buffer_index_ + 1) % kNumBuffers;
187 if (expected_offset_ + size > size_) {
188 expected_offset_ = result_size_;
190 uint32 offset = expected_offset_;
191 expected_offset_ += RoundToAlignment(size);
193 // Make sure each buffer has a different offset.
194 return offset + expected_buffer_index_ * alignment_;
197 void* GetExpectedTransferAddressFromOffset(uint32 offset, size_t size) {
198 EXPECT_GE(offset, expected_buffer_index_ * alignment_);
199 EXPECT_LE(offset + size, size_ + expected_buffer_index_ * alignment_);
200 return expected_buffer() + offset;
203 int GetExpectedResultBufferId() {
204 return buffer_ids_[expected_buffer_index_];
207 uint32 GetExpectedResultBufferOffset() {
208 return expected_buffer_index_ * alignment_;
211 int GetExpectedTransferBufferId() {
212 return buffer_ids_[expected_buffer_index_];
215 CommandBuffer* command_buffer_;
216 size_t size_;
217 size_t result_size_;
218 uint32 alignment_;
219 int buffer_ids_[kNumBuffers];
220 scoped_refptr<Buffer> buffers_[kNumBuffers];
221 int actual_buffer_index_;
222 int expected_buffer_index_;
223 void* last_alloc_;
224 uint32 expected_offset_;
225 uint32 actual_offset_;
226 bool initialize_fail_;
228 DISALLOW_COPY_AND_ASSIGN(MockTransferBuffer);
231 bool MockTransferBuffer::Initialize(
232 unsigned int starting_buffer_size,
233 unsigned int result_size,
234 unsigned int /* min_buffer_size */,
235 unsigned int /* max_buffer_size */,
236 unsigned int alignment,
237 unsigned int /* size_to_flush */) {
238 // Just check they match.
239 return size_ == starting_buffer_size &&
240 result_size_ == result_size &&
241 alignment_ == alignment && !initialize_fail_;
244 int MockTransferBuffer::GetShmId() {
245 return buffer_ids_[actual_buffer_index_];
248 void* MockTransferBuffer::GetResultBuffer() {
249 return actual_buffer() + actual_buffer_index_ * alignment_;
252 int MockTransferBuffer::GetResultOffset() {
253 return actual_buffer_index_ * alignment_;
256 void MockTransferBuffer::Free() {
257 NOTREACHED();
260 bool MockTransferBuffer::HaveBuffer() const {
261 return true;
264 void* MockTransferBuffer::AllocUpTo(
265 unsigned int size, unsigned int* size_allocated) {
266 EXPECT_TRUE(size_allocated != NULL);
267 EXPECT_TRUE(last_alloc_ == NULL);
269 // Toggle which buffer we get each time to simulate the buffer being
270 // reallocated.
271 actual_buffer_index_ = (actual_buffer_index_ + 1) % kNumBuffers;
273 size = std::min(static_cast<size_t>(size), MaxTransferBufferSize());
274 if (actual_offset_ + size > size_) {
275 actual_offset_ = result_size_;
277 uint32 offset = actual_offset_;
278 actual_offset_ += RoundToAlignment(size);
279 *size_allocated = size;
281 // Make sure each buffer has a different offset.
282 last_alloc_ = actual_buffer() + offset + actual_buffer_index_ * alignment_;
283 return last_alloc_;
286 void* MockTransferBuffer::Alloc(unsigned int size) {
287 EXPECT_LE(size, MaxTransferBufferSize());
288 unsigned int temp = 0;
289 void* p = AllocUpTo(size, &temp);
290 EXPECT_EQ(temp, size);
291 return p;
294 RingBuffer::Offset MockTransferBuffer::GetOffset(void* pointer) const {
295 // Make sure each buffer has a different offset.
296 return static_cast<uint8*>(pointer) - actual_buffer();
299 void MockTransferBuffer::FreePendingToken(void* p, unsigned int /* token */) {
300 EXPECT_EQ(last_alloc_, p);
301 last_alloc_ = NULL;
304 // API wrapper for Buffers.
305 class GenBuffersAPI {
306 public:
307 static void Gen(GLES2Implementation* gl_impl, GLsizei n, GLuint* ids) {
308 gl_impl->GenBuffers(n, ids);
311 static void Delete(GLES2Implementation* gl_impl,
312 GLsizei n,
313 const GLuint* ids) {
314 gl_impl->DeleteBuffers(n, ids);
318 // API wrapper for Framebuffers.
319 class GenFramebuffersAPI {
320 public:
321 static void Gen(GLES2Implementation* gl_impl, GLsizei n, GLuint* ids) {
322 gl_impl->GenFramebuffers(n, ids);
325 static void Delete(GLES2Implementation* gl_impl,
326 GLsizei n,
327 const GLuint* ids) {
328 gl_impl->DeleteFramebuffers(n, ids);
332 // API wrapper for Renderbuffers.
333 class GenRenderbuffersAPI {
334 public:
335 static void Gen(GLES2Implementation* gl_impl, GLsizei n, GLuint* ids) {
336 gl_impl->GenRenderbuffers(n, ids);
339 static void Delete(GLES2Implementation* gl_impl,
340 GLsizei n,
341 const GLuint* ids) {
342 gl_impl->DeleteRenderbuffers(n, ids);
346 // API wrapper for Textures.
347 class GenTexturesAPI {
348 public:
349 static void Gen(GLES2Implementation* gl_impl, GLsizei n, GLuint* ids) {
350 gl_impl->GenTextures(n, ids);
353 static void Delete(GLES2Implementation* gl_impl,
354 GLsizei n,
355 const GLuint* ids) {
356 gl_impl->DeleteTextures(n, ids);
360 class GLES2ImplementationTest : public testing::Test {
361 protected:
362 static const int kNumTestContexts = 2;
363 static const uint8 kInitialValue = 0xBD;
364 static const int32 kNumCommandEntries = 500;
365 static const int32 kCommandBufferSizeBytes =
366 kNumCommandEntries * sizeof(CommandBufferEntry);
367 static const size_t kTransferBufferSize = 512;
369 static const GLint kMaxCombinedTextureImageUnits = 8;
370 static const GLint kMaxCubeMapTextureSize = 64;
371 static const GLint kMaxFragmentUniformVectors = 16;
372 static const GLint kMaxRenderbufferSize = 64;
373 static const GLint kMaxTextureImageUnits = 8;
374 static const GLint kMaxTextureSize = 128;
375 static const GLint kMaxVaryingVectors = 8;
376 static const GLint kMaxVertexAttribs = 8;
377 static const GLint kMaxVertexTextureImageUnits = 0;
378 static const GLint kMaxVertexUniformVectors = 128;
379 static const GLint kNumCompressedTextureFormats = 0;
380 static const GLint kNumShaderBinaryFormats = 0;
381 static const GLuint kMaxTransformFeedbackSeparateAttribs = 4;
382 static const GLuint kMaxUniformBufferBindings = 36;
383 static const GLuint kStartId = 1024;
384 static const GLuint kBuffersStartId = 1;
385 static const GLuint kFramebuffersStartId = 1;
386 static const GLuint kProgramsAndShadersStartId = 1;
387 static const GLuint kRenderbuffersStartId = 1;
388 static const GLuint kSamplersStartId = 1;
389 static const GLuint kTexturesStartId = 1;
390 static const GLuint kTransformFeedbacksStartId = 1;
391 static const GLuint kQueriesStartId = 1;
392 static const GLuint kVertexArraysStartId = 1;
393 static const GLuint kValuebuffersStartId = 1;
395 typedef MockTransferBuffer::ExpectedMemoryInfo ExpectedMemoryInfo;
397 class TestContext {
398 public:
399 TestContext() : commands_(NULL), token_(0) {}
401 bool Initialize(ShareGroup* share_group,
402 bool bind_generates_resource_client,
403 bool bind_generates_resource_service,
404 bool lose_context_when_out_of_memory,
405 bool transfer_buffer_initialize_fail) {
406 command_buffer_.reset(new StrictMock<MockClientCommandBuffer>());
407 if (!command_buffer_->Initialize())
408 return false;
410 transfer_buffer_.reset(
411 new MockTransferBuffer(command_buffer_.get(),
412 kTransferBufferSize,
413 GLES2Implementation::kStartingOffset,
414 GLES2Implementation::kAlignment,
415 transfer_buffer_initialize_fail));
417 helper_.reset(new GLES2CmdHelper(command_buffer()));
418 helper_->Initialize(kCommandBufferSizeBytes);
420 gpu_control_.reset(new StrictMock<MockClientGpuControl>());
421 Capabilities capabilities;
422 capabilities.VisitPrecisions(
423 [](GLenum shader, GLenum type,
424 Capabilities::ShaderPrecision* precision) {
425 precision->min_range = 3;
426 precision->max_range = 5;
427 precision->precision = 7;
429 capabilities.max_combined_texture_image_units =
430 kMaxCombinedTextureImageUnits;
431 capabilities.max_cube_map_texture_size = kMaxCubeMapTextureSize;
432 capabilities.max_fragment_uniform_vectors = kMaxFragmentUniformVectors;
433 capabilities.max_renderbuffer_size = kMaxRenderbufferSize;
434 capabilities.max_texture_image_units = kMaxTextureImageUnits;
435 capabilities.max_texture_size = kMaxTextureSize;
436 capabilities.max_varying_vectors = kMaxVaryingVectors;
437 capabilities.max_vertex_attribs = kMaxVertexAttribs;
438 capabilities.max_vertex_texture_image_units = kMaxVertexTextureImageUnits;
439 capabilities.max_vertex_uniform_vectors = kMaxVertexUniformVectors;
440 capabilities.num_compressed_texture_formats =
441 kNumCompressedTextureFormats;
442 capabilities.num_shader_binary_formats = kNumShaderBinaryFormats;
443 capabilities.max_transform_feedback_separate_attribs =
444 kMaxTransformFeedbackSeparateAttribs;
445 capabilities.max_uniform_buffer_bindings = kMaxUniformBufferBindings;
446 capabilities.bind_generates_resource_chromium =
447 bind_generates_resource_service ? 1 : 0;
448 EXPECT_CALL(*gpu_control_, GetCapabilities())
449 .WillOnce(testing::Return(capabilities));
452 InSequence sequence;
454 const bool support_client_side_arrays = true;
455 gl_.reset(new GLES2Implementation(helper_.get(),
456 share_group,
457 transfer_buffer_.get(),
458 bind_generates_resource_client,
459 lose_context_when_out_of_memory,
460 support_client_side_arrays,
461 gpu_control_.get()));
463 if (!gl_->Initialize(kTransferBufferSize,
464 kTransferBufferSize,
465 kTransferBufferSize,
466 GLES2Implementation::kNoLimit))
467 return false;
470 helper_->CommandBufferHelper::Finish();
471 ::testing::Mock::VerifyAndClearExpectations(gl_.get());
473 scoped_refptr<Buffer> ring_buffer = helper_->get_ring_buffer();
474 commands_ = static_cast<CommandBufferEntry*>(ring_buffer->memory()) +
475 command_buffer()->GetPutOffset();
476 ClearCommands();
477 EXPECT_TRUE(transfer_buffer_->InSync());
479 ::testing::Mock::VerifyAndClearExpectations(command_buffer());
480 return true;
483 void TearDown() {
484 Mock::VerifyAndClear(gl_.get());
485 EXPECT_CALL(*command_buffer(), OnFlush()).Times(AnyNumber());
486 // For command buffer.
487 EXPECT_CALL(*command_buffer(), DestroyTransferBuffer(_))
488 .Times(AtLeast(1));
489 gl_.reset();
492 MockClientCommandBuffer* command_buffer() const {
493 return command_buffer_.get();
496 int GetNextToken() { return ++token_; }
498 void ClearCommands() {
499 scoped_refptr<Buffer> ring_buffer = helper_->get_ring_buffer();
500 memset(ring_buffer->memory(), kInitialValue, ring_buffer->size());
503 scoped_ptr<MockClientCommandBuffer> command_buffer_;
504 scoped_ptr<MockClientGpuControl> gpu_control_;
505 scoped_ptr<GLES2CmdHelper> helper_;
506 scoped_ptr<MockTransferBuffer> transfer_buffer_;
507 scoped_ptr<GLES2Implementation> gl_;
508 CommandBufferEntry* commands_;
509 int token_;
512 GLES2ImplementationTest() : commands_(NULL) {}
514 void SetUp() override;
515 void TearDown() override;
517 bool NoCommandsWritten() {
518 scoped_refptr<Buffer> ring_buffer = helper_->get_ring_buffer();
519 const uint8* cmds = reinterpret_cast<const uint8*>(ring_buffer->memory());
520 const uint8* end = cmds + ring_buffer->size();
521 for (; cmds < end; ++cmds) {
522 if (*cmds != kInitialValue) {
523 return false;
526 return true;
529 QueryTracker::Query* GetQuery(GLuint id) {
530 return gl_->query_tracker_->GetQuery(id);
533 struct ContextInitOptions {
534 ContextInitOptions()
535 : bind_generates_resource_client(true),
536 bind_generates_resource_service(true),
537 lose_context_when_out_of_memory(false),
538 transfer_buffer_initialize_fail(false) {}
540 bool bind_generates_resource_client;
541 bool bind_generates_resource_service;
542 bool lose_context_when_out_of_memory;
543 bool transfer_buffer_initialize_fail;
546 bool Initialize(const ContextInitOptions& init_options) {
547 bool success = true;
548 share_group_ = new ShareGroup(init_options.bind_generates_resource_client);
550 for (int i = 0; i < kNumTestContexts; i++) {
551 if (!test_contexts_[i].Initialize(
552 share_group_.get(),
553 init_options.bind_generates_resource_client,
554 init_options.bind_generates_resource_service,
555 init_options.lose_context_when_out_of_memory,
556 init_options.transfer_buffer_initialize_fail))
557 success = false;
560 // Default to test context 0.
561 gpu_control_ = test_contexts_[0].gpu_control_.get();
562 helper_ = test_contexts_[0].helper_.get();
563 transfer_buffer_ = test_contexts_[0].transfer_buffer_.get();
564 gl_ = test_contexts_[0].gl_.get();
565 commands_ = test_contexts_[0].commands_;
566 return success;
569 MockClientCommandBuffer* command_buffer() const {
570 return test_contexts_[0].command_buffer_.get();
573 int GetNextToken() { return test_contexts_[0].GetNextToken(); }
575 const void* GetPut() {
576 return helper_->GetSpace(0);
579 void ClearCommands() {
580 scoped_refptr<Buffer> ring_buffer = helper_->get_ring_buffer();
581 memset(ring_buffer->memory(), kInitialValue, ring_buffer->size());
584 size_t MaxTransferBufferSize() {
585 return transfer_buffer_->MaxTransferBufferSize();
588 ExpectedMemoryInfo GetExpectedMemory(size_t size) {
589 return transfer_buffer_->GetExpectedMemory(size);
592 ExpectedMemoryInfo GetExpectedResultMemory(size_t size) {
593 return transfer_buffer_->GetExpectedResultMemory(size);
596 // Sets the ProgramInfoManager. The manager will be owned
597 // by the ShareGroup.
598 void SetProgramInfoManager(ProgramInfoManager* manager) {
599 gl_->share_group()->set_program_info_manager(manager);
602 int CheckError() {
603 ExpectedMemoryInfo result =
604 GetExpectedResultMemory(sizeof(cmds::GetError::Result));
605 EXPECT_CALL(*command_buffer(), OnFlush())
606 .WillOnce(SetMemory(result.ptr, GLuint(GL_NO_ERROR)))
607 .RetiresOnSaturation();
608 return gl_->GetError();
611 const std::string& GetLastError() {
612 return gl_->GetLastError();
615 bool GetBucketContents(uint32 bucket_id, std::vector<int8>* data) {
616 return gl_->GetBucketContents(bucket_id, data);
619 TestContext test_contexts_[kNumTestContexts];
621 scoped_refptr<ShareGroup> share_group_;
622 MockClientGpuControl* gpu_control_;
623 GLES2CmdHelper* helper_;
624 MockTransferBuffer* transfer_buffer_;
625 GLES2Implementation* gl_;
626 CommandBufferEntry* commands_;
629 void GLES2ImplementationTest::SetUp() {
630 ContextInitOptions init_options;
631 ASSERT_TRUE(Initialize(init_options));
634 void GLES2ImplementationTest::TearDown() {
635 for (int i = 0; i < kNumTestContexts; i++)
636 test_contexts_[i].TearDown();
639 class GLES2ImplementationManualInitTest : public GLES2ImplementationTest {
640 protected:
641 void SetUp() override {}
644 class GLES2ImplementationStrictSharedTest : public GLES2ImplementationTest {
645 protected:
646 void SetUp() override;
648 template <class ResApi>
649 void FlushGenerationTest() {
650 GLuint id1, id2, id3;
652 // Generate valid id.
653 ResApi::Gen(gl_, 1, &id1);
654 EXPECT_NE(id1, 0u);
656 // Delete id1 and generate id2. id1 should not be reused.
657 ResApi::Delete(gl_, 1, &id1);
658 ResApi::Gen(gl_, 1, &id2);
659 EXPECT_NE(id2, 0u);
660 EXPECT_NE(id2, id1);
662 // Expect id1 reuse after Flush.
663 gl_->Flush();
664 ResApi::Gen(gl_, 1, &id3);
665 EXPECT_EQ(id3, id1);
668 // Ids should not be reused unless the |Deleting| context does a Flush()
669 // AND triggers a lazy release after that.
670 template <class ResApi>
671 void CrossContextGenerationTest() {
672 GLES2Implementation* gl1 = test_contexts_[0].gl_.get();
673 GLES2Implementation* gl2 = test_contexts_[1].gl_.get();
674 GLuint id1, id2, id3;
676 // Delete, no flush on context 1. No reuse.
677 ResApi::Gen(gl1, 1, &id1);
678 ResApi::Delete(gl1, 1, &id1);
679 ResApi::Gen(gl1, 1, &id2);
680 EXPECT_NE(id1, id2);
682 // Flush context 2. Still no reuse.
683 gl2->Flush();
684 ResApi::Gen(gl2, 1, &id3);
685 EXPECT_NE(id1, id3);
686 EXPECT_NE(id2, id3);
688 // Flush on context 1, but no lazy release. Still no reuse.
689 gl1->Flush();
690 ResApi::Gen(gl2, 1, &id3);
691 EXPECT_NE(id1, id3);
693 // Lazy release triggered by another Delete. Should reuse id1.
694 ResApi::Delete(gl1, 1, &id2);
695 ResApi::Gen(gl2, 1, &id3);
696 EXPECT_EQ(id1, id3);
699 // Same as CrossContextGenerationTest(), but triggers an Auto Flush on
700 // the Delete(). Tests an edge case regression.
701 template <class ResApi>
702 void CrossContextGenerationAutoFlushTest() {
703 GLES2Implementation* gl1 = test_contexts_[0].gl_.get();
704 GLES2Implementation* gl2 = test_contexts_[1].gl_.get();
705 GLuint id1, id2, id3;
707 // Delete, no flush on context 1. No reuse.
708 // By half filling the buffer, an internal flush is forced on the Delete().
709 ResApi::Gen(gl1, 1, &id1);
710 gl1->helper()->Noop(kNumCommandEntries / 2);
711 ResApi::Delete(gl1, 1, &id1);
712 ResApi::Gen(gl1, 1, &id2);
713 EXPECT_NE(id1, id2);
715 // Flush context 2. Still no reuse.
716 gl2->Flush();
717 ResApi::Gen(gl2, 1, &id3);
718 EXPECT_NE(id1, id3);
719 EXPECT_NE(id2, id3);
721 // Flush on context 1, but no lazy release. Still no reuse.
722 gl1->Flush();
723 ResApi::Gen(gl2, 1, &id3);
724 EXPECT_NE(id1, id3);
726 // Lazy release triggered by another Delete. Should reuse id1.
727 ResApi::Delete(gl1, 1, &id2);
728 ResApi::Gen(gl2, 1, &id3);
729 EXPECT_EQ(id1, id3);
733 void GLES2ImplementationStrictSharedTest::SetUp() {
734 ContextInitOptions init_options;
735 init_options.bind_generates_resource_client = false;
736 init_options.bind_generates_resource_service = false;
737 ASSERT_TRUE(Initialize(init_options));
740 // GCC requires these declarations, but MSVC requires they not be present
741 #ifndef _MSC_VER
742 const uint8 GLES2ImplementationTest::kInitialValue;
743 const int32 GLES2ImplementationTest::kNumCommandEntries;
744 const int32 GLES2ImplementationTest::kCommandBufferSizeBytes;
745 const size_t GLES2ImplementationTest::kTransferBufferSize;
746 const GLint GLES2ImplementationTest::kMaxCombinedTextureImageUnits;
747 const GLint GLES2ImplementationTest::kMaxCubeMapTextureSize;
748 const GLint GLES2ImplementationTest::kMaxFragmentUniformVectors;
749 const GLint GLES2ImplementationTest::kMaxRenderbufferSize;
750 const GLint GLES2ImplementationTest::kMaxTextureImageUnits;
751 const GLint GLES2ImplementationTest::kMaxTextureSize;
752 const GLint GLES2ImplementationTest::kMaxVaryingVectors;
753 const GLint GLES2ImplementationTest::kMaxVertexAttribs;
754 const GLint GLES2ImplementationTest::kMaxVertexTextureImageUnits;
755 const GLint GLES2ImplementationTest::kMaxVertexUniformVectors;
756 const GLint GLES2ImplementationTest::kNumCompressedTextureFormats;
757 const GLint GLES2ImplementationTest::kNumShaderBinaryFormats;
758 const GLuint GLES2ImplementationTest::kStartId;
759 const GLuint GLES2ImplementationTest::kBuffersStartId;
760 const GLuint GLES2ImplementationTest::kFramebuffersStartId;
761 const GLuint GLES2ImplementationTest::kProgramsAndShadersStartId;
762 const GLuint GLES2ImplementationTest::kRenderbuffersStartId;
763 const GLuint GLES2ImplementationTest::kSamplersStartId;
764 const GLuint GLES2ImplementationTest::kTexturesStartId;
765 const GLuint GLES2ImplementationTest::kTransformFeedbacksStartId;
766 const GLuint GLES2ImplementationTest::kQueriesStartId;
767 const GLuint GLES2ImplementationTest::kVertexArraysStartId;
768 const GLuint GLES2ImplementationTest::kValuebuffersStartId;
769 #endif
771 TEST_F(GLES2ImplementationTest, Basic) {
772 EXPECT_TRUE(gl_->share_group() != NULL);
775 TEST_F(GLES2ImplementationTest, GetBucketContents) {
776 const uint32 kBucketId = GLES2Implementation::kResultBucketId;
777 const uint32 kTestSize = MaxTransferBufferSize() + 32;
779 scoped_ptr<uint8[]> buf(new uint8 [kTestSize]);
780 uint8* expected_data = buf.get();
781 for (uint32 ii = 0; ii < kTestSize; ++ii) {
782 expected_data[ii] = ii * 3;
785 struct Cmds {
786 cmd::GetBucketStart get_bucket_start;
787 cmd::SetToken set_token1;
788 cmd::GetBucketData get_bucket_data;
789 cmd::SetToken set_token2;
790 cmd::SetBucketSize set_bucket_size2;
793 ExpectedMemoryInfo mem1 = GetExpectedMemory(MaxTransferBufferSize());
794 ExpectedMemoryInfo result1 = GetExpectedResultMemory(sizeof(uint32));
795 ExpectedMemoryInfo mem2 = GetExpectedMemory(
796 kTestSize - MaxTransferBufferSize());
798 Cmds expected;
799 expected.get_bucket_start.Init(
800 kBucketId, result1.id, result1.offset,
801 MaxTransferBufferSize(), mem1.id, mem1.offset);
802 expected.set_token1.Init(GetNextToken());
803 expected.get_bucket_data.Init(
804 kBucketId, MaxTransferBufferSize(),
805 kTestSize - MaxTransferBufferSize(), mem2.id, mem2.offset);
806 expected.set_bucket_size2.Init(kBucketId, 0);
807 expected.set_token2.Init(GetNextToken());
809 EXPECT_CALL(*command_buffer(), OnFlush())
810 .WillOnce(DoAll(
811 SetMemory(result1.ptr, kTestSize),
812 SetMemoryFromArray(
813 mem1.ptr, expected_data, MaxTransferBufferSize())))
814 .WillOnce(SetMemoryFromArray(
815 mem2.ptr, expected_data + MaxTransferBufferSize(),
816 kTestSize - MaxTransferBufferSize()))
817 .RetiresOnSaturation();
819 std::vector<int8> data;
820 GetBucketContents(kBucketId, &data);
821 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
822 ASSERT_EQ(kTestSize, data.size());
823 EXPECT_EQ(0, memcmp(expected_data, &data[0], data.size()));
826 TEST_F(GLES2ImplementationTest, GetShaderPrecisionFormat) {
827 struct Cmds {
828 cmds::GetShaderPrecisionFormat cmd;
830 typedef cmds::GetShaderPrecisionFormat::Result Result;
831 const unsigned kDummyType1 = 3;
832 const unsigned kDummyType2 = 4;
834 // The first call for dummy type 1 should trigger a command buffer request.
835 GLint range1[2] = {0, 0};
836 GLint precision1 = 0;
837 Cmds expected1;
838 ExpectedMemoryInfo client_result1 = GetExpectedResultMemory(4);
839 expected1.cmd.Init(GL_FRAGMENT_SHADER, kDummyType1, client_result1.id,
840 client_result1.offset);
841 Result server_result1 = {true, 14, 14, 10};
842 EXPECT_CALL(*command_buffer(), OnFlush())
843 .WillOnce(SetMemory(client_result1.ptr, server_result1))
844 .RetiresOnSaturation();
845 gl_->GetShaderPrecisionFormat(GL_FRAGMENT_SHADER, kDummyType1, range1,
846 &precision1);
847 const void* commands2 = GetPut();
848 EXPECT_NE(commands_, commands2);
849 EXPECT_EQ(0, memcmp(&expected1, commands_, sizeof(expected1)));
850 EXPECT_EQ(range1[0], 14);
851 EXPECT_EQ(range1[1], 14);
852 EXPECT_EQ(precision1, 10);
854 // The second call for dummy type 1 should use the cached value and avoid
855 // triggering a command buffer request, so we do not expect a call to
856 // OnFlush() here. We do expect the results to be correct though.
857 GLint range2[2] = {0, 0};
858 GLint precision2 = 0;
859 gl_->GetShaderPrecisionFormat(GL_FRAGMENT_SHADER, kDummyType1, range2,
860 &precision2);
861 const void* commands3 = GetPut();
862 EXPECT_EQ(commands2, commands3);
863 EXPECT_EQ(range2[0], 14);
864 EXPECT_EQ(range2[1], 14);
865 EXPECT_EQ(precision2, 10);
867 // If we then make a request for dummy type 2, we should get another command
868 // buffer request since it hasn't been cached yet.
869 GLint range3[2] = {0, 0};
870 GLint precision3 = 0;
871 Cmds expected3;
872 ExpectedMemoryInfo result3 = GetExpectedResultMemory(4);
873 expected3.cmd.Init(GL_FRAGMENT_SHADER, kDummyType2, result3.id,
874 result3.offset);
875 Result result3_source = {true, 62, 62, 16};
876 EXPECT_CALL(*command_buffer(), OnFlush())
877 .WillOnce(SetMemory(result3.ptr, result3_source))
878 .RetiresOnSaturation();
879 gl_->GetShaderPrecisionFormat(GL_FRAGMENT_SHADER, kDummyType2, range3,
880 &precision3);
881 const void* commands4 = GetPut();
882 EXPECT_NE(commands3, commands4);
883 EXPECT_EQ(0, memcmp(&expected3, commands3, sizeof(expected3)));
884 EXPECT_EQ(range3[0], 62);
885 EXPECT_EQ(range3[1], 62);
886 EXPECT_EQ(precision3, 16);
888 // Any call for predefined types should use the cached value from the
889 // Capabilities and avoid triggering a command buffer request, so we do not
890 // expect a call to OnFlush() here. We do expect the results to be correct
891 // though.
892 GLint range4[2] = {0, 0};
893 GLint precision4 = 0;
894 gl_->GetShaderPrecisionFormat(GL_FRAGMENT_SHADER, GL_MEDIUM_FLOAT, range4,
895 &precision4);
896 const void* commands5 = GetPut();
897 EXPECT_EQ(commands4, commands5);
898 EXPECT_EQ(range4[0], 3);
899 EXPECT_EQ(range4[1], 5);
900 EXPECT_EQ(precision4, 7);
903 TEST_F(GLES2ImplementationTest, GetShaderSource) {
904 const uint32 kBucketId = GLES2Implementation::kResultBucketId;
905 const GLuint kShaderId = 456;
906 const Str7 kString = {"foobar"};
907 const char kBad = 0x12;
908 struct Cmds {
909 cmd::SetBucketSize set_bucket_size1;
910 cmds::GetShaderSource get_shader_source;
911 cmd::GetBucketStart get_bucket_start;
912 cmd::SetToken set_token1;
913 cmd::SetBucketSize set_bucket_size2;
916 ExpectedMemoryInfo mem1 = GetExpectedMemory(MaxTransferBufferSize());
917 ExpectedMemoryInfo result1 = GetExpectedResultMemory(sizeof(uint32));
919 Cmds expected;
920 expected.set_bucket_size1.Init(kBucketId, 0);
921 expected.get_shader_source.Init(kShaderId, kBucketId);
922 expected.get_bucket_start.Init(
923 kBucketId, result1.id, result1.offset,
924 MaxTransferBufferSize(), mem1.id, mem1.offset);
925 expected.set_token1.Init(GetNextToken());
926 expected.set_bucket_size2.Init(kBucketId, 0);
927 char buf[sizeof(kString) + 1];
928 memset(buf, kBad, sizeof(buf));
930 EXPECT_CALL(*command_buffer(), OnFlush())
931 .WillOnce(DoAll(SetMemory(result1.ptr, uint32(sizeof(kString))),
932 SetMemory(mem1.ptr, kString)))
933 .RetiresOnSaturation();
935 GLsizei length = 0;
936 gl_->GetShaderSource(kShaderId, sizeof(buf), &length, buf);
937 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
938 EXPECT_EQ(sizeof(kString) - 1, static_cast<size_t>(length));
939 EXPECT_STREQ(kString.str, buf);
940 EXPECT_EQ(buf[sizeof(kString)], kBad);
943 #if defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS)
945 TEST_F(GLES2ImplementationTest, DrawArraysClientSideBuffers) {
946 static const float verts[][4] = {
947 { 12.0f, 23.0f, 34.0f, 45.0f, },
948 { 56.0f, 67.0f, 78.0f, 89.0f, },
949 { 13.0f, 24.0f, 35.0f, 46.0f, },
951 struct Cmds {
952 cmds::EnableVertexAttribArray enable1;
953 cmds::EnableVertexAttribArray enable2;
954 cmds::BindBuffer bind_to_emu;
955 cmds::BufferData set_size;
956 cmds::BufferSubData copy_data1;
957 cmd::SetToken set_token1;
958 cmds::VertexAttribPointer set_pointer1;
959 cmds::BufferSubData copy_data2;
960 cmd::SetToken set_token2;
961 cmds::VertexAttribPointer set_pointer2;
962 cmds::DrawArrays draw;
963 cmds::BindBuffer restore;
965 const GLuint kEmuBufferId = GLES2Implementation::kClientSideArrayId;
966 const GLuint kAttribIndex1 = 1;
967 const GLuint kAttribIndex2 = 3;
968 const GLint kNumComponents1 = 3;
969 const GLint kNumComponents2 = 2;
970 const GLsizei kClientStride = sizeof(verts[0]);
971 const GLint kFirst = 1;
972 const GLsizei kCount = 2;
973 const GLsizei kSize1 =
974 arraysize(verts) * kNumComponents1 * sizeof(verts[0][0]);
975 const GLsizei kSize2 =
976 arraysize(verts) * kNumComponents2 * sizeof(verts[0][0]);
977 const GLsizei kEmuOffset1 = 0;
978 const GLsizei kEmuOffset2 = kSize1;
979 const GLsizei kTotalSize = kSize1 + kSize2;
981 ExpectedMemoryInfo mem1 = GetExpectedMemory(kSize1);
982 ExpectedMemoryInfo mem2 = GetExpectedMemory(kSize2);
984 Cmds expected;
985 expected.enable1.Init(kAttribIndex1);
986 expected.enable2.Init(kAttribIndex2);
987 expected.bind_to_emu.Init(GL_ARRAY_BUFFER, kEmuBufferId);
988 expected.set_size.Init(GL_ARRAY_BUFFER, kTotalSize, 0, 0, GL_DYNAMIC_DRAW);
989 expected.copy_data1.Init(
990 GL_ARRAY_BUFFER, kEmuOffset1, kSize1, mem1.id, mem1.offset);
991 expected.set_token1.Init(GetNextToken());
992 expected.set_pointer1.Init(
993 kAttribIndex1, kNumComponents1, GL_FLOAT, GL_FALSE, 0, kEmuOffset1);
994 expected.copy_data2.Init(
995 GL_ARRAY_BUFFER, kEmuOffset2, kSize2, mem2.id, mem2.offset);
996 expected.set_token2.Init(GetNextToken());
997 expected.set_pointer2.Init(
998 kAttribIndex2, kNumComponents2, GL_FLOAT, GL_FALSE, 0, kEmuOffset2);
999 expected.draw.Init(GL_POINTS, kFirst, kCount);
1000 expected.restore.Init(GL_ARRAY_BUFFER, 0);
1001 gl_->EnableVertexAttribArray(kAttribIndex1);
1002 gl_->EnableVertexAttribArray(kAttribIndex2);
1003 gl_->VertexAttribPointer(
1004 kAttribIndex1, kNumComponents1, GL_FLOAT, GL_FALSE, kClientStride, verts);
1005 gl_->VertexAttribPointer(
1006 kAttribIndex2, kNumComponents2, GL_FLOAT, GL_FALSE, kClientStride, verts);
1007 gl_->DrawArrays(GL_POINTS, kFirst, kCount);
1008 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
1011 TEST_F(GLES2ImplementationTest, DrawArraysInstancedANGLEClientSideBuffers) {
1012 static const float verts[][4] = {
1013 { 12.0f, 23.0f, 34.0f, 45.0f, },
1014 { 56.0f, 67.0f, 78.0f, 89.0f, },
1015 { 13.0f, 24.0f, 35.0f, 46.0f, },
1017 struct Cmds {
1018 cmds::EnableVertexAttribArray enable1;
1019 cmds::EnableVertexAttribArray enable2;
1020 cmds::VertexAttribDivisorANGLE divisor;
1021 cmds::BindBuffer bind_to_emu;
1022 cmds::BufferData set_size;
1023 cmds::BufferSubData copy_data1;
1024 cmd::SetToken set_token1;
1025 cmds::VertexAttribPointer set_pointer1;
1026 cmds::BufferSubData copy_data2;
1027 cmd::SetToken set_token2;
1028 cmds::VertexAttribPointer set_pointer2;
1029 cmds::DrawArraysInstancedANGLE draw;
1030 cmds::BindBuffer restore;
1032 const GLuint kEmuBufferId = GLES2Implementation::kClientSideArrayId;
1033 const GLuint kAttribIndex1 = 1;
1034 const GLuint kAttribIndex2 = 3;
1035 const GLint kNumComponents1 = 3;
1036 const GLint kNumComponents2 = 2;
1037 const GLsizei kClientStride = sizeof(verts[0]);
1038 const GLint kFirst = 1;
1039 const GLsizei kCount = 2;
1040 const GLuint kDivisor = 1;
1041 const GLsizei kSize1 =
1042 arraysize(verts) * kNumComponents1 * sizeof(verts[0][0]);
1043 const GLsizei kSize2 =
1044 1 * kNumComponents2 * sizeof(verts[0][0]);
1045 const GLsizei kEmuOffset1 = 0;
1046 const GLsizei kEmuOffset2 = kSize1;
1047 const GLsizei kTotalSize = kSize1 + kSize2;
1049 ExpectedMemoryInfo mem1 = GetExpectedMemory(kSize1);
1050 ExpectedMemoryInfo mem2 = GetExpectedMemory(kSize2);
1052 Cmds expected;
1053 expected.enable1.Init(kAttribIndex1);
1054 expected.enable2.Init(kAttribIndex2);
1055 expected.divisor.Init(kAttribIndex2, kDivisor);
1056 expected.bind_to_emu.Init(GL_ARRAY_BUFFER, kEmuBufferId);
1057 expected.set_size.Init(GL_ARRAY_BUFFER, kTotalSize, 0, 0, GL_DYNAMIC_DRAW);
1058 expected.copy_data1.Init(
1059 GL_ARRAY_BUFFER, kEmuOffset1, kSize1, mem1.id, mem1.offset);
1060 expected.set_token1.Init(GetNextToken());
1061 expected.set_pointer1.Init(
1062 kAttribIndex1, kNumComponents1, GL_FLOAT, GL_FALSE, 0, kEmuOffset1);
1063 expected.copy_data2.Init(
1064 GL_ARRAY_BUFFER, kEmuOffset2, kSize2, mem2.id, mem2.offset);
1065 expected.set_token2.Init(GetNextToken());
1066 expected.set_pointer2.Init(
1067 kAttribIndex2, kNumComponents2, GL_FLOAT, GL_FALSE, 0, kEmuOffset2);
1068 expected.draw.Init(GL_POINTS, kFirst, kCount, 1);
1069 expected.restore.Init(GL_ARRAY_BUFFER, 0);
1070 gl_->EnableVertexAttribArray(kAttribIndex1);
1071 gl_->EnableVertexAttribArray(kAttribIndex2);
1072 gl_->VertexAttribPointer(
1073 kAttribIndex1, kNumComponents1, GL_FLOAT, GL_FALSE, kClientStride, verts);
1074 gl_->VertexAttribPointer(
1075 kAttribIndex2, kNumComponents2, GL_FLOAT, GL_FALSE, kClientStride, verts);
1076 gl_->VertexAttribDivisorANGLE(kAttribIndex2, kDivisor);
1077 gl_->DrawArraysInstancedANGLE(GL_POINTS, kFirst, kCount, 1);
1078 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
1081 TEST_F(GLES2ImplementationTest, DrawElementsClientSideBuffers) {
1082 static const float verts[][4] = {
1083 { 12.0f, 23.0f, 34.0f, 45.0f, },
1084 { 56.0f, 67.0f, 78.0f, 89.0f, },
1085 { 13.0f, 24.0f, 35.0f, 46.0f, },
1087 static const uint16 indices[] = {
1088 1, 2,
1090 struct Cmds {
1091 cmds::EnableVertexAttribArray enable1;
1092 cmds::EnableVertexAttribArray enable2;
1093 cmds::BindBuffer bind_to_index_emu;
1094 cmds::BufferData set_index_size;
1095 cmds::BufferSubData copy_data0;
1096 cmd::SetToken set_token0;
1097 cmds::BindBuffer bind_to_emu;
1098 cmds::BufferData set_size;
1099 cmds::BufferSubData copy_data1;
1100 cmd::SetToken set_token1;
1101 cmds::VertexAttribPointer set_pointer1;
1102 cmds::BufferSubData copy_data2;
1103 cmd::SetToken set_token2;
1104 cmds::VertexAttribPointer set_pointer2;
1105 cmds::DrawElements draw;
1106 cmds::BindBuffer restore;
1107 cmds::BindBuffer restore_element;
1109 const GLsizei kIndexSize = sizeof(indices);
1110 const GLuint kEmuBufferId = GLES2Implementation::kClientSideArrayId;
1111 const GLuint kEmuIndexBufferId =
1112 GLES2Implementation::kClientSideElementArrayId;
1113 const GLuint kAttribIndex1 = 1;
1114 const GLuint kAttribIndex2 = 3;
1115 const GLint kNumComponents1 = 3;
1116 const GLint kNumComponents2 = 2;
1117 const GLsizei kClientStride = sizeof(verts[0]);
1118 const GLsizei kCount = 2;
1119 const GLsizei kSize1 =
1120 arraysize(verts) * kNumComponents1 * sizeof(verts[0][0]);
1121 const GLsizei kSize2 =
1122 arraysize(verts) * kNumComponents2 * sizeof(verts[0][0]);
1123 const GLsizei kEmuOffset1 = 0;
1124 const GLsizei kEmuOffset2 = kSize1;
1125 const GLsizei kTotalSize = kSize1 + kSize2;
1127 ExpectedMemoryInfo mem1 = GetExpectedMemory(kIndexSize);
1128 ExpectedMemoryInfo mem2 = GetExpectedMemory(kSize1);
1129 ExpectedMemoryInfo mem3 = GetExpectedMemory(kSize2);
1131 Cmds expected;
1132 expected.enable1.Init(kAttribIndex1);
1133 expected.enable2.Init(kAttribIndex2);
1134 expected.bind_to_index_emu.Init(GL_ELEMENT_ARRAY_BUFFER, kEmuIndexBufferId);
1135 expected.set_index_size.Init(
1136 GL_ELEMENT_ARRAY_BUFFER, kIndexSize, 0, 0, GL_DYNAMIC_DRAW);
1137 expected.copy_data0.Init(
1138 GL_ELEMENT_ARRAY_BUFFER, 0, kIndexSize, mem1.id, mem1.offset);
1139 expected.set_token0.Init(GetNextToken());
1140 expected.bind_to_emu.Init(GL_ARRAY_BUFFER, kEmuBufferId);
1141 expected.set_size.Init(GL_ARRAY_BUFFER, kTotalSize, 0, 0, GL_DYNAMIC_DRAW);
1142 expected.copy_data1.Init(
1143 GL_ARRAY_BUFFER, kEmuOffset1, kSize1, mem2.id, mem2.offset);
1144 expected.set_token1.Init(GetNextToken());
1145 expected.set_pointer1.Init(
1146 kAttribIndex1, kNumComponents1, GL_FLOAT, GL_FALSE, 0, kEmuOffset1);
1147 expected.copy_data2.Init(
1148 GL_ARRAY_BUFFER, kEmuOffset2, kSize2, mem3.id, mem3.offset);
1149 expected.set_token2.Init(GetNextToken());
1150 expected.set_pointer2.Init(kAttribIndex2, kNumComponents2,
1151 GL_FLOAT, GL_FALSE, 0, kEmuOffset2);
1152 expected.draw.Init(GL_POINTS, kCount, GL_UNSIGNED_SHORT, 0);
1153 expected.restore.Init(GL_ARRAY_BUFFER, 0);
1154 expected.restore_element.Init(GL_ELEMENT_ARRAY_BUFFER, 0);
1155 gl_->EnableVertexAttribArray(kAttribIndex1);
1156 gl_->EnableVertexAttribArray(kAttribIndex2);
1157 gl_->VertexAttribPointer(kAttribIndex1, kNumComponents1,
1158 GL_FLOAT, GL_FALSE, kClientStride, verts);
1159 gl_->VertexAttribPointer(kAttribIndex2, kNumComponents2,
1160 GL_FLOAT, GL_FALSE, kClientStride, verts);
1161 gl_->DrawElements(GL_POINTS, kCount, GL_UNSIGNED_SHORT, indices);
1162 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
1165 TEST_F(GLES2ImplementationTest, DrawElementsClientSideBuffersIndexUint) {
1166 static const float verts[][4] = {
1167 { 12.0f, 23.0f, 34.0f, 45.0f, },
1168 { 56.0f, 67.0f, 78.0f, 89.0f, },
1169 { 13.0f, 24.0f, 35.0f, 46.0f, },
1171 static const uint32 indices[] = {
1172 1, 2,
1174 struct Cmds {
1175 cmds::EnableVertexAttribArray enable1;
1176 cmds::EnableVertexAttribArray enable2;
1177 cmds::BindBuffer bind_to_index_emu;
1178 cmds::BufferData set_index_size;
1179 cmds::BufferSubData copy_data0;
1180 cmd::SetToken set_token0;
1181 cmds::BindBuffer bind_to_emu;
1182 cmds::BufferData set_size;
1183 cmds::BufferSubData copy_data1;
1184 cmd::SetToken set_token1;
1185 cmds::VertexAttribPointer set_pointer1;
1186 cmds::BufferSubData copy_data2;
1187 cmd::SetToken set_token2;
1188 cmds::VertexAttribPointer set_pointer2;
1189 cmds::DrawElements draw;
1190 cmds::BindBuffer restore;
1191 cmds::BindBuffer restore_element;
1193 const GLsizei kIndexSize = sizeof(indices);
1194 const GLuint kEmuBufferId = GLES2Implementation::kClientSideArrayId;
1195 const GLuint kEmuIndexBufferId =
1196 GLES2Implementation::kClientSideElementArrayId;
1197 const GLuint kAttribIndex1 = 1;
1198 const GLuint kAttribIndex2 = 3;
1199 const GLint kNumComponents1 = 3;
1200 const GLint kNumComponents2 = 2;
1201 const GLsizei kClientStride = sizeof(verts[0]);
1202 const GLsizei kCount = 2;
1203 const GLsizei kSize1 =
1204 arraysize(verts) * kNumComponents1 * sizeof(verts[0][0]);
1205 const GLsizei kSize2 =
1206 arraysize(verts) * kNumComponents2 * sizeof(verts[0][0]);
1207 const GLsizei kEmuOffset1 = 0;
1208 const GLsizei kEmuOffset2 = kSize1;
1209 const GLsizei kTotalSize = kSize1 + kSize2;
1211 ExpectedMemoryInfo mem1 = GetExpectedMemory(kIndexSize);
1212 ExpectedMemoryInfo mem2 = GetExpectedMemory(kSize1);
1213 ExpectedMemoryInfo mem3 = GetExpectedMemory(kSize2);
1215 Cmds expected;
1216 expected.enable1.Init(kAttribIndex1);
1217 expected.enable2.Init(kAttribIndex2);
1218 expected.bind_to_index_emu.Init(GL_ELEMENT_ARRAY_BUFFER, kEmuIndexBufferId);
1219 expected.set_index_size.Init(
1220 GL_ELEMENT_ARRAY_BUFFER, kIndexSize, 0, 0, GL_DYNAMIC_DRAW);
1221 expected.copy_data0.Init(
1222 GL_ELEMENT_ARRAY_BUFFER, 0, kIndexSize, mem1.id, mem1.offset);
1223 expected.set_token0.Init(GetNextToken());
1224 expected.bind_to_emu.Init(GL_ARRAY_BUFFER, kEmuBufferId);
1225 expected.set_size.Init(GL_ARRAY_BUFFER, kTotalSize, 0, 0, GL_DYNAMIC_DRAW);
1226 expected.copy_data1.Init(
1227 GL_ARRAY_BUFFER, kEmuOffset1, kSize1, mem2.id, mem2.offset);
1228 expected.set_token1.Init(GetNextToken());
1229 expected.set_pointer1.Init(
1230 kAttribIndex1, kNumComponents1, GL_FLOAT, GL_FALSE, 0, kEmuOffset1);
1231 expected.copy_data2.Init(
1232 GL_ARRAY_BUFFER, kEmuOffset2, kSize2, mem3.id, mem3.offset);
1233 expected.set_token2.Init(GetNextToken());
1234 expected.set_pointer2.Init(kAttribIndex2, kNumComponents2,
1235 GL_FLOAT, GL_FALSE, 0, kEmuOffset2);
1236 expected.draw.Init(GL_POINTS, kCount, GL_UNSIGNED_INT, 0);
1237 expected.restore.Init(GL_ARRAY_BUFFER, 0);
1238 expected.restore_element.Init(GL_ELEMENT_ARRAY_BUFFER, 0);
1239 gl_->EnableVertexAttribArray(kAttribIndex1);
1240 gl_->EnableVertexAttribArray(kAttribIndex2);
1241 gl_->VertexAttribPointer(kAttribIndex1, kNumComponents1,
1242 GL_FLOAT, GL_FALSE, kClientStride, verts);
1243 gl_->VertexAttribPointer(kAttribIndex2, kNumComponents2,
1244 GL_FLOAT, GL_FALSE, kClientStride, verts);
1245 gl_->DrawElements(GL_POINTS, kCount, GL_UNSIGNED_INT, indices);
1246 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
1249 TEST_F(GLES2ImplementationTest, DrawElementsClientSideBuffersInvalidIndexUint) {
1250 static const float verts[][4] = {
1251 { 12.0f, 23.0f, 34.0f, 45.0f, },
1252 { 56.0f, 67.0f, 78.0f, 89.0f, },
1253 { 13.0f, 24.0f, 35.0f, 46.0f, },
1255 static const uint32 indices[] = {
1256 1, 0x90000000
1259 const GLuint kAttribIndex1 = 1;
1260 const GLuint kAttribIndex2 = 3;
1261 const GLint kNumComponents1 = 3;
1262 const GLint kNumComponents2 = 2;
1263 const GLsizei kClientStride = sizeof(verts[0]);
1264 const GLsizei kCount = 2;
1266 EXPECT_CALL(*command_buffer(), OnFlush())
1267 .Times(1)
1268 .RetiresOnSaturation();
1270 gl_->EnableVertexAttribArray(kAttribIndex1);
1271 gl_->EnableVertexAttribArray(kAttribIndex2);
1272 gl_->VertexAttribPointer(kAttribIndex1, kNumComponents1,
1273 GL_FLOAT, GL_FALSE, kClientStride, verts);
1274 gl_->VertexAttribPointer(kAttribIndex2, kNumComponents2,
1275 GL_FLOAT, GL_FALSE, kClientStride, verts);
1276 gl_->DrawElements(GL_POINTS, kCount, GL_UNSIGNED_INT, indices);
1278 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_OPERATION), gl_->GetError());
1281 TEST_F(GLES2ImplementationTest,
1282 DrawElementsClientSideBuffersServiceSideIndices) {
1283 static const float verts[][4] = {
1284 { 12.0f, 23.0f, 34.0f, 45.0f, },
1285 { 56.0f, 67.0f, 78.0f, 89.0f, },
1286 { 13.0f, 24.0f, 35.0f, 46.0f, },
1288 struct Cmds {
1289 cmds::EnableVertexAttribArray enable1;
1290 cmds::EnableVertexAttribArray enable2;
1291 cmds::BindBuffer bind_to_index;
1292 cmds::GetMaxValueInBufferCHROMIUM get_max;
1293 cmds::BindBuffer bind_to_emu;
1294 cmds::BufferData set_size;
1295 cmds::BufferSubData copy_data1;
1296 cmd::SetToken set_token1;
1297 cmds::VertexAttribPointer set_pointer1;
1298 cmds::BufferSubData copy_data2;
1299 cmd::SetToken set_token2;
1300 cmds::VertexAttribPointer set_pointer2;
1301 cmds::DrawElements draw;
1302 cmds::BindBuffer restore;
1304 const GLuint kEmuBufferId = GLES2Implementation::kClientSideArrayId;
1305 const GLuint kClientIndexBufferId = 0x789;
1306 const GLuint kIndexOffset = 0x40;
1307 const GLuint kMaxIndex = 2;
1308 const GLuint kAttribIndex1 = 1;
1309 const GLuint kAttribIndex2 = 3;
1310 const GLint kNumComponents1 = 3;
1311 const GLint kNumComponents2 = 2;
1312 const GLsizei kClientStride = sizeof(verts[0]);
1313 const GLsizei kCount = 2;
1314 const GLsizei kSize1 =
1315 arraysize(verts) * kNumComponents1 * sizeof(verts[0][0]);
1316 const GLsizei kSize2 =
1317 arraysize(verts) * kNumComponents2 * sizeof(verts[0][0]);
1318 const GLsizei kEmuOffset1 = 0;
1319 const GLsizei kEmuOffset2 = kSize1;
1320 const GLsizei kTotalSize = kSize1 + kSize2;
1322 ExpectedMemoryInfo mem1 = GetExpectedResultMemory(sizeof(uint32));
1323 ExpectedMemoryInfo mem2 = GetExpectedMemory(kSize1);
1324 ExpectedMemoryInfo mem3 = GetExpectedMemory(kSize2);
1327 Cmds expected;
1328 expected.enable1.Init(kAttribIndex1);
1329 expected.enable2.Init(kAttribIndex2);
1330 expected.bind_to_index.Init(GL_ELEMENT_ARRAY_BUFFER, kClientIndexBufferId);
1331 expected.get_max.Init(kClientIndexBufferId, kCount, GL_UNSIGNED_SHORT,
1332 kIndexOffset, mem1.id, mem1.offset);
1333 expected.bind_to_emu.Init(GL_ARRAY_BUFFER, kEmuBufferId);
1334 expected.set_size.Init(GL_ARRAY_BUFFER, kTotalSize, 0, 0, GL_DYNAMIC_DRAW);
1335 expected.copy_data1.Init(
1336 GL_ARRAY_BUFFER, kEmuOffset1, kSize1, mem2.id, mem2.offset);
1337 expected.set_token1.Init(GetNextToken());
1338 expected.set_pointer1.Init(kAttribIndex1, kNumComponents1,
1339 GL_FLOAT, GL_FALSE, 0, kEmuOffset1);
1340 expected.copy_data2.Init(
1341 GL_ARRAY_BUFFER, kEmuOffset2, kSize2, mem3.id, mem3.offset);
1342 expected.set_token2.Init(GetNextToken());
1343 expected.set_pointer2.Init(kAttribIndex2, kNumComponents2,
1344 GL_FLOAT, GL_FALSE, 0, kEmuOffset2);
1345 expected.draw.Init(GL_POINTS, kCount, GL_UNSIGNED_SHORT, kIndexOffset);
1346 expected.restore.Init(GL_ARRAY_BUFFER, 0);
1348 EXPECT_CALL(*command_buffer(), OnFlush())
1349 .WillOnce(SetMemory(mem1.ptr,kMaxIndex))
1350 .RetiresOnSaturation();
1352 gl_->EnableVertexAttribArray(kAttribIndex1);
1353 gl_->EnableVertexAttribArray(kAttribIndex2);
1354 gl_->BindBuffer(GL_ELEMENT_ARRAY_BUFFER, kClientIndexBufferId);
1355 gl_->VertexAttribPointer(kAttribIndex1, kNumComponents1,
1356 GL_FLOAT, GL_FALSE, kClientStride, verts);
1357 gl_->VertexAttribPointer(kAttribIndex2, kNumComponents2,
1358 GL_FLOAT, GL_FALSE, kClientStride, verts);
1359 gl_->DrawElements(GL_POINTS, kCount, GL_UNSIGNED_SHORT,
1360 reinterpret_cast<const void*>(kIndexOffset));
1361 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
1364 TEST_F(GLES2ImplementationTest, DrawElementsInstancedANGLEClientSideBuffers) {
1365 static const float verts[][4] = {
1366 { 12.0f, 23.0f, 34.0f, 45.0f, },
1367 { 56.0f, 67.0f, 78.0f, 89.0f, },
1368 { 13.0f, 24.0f, 35.0f, 46.0f, },
1370 static const uint16 indices[] = {
1371 1, 2,
1373 struct Cmds {
1374 cmds::EnableVertexAttribArray enable1;
1375 cmds::EnableVertexAttribArray enable2;
1376 cmds::VertexAttribDivisorANGLE divisor;
1377 cmds::BindBuffer bind_to_index_emu;
1378 cmds::BufferData set_index_size;
1379 cmds::BufferSubData copy_data0;
1380 cmd::SetToken set_token0;
1381 cmds::BindBuffer bind_to_emu;
1382 cmds::BufferData set_size;
1383 cmds::BufferSubData copy_data1;
1384 cmd::SetToken set_token1;
1385 cmds::VertexAttribPointer set_pointer1;
1386 cmds::BufferSubData copy_data2;
1387 cmd::SetToken set_token2;
1388 cmds::VertexAttribPointer set_pointer2;
1389 cmds::DrawElementsInstancedANGLE draw;
1390 cmds::BindBuffer restore;
1391 cmds::BindBuffer restore_element;
1393 const GLsizei kIndexSize = sizeof(indices);
1394 const GLuint kEmuBufferId = GLES2Implementation::kClientSideArrayId;
1395 const GLuint kEmuIndexBufferId =
1396 GLES2Implementation::kClientSideElementArrayId;
1397 const GLuint kAttribIndex1 = 1;
1398 const GLuint kAttribIndex2 = 3;
1399 const GLint kNumComponents1 = 3;
1400 const GLint kNumComponents2 = 2;
1401 const GLsizei kClientStride = sizeof(verts[0]);
1402 const GLsizei kCount = 2;
1403 const GLsizei kSize1 =
1404 arraysize(verts) * kNumComponents1 * sizeof(verts[0][0]);
1405 const GLsizei kSize2 =
1406 1 * kNumComponents2 * sizeof(verts[0][0]);
1407 const GLuint kDivisor = 1;
1408 const GLsizei kEmuOffset1 = 0;
1409 const GLsizei kEmuOffset2 = kSize1;
1410 const GLsizei kTotalSize = kSize1 + kSize2;
1412 ExpectedMemoryInfo mem1 = GetExpectedMemory(kIndexSize);
1413 ExpectedMemoryInfo mem2 = GetExpectedMemory(kSize1);
1414 ExpectedMemoryInfo mem3 = GetExpectedMemory(kSize2);
1416 Cmds expected;
1417 expected.enable1.Init(kAttribIndex1);
1418 expected.enable2.Init(kAttribIndex2);
1419 expected.divisor.Init(kAttribIndex2, kDivisor);
1420 expected.bind_to_index_emu.Init(GL_ELEMENT_ARRAY_BUFFER, kEmuIndexBufferId);
1421 expected.set_index_size.Init(
1422 GL_ELEMENT_ARRAY_BUFFER, kIndexSize, 0, 0, GL_DYNAMIC_DRAW);
1423 expected.copy_data0.Init(
1424 GL_ELEMENT_ARRAY_BUFFER, 0, kIndexSize, mem1.id, mem1.offset);
1425 expected.set_token0.Init(GetNextToken());
1426 expected.bind_to_emu.Init(GL_ARRAY_BUFFER, kEmuBufferId);
1427 expected.set_size.Init(GL_ARRAY_BUFFER, kTotalSize, 0, 0, GL_DYNAMIC_DRAW);
1428 expected.copy_data1.Init(
1429 GL_ARRAY_BUFFER, kEmuOffset1, kSize1, mem2.id, mem2.offset);
1430 expected.set_token1.Init(GetNextToken());
1431 expected.set_pointer1.Init(
1432 kAttribIndex1, kNumComponents1, GL_FLOAT, GL_FALSE, 0, kEmuOffset1);
1433 expected.copy_data2.Init(
1434 GL_ARRAY_BUFFER, kEmuOffset2, kSize2, mem3.id, mem3.offset);
1435 expected.set_token2.Init(GetNextToken());
1436 expected.set_pointer2.Init(kAttribIndex2, kNumComponents2,
1437 GL_FLOAT, GL_FALSE, 0, kEmuOffset2);
1438 expected.draw.Init(GL_POINTS, kCount, GL_UNSIGNED_SHORT, 0, 1);
1439 expected.restore.Init(GL_ARRAY_BUFFER, 0);
1440 expected.restore_element.Init(GL_ELEMENT_ARRAY_BUFFER, 0);
1441 gl_->EnableVertexAttribArray(kAttribIndex1);
1442 gl_->EnableVertexAttribArray(kAttribIndex2);
1443 gl_->VertexAttribPointer(kAttribIndex1, kNumComponents1,
1444 GL_FLOAT, GL_FALSE, kClientStride, verts);
1445 gl_->VertexAttribPointer(kAttribIndex2, kNumComponents2,
1446 GL_FLOAT, GL_FALSE, kClientStride, verts);
1447 gl_->VertexAttribDivisorANGLE(kAttribIndex2, kDivisor);
1448 gl_->DrawElementsInstancedANGLE(
1449 GL_POINTS, kCount, GL_UNSIGNED_SHORT, indices, 1);
1450 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
1453 TEST_F(GLES2ImplementationTest, GetVertexBufferPointerv) {
1454 static const float verts[1] = { 0.0f, };
1455 const GLuint kAttribIndex1 = 1;
1456 const GLuint kAttribIndex2 = 3;
1457 const GLint kNumComponents1 = 3;
1458 const GLint kNumComponents2 = 2;
1459 const GLsizei kStride1 = 12;
1460 const GLsizei kStride2 = 0;
1461 const GLuint kBufferId = 0x123;
1462 const GLint kOffset2 = 0x456;
1464 // It's all cached on the client side so no get commands are issued.
1465 struct Cmds {
1466 cmds::BindBuffer bind;
1467 cmds::VertexAttribPointer set_pointer;
1470 Cmds expected;
1471 expected.bind.Init(GL_ARRAY_BUFFER, kBufferId);
1472 expected.set_pointer.Init(kAttribIndex2, kNumComponents2, GL_FLOAT, GL_FALSE,
1473 kStride2, kOffset2);
1475 // Set one client side buffer.
1476 gl_->VertexAttribPointer(kAttribIndex1, kNumComponents1,
1477 GL_FLOAT, GL_FALSE, kStride1, verts);
1478 // Set one VBO
1479 gl_->BindBuffer(GL_ARRAY_BUFFER, kBufferId);
1480 gl_->VertexAttribPointer(kAttribIndex2, kNumComponents2,
1481 GL_FLOAT, GL_FALSE, kStride2,
1482 reinterpret_cast<const void*>(kOffset2));
1483 // now get them both.
1484 void* ptr1 = NULL;
1485 void* ptr2 = NULL;
1487 gl_->GetVertexAttribPointerv(
1488 kAttribIndex1, GL_VERTEX_ATTRIB_ARRAY_POINTER, &ptr1);
1489 gl_->GetVertexAttribPointerv(
1490 kAttribIndex2, GL_VERTEX_ATTRIB_ARRAY_POINTER, &ptr2);
1492 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
1493 EXPECT_TRUE(static_cast<const void*>(&verts) == ptr1);
1494 EXPECT_TRUE(ptr2 == reinterpret_cast<void*>(kOffset2));
1497 TEST_F(GLES2ImplementationTest, GetVertexAttrib) {
1498 static const float verts[1] = { 0.0f, };
1499 const GLuint kAttribIndex1 = 1;
1500 const GLuint kAttribIndex2 = 3;
1501 const GLint kNumComponents1 = 3;
1502 const GLint kNumComponents2 = 2;
1503 const GLsizei kStride1 = 12;
1504 const GLsizei kStride2 = 0;
1505 const GLuint kBufferId = 0x123;
1506 const GLint kOffset2 = 0x456;
1508 // Only one set and one get because the client side buffer's info is stored
1509 // on the client side.
1510 struct Cmds {
1511 cmds::EnableVertexAttribArray enable;
1512 cmds::BindBuffer bind;
1513 cmds::VertexAttribPointer set_pointer;
1514 cmds::GetVertexAttribfv get2; // for getting the value from attrib1
1517 ExpectedMemoryInfo mem2 = GetExpectedResultMemory(16);
1519 Cmds expected;
1520 expected.enable.Init(kAttribIndex1);
1521 expected.bind.Init(GL_ARRAY_BUFFER, kBufferId);
1522 expected.set_pointer.Init(kAttribIndex2, kNumComponents2, GL_FLOAT, GL_FALSE,
1523 kStride2, kOffset2);
1524 expected.get2.Init(kAttribIndex1,
1525 GL_CURRENT_VERTEX_ATTRIB,
1526 mem2.id, mem2.offset);
1528 FourFloats current_attrib(1.2f, 3.4f, 5.6f, 7.8f);
1530 // One call to flush to wait for last call to GetVertexAttribiv
1531 // as others are all cached.
1532 EXPECT_CALL(*command_buffer(), OnFlush())
1533 .WillOnce(SetMemory(
1534 mem2.ptr, SizedResultHelper<FourFloats>(current_attrib)))
1535 .RetiresOnSaturation();
1537 gl_->EnableVertexAttribArray(kAttribIndex1);
1538 // Set one client side buffer.
1539 gl_->VertexAttribPointer(kAttribIndex1, kNumComponents1,
1540 GL_FLOAT, GL_FALSE, kStride1, verts);
1541 // Set one VBO
1542 gl_->BindBuffer(GL_ARRAY_BUFFER, kBufferId);
1543 gl_->VertexAttribPointer(kAttribIndex2, kNumComponents2,
1544 GL_FLOAT, GL_FALSE, kStride2,
1545 reinterpret_cast<const void*>(kOffset2));
1546 // first get the service side once to see that we make a command
1547 GLint buffer_id = 0;
1548 GLint enabled = 0;
1549 GLint size = 0;
1550 GLint stride = 0;
1551 GLint type = 0;
1552 GLint normalized = 1;
1553 float current[4] = { 0.0f, };
1555 gl_->GetVertexAttribiv(
1556 kAttribIndex2, GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING, &buffer_id);
1557 EXPECT_EQ(kBufferId, static_cast<GLuint>(buffer_id));
1558 gl_->GetVertexAttribiv(
1559 kAttribIndex1, GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING, &buffer_id);
1560 gl_->GetVertexAttribiv(
1561 kAttribIndex1, GL_VERTEX_ATTRIB_ARRAY_ENABLED, &enabled);
1562 gl_->GetVertexAttribiv(
1563 kAttribIndex1, GL_VERTEX_ATTRIB_ARRAY_SIZE, &size);
1564 gl_->GetVertexAttribiv(
1565 kAttribIndex1, GL_VERTEX_ATTRIB_ARRAY_STRIDE, &stride);
1566 gl_->GetVertexAttribiv(
1567 kAttribIndex1, GL_VERTEX_ATTRIB_ARRAY_TYPE, &type);
1568 gl_->GetVertexAttribiv(
1569 kAttribIndex1, GL_VERTEX_ATTRIB_ARRAY_NORMALIZED, &normalized);
1570 gl_->GetVertexAttribfv(
1571 kAttribIndex1, GL_CURRENT_VERTEX_ATTRIB, &current[0]);
1573 EXPECT_EQ(0, buffer_id);
1574 EXPECT_EQ(GL_TRUE, enabled);
1575 EXPECT_EQ(kNumComponents1, size);
1576 EXPECT_EQ(kStride1, stride);
1577 EXPECT_EQ(GL_FLOAT, type);
1578 EXPECT_EQ(GL_FALSE, normalized);
1579 EXPECT_EQ(0, memcmp(&current_attrib, &current, sizeof(current_attrib)));
1581 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
1584 TEST_F(GLES2ImplementationTest, ReservedIds) {
1585 // Only the get error command should be issued.
1586 struct Cmds {
1587 cmds::GetError get;
1589 Cmds expected;
1591 ExpectedMemoryInfo mem1 = GetExpectedResultMemory(
1592 sizeof(cmds::GetError::Result));
1594 expected.get.Init(mem1.id, mem1.offset);
1596 // One call to flush to wait for GetError
1597 EXPECT_CALL(*command_buffer(), OnFlush())
1598 .WillOnce(SetMemory(mem1.ptr, GLuint(GL_NO_ERROR)))
1599 .RetiresOnSaturation();
1601 gl_->BindBuffer(
1602 GL_ARRAY_BUFFER,
1603 GLES2Implementation::kClientSideArrayId);
1604 gl_->BindBuffer(
1605 GL_ARRAY_BUFFER,
1606 GLES2Implementation::kClientSideElementArrayId);
1607 GLenum err = gl_->GetError();
1608 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_OPERATION), err);
1609 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
1612 #endif // defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS)
1614 TEST_F(GLES2ImplementationTest, ReadPixels2Reads) {
1615 struct Cmds {
1616 cmds::ReadPixels read1;
1617 cmd::SetToken set_token1;
1618 cmds::ReadPixels read2;
1619 cmd::SetToken set_token2;
1621 const GLint kBytesPerPixel = 4;
1622 const GLint kWidth =
1623 (kTransferBufferSize - GLES2Implementation::kStartingOffset) /
1624 kBytesPerPixel;
1625 const GLint kHeight = 2;
1626 const GLenum kFormat = GL_RGBA;
1627 const GLenum kType = GL_UNSIGNED_BYTE;
1629 ExpectedMemoryInfo mem1 =
1630 GetExpectedMemory(kWidth * kHeight / 2 * kBytesPerPixel);
1631 ExpectedMemoryInfo result1 =
1632 GetExpectedResultMemory(sizeof(cmds::ReadPixels::Result));
1633 ExpectedMemoryInfo mem2 =
1634 GetExpectedMemory(kWidth * kHeight / 2 * kBytesPerPixel);
1635 ExpectedMemoryInfo result2 =
1636 GetExpectedResultMemory(sizeof(cmds::ReadPixels::Result));
1638 Cmds expected;
1639 expected.read1.Init(
1640 0, 0, kWidth, kHeight / 2, kFormat, kType,
1641 mem1.id, mem1.offset, result1.id, result1.offset,
1642 false);
1643 expected.set_token1.Init(GetNextToken());
1644 expected.read2.Init(
1645 0, kHeight / 2, kWidth, kHeight / 2, kFormat, kType,
1646 mem2.id, mem2.offset, result2.id, result2.offset, false);
1647 expected.set_token2.Init(GetNextToken());
1648 scoped_ptr<int8[]> buffer(new int8[kWidth * kHeight * kBytesPerPixel]);
1650 EXPECT_CALL(*command_buffer(), OnFlush())
1651 .WillOnce(SetMemory(result1.ptr, static_cast<uint32>(1)))
1652 .WillOnce(SetMemory(result2.ptr, static_cast<uint32>(1)))
1653 .RetiresOnSaturation();
1655 gl_->ReadPixels(0, 0, kWidth, kHeight, kFormat, kType, buffer.get());
1656 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
1659 TEST_F(GLES2ImplementationTest, ReadPixelsBadFormatType) {
1660 struct Cmds {
1661 cmds::ReadPixels read;
1662 cmd::SetToken set_token;
1664 const GLint kBytesPerPixel = 4;
1665 const GLint kWidth = 2;
1666 const GLint kHeight = 2;
1667 const GLenum kFormat = 0;
1668 const GLenum kType = 0;
1670 ExpectedMemoryInfo mem1 =
1671 GetExpectedMemory(kWidth * kHeight * kBytesPerPixel);
1672 ExpectedMemoryInfo result1 =
1673 GetExpectedResultMemory(sizeof(cmds::ReadPixels::Result));
1675 Cmds expected;
1676 expected.read.Init(
1677 0, 0, kWidth, kHeight, kFormat, kType,
1678 mem1.id, mem1.offset, result1.id, result1.offset, false);
1679 expected.set_token.Init(GetNextToken());
1680 scoped_ptr<int8[]> buffer(new int8[kWidth * kHeight * kBytesPerPixel]);
1682 EXPECT_CALL(*command_buffer(), OnFlush())
1683 .Times(1)
1684 .RetiresOnSaturation();
1686 gl_->ReadPixels(0, 0, kWidth, kHeight, kFormat, kType, buffer.get());
1689 TEST_F(GLES2ImplementationTest, FreeUnusedSharedMemory) {
1690 struct Cmds {
1691 cmds::BufferSubData buf;
1692 cmd::SetToken set_token;
1694 const GLenum kTarget = GL_ELEMENT_ARRAY_BUFFER;
1695 const GLintptr kOffset = 15;
1696 const GLsizeiptr kSize = 16;
1698 ExpectedMemoryInfo mem1 = GetExpectedMemory(kSize);
1700 Cmds expected;
1701 expected.buf.Init(
1702 kTarget, kOffset, kSize, mem1.id, mem1.offset);
1703 expected.set_token.Init(GetNextToken());
1705 void* mem = gl_->MapBufferSubDataCHROMIUM(
1706 kTarget, kOffset, kSize, GL_WRITE_ONLY);
1707 ASSERT_TRUE(mem != NULL);
1708 gl_->UnmapBufferSubDataCHROMIUM(mem);
1709 EXPECT_CALL(*command_buffer(), DestroyTransferBuffer(_))
1710 .Times(1)
1711 .RetiresOnSaturation();
1712 gl_->FreeUnusedSharedMemory();
1715 TEST_F(GLES2ImplementationTest, MapUnmapBufferSubDataCHROMIUM) {
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 uint32 offset = 0;
1725 Cmds expected;
1726 expected.buf.Init(
1727 kTarget, kOffset, kSize,
1728 command_buffer()->GetNextFreeTransferBufferId(), 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_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
1738 TEST_F(GLES2ImplementationTest, MapUnmapBufferSubDataCHROMIUMBadArgs) {
1739 const GLenum kTarget = GL_ELEMENT_ARRAY_BUFFER;
1740 const GLintptr kOffset = 15;
1741 const GLsizeiptr kSize = 16;
1743 ExpectedMemoryInfo result1 =
1744 GetExpectedResultMemory(sizeof(cmds::GetError::Result));
1745 ExpectedMemoryInfo result2 =
1746 GetExpectedResultMemory(sizeof(cmds::GetError::Result));
1747 ExpectedMemoryInfo result3 =
1748 GetExpectedResultMemory(sizeof(cmds::GetError::Result));
1749 ExpectedMemoryInfo result4 =
1750 GetExpectedResultMemory(sizeof(cmds::GetError::Result));
1752 // Calls to flush to wait for GetError
1753 EXPECT_CALL(*command_buffer(), OnFlush())
1754 .WillOnce(SetMemory(result1.ptr, GLuint(GL_NO_ERROR)))
1755 .WillOnce(SetMemory(result2.ptr, GLuint(GL_NO_ERROR)))
1756 .WillOnce(SetMemory(result3.ptr, GLuint(GL_NO_ERROR)))
1757 .WillOnce(SetMemory(result4.ptr, GLuint(GL_NO_ERROR)))
1758 .RetiresOnSaturation();
1760 void* mem;
1761 mem = gl_->MapBufferSubDataCHROMIUM(kTarget, -1, kSize, GL_WRITE_ONLY);
1762 ASSERT_TRUE(mem == NULL);
1763 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE), gl_->GetError());
1764 mem = gl_->MapBufferSubDataCHROMIUM(kTarget, kOffset, -1, GL_WRITE_ONLY);
1765 ASSERT_TRUE(mem == NULL);
1766 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE), gl_->GetError());
1767 mem = gl_->MapBufferSubDataCHROMIUM(kTarget, kOffset, kSize, GL_READ_ONLY);
1768 ASSERT_TRUE(mem == NULL);
1769 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_ENUM), gl_->GetError());
1770 const char* kPtr = "something";
1771 gl_->UnmapBufferSubDataCHROMIUM(kPtr);
1772 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE), gl_->GetError());
1775 TEST_F(GLES2ImplementationTest, MapUnmapTexSubImage2DCHROMIUM) {
1776 struct Cmds {
1777 cmds::TexSubImage2D tex;
1778 cmd::SetToken set_token;
1780 const GLint kLevel = 1;
1781 const GLint kXOffset = 2;
1782 const GLint kYOffset = 3;
1783 const GLint kWidth = 4;
1784 const GLint kHeight = 5;
1785 const GLenum kFormat = GL_RGBA;
1786 const GLenum kType = GL_UNSIGNED_BYTE;
1788 uint32 offset = 0;
1789 Cmds expected;
1790 expected.tex.Init(
1791 GL_TEXTURE_2D, kLevel, kXOffset, kYOffset, kWidth, kHeight, kFormat,
1792 kType,
1793 command_buffer()->GetNextFreeTransferBufferId(), offset, GL_FALSE);
1794 expected.set_token.Init(GetNextToken());
1796 void* mem = gl_->MapTexSubImage2DCHROMIUM(
1797 GL_TEXTURE_2D,
1798 kLevel,
1799 kXOffset,
1800 kYOffset,
1801 kWidth,
1802 kHeight,
1803 kFormat,
1804 kType,
1805 GL_WRITE_ONLY);
1806 ASSERT_TRUE(mem != NULL);
1807 gl_->UnmapTexSubImage2DCHROMIUM(mem);
1808 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
1811 TEST_F(GLES2ImplementationTest, MapUnmapTexSubImage2DCHROMIUMBadArgs) {
1812 const GLint kLevel = 1;
1813 const GLint kXOffset = 2;
1814 const GLint kYOffset = 3;
1815 const GLint kWidth = 4;
1816 const GLint kHeight = 5;
1817 const GLenum kFormat = GL_RGBA;
1818 const GLenum kType = GL_UNSIGNED_BYTE;
1820 ExpectedMemoryInfo result1 =
1821 GetExpectedResultMemory(sizeof(cmds::GetError::Result));
1822 ExpectedMemoryInfo result2 =
1823 GetExpectedResultMemory(sizeof(cmds::GetError::Result));
1824 ExpectedMemoryInfo result3 =
1825 GetExpectedResultMemory(sizeof(cmds::GetError::Result));
1826 ExpectedMemoryInfo result4 =
1827 GetExpectedResultMemory(sizeof(cmds::GetError::Result));
1828 ExpectedMemoryInfo result5 =
1829 GetExpectedResultMemory(sizeof(cmds::GetError::Result));
1830 ExpectedMemoryInfo result6 =
1831 GetExpectedResultMemory(sizeof(cmds::GetError::Result));
1832 ExpectedMemoryInfo result7 =
1833 GetExpectedResultMemory(sizeof(cmds::GetError::Result));
1835 // Calls to flush to wait for GetError
1836 EXPECT_CALL(*command_buffer(), OnFlush())
1837 .WillOnce(SetMemory(result1.ptr, GLuint(GL_NO_ERROR)))
1838 .WillOnce(SetMemory(result2.ptr, GLuint(GL_NO_ERROR)))
1839 .WillOnce(SetMemory(result3.ptr, GLuint(GL_NO_ERROR)))
1840 .WillOnce(SetMemory(result4.ptr, GLuint(GL_NO_ERROR)))
1841 .WillOnce(SetMemory(result5.ptr, GLuint(GL_NO_ERROR)))
1842 .WillOnce(SetMemory(result6.ptr, GLuint(GL_NO_ERROR)))
1843 .WillOnce(SetMemory(result7.ptr, GLuint(GL_NO_ERROR)))
1844 .RetiresOnSaturation();
1846 void* mem;
1847 mem = gl_->MapTexSubImage2DCHROMIUM(
1848 GL_TEXTURE_2D,
1850 kXOffset,
1851 kYOffset,
1852 kWidth,
1853 kHeight,
1854 kFormat,
1855 kType,
1856 GL_WRITE_ONLY);
1857 EXPECT_TRUE(mem == NULL);
1858 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE), gl_->GetError());
1859 mem = gl_->MapTexSubImage2DCHROMIUM(
1860 GL_TEXTURE_2D,
1861 kLevel,
1863 kYOffset,
1864 kWidth,
1865 kHeight,
1866 kFormat,
1867 kType,
1868 GL_WRITE_ONLY);
1869 EXPECT_TRUE(mem == NULL);
1870 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE), gl_->GetError());
1871 mem = gl_->MapTexSubImage2DCHROMIUM(
1872 GL_TEXTURE_2D,
1873 kLevel,
1874 kXOffset,
1876 kWidth,
1877 kHeight,
1878 kFormat,
1879 kType,
1880 GL_WRITE_ONLY);
1881 EXPECT_TRUE(mem == NULL);
1882 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE), gl_->GetError());
1883 mem = gl_->MapTexSubImage2DCHROMIUM(
1884 GL_TEXTURE_2D,
1885 kLevel,
1886 kXOffset,
1887 kYOffset,
1889 kHeight,
1890 kFormat,
1891 kType,
1892 GL_WRITE_ONLY);
1893 EXPECT_TRUE(mem == NULL);
1894 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE), gl_->GetError());
1895 mem = gl_->MapTexSubImage2DCHROMIUM(
1896 GL_TEXTURE_2D,
1897 kLevel,
1898 kXOffset,
1899 kYOffset,
1900 kWidth,
1902 kFormat,
1903 kType,
1904 GL_WRITE_ONLY);
1905 EXPECT_TRUE(mem == NULL);
1906 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE), gl_->GetError());
1907 mem = gl_->MapTexSubImage2DCHROMIUM(
1908 GL_TEXTURE_2D,
1909 kLevel,
1910 kXOffset,
1911 kYOffset,
1912 kWidth,
1913 kHeight,
1914 kFormat,
1915 kType,
1916 GL_READ_ONLY);
1917 EXPECT_TRUE(mem == NULL);
1918 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_ENUM), gl_->GetError());
1919 const char* kPtr = "something";
1920 gl_->UnmapTexSubImage2DCHROMIUM(kPtr);
1921 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE), gl_->GetError());
1924 TEST_F(GLES2ImplementationTest, GetProgramInfoCHROMIUMGoodArgs) {
1925 const uint32 kBucketId = GLES2Implementation::kResultBucketId;
1926 const GLuint kProgramId = 123;
1927 const char kBad = 0x12;
1928 GLsizei size = 0;
1929 const Str7 kString = {"foobar"};
1930 char buf[20];
1932 ExpectedMemoryInfo mem1 =
1933 GetExpectedMemory(MaxTransferBufferSize());
1934 ExpectedMemoryInfo result1 =
1935 GetExpectedResultMemory(sizeof(cmd::GetBucketStart::Result));
1936 ExpectedMemoryInfo result2 =
1937 GetExpectedResultMemory(sizeof(cmds::GetError::Result));
1939 memset(buf, kBad, sizeof(buf));
1940 EXPECT_CALL(*command_buffer(), OnFlush())
1941 .WillOnce(DoAll(SetMemory(result1.ptr, uint32(sizeof(kString))),
1942 SetMemory(mem1.ptr, kString)))
1943 .WillOnce(SetMemory(result2.ptr, GLuint(GL_NO_ERROR)))
1944 .RetiresOnSaturation();
1946 struct Cmds {
1947 cmd::SetBucketSize set_bucket_size1;
1948 cmds::GetProgramInfoCHROMIUM get_program_info;
1949 cmd::GetBucketStart get_bucket_start;
1950 cmd::SetToken set_token1;
1951 cmd::SetBucketSize set_bucket_size2;
1953 Cmds expected;
1954 expected.set_bucket_size1.Init(kBucketId, 0);
1955 expected.get_program_info.Init(kProgramId, kBucketId);
1956 expected.get_bucket_start.Init(
1957 kBucketId, result1.id, result1.offset,
1958 MaxTransferBufferSize(), mem1.id, mem1.offset);
1959 expected.set_token1.Init(GetNextToken());
1960 expected.set_bucket_size2.Init(kBucketId, 0);
1961 gl_->GetProgramInfoCHROMIUM(kProgramId, sizeof(buf), &size, &buf);
1962 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
1963 EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), gl_->GetError());
1964 EXPECT_EQ(sizeof(kString), static_cast<size_t>(size));
1965 EXPECT_STREQ(kString.str, buf);
1966 EXPECT_EQ(buf[sizeof(kString)], kBad);
1969 TEST_F(GLES2ImplementationTest, GetProgramInfoCHROMIUMBadArgs) {
1970 const uint32 kBucketId = GLES2Implementation::kResultBucketId;
1971 const GLuint kProgramId = 123;
1972 GLsizei size = 0;
1973 const Str7 kString = {"foobar"};
1974 char buf[20];
1976 ExpectedMemoryInfo mem1 = GetExpectedMemory(MaxTransferBufferSize());
1977 ExpectedMemoryInfo result1 =
1978 GetExpectedResultMemory(sizeof(cmd::GetBucketStart::Result));
1979 ExpectedMemoryInfo result2 =
1980 GetExpectedResultMemory(sizeof(cmds::GetError::Result));
1981 ExpectedMemoryInfo result3 =
1982 GetExpectedResultMemory(sizeof(cmds::GetError::Result));
1983 ExpectedMemoryInfo result4 =
1984 GetExpectedResultMemory(sizeof(cmds::GetError::Result));
1986 EXPECT_CALL(*command_buffer(), OnFlush())
1987 .WillOnce(DoAll(SetMemory(result1.ptr, uint32(sizeof(kString))),
1988 SetMemory(mem1.ptr, kString)))
1989 .WillOnce(SetMemory(result2.ptr, GLuint(GL_NO_ERROR)))
1990 .WillOnce(SetMemory(result3.ptr, GLuint(GL_NO_ERROR)))
1991 .WillOnce(SetMemory(result4.ptr, GLuint(GL_NO_ERROR)))
1992 .RetiresOnSaturation();
1994 // try bufsize not big enough.
1995 struct Cmds {
1996 cmd::SetBucketSize set_bucket_size1;
1997 cmds::GetProgramInfoCHROMIUM get_program_info;
1998 cmd::GetBucketStart get_bucket_start;
1999 cmd::SetToken set_token1;
2000 cmd::SetBucketSize set_bucket_size2;
2002 Cmds expected;
2003 expected.set_bucket_size1.Init(kBucketId, 0);
2004 expected.get_program_info.Init(kProgramId, kBucketId);
2005 expected.get_bucket_start.Init(
2006 kBucketId, result1.id, result1.offset,
2007 MaxTransferBufferSize(), mem1.id, mem1.offset);
2008 expected.set_token1.Init(GetNextToken());
2009 expected.set_bucket_size2.Init(kBucketId, 0);
2010 gl_->GetProgramInfoCHROMIUM(kProgramId, 6, &size, &buf);
2011 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
2012 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_OPERATION), gl_->GetError());
2013 ClearCommands();
2015 // try bad bufsize
2016 gl_->GetProgramInfoCHROMIUM(kProgramId, -1, &size, &buf);
2017 EXPECT_TRUE(NoCommandsWritten());
2018 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE), gl_->GetError());
2019 ClearCommands();
2020 // try no size ptr.
2021 gl_->GetProgramInfoCHROMIUM(kProgramId, sizeof(buf), NULL, &buf);
2022 EXPECT_TRUE(NoCommandsWritten());
2023 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE), gl_->GetError());
2026 TEST_F(GLES2ImplementationTest, GetUniformBlocksCHROMIUMGoodArgs) {
2027 const uint32 kBucketId = GLES2Implementation::kResultBucketId;
2028 const GLuint kProgramId = 123;
2029 const char kBad = 0x12;
2030 GLsizei size = 0;
2031 const Str7 kString = {"foobar"};
2032 char buf[20];
2034 ExpectedMemoryInfo mem1 =
2035 GetExpectedMemory(MaxTransferBufferSize());
2036 ExpectedMemoryInfo result1 =
2037 GetExpectedResultMemory(sizeof(cmd::GetBucketStart::Result));
2038 ExpectedMemoryInfo result2 =
2039 GetExpectedResultMemory(sizeof(cmds::GetError::Result));
2041 memset(buf, kBad, sizeof(buf));
2042 EXPECT_CALL(*command_buffer(), OnFlush())
2043 .WillOnce(DoAll(SetMemory(result1.ptr, uint32(sizeof(kString))),
2044 SetMemory(mem1.ptr, kString)))
2045 .WillOnce(SetMemory(result2.ptr, GLuint(GL_NO_ERROR)))
2046 .RetiresOnSaturation();
2048 struct Cmds {
2049 cmd::SetBucketSize set_bucket_size1;
2050 cmds::GetUniformBlocksCHROMIUM get_uniform_blocks;
2051 cmd::GetBucketStart get_bucket_start;
2052 cmd::SetToken set_token1;
2053 cmd::SetBucketSize set_bucket_size2;
2055 Cmds expected;
2056 expected.set_bucket_size1.Init(kBucketId, 0);
2057 expected.get_uniform_blocks.Init(kProgramId, kBucketId);
2058 expected.get_bucket_start.Init(
2059 kBucketId, result1.id, result1.offset,
2060 MaxTransferBufferSize(), mem1.id, mem1.offset);
2061 expected.set_token1.Init(GetNextToken());
2062 expected.set_bucket_size2.Init(kBucketId, 0);
2063 gl_->GetUniformBlocksCHROMIUM(kProgramId, sizeof(buf), &size, &buf);
2064 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
2065 EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), gl_->GetError());
2066 EXPECT_EQ(sizeof(kString), static_cast<size_t>(size));
2067 EXPECT_STREQ(kString.str, buf);
2068 EXPECT_EQ(buf[sizeof(kString)], kBad);
2071 TEST_F(GLES2ImplementationTest, GetUniformBlocksCHROMIUMBadArgs) {
2072 const uint32 kBucketId = GLES2Implementation::kResultBucketId;
2073 const GLuint kProgramId = 123;
2074 GLsizei size = 0;
2075 const Str7 kString = {"foobar"};
2076 char buf[20];
2078 ExpectedMemoryInfo mem1 = GetExpectedMemory(MaxTransferBufferSize());
2079 ExpectedMemoryInfo result1 =
2080 GetExpectedResultMemory(sizeof(cmd::GetBucketStart::Result));
2081 ExpectedMemoryInfo result2 =
2082 GetExpectedResultMemory(sizeof(cmds::GetError::Result));
2083 ExpectedMemoryInfo result3 =
2084 GetExpectedResultMemory(sizeof(cmds::GetError::Result));
2085 ExpectedMemoryInfo result4 =
2086 GetExpectedResultMemory(sizeof(cmds::GetError::Result));
2088 EXPECT_CALL(*command_buffer(), OnFlush())
2089 .WillOnce(DoAll(SetMemory(result1.ptr, uint32(sizeof(kString))),
2090 SetMemory(mem1.ptr, kString)))
2091 .WillOnce(SetMemory(result2.ptr, GLuint(GL_NO_ERROR)))
2092 .WillOnce(SetMemory(result3.ptr, GLuint(GL_NO_ERROR)))
2093 .WillOnce(SetMemory(result4.ptr, GLuint(GL_NO_ERROR)))
2094 .RetiresOnSaturation();
2096 // try bufsize not big enough.
2097 struct Cmds {
2098 cmd::SetBucketSize set_bucket_size1;
2099 cmds::GetUniformBlocksCHROMIUM get_uniform_blocks;
2100 cmd::GetBucketStart get_bucket_start;
2101 cmd::SetToken set_token1;
2102 cmd::SetBucketSize set_bucket_size2;
2104 Cmds expected;
2105 expected.set_bucket_size1.Init(kBucketId, 0);
2106 expected.get_uniform_blocks.Init(kProgramId, kBucketId);
2107 expected.get_bucket_start.Init(
2108 kBucketId, result1.id, result1.offset,
2109 MaxTransferBufferSize(), mem1.id, mem1.offset);
2110 expected.set_token1.Init(GetNextToken());
2111 expected.set_bucket_size2.Init(kBucketId, 0);
2112 gl_->GetUniformBlocksCHROMIUM(kProgramId, 6, &size, &buf);
2113 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
2114 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_OPERATION), gl_->GetError());
2115 ClearCommands();
2117 // try bad bufsize
2118 gl_->GetUniformBlocksCHROMIUM(kProgramId, -1, &size, &buf);
2119 EXPECT_TRUE(NoCommandsWritten());
2120 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE), gl_->GetError());
2121 ClearCommands();
2122 // try no size ptr.
2123 gl_->GetUniformBlocksCHROMIUM(kProgramId, sizeof(buf), NULL, &buf);
2124 EXPECT_TRUE(NoCommandsWritten());
2125 EXPECT_EQ(static_cast<GLenum>(GL_INVALID_VALUE), gl_->GetError());
2128 // Test that things are cached
2129 TEST_F(GLES2ImplementationTest, GetIntegerCacheRead) {
2130 struct PNameValue {
2131 GLenum pname;
2132 GLint expected;
2134 const PNameValue pairs[] = {
2135 {GL_ACTIVE_TEXTURE, GL_TEXTURE0, },
2136 {GL_TEXTURE_BINDING_2D, 0, },
2137 {GL_TEXTURE_BINDING_CUBE_MAP, 0, },
2138 {GL_TEXTURE_BINDING_EXTERNAL_OES, 0, },
2139 {GL_FRAMEBUFFER_BINDING, 0, },
2140 {GL_RENDERBUFFER_BINDING, 0, },
2141 {GL_ARRAY_BUFFER_BINDING, 0, },
2142 {GL_ELEMENT_ARRAY_BUFFER_BINDING, 0, },
2143 {GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, kMaxCombinedTextureImageUnits, },
2144 {GL_MAX_CUBE_MAP_TEXTURE_SIZE, kMaxCubeMapTextureSize, },
2145 {GL_MAX_FRAGMENT_UNIFORM_VECTORS, kMaxFragmentUniformVectors, },
2146 {GL_MAX_RENDERBUFFER_SIZE, kMaxRenderbufferSize, },
2147 {GL_MAX_TEXTURE_IMAGE_UNITS, kMaxTextureImageUnits, },
2148 {GL_MAX_TEXTURE_SIZE, kMaxTextureSize, },
2149 {GL_MAX_VARYING_VECTORS, kMaxVaryingVectors, },
2150 {GL_MAX_VERTEX_ATTRIBS, kMaxVertexAttribs, },
2151 {GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, kMaxVertexTextureImageUnits, },
2152 {GL_MAX_VERTEX_UNIFORM_VECTORS, kMaxVertexUniformVectors, },
2153 {GL_NUM_COMPRESSED_TEXTURE_FORMATS, kNumCompressedTextureFormats, },
2154 {GL_NUM_SHADER_BINARY_FORMATS, kNumShaderBinaryFormats, }, };
2155 size_t num_pairs = sizeof(pairs) / sizeof(pairs[0]);
2156 for (size_t ii = 0; ii < num_pairs; ++ii) {
2157 const PNameValue& pv = pairs[ii];
2158 GLint v = -1;
2159 gl_->GetIntegerv(pv.pname, &v);
2160 EXPECT_TRUE(NoCommandsWritten());
2161 EXPECT_EQ(pv.expected, v);
2164 ExpectedMemoryInfo result1 =
2165 GetExpectedResultMemory(sizeof(cmds::GetError::Result));
2167 EXPECT_CALL(*command_buffer(), OnFlush())
2168 .WillOnce(SetMemory(result1.ptr, GLuint(GL_NO_ERROR)))
2169 .RetiresOnSaturation();
2170 EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), gl_->GetError());
2173 TEST_F(GLES2ImplementationTest, GetIntegerCacheWrite) {
2174 struct PNameValue {
2175 GLenum pname;
2176 GLint expected;
2178 gl_->ActiveTexture(GL_TEXTURE4);
2179 gl_->BindBuffer(GL_ARRAY_BUFFER, 2);
2180 gl_->BindBuffer(GL_ELEMENT_ARRAY_BUFFER, 3);
2181 gl_->BindFramebuffer(GL_FRAMEBUFFER, 4);
2182 gl_->BindRenderbuffer(GL_RENDERBUFFER, 5);
2183 gl_->BindTexture(GL_TEXTURE_2D, 6);
2184 gl_->BindTexture(GL_TEXTURE_CUBE_MAP, 7);
2185 gl_->BindTexture(GL_TEXTURE_EXTERNAL_OES, 8);
2187 const PNameValue pairs[] = {{GL_ACTIVE_TEXTURE, GL_TEXTURE4, },
2188 {GL_ARRAY_BUFFER_BINDING, 2, },
2189 {GL_ELEMENT_ARRAY_BUFFER_BINDING, 3, },
2190 {GL_FRAMEBUFFER_BINDING, 4, },
2191 {GL_RENDERBUFFER_BINDING, 5, },
2192 {GL_TEXTURE_BINDING_2D, 6, },
2193 {GL_TEXTURE_BINDING_CUBE_MAP, 7, },
2194 {GL_TEXTURE_BINDING_EXTERNAL_OES, 8, }, };
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_EQ(pv.expected, v);
2203 ExpectedMemoryInfo result1 =
2204 GetExpectedResultMemory(sizeof(cmds::GetError::Result));
2206 EXPECT_CALL(*command_buffer(), OnFlush())
2207 .WillOnce(SetMemory(result1.ptr, GLuint(GL_NO_ERROR)))
2208 .RetiresOnSaturation();
2209 EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), gl_->GetError());
2212 static bool CheckRect(
2213 int width, int height, GLenum format, GLenum type, int alignment,
2214 bool flip_y, const uint8* r1, const uint8* r2) {
2215 uint32 size = 0;
2216 uint32 unpadded_row_size = 0;
2217 uint32 padded_row_size = 0;
2218 if (!GLES2Util::ComputeImageDataSizes(
2219 width, height, 1, format, type, alignment, &size, &unpadded_row_size,
2220 &padded_row_size)) {
2221 return false;
2224 int r2_stride = flip_y ?
2225 -static_cast<int>(padded_row_size) :
2226 static_cast<int>(padded_row_size);
2227 r2 = flip_y ? (r2 + (height - 1) * padded_row_size) : r2;
2229 for (int y = 0; y < height; ++y) {
2230 if (memcmp(r1, r2, unpadded_row_size) != 0) {
2231 return false;
2233 r1 += padded_row_size;
2234 r2 += r2_stride;
2236 return true;
2239 ACTION_P8(CheckRectAction, width, height, format, type, alignment, flip_y,
2240 r1, r2) {
2241 EXPECT_TRUE(CheckRect(
2242 width, height, format, type, alignment, flip_y, r1, r2));
2245 // Test TexImage2D with and without flip_y
2246 TEST_F(GLES2ImplementationTest, TexImage2D) {
2247 struct Cmds {
2248 cmds::TexImage2D tex_image_2d;
2249 cmd::SetToken set_token;
2251 struct Cmds2 {
2252 cmds::TexImage2D tex_image_2d;
2253 cmd::SetToken set_token;
2255 const GLenum kTarget = GL_TEXTURE_2D;
2256 const GLint kLevel = 0;
2257 const GLenum kFormat = GL_RGB;
2258 const GLsizei kWidth = 3;
2259 const GLsizei kHeight = 4;
2260 const GLint kBorder = 0;
2261 const GLenum kType = GL_UNSIGNED_BYTE;
2262 const GLint kPixelStoreUnpackAlignment = 4;
2263 static uint8 pixels[] = {
2264 11, 12, 13, 13, 14, 15, 15, 16, 17, 101, 102, 103,
2265 21, 22, 23, 23, 24, 25, 25, 26, 27, 201, 202, 203,
2266 31, 32, 33, 33, 34, 35, 35, 36, 37, 123, 124, 125,
2267 41, 42, 43, 43, 44, 45, 45, 46, 47,
2270 ExpectedMemoryInfo mem1 = GetExpectedMemory(sizeof(pixels));
2272 Cmds expected;
2273 expected.tex_image_2d.Init(
2274 kTarget, kLevel, kFormat, kWidth, kHeight, kFormat, kType,
2275 mem1.id, mem1.offset);
2276 expected.set_token.Init(GetNextToken());
2277 gl_->TexImage2D(
2278 kTarget, kLevel, kFormat, kWidth, kHeight, kBorder, kFormat, kType,
2279 pixels);
2280 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
2281 EXPECT_TRUE(CheckRect(
2282 kWidth, kHeight, kFormat, kType, kPixelStoreUnpackAlignment, false,
2283 pixels, mem1.ptr));
2285 ClearCommands();
2286 gl_->PixelStorei(GL_UNPACK_FLIP_Y_CHROMIUM, GL_TRUE);
2288 ExpectedMemoryInfo mem2 = GetExpectedMemory(sizeof(pixels));
2289 Cmds2 expected2;
2290 expected2.tex_image_2d.Init(
2291 kTarget, kLevel, kFormat, kWidth, kHeight, kFormat, kType,
2292 mem2.id, mem2.offset);
2293 expected2.set_token.Init(GetNextToken());
2294 const void* commands2 = GetPut();
2295 gl_->TexImage2D(
2296 kTarget, kLevel, kFormat, kWidth, kHeight, kBorder, kFormat, kType,
2297 pixels);
2298 EXPECT_EQ(0, memcmp(&expected2, commands2, sizeof(expected2)));
2299 EXPECT_TRUE(CheckRect(
2300 kWidth, kHeight, kFormat, kType, kPixelStoreUnpackAlignment, true,
2301 pixels, mem2.ptr));
2304 // Test TexImage2D with 2 writes
2305 TEST_F(GLES2ImplementationTest, TexImage2D2Writes) {
2306 struct Cmds {
2307 cmds::TexImage2D tex_image_2d;
2308 cmds::TexSubImage2D tex_sub_image_2d1;
2309 cmd::SetToken set_token1;
2310 cmds::TexSubImage2D tex_sub_image_2d2;
2311 cmd::SetToken set_token2;
2313 const GLenum kTarget = GL_TEXTURE_2D;
2314 const GLint kLevel = 0;
2315 const GLenum kFormat = GL_RGB;
2316 const GLint kBorder = 0;
2317 const GLenum kType = GL_UNSIGNED_BYTE;
2318 const GLint kPixelStoreUnpackAlignment = 4;
2319 const GLsizei kWidth = 3;
2321 uint32 size = 0;
2322 uint32 unpadded_row_size = 0;
2323 uint32 padded_row_size = 0;
2324 ASSERT_TRUE(GLES2Util::ComputeImageDataSizes(
2325 kWidth, 2, 1, kFormat, kType, kPixelStoreUnpackAlignment,
2326 &size, &unpadded_row_size, &padded_row_size));
2327 const GLsizei kHeight = (MaxTransferBufferSize() / padded_row_size) * 2;
2328 ASSERT_TRUE(GLES2Util::ComputeImageDataSizes(
2329 kWidth, kHeight, 1, kFormat, kType, kPixelStoreUnpackAlignment,
2330 &size, NULL, NULL));
2331 uint32 half_size = 0;
2332 ASSERT_TRUE(GLES2Util::ComputeImageDataSizes(
2333 kWidth, kHeight / 2, 1, kFormat, kType, kPixelStoreUnpackAlignment,
2334 &half_size, NULL, NULL));
2336 scoped_ptr<uint8[]> pixels(new uint8[size]);
2337 for (uint32 ii = 0; ii < size; ++ii) {
2338 pixels[ii] = static_cast<uint8>(ii);
2341 ExpectedMemoryInfo mem1 = GetExpectedMemory(half_size);
2342 ExpectedMemoryInfo mem2 = GetExpectedMemory(half_size);
2344 Cmds expected;
2345 expected.tex_image_2d.Init(
2346 kTarget, kLevel, kFormat, kWidth, kHeight, kFormat, kType,
2347 0, 0);
2348 expected.tex_sub_image_2d1.Init(
2349 kTarget, kLevel, 0, 0, kWidth, kHeight / 2, kFormat, kType,
2350 mem1.id, mem1.offset, true);
2351 expected.set_token1.Init(GetNextToken());
2352 expected.tex_sub_image_2d2.Init(
2353 kTarget, kLevel, 0, kHeight / 2, kWidth, kHeight / 2, kFormat, kType,
2354 mem2.id, mem2.offset, true);
2355 expected.set_token2.Init(GetNextToken());
2357 // TODO(gman): Make it possible to run this test
2358 // EXPECT_CALL(*command_buffer(), OnFlush())
2359 // .WillOnce(CheckRectAction(
2360 // kWidth, kHeight / 2, kFormat, kType, kPixelStoreUnpackAlignment,
2361 // false, pixels.get(),
2362 // GetExpectedTransferAddressFromOffsetAs<uint8>(offset1, half_size)))
2363 // .RetiresOnSaturation();
2365 gl_->TexImage2D(
2366 kTarget, kLevel, kFormat, kWidth, kHeight, kBorder, kFormat, kType,
2367 pixels.get());
2368 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
2369 EXPECT_TRUE(CheckRect(
2370 kWidth, kHeight / 2, kFormat, kType, kPixelStoreUnpackAlignment, false,
2371 pixels.get() + kHeight / 2 * padded_row_size, mem2.ptr));
2373 ClearCommands();
2374 gl_->PixelStorei(GL_UNPACK_FLIP_Y_CHROMIUM, GL_TRUE);
2375 const void* commands2 = GetPut();
2376 ExpectedMemoryInfo mem3 = GetExpectedMemory(half_size);
2377 ExpectedMemoryInfo mem4 = GetExpectedMemory(half_size);
2378 expected.tex_image_2d.Init(
2379 kTarget, kLevel, kFormat, kWidth, kHeight, kFormat, kType,
2380 0, 0);
2381 expected.tex_sub_image_2d1.Init(
2382 kTarget, kLevel, 0, kHeight / 2, kWidth, kHeight / 2, kFormat, kType,
2383 mem3.id, mem3.offset, true);
2384 expected.set_token1.Init(GetNextToken());
2385 expected.tex_sub_image_2d2.Init(
2386 kTarget, kLevel, 0, 0, kWidth, kHeight / 2, kFormat, kType,
2387 mem4.id, mem4.offset, true);
2388 expected.set_token2.Init(GetNextToken());
2390 // TODO(gman): Make it possible to run this test
2391 // EXPECT_CALL(*command_buffer(), OnFlush())
2392 // .WillOnce(CheckRectAction(
2393 // kWidth, kHeight / 2, kFormat, kType, kPixelStoreUnpackAlignment,
2394 // true, pixels.get(),
2395 // GetExpectedTransferAddressFromOffsetAs<uint8>(offset3, half_size)))
2396 // .RetiresOnSaturation();
2398 gl_->TexImage2D(
2399 kTarget, kLevel, kFormat, kWidth, kHeight, kBorder, kFormat, kType,
2400 pixels.get());
2401 EXPECT_EQ(0, memcmp(&expected, commands2, sizeof(expected)));
2402 EXPECT_TRUE(CheckRect(
2403 kWidth, kHeight / 2, kFormat, kType, kPixelStoreUnpackAlignment, true,
2404 pixels.get() + kHeight / 2 * padded_row_size, mem4.ptr));
2407 // Test TexSubImage2D with GL_PACK_FLIP_Y set and partial multirow transfers
2408 TEST_F(GLES2ImplementationTest, TexSubImage2DFlipY) {
2409 const GLsizei kTextureWidth = MaxTransferBufferSize() / 4;
2410 const GLsizei kTextureHeight = 7;
2411 const GLsizei kSubImageWidth = MaxTransferBufferSize() / 8;
2412 const GLsizei kSubImageHeight = 4;
2413 const GLint kSubImageXOffset = 1;
2414 const GLint kSubImageYOffset = 2;
2415 const GLenum kFormat = GL_RGBA;
2416 const GLenum kType = GL_UNSIGNED_BYTE;
2417 const GLenum kTarget = GL_TEXTURE_2D;
2418 const GLint kLevel = 0;
2419 const GLint kBorder = 0;
2420 const GLint kPixelStoreUnpackAlignment = 4;
2422 struct Cmds {
2423 cmds::PixelStorei pixel_store_i1;
2424 cmds::TexImage2D tex_image_2d;
2425 cmds::PixelStorei pixel_store_i2;
2426 cmds::TexSubImage2D tex_sub_image_2d1;
2427 cmd::SetToken set_token1;
2428 cmds::TexSubImage2D tex_sub_image_2d2;
2429 cmd::SetToken set_token2;
2432 uint32 sub_2_high_size = 0;
2433 ASSERT_TRUE(GLES2Util::ComputeImageDataSizes(
2434 kSubImageWidth, 2, 1, kFormat, kType, kPixelStoreUnpackAlignment,
2435 &sub_2_high_size, NULL, NULL));
2437 ExpectedMemoryInfo mem1 = GetExpectedMemory(sub_2_high_size);
2438 ExpectedMemoryInfo mem2 = GetExpectedMemory(sub_2_high_size);
2440 Cmds expected;
2441 expected.pixel_store_i1.Init(GL_UNPACK_ALIGNMENT, kPixelStoreUnpackAlignment);
2442 expected.tex_image_2d.Init(
2443 kTarget, kLevel, kFormat, kTextureWidth, kTextureHeight, kFormat,
2444 kType, 0, 0);
2445 expected.pixel_store_i2.Init(GL_UNPACK_FLIP_Y_CHROMIUM, GL_TRUE);
2446 expected.tex_sub_image_2d1.Init(kTarget, kLevel, kSubImageXOffset,
2447 kSubImageYOffset + 2, kSubImageWidth, 2, kFormat, kType,
2448 mem1.id, mem1.offset, false);
2449 expected.set_token1.Init(GetNextToken());
2450 expected.tex_sub_image_2d2.Init(kTarget, kLevel, kSubImageXOffset,
2451 kSubImageYOffset, kSubImageWidth , 2, kFormat, kType,
2452 mem2.id, mem2.offset, false);
2453 expected.set_token2.Init(GetNextToken());
2455 gl_->PixelStorei(GL_UNPACK_ALIGNMENT, kPixelStoreUnpackAlignment);
2456 gl_->TexImage2D(
2457 kTarget, kLevel, kFormat, kTextureWidth, kTextureHeight, kBorder, kFormat,
2458 kType, NULL);
2459 gl_->PixelStorei(GL_UNPACK_FLIP_Y_CHROMIUM, GL_TRUE);
2460 scoped_ptr<uint32[]> pixels(new uint32[kSubImageWidth * kSubImageHeight]);
2461 for (int y = 0; y < kSubImageHeight; ++y) {
2462 for (int x = 0; x < kSubImageWidth; ++x) {
2463 pixels.get()[kSubImageWidth * y + x] = x | (y << 16);
2466 gl_->TexSubImage2D(
2467 GL_TEXTURE_2D, 0, kSubImageXOffset, kSubImageYOffset, kSubImageWidth,
2468 kSubImageHeight, GL_RGBA, GL_UNSIGNED_BYTE, pixels.get());
2470 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
2471 EXPECT_TRUE(CheckRect(
2472 kSubImageWidth, 2, kFormat, kType, kPixelStoreUnpackAlignment, true,
2473 reinterpret_cast<uint8*>(pixels.get() + 2 * kSubImageWidth),
2474 mem2.ptr));
2477 TEST_F(GLES2ImplementationTest, SubImageUnpack) {
2478 static const GLint unpack_alignments[] = { 1, 2, 4, 8 };
2480 static const GLenum kFormat = GL_RGB;
2481 static const GLenum kType = GL_UNSIGNED_BYTE;
2482 static const GLint kLevel = 0;
2483 static const GLint kBorder = 0;
2484 // We're testing using the unpack params to pull a subimage out of a larger
2485 // source of pixels. Here we specify the subimage by its border rows /
2486 // columns.
2487 static const GLint kSrcWidth = 33;
2488 static const GLint kSrcSubImageX0 = 11;
2489 static const GLint kSrcSubImageX1 = 20;
2490 static const GLint kSrcSubImageY0 = 18;
2491 static const GLint kSrcSubImageY1 = 23;
2492 static const GLint kSrcSubImageWidth = kSrcSubImageX1 - kSrcSubImageX0;
2493 static const GLint kSrcSubImageHeight = kSrcSubImageY1 - kSrcSubImageY0;
2495 // these are only used in the texsubimage tests
2496 static const GLint kTexWidth = 1023;
2497 static const GLint kTexHeight = 511;
2498 static const GLint kTexSubXOffset = 419;
2499 static const GLint kTexSubYOffset = 103;
2501 struct {
2502 cmds::PixelStorei pixel_store_i;
2503 cmds::PixelStorei pixel_store_i2;
2504 cmds::TexImage2D tex_image_2d;
2505 } texImageExpected;
2507 struct {
2508 cmds::PixelStorei pixel_store_i;
2509 cmds::PixelStorei pixel_store_i2;
2510 cmds::TexImage2D tex_image_2d;
2511 cmds::TexSubImage2D tex_sub_image_2d;
2512 } texSubImageExpected;
2514 uint32 src_size;
2515 ASSERT_TRUE(GLES2Util::ComputeImageDataSizes(
2516 kSrcWidth, kSrcSubImageY1, 1, kFormat, kType, 8, &src_size, NULL, NULL));
2517 scoped_ptr<uint8[]> src_pixels;
2518 src_pixels.reset(new uint8[src_size]);
2519 for (size_t i = 0; i < src_size; ++i) {
2520 src_pixels[i] = static_cast<int8>(i);
2523 for (int sub = 0; sub < 2; ++sub) {
2524 for (int flip_y = 0; flip_y < 2; ++flip_y) {
2525 for (size_t a = 0; a < arraysize(unpack_alignments); ++a) {
2526 GLint alignment = unpack_alignments[a];
2527 uint32 size;
2528 uint32 unpadded_row_size;
2529 uint32 padded_row_size;
2530 ASSERT_TRUE(GLES2Util::ComputeImageDataSizes(
2531 kSrcSubImageWidth, kSrcSubImageHeight, 1, kFormat, kType, alignment,
2532 &size, &unpadded_row_size, &padded_row_size));
2533 ASSERT_TRUE(size <= MaxTransferBufferSize());
2534 ExpectedMemoryInfo mem = GetExpectedMemory(size);
2536 const void* commands = GetPut();
2537 gl_->PixelStorei(GL_UNPACK_ALIGNMENT, alignment);
2538 gl_->PixelStorei(GL_UNPACK_ROW_LENGTH_EXT, kSrcWidth);
2539 gl_->PixelStorei(GL_UNPACK_SKIP_PIXELS_EXT, kSrcSubImageX0);
2540 gl_->PixelStorei(GL_UNPACK_SKIP_ROWS_EXT, kSrcSubImageY0);
2541 gl_->PixelStorei(GL_UNPACK_FLIP_Y_CHROMIUM, flip_y);
2542 if (sub) {
2543 gl_->TexImage2D(
2544 GL_TEXTURE_2D, kLevel, kFormat, kTexWidth, kTexHeight, kBorder,
2545 kFormat, kType, NULL);
2546 gl_->TexSubImage2D(
2547 GL_TEXTURE_2D, kLevel, kTexSubXOffset, kTexSubYOffset,
2548 kSrcSubImageWidth, kSrcSubImageHeight, kFormat, kType,
2549 src_pixels.get());
2550 texSubImageExpected.pixel_store_i.Init(
2551 GL_UNPACK_ALIGNMENT, alignment);
2552 texSubImageExpected.pixel_store_i2.Init(
2553 GL_UNPACK_FLIP_Y_CHROMIUM, flip_y);
2554 texSubImageExpected.tex_image_2d.Init(
2555 GL_TEXTURE_2D, kLevel, kFormat, kTexWidth, kTexHeight,
2556 kFormat, kType, 0, 0);
2557 texSubImageExpected.tex_sub_image_2d.Init(
2558 GL_TEXTURE_2D, kLevel, kTexSubXOffset, kTexSubYOffset,
2559 kSrcSubImageWidth, kSrcSubImageHeight, kFormat, kType, mem.id,
2560 mem.offset, GL_FALSE);
2561 EXPECT_EQ(0, memcmp(
2562 &texSubImageExpected, commands, sizeof(texSubImageExpected)));
2563 } else {
2564 gl_->TexImage2D(
2565 GL_TEXTURE_2D, kLevel, kFormat,
2566 kSrcSubImageWidth, kSrcSubImageHeight, kBorder, kFormat, kType,
2567 src_pixels.get());
2568 texImageExpected.pixel_store_i.Init(GL_UNPACK_ALIGNMENT, alignment);
2569 texImageExpected.pixel_store_i2.Init(
2570 GL_UNPACK_FLIP_Y_CHROMIUM, flip_y);
2571 texImageExpected.tex_image_2d.Init(
2572 GL_TEXTURE_2D, kLevel, kFormat, kSrcSubImageWidth,
2573 kSrcSubImageHeight, kFormat, kType, mem.id, mem.offset);
2574 EXPECT_EQ(0, memcmp(
2575 &texImageExpected, commands, sizeof(texImageExpected)));
2577 uint32 src_padded_row_size;
2578 ASSERT_TRUE(GLES2Util::ComputeImagePaddedRowSize(
2579 kSrcWidth, kFormat, kType, alignment, &src_padded_row_size));
2580 uint32 bytes_per_group = GLES2Util::ComputeImageGroupSize(
2581 kFormat, kType);
2582 for (int y = 0; y < kSrcSubImageHeight; ++y) {
2583 GLint src_sub_y = flip_y ? kSrcSubImageHeight - y - 1 : y;
2584 const uint8* src_row = src_pixels.get() +
2585 (kSrcSubImageY0 + src_sub_y) * src_padded_row_size +
2586 bytes_per_group * kSrcSubImageX0;
2587 const uint8* dst_row = mem.ptr + y * padded_row_size;
2588 EXPECT_EQ(0, memcmp(src_row, dst_row, unpadded_row_size));
2590 ClearCommands();
2596 // Test texture related calls with invalid arguments.
2597 TEST_F(GLES2ImplementationTest, TextureInvalidArguments) {
2598 struct Cmds {
2599 cmds::TexImage2D tex_image_2d;
2600 cmd::SetToken set_token;
2602 const GLenum kTarget = GL_TEXTURE_2D;
2603 const GLint kLevel = 0;
2604 const GLenum kFormat = GL_RGB;
2605 const GLsizei kWidth = 3;
2606 const GLsizei kHeight = 4;
2607 const GLint kBorder = 0;
2608 const GLint kInvalidBorder = 1;
2609 const GLenum kType = GL_UNSIGNED_BYTE;
2610 const GLint kPixelStoreUnpackAlignment = 4;
2611 static uint8 pixels[] = {
2612 11, 12, 13, 13, 14, 15, 15, 16, 17, 101, 102, 103,
2613 21, 22, 23, 23, 24, 25, 25, 26, 27, 201, 202, 203,
2614 31, 32, 33, 33, 34, 35, 35, 36, 37, 123, 124, 125,
2615 41, 42, 43, 43, 44, 45, 45, 46, 47,
2618 // Verify that something works.
2620 ExpectedMemoryInfo mem1 = GetExpectedMemory(sizeof(pixels));
2622 Cmds expected;
2623 expected.tex_image_2d.Init(
2624 kTarget, kLevel, kFormat, kWidth, kHeight, kFormat, kType,
2625 mem1.id, mem1.offset);
2626 expected.set_token.Init(GetNextToken());
2627 gl_->TexImage2D(
2628 kTarget, kLevel, kFormat, kWidth, kHeight, kBorder, kFormat, kType,
2629 pixels);
2630 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
2631 EXPECT_TRUE(CheckRect(
2632 kWidth, kHeight, kFormat, kType, kPixelStoreUnpackAlignment, false,
2633 pixels, mem1.ptr));
2635 ClearCommands();
2637 // Use invalid border.
2638 gl_->TexImage2D(
2639 kTarget, kLevel, kFormat, kWidth, kHeight, kInvalidBorder, kFormat, kType,
2640 pixels);
2642 EXPECT_TRUE(NoCommandsWritten());
2643 EXPECT_EQ(GL_INVALID_VALUE, CheckError());
2645 ClearCommands();
2647 gl_->AsyncTexImage2DCHROMIUM(
2648 kTarget, kLevel, kFormat, kWidth, kHeight, kInvalidBorder, kFormat, kType,
2649 NULL);
2651 EXPECT_TRUE(NoCommandsWritten());
2652 EXPECT_EQ(GL_INVALID_VALUE, CheckError());
2654 ClearCommands();
2656 // Checking for CompressedTexImage2D argument validation is a bit tricky due
2657 // to (runtime-detected) compression formats. Try to infer the error with an
2658 // aux check.
2659 const GLenum kCompressedFormat = GL_ETC1_RGB8_OES;
2660 gl_->CompressedTexImage2D(
2661 kTarget, kLevel, kCompressedFormat, kWidth, kHeight, kBorder,
2662 arraysize(pixels), pixels);
2664 // In the above, kCompressedFormat and arraysize(pixels) are possibly wrong
2665 // values. First ensure that these do not cause failures at the client. If
2666 // this check ever fails, it probably means that client checks more than at
2667 // the time of writing of this test. In this case, more code needs to be
2668 // written for this test.
2669 EXPECT_FALSE(NoCommandsWritten());
2671 ClearCommands();
2673 // Changing border to invalid border should make the call fail at the client
2674 // checks.
2675 gl_->CompressedTexImage2D(
2676 kTarget, kLevel, kCompressedFormat, kWidth, kHeight, kInvalidBorder,
2677 arraysize(pixels), pixels);
2678 EXPECT_TRUE(NoCommandsWritten());
2679 EXPECT_EQ(GL_INVALID_VALUE, CheckError());
2682 TEST_F(GLES2ImplementationTest, TexImage3DSingleCommand) {
2683 struct Cmds {
2684 cmds::TexImage3D tex_image_3d;
2686 const GLenum kTarget = GL_TEXTURE_3D;
2687 const GLint kLevel = 0;
2688 const GLint kBorder = 0;
2689 const GLenum kFormat = GL_RGB;
2690 const GLenum kType = GL_UNSIGNED_BYTE;
2691 const GLint kPixelStoreUnpackAlignment = 4;
2692 const GLsizei kWidth = 3;
2693 const GLsizei kDepth = 2;
2695 uint32 size = 0;
2696 uint32 unpadded_row_size = 0;
2697 uint32 padded_row_size = 0;
2698 ASSERT_TRUE(GLES2Util::ComputeImageDataSizes(
2699 kWidth, 2, kDepth, kFormat, kType, kPixelStoreUnpackAlignment,
2700 &size, &unpadded_row_size, &padded_row_size));
2701 // Makes sure we can just send over the data in one command.
2702 const GLsizei kHeight = MaxTransferBufferSize() / padded_row_size / kDepth;
2703 ASSERT_TRUE(GLES2Util::ComputeImageDataSizes(
2704 kWidth, kHeight, kDepth, kFormat, kType, kPixelStoreUnpackAlignment,
2705 &size, NULL, NULL));
2707 scoped_ptr<uint8[]> pixels(new uint8[size]);
2708 for (uint32 ii = 0; ii < size; ++ii) {
2709 pixels[ii] = static_cast<uint8>(ii);
2712 ExpectedMemoryInfo mem = GetExpectedMemory(size);
2714 Cmds expected;
2715 expected.tex_image_3d.Init(
2716 kTarget, kLevel, kFormat, kWidth, kHeight, kDepth,
2717 kFormat, kType, mem.id, mem.offset);
2719 gl_->TexImage3D(
2720 kTarget, kLevel, kFormat, kWidth, kHeight, kDepth, kBorder,
2721 kFormat, kType, pixels.get());
2723 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
2724 EXPECT_TRUE(CheckRect(
2725 kWidth, kHeight * kDepth, kFormat, kType, kPixelStoreUnpackAlignment,
2726 false, reinterpret_cast<uint8*>(pixels.get()), mem.ptr));
2729 TEST_F(GLES2ImplementationTest, TexImage3DViaTexSubImage3D) {
2730 struct Cmds {
2731 cmds::TexImage3D tex_image_3d;
2732 cmds::TexSubImage3D tex_sub_image_3d1;
2733 cmd::SetToken set_token;
2734 cmds::TexSubImage3D tex_sub_image_3d2;
2736 const GLenum kTarget = GL_TEXTURE_3D;
2737 const GLint kLevel = 0;
2738 const GLint kBorder = 0;
2739 const GLenum kFormat = GL_RGB;
2740 const GLenum kType = GL_UNSIGNED_BYTE;
2741 const GLint kPixelStoreUnpackAlignment = 4;
2742 const GLsizei kWidth = 3;
2744 uint32 size = 0;
2745 uint32 unpadded_row_size = 0;
2746 uint32 padded_row_size = 0;
2747 ASSERT_TRUE(GLES2Util::ComputeImageDataSizes(
2748 kWidth, 2, 1, kFormat, kType, kPixelStoreUnpackAlignment,
2749 &size, &unpadded_row_size, &padded_row_size));
2750 // Makes sure the data is more than one command can hold.
2751 const GLsizei kHeight = MaxTransferBufferSize() / padded_row_size + 3;
2752 ASSERT_TRUE(GLES2Util::ComputeImageDataSizes(
2753 kWidth, kHeight, 1, kFormat, kType, kPixelStoreUnpackAlignment,
2754 &size, NULL, NULL));
2755 uint32 first_size = padded_row_size * (kHeight - 3);
2756 uint32 second_size =
2757 padded_row_size * 3 - (padded_row_size - unpadded_row_size);
2758 EXPECT_EQ(size, first_size + second_size);
2759 ExpectedMemoryInfo mem1 = GetExpectedMemory(first_size);
2760 ExpectedMemoryInfo mem2 = GetExpectedMemory(second_size);
2761 scoped_ptr<uint8[]> pixels(new uint8[size]);
2762 for (uint32 ii = 0; ii < size; ++ii) {
2763 pixels[ii] = static_cast<uint8>(ii);
2766 Cmds expected;
2767 expected.tex_image_3d.Init(
2768 kTarget, kLevel, kFormat, kWidth, kHeight, 1, kFormat, kType, 0, 0);
2769 expected.tex_sub_image_3d1.Init(
2770 kTarget, kLevel, 0, 0, 0, kWidth, kHeight - 3, 1, kFormat, kType,
2771 mem1.id, mem1.offset, GL_TRUE);
2772 expected.tex_sub_image_3d2.Init(
2773 kTarget, kLevel, 0, kHeight - 3, 0, kWidth, 3, 1, kFormat, kType,
2774 mem2.id, mem2.offset, GL_TRUE);
2775 expected.set_token.Init(GetNextToken());
2777 gl_->TexImage3D(
2778 kTarget, kLevel, kFormat, kWidth, kHeight, 1, kBorder,
2779 kFormat, kType, pixels.get());
2780 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
2783 // Test TexSubImage3D with 4 writes
2784 TEST_F(GLES2ImplementationTest, TexSubImage3D4Writes) {
2785 struct Cmds {
2786 cmds::TexSubImage3D tex_sub_image_3d1_1;
2787 cmd::SetToken set_token1;
2788 cmds::TexSubImage3D tex_sub_image_3d1_2;
2789 cmd::SetToken set_token2;
2790 cmds::TexSubImage3D tex_sub_image_3d2_1;
2791 cmd::SetToken set_token3;
2792 cmds::TexSubImage3D tex_sub_image_3d2_2;
2794 const GLenum kTarget = GL_TEXTURE_3D;
2795 const GLint kLevel = 0;
2796 const GLint kXOffset = 0;
2797 const GLint kYOffset = 0;
2798 const GLint kZOffset = 0;
2799 const GLenum kFormat = GL_RGB;
2800 const GLenum kType = GL_UNSIGNED_BYTE;
2801 const GLint kPixelStoreUnpackAlignment = 4;
2802 const GLsizei kWidth = 3;
2803 const GLsizei kDepth = 2;
2805 uint32 size = 0;
2806 uint32 unpadded_row_size = 0;
2807 uint32 padded_row_size = 0;
2808 ASSERT_TRUE(GLES2Util::ComputeImageDataSizes(
2809 kWidth, 2, 1, kFormat, kType, kPixelStoreUnpackAlignment,
2810 &size, &unpadded_row_size, &padded_row_size));
2811 const GLsizei kHeight = MaxTransferBufferSize() / padded_row_size + 2;
2812 ASSERT_TRUE(GLES2Util::ComputeImageDataSizes(
2813 kWidth, kHeight, kDepth, kFormat, kType, kPixelStoreUnpackAlignment,
2814 &size, NULL, NULL));
2815 uint32 first_size = (kHeight - 2) * padded_row_size;
2816 uint32 second_size = 2 * padded_row_size;
2817 uint32 third_size = first_size;
2818 uint32 fourth_size = second_size - (padded_row_size - unpadded_row_size);
2819 EXPECT_EQ(size, first_size + second_size + third_size + fourth_size);
2821 scoped_ptr<uint8[]> pixels(new uint8[size]);
2822 for (uint32 ii = 0; ii < size; ++ii) {
2823 pixels[ii] = static_cast<uint8>(ii);
2826 ExpectedMemoryInfo mem1_1 = GetExpectedMemory(first_size);
2827 ExpectedMemoryInfo mem1_2 = GetExpectedMemory(second_size);
2828 ExpectedMemoryInfo mem2_1 = GetExpectedMemory(third_size);
2829 ExpectedMemoryInfo mem2_2 = GetExpectedMemory(fourth_size);
2831 Cmds expected;
2832 expected.tex_sub_image_3d1_1.Init(
2833 kTarget, kLevel, kXOffset, kYOffset, kZOffset,
2834 kWidth, kHeight - 2, 1, kFormat, kType,
2835 mem1_1.id, mem1_1.offset, GL_FALSE);
2836 expected.tex_sub_image_3d1_2.Init(
2837 kTarget, kLevel, kXOffset, kYOffset + kHeight - 2, kZOffset,
2838 kWidth, 2, 1, kFormat, kType, mem1_2.id, mem1_2.offset, GL_FALSE);
2839 expected.tex_sub_image_3d2_1.Init(
2840 kTarget, kLevel, kXOffset, kYOffset, kZOffset + 1,
2841 kWidth, kHeight - 2, 1, kFormat, kType,
2842 mem2_1.id, mem2_1.offset, GL_FALSE);
2843 expected.tex_sub_image_3d2_2.Init(
2844 kTarget, kLevel, kXOffset, kYOffset + kHeight - 2, kZOffset + 1,
2845 kWidth, 2, 1, kFormat, kType, mem2_2.id, mem2_2.offset, GL_FALSE);
2846 expected.set_token1.Init(GetNextToken());
2847 expected.set_token2.Init(GetNextToken());
2848 expected.set_token3.Init(GetNextToken());
2850 gl_->TexSubImage3D(
2851 kTarget, kLevel, kXOffset, kYOffset, kZOffset, kWidth, kHeight, kDepth,
2852 kFormat, kType, pixels.get());
2854 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
2855 uint32 offset_to_last = first_size + second_size + third_size;
2856 EXPECT_TRUE(CheckRect(
2857 kWidth, 2, kFormat, kType, kPixelStoreUnpackAlignment, false,
2858 reinterpret_cast<uint8*>(pixels.get()) + offset_to_last, mem2_2.ptr));
2861 // glGen* Ids must not be reused until glDelete* commands have been
2862 // flushed by glFlush.
2863 TEST_F(GLES2ImplementationStrictSharedTest, FlushGenerationTestBuffers) {
2864 FlushGenerationTest<GenBuffersAPI>();
2866 TEST_F(GLES2ImplementationStrictSharedTest, FlushGenerationTestFramebuffers) {
2867 FlushGenerationTest<GenFramebuffersAPI>();
2869 TEST_F(GLES2ImplementationStrictSharedTest, FlushGenerationTestRenderbuffers) {
2870 FlushGenerationTest<GenRenderbuffersAPI>();
2872 TEST_F(GLES2ImplementationStrictSharedTest, FlushGenerationTestTextures) {
2873 FlushGenerationTest<GenTexturesAPI>();
2876 // glGen* Ids must not be reused cross-context until glDelete* commands are
2877 // flushed by glFlush, and the Ids are lazily freed after.
2878 TEST_F(GLES2ImplementationStrictSharedTest, CrossContextGenerationTestBuffers) {
2879 CrossContextGenerationTest<GenBuffersAPI>();
2881 TEST_F(GLES2ImplementationStrictSharedTest,
2882 CrossContextGenerationTestFramebuffers) {
2883 CrossContextGenerationTest<GenFramebuffersAPI>();
2885 TEST_F(GLES2ImplementationStrictSharedTest,
2886 CrossContextGenerationTestRenderbuffers) {
2887 CrossContextGenerationTest<GenRenderbuffersAPI>();
2889 TEST_F(GLES2ImplementationStrictSharedTest,
2890 CrossContextGenerationTestTextures) {
2891 CrossContextGenerationTest<GenTexturesAPI>();
2894 // Test Delete which causes auto flush. Tests a regression case that occurred
2895 // in testing.
2896 TEST_F(GLES2ImplementationStrictSharedTest,
2897 CrossContextGenerationAutoFlushTestBuffers) {
2898 CrossContextGenerationAutoFlushTest<GenBuffersAPI>();
2900 TEST_F(GLES2ImplementationStrictSharedTest,
2901 CrossContextGenerationAutoFlushTestFramebuffers) {
2902 CrossContextGenerationAutoFlushTest<GenFramebuffersAPI>();
2904 TEST_F(GLES2ImplementationStrictSharedTest,
2905 CrossContextGenerationAutoFlushTestRenderbuffers) {
2906 CrossContextGenerationAutoFlushTest<GenRenderbuffersAPI>();
2908 TEST_F(GLES2ImplementationStrictSharedTest,
2909 CrossContextGenerationAutoFlushTestTextures) {
2910 CrossContextGenerationAutoFlushTest<GenTexturesAPI>();
2913 TEST_F(GLES2ImplementationTest, GetString) {
2914 const uint32 kBucketId = GLES2Implementation::kResultBucketId;
2915 const Str7 kString = {"foobar"};
2916 // GL_CHROMIUM_map_sub GL_CHROMIUM_flipy are hard coded into
2917 // GLES2Implementation.
2918 const char* expected_str =
2919 "foobar "
2920 "GL_CHROMIUM_flipy "
2921 "GL_EXT_unpack_subimage "
2922 "GL_CHROMIUM_map_sub";
2923 const char kBad = 0x12;
2924 struct Cmds {
2925 cmd::SetBucketSize set_bucket_size1;
2926 cmds::GetString get_string;
2927 cmd::GetBucketStart get_bucket_start;
2928 cmd::SetToken set_token1;
2929 cmd::SetBucketSize set_bucket_size2;
2931 ExpectedMemoryInfo mem1 = GetExpectedMemory(MaxTransferBufferSize());
2932 ExpectedMemoryInfo result1 =
2933 GetExpectedResultMemory(sizeof(cmd::GetBucketStart::Result));
2934 Cmds expected;
2935 expected.set_bucket_size1.Init(kBucketId, 0);
2936 expected.get_string.Init(GL_EXTENSIONS, kBucketId);
2937 expected.get_bucket_start.Init(
2938 kBucketId, result1.id, result1.offset,
2939 MaxTransferBufferSize(), mem1.id, mem1.offset);
2940 expected.set_token1.Init(GetNextToken());
2941 expected.set_bucket_size2.Init(kBucketId, 0);
2942 char buf[sizeof(kString) + 1];
2943 memset(buf, kBad, sizeof(buf));
2945 EXPECT_CALL(*command_buffer(), OnFlush())
2946 .WillOnce(DoAll(SetMemory(result1.ptr, uint32(sizeof(kString))),
2947 SetMemory(mem1.ptr, kString)))
2948 .RetiresOnSaturation();
2950 const GLubyte* result = gl_->GetString(GL_EXTENSIONS);
2951 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
2952 EXPECT_STREQ(expected_str, reinterpret_cast<const char*>(result));
2955 TEST_F(GLES2ImplementationTest, PixelStoreiGLPackReverseRowOrderANGLE) {
2956 const uint32 kBucketId = GLES2Implementation::kResultBucketId;
2957 const Str7 kString = {"foobar"};
2958 struct Cmds {
2959 cmd::SetBucketSize set_bucket_size1;
2960 cmds::GetString get_string;
2961 cmd::GetBucketStart get_bucket_start;
2962 cmd::SetToken set_token1;
2963 cmd::SetBucketSize set_bucket_size2;
2964 cmds::PixelStorei pixel_store;
2967 ExpectedMemoryInfo mem1 = GetExpectedMemory(MaxTransferBufferSize());
2968 ExpectedMemoryInfo result1 =
2969 GetExpectedResultMemory(sizeof(cmd::GetBucketStart::Result));
2971 Cmds expected;
2972 expected.set_bucket_size1.Init(kBucketId, 0);
2973 expected.get_string.Init(GL_EXTENSIONS, kBucketId);
2974 expected.get_bucket_start.Init(
2975 kBucketId, result1.id, result1.offset,
2976 MaxTransferBufferSize(), mem1.id, mem1.offset);
2977 expected.set_token1.Init(GetNextToken());
2978 expected.set_bucket_size2.Init(kBucketId, 0);
2979 expected.pixel_store.Init(GL_PACK_REVERSE_ROW_ORDER_ANGLE, 1);
2981 EXPECT_CALL(*command_buffer(), OnFlush())
2982 .WillOnce(DoAll(SetMemory(result1.ptr, uint32(sizeof(kString))),
2983 SetMemory(mem1.ptr, kString)))
2984 .RetiresOnSaturation();
2986 gl_->PixelStorei(GL_PACK_REVERSE_ROW_ORDER_ANGLE, 1);
2987 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
2990 TEST_F(GLES2ImplementationTest, CreateProgram) {
2991 struct Cmds {
2992 cmds::CreateProgram cmd;
2995 Cmds expected;
2996 expected.cmd.Init(kProgramsAndShadersStartId);
2997 GLuint id = gl_->CreateProgram();
2998 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
2999 EXPECT_EQ(kProgramsAndShadersStartId, id);
3002 TEST_F(GLES2ImplementationTest, BufferDataLargerThanTransferBuffer) {
3003 struct Cmds {
3004 cmds::BufferData set_size;
3005 cmds::BufferSubData copy_data1;
3006 cmd::SetToken set_token1;
3007 cmds::BufferSubData copy_data2;
3008 cmd::SetToken set_token2;
3010 const unsigned kUsableSize =
3011 kTransferBufferSize - GLES2Implementation::kStartingOffset;
3012 uint8 buf[kUsableSize * 2] = { 0, };
3014 ExpectedMemoryInfo mem1 = GetExpectedMemory(kUsableSize);
3015 ExpectedMemoryInfo mem2 = GetExpectedMemory(kUsableSize);
3017 Cmds expected;
3018 expected.set_size.Init(
3019 GL_ARRAY_BUFFER, arraysize(buf), 0, 0, GL_DYNAMIC_DRAW);
3020 expected.copy_data1.Init(
3021 GL_ARRAY_BUFFER, 0, kUsableSize, mem1.id, mem1.offset);
3022 expected.set_token1.Init(GetNextToken());
3023 expected.copy_data2.Init(
3024 GL_ARRAY_BUFFER, kUsableSize, kUsableSize, mem2.id, mem2.offset);
3025 expected.set_token2.Init(GetNextToken());
3026 gl_->BufferData(GL_ARRAY_BUFFER, arraysize(buf), buf, GL_DYNAMIC_DRAW);
3027 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
3030 TEST_F(GLES2ImplementationTest, CapabilitiesAreCached) {
3031 static const GLenum kStates[] = {
3032 GL_DITHER,
3033 GL_BLEND,
3034 GL_CULL_FACE,
3035 GL_DEPTH_TEST,
3036 GL_POLYGON_OFFSET_FILL,
3037 GL_SAMPLE_ALPHA_TO_COVERAGE,
3038 GL_SAMPLE_COVERAGE,
3039 GL_SCISSOR_TEST,
3040 GL_STENCIL_TEST,
3042 struct Cmds {
3043 cmds::Enable enable_cmd;
3045 Cmds expected;
3047 for (size_t ii = 0; ii < arraysize(kStates); ++ii) {
3048 GLenum state = kStates[ii];
3049 expected.enable_cmd.Init(state);
3050 GLboolean result = gl_->IsEnabled(state);
3051 EXPECT_EQ(static_cast<GLboolean>(ii == 0), result);
3052 EXPECT_TRUE(NoCommandsWritten());
3053 const void* commands = GetPut();
3054 if (!result) {
3055 gl_->Enable(state);
3056 EXPECT_EQ(0, memcmp(&expected, commands, sizeof(expected)));
3058 ClearCommands();
3059 result = gl_->IsEnabled(state);
3060 EXPECT_TRUE(result);
3061 EXPECT_TRUE(NoCommandsWritten());
3065 TEST_F(GLES2ImplementationTest, BindVertexArrayOES) {
3066 GLuint id = 0;
3067 gl_->GenVertexArraysOES(1, &id);
3068 ClearCommands();
3070 struct Cmds {
3071 cmds::BindVertexArrayOES cmd;
3073 Cmds expected;
3074 expected.cmd.Init(id);
3076 const void* commands = GetPut();
3077 gl_->BindVertexArrayOES(id);
3078 EXPECT_EQ(0, memcmp(&expected, commands, sizeof(expected)));
3079 ClearCommands();
3080 gl_->BindVertexArrayOES(id);
3081 EXPECT_TRUE(NoCommandsWritten());
3084 TEST_F(GLES2ImplementationTest, BeginEndQueryEXT) {
3085 // Test GetQueryivEXT returns 0 if no current query.
3086 GLint param = -1;
3087 gl_->GetQueryivEXT(GL_ANY_SAMPLES_PASSED_EXT, GL_CURRENT_QUERY_EXT, &param);
3088 EXPECT_EQ(0, param);
3090 GLuint expected_ids[2] = { 1, 2 }; // These must match what's actually genned.
3091 struct GenCmds {
3092 cmds::GenQueriesEXTImmediate gen;
3093 GLuint data[2];
3095 GenCmds expected_gen_cmds;
3096 expected_gen_cmds.gen.Init(arraysize(expected_ids), &expected_ids[0]);
3097 GLuint ids[arraysize(expected_ids)] = { 0, };
3098 gl_->GenQueriesEXT(arraysize(expected_ids), &ids[0]);
3099 EXPECT_EQ(0, memcmp(
3100 &expected_gen_cmds, commands_, sizeof(expected_gen_cmds)));
3101 GLuint id1 = ids[0];
3102 GLuint id2 = ids[1];
3103 ClearCommands();
3105 // Test BeginQueryEXT fails if id = 0.
3106 gl_->BeginQueryEXT(GL_ANY_SAMPLES_PASSED_EXT, 0);
3107 EXPECT_TRUE(NoCommandsWritten());
3108 EXPECT_EQ(GL_INVALID_OPERATION, CheckError());
3110 // Test BeginQueryEXT inserts command.
3111 struct BeginCmds {
3112 cmds::BeginQueryEXT begin_query;
3114 BeginCmds expected_begin_cmds;
3115 const void* commands = GetPut();
3116 gl_->BeginQueryEXT(GL_ANY_SAMPLES_PASSED_EXT, id1);
3117 QueryTracker::Query* query = GetQuery(id1);
3118 ASSERT_TRUE(query != NULL);
3119 expected_begin_cmds.begin_query.Init(
3120 GL_ANY_SAMPLES_PASSED_EXT, id1, query->shm_id(), query->shm_offset());
3121 EXPECT_EQ(0, memcmp(
3122 &expected_begin_cmds, commands, sizeof(expected_begin_cmds)));
3123 ClearCommands();
3125 // Test GetQueryivEXT returns id.
3126 param = -1;
3127 gl_->GetQueryivEXT(GL_ANY_SAMPLES_PASSED_EXT, GL_CURRENT_QUERY_EXT, &param);
3128 EXPECT_EQ(id1, static_cast<GLuint>(param));
3129 gl_->GetQueryivEXT(
3130 GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT, GL_CURRENT_QUERY_EXT, &param);
3131 EXPECT_EQ(0, param);
3133 // Test BeginQueryEXT fails if between Begin/End.
3134 gl_->BeginQueryEXT(GL_ANY_SAMPLES_PASSED_EXT, id2);
3135 EXPECT_TRUE(NoCommandsWritten());
3136 EXPECT_EQ(GL_INVALID_OPERATION, CheckError());
3138 // Test EndQueryEXT fails if target not same as current query.
3139 ClearCommands();
3140 gl_->EndQueryEXT(GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT);
3141 EXPECT_TRUE(NoCommandsWritten());
3142 EXPECT_EQ(GL_INVALID_OPERATION, CheckError());
3144 // Test EndQueryEXT sends command
3145 struct EndCmds {
3146 cmds::EndQueryEXT end_query;
3148 EndCmds expected_end_cmds;
3149 expected_end_cmds.end_query.Init(
3150 GL_ANY_SAMPLES_PASSED_EXT, query->submit_count());
3151 commands = GetPut();
3152 gl_->EndQueryEXT(GL_ANY_SAMPLES_PASSED_EXT);
3153 EXPECT_EQ(0, memcmp(
3154 &expected_end_cmds, commands, sizeof(expected_end_cmds)));
3156 // Test EndQueryEXT fails if no current query.
3157 ClearCommands();
3158 gl_->EndQueryEXT(GL_ANY_SAMPLES_PASSED_EXT);
3159 EXPECT_TRUE(NoCommandsWritten());
3160 EXPECT_EQ(GL_INVALID_OPERATION, CheckError());
3162 // Test 2nd Begin/End increments count.
3163 base::subtle::Atomic32 old_submit_count = query->submit_count();
3164 gl_->BeginQueryEXT(GL_ANY_SAMPLES_PASSED_EXT, id1);
3165 EXPECT_NE(old_submit_count, query->submit_count());
3166 expected_end_cmds.end_query.Init(
3167 GL_ANY_SAMPLES_PASSED_EXT, query->submit_count());
3168 commands = GetPut();
3169 gl_->EndQueryEXT(GL_ANY_SAMPLES_PASSED_EXT);
3170 EXPECT_EQ(0, memcmp(
3171 &expected_end_cmds, commands, sizeof(expected_end_cmds)));
3173 // Test BeginQueryEXT fails if target changed.
3174 ClearCommands();
3175 gl_->BeginQueryEXT(GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT, id1);
3176 EXPECT_TRUE(NoCommandsWritten());
3177 EXPECT_EQ(GL_INVALID_OPERATION, CheckError());
3179 // Test GetQueryObjectuivEXT fails if unused id
3180 GLuint available = 0xBDu;
3181 ClearCommands();
3182 gl_->GetQueryObjectuivEXT(id2, GL_QUERY_RESULT_AVAILABLE_EXT, &available);
3183 EXPECT_TRUE(NoCommandsWritten());
3184 EXPECT_EQ(0xBDu, available);
3185 EXPECT_EQ(GL_INVALID_OPERATION, CheckError());
3187 // Test GetQueryObjectuivEXT fails if bad id
3188 ClearCommands();
3189 gl_->GetQueryObjectuivEXT(4567, GL_QUERY_RESULT_AVAILABLE_EXT, &available);
3190 EXPECT_TRUE(NoCommandsWritten());
3191 EXPECT_EQ(0xBDu, available);
3192 EXPECT_EQ(GL_INVALID_OPERATION, CheckError());
3194 // Test GetQueryObjectuivEXT CheckResultsAvailable
3195 ClearCommands();
3196 gl_->GetQueryObjectuivEXT(id1, GL_QUERY_RESULT_AVAILABLE_EXT, &available);
3197 EXPECT_EQ(0u, available);
3200 TEST_F(GLES2ImplementationTest, ErrorQuery) {
3201 GLuint id = 0;
3202 gl_->GenQueriesEXT(1, &id);
3203 ClearCommands();
3205 // Test BeginQueryEXT does NOT insert commands.
3206 gl_->BeginQueryEXT(GL_GET_ERROR_QUERY_CHROMIUM, id);
3207 EXPECT_TRUE(NoCommandsWritten());
3208 QueryTracker::Query* query = GetQuery(id);
3209 ASSERT_TRUE(query != NULL);
3211 // Test EndQueryEXT sends both begin and end command
3212 struct EndCmds {
3213 cmds::BeginQueryEXT begin_query;
3214 cmds::EndQueryEXT end_query;
3216 EndCmds expected_end_cmds;
3217 expected_end_cmds.begin_query.Init(
3218 GL_GET_ERROR_QUERY_CHROMIUM, id, query->shm_id(), query->shm_offset());
3219 expected_end_cmds.end_query.Init(
3220 GL_GET_ERROR_QUERY_CHROMIUM, query->submit_count());
3221 const void* commands = GetPut();
3222 gl_->EndQueryEXT(GL_GET_ERROR_QUERY_CHROMIUM);
3223 EXPECT_EQ(0, memcmp(
3224 &expected_end_cmds, commands, sizeof(expected_end_cmds)));
3225 ClearCommands();
3227 // Check result is not yet available.
3228 GLuint available = 0xBDu;
3229 gl_->GetQueryObjectuivEXT(id, GL_QUERY_RESULT_AVAILABLE_EXT, &available);
3230 EXPECT_TRUE(NoCommandsWritten());
3231 EXPECT_EQ(0u, available);
3233 // Test no commands are sent if there is a client side error.
3235 // Generate a client side error
3236 gl_->ActiveTexture(GL_TEXTURE0 - 1);
3238 gl_->BeginQueryEXT(GL_GET_ERROR_QUERY_CHROMIUM, id);
3239 gl_->EndQueryEXT(GL_GET_ERROR_QUERY_CHROMIUM);
3240 EXPECT_TRUE(NoCommandsWritten());
3242 // Check result is available.
3243 gl_->GetQueryObjectuivEXT(id, GL_QUERY_RESULT_AVAILABLE_EXT, &available);
3244 EXPECT_TRUE(NoCommandsWritten());
3245 EXPECT_NE(0u, available);
3247 // Check result.
3248 GLuint result = 0xBDu;
3249 gl_->GetQueryObjectuivEXT(id, GL_QUERY_RESULT_EXT, &result);
3250 EXPECT_TRUE(NoCommandsWritten());
3251 EXPECT_EQ(static_cast<GLuint>(GL_INVALID_ENUM), result);
3254 #if !defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS)
3255 TEST_F(GLES2ImplementationTest, VertexArrays) {
3256 const GLuint kAttribIndex1 = 1;
3257 const GLint kNumComponents1 = 3;
3258 const GLsizei kClientStride = 12;
3260 GLuint id = 0;
3261 gl_->GenVertexArraysOES(1, &id);
3262 ClearCommands();
3264 gl_->BindVertexArrayOES(id);
3266 // Test that VertexAttribPointer cannot be called with a bound buffer of 0
3267 // unless the offset is NULL
3268 gl_->BindBuffer(GL_ARRAY_BUFFER, 0);
3270 gl_->VertexAttribPointer(
3271 kAttribIndex1, kNumComponents1, GL_FLOAT, GL_FALSE, kClientStride,
3272 reinterpret_cast<const void*>(4));
3273 EXPECT_EQ(GL_INVALID_OPERATION, CheckError());
3275 gl_->VertexAttribPointer(
3276 kAttribIndex1, kNumComponents1, GL_FLOAT, GL_FALSE, kClientStride, NULL);
3277 EXPECT_EQ(GL_NO_ERROR, CheckError());
3279 #endif
3281 TEST_F(GLES2ImplementationTest, Disable) {
3282 struct Cmds {
3283 cmds::Disable cmd;
3285 Cmds expected;
3286 expected.cmd.Init(GL_DITHER); // Note: DITHER defaults to enabled.
3288 gl_->Disable(GL_DITHER);
3289 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
3290 // Check it's cached and not called again.
3291 ClearCommands();
3292 gl_->Disable(GL_DITHER);
3293 EXPECT_TRUE(NoCommandsWritten());
3296 TEST_F(GLES2ImplementationTest, Enable) {
3297 struct Cmds {
3298 cmds::Enable cmd;
3300 Cmds expected;
3301 expected.cmd.Init(GL_BLEND); // Note: BLEND defaults to disabled.
3303 gl_->Enable(GL_BLEND);
3304 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
3305 // Check it's cached and not called again.
3306 ClearCommands();
3307 gl_->Enable(GL_BLEND);
3308 EXPECT_TRUE(NoCommandsWritten());
3311 TEST_F(GLES2ImplementationTest, ConsumeTextureCHROMIUM) {
3312 struct Cmds {
3313 cmds::ConsumeTextureCHROMIUMImmediate cmd;
3314 GLbyte data[64];
3317 Mailbox mailbox = Mailbox::Generate();
3318 Cmds expected;
3319 expected.cmd.Init(GL_TEXTURE_2D, mailbox.name);
3320 gl_->ConsumeTextureCHROMIUM(GL_TEXTURE_2D, mailbox.name);
3321 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
3324 TEST_F(GLES2ImplementationTest, CreateAndConsumeTextureCHROMIUM) {
3325 struct Cmds {
3326 cmds::CreateAndConsumeTextureCHROMIUMImmediate cmd;
3327 GLbyte data[64];
3330 Mailbox mailbox = Mailbox::Generate();
3331 Cmds expected;
3332 expected.cmd.Init(GL_TEXTURE_2D, kTexturesStartId, mailbox.name);
3333 GLuint id = gl_->CreateAndConsumeTextureCHROMIUM(GL_TEXTURE_2D, mailbox.name);
3334 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
3335 EXPECT_EQ(kTexturesStartId, id);
3338 TEST_F(GLES2ImplementationTest, ProduceTextureCHROMIUM) {
3339 struct Cmds {
3340 cmds::ProduceTextureCHROMIUMImmediate cmd;
3341 GLbyte data[64];
3344 Mailbox mailbox = Mailbox::Generate();
3345 Cmds expected;
3346 expected.cmd.Init(GL_TEXTURE_2D, mailbox.name);
3347 gl_->ProduceTextureCHROMIUM(GL_TEXTURE_2D, mailbox.name);
3348 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
3351 TEST_F(GLES2ImplementationTest, ProduceTextureDirectCHROMIUM) {
3352 struct Cmds {
3353 cmds::ProduceTextureDirectCHROMIUMImmediate cmd;
3354 GLbyte data[64];
3357 Mailbox mailbox = Mailbox::Generate();
3358 Cmds expected;
3359 expected.cmd.Init(kTexturesStartId, GL_TEXTURE_2D, mailbox.name);
3360 gl_->ProduceTextureDirectCHROMIUM(
3361 kTexturesStartId, GL_TEXTURE_2D, mailbox.name);
3362 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
3365 TEST_F(GLES2ImplementationTest, LimitSizeAndOffsetTo32Bit) {
3366 GLsizeiptr size;
3367 GLintptr offset;
3368 if (sizeof(size) <= 4 || sizeof(offset) <= 4)
3369 return;
3370 // The below two casts should be no-op, as we return early if
3371 // it's 32-bit system.
3372 int64 value64 = 0x100000000;
3373 size = static_cast<GLsizeiptr>(value64);
3374 offset = static_cast<GLintptr>(value64);
3376 const char kSizeOverflowMessage[] = "size more than 32-bit";
3377 const char kOffsetOverflowMessage[] = "offset more than 32-bit";
3379 const GLfloat buf[] = { 1.0, 1.0, 1.0, 1.0 };
3380 const GLubyte indices[] = { 0 };
3382 const GLuint kClientArrayBufferId = 0x789;
3383 const GLuint kClientElementArrayBufferId = 0x790;
3384 gl_->BindBuffer(GL_ARRAY_BUFFER, kClientArrayBufferId);
3385 gl_->BindBuffer(GL_ELEMENT_ARRAY_BUFFER, kClientElementArrayBufferId);
3386 EXPECT_EQ(GL_NO_ERROR, CheckError());
3388 // Call BufferData() should succeed with legal paramaters.
3389 gl_->BufferData(GL_ARRAY_BUFFER, sizeof(buf), buf, GL_DYNAMIC_DRAW);
3390 gl_->BufferData(
3391 GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_DYNAMIC_DRAW);
3392 EXPECT_EQ(GL_NO_ERROR, CheckError());
3394 // BufferData: size
3395 gl_->BufferData(GL_ARRAY_BUFFER, size, buf, GL_DYNAMIC_DRAW);
3396 EXPECT_EQ(GL_INVALID_OPERATION, CheckError());
3397 EXPECT_STREQ(kSizeOverflowMessage, GetLastError().c_str());
3399 // Call BufferSubData() should succeed with legal paramaters.
3400 gl_->BufferSubData(GL_ARRAY_BUFFER, 0, sizeof(buf[0]), buf);
3401 EXPECT_EQ(GL_NO_ERROR, CheckError());
3403 // BufferSubData: offset
3404 gl_->BufferSubData(GL_ARRAY_BUFFER, offset, 1, buf);
3405 EXPECT_EQ(GL_INVALID_OPERATION, CheckError());
3406 EXPECT_STREQ(kOffsetOverflowMessage, GetLastError().c_str());
3408 // BufferSubData: size
3409 EXPECT_EQ(GL_NO_ERROR, CheckError());
3410 gl_->BufferSubData(GL_ARRAY_BUFFER, 0, size, buf);
3411 EXPECT_EQ(GL_INVALID_OPERATION, CheckError());
3412 EXPECT_STREQ(kSizeOverflowMessage, GetLastError().c_str());
3414 // Call MapBufferSubDataCHROMIUM() should succeed with legal paramaters.
3415 void* mem =
3416 gl_->MapBufferSubDataCHROMIUM(GL_ARRAY_BUFFER, 0, 1, GL_WRITE_ONLY);
3417 EXPECT_TRUE(NULL != mem);
3418 EXPECT_EQ(GL_NO_ERROR, CheckError());
3419 gl_->UnmapBufferSubDataCHROMIUM(mem);
3421 // MapBufferSubDataCHROMIUM: offset
3422 EXPECT_TRUE(NULL == gl_->MapBufferSubDataCHROMIUM(
3423 GL_ARRAY_BUFFER, offset, 1, GL_WRITE_ONLY));
3424 EXPECT_EQ(GL_INVALID_OPERATION, CheckError());
3425 EXPECT_STREQ(kOffsetOverflowMessage, GetLastError().c_str());
3427 // MapBufferSubDataCHROMIUM: size
3428 EXPECT_EQ(GL_NO_ERROR, CheckError());
3429 EXPECT_TRUE(NULL == gl_->MapBufferSubDataCHROMIUM(
3430 GL_ARRAY_BUFFER, 0, size, GL_WRITE_ONLY));
3431 EXPECT_EQ(GL_INVALID_OPERATION, CheckError());
3432 EXPECT_STREQ(kSizeOverflowMessage, GetLastError().c_str());
3434 // Call DrawElements() should succeed with legal paramaters.
3435 gl_->DrawElements(GL_POINTS, 1, GL_UNSIGNED_BYTE, NULL);
3436 EXPECT_EQ(GL_NO_ERROR, CheckError());
3438 // DrawElements: offset
3439 gl_->DrawElements(
3440 GL_POINTS, 1, GL_UNSIGNED_BYTE, reinterpret_cast<void*>(offset));
3441 EXPECT_EQ(GL_INVALID_OPERATION, CheckError());
3442 EXPECT_STREQ(kOffsetOverflowMessage, GetLastError().c_str());
3444 // Call DrawElementsInstancedANGLE() should succeed with legal paramaters.
3445 gl_->DrawElementsInstancedANGLE(GL_POINTS, 1, GL_UNSIGNED_BYTE, NULL, 1);
3446 EXPECT_EQ(GL_NO_ERROR, CheckError());
3448 // DrawElementsInstancedANGLE: offset
3449 gl_->DrawElementsInstancedANGLE(
3450 GL_POINTS, 1, GL_UNSIGNED_BYTE, reinterpret_cast<void*>(offset), 1);
3451 EXPECT_EQ(GL_INVALID_OPERATION, CheckError());
3452 EXPECT_STREQ(kOffsetOverflowMessage, GetLastError().c_str());
3454 // Call VertexAttribPointer() should succeed with legal paramaters.
3455 const GLuint kAttribIndex = 1;
3456 const GLsizei kStride = 4;
3457 gl_->VertexAttribPointer(
3458 kAttribIndex, 1, GL_FLOAT, GL_FALSE, kStride, NULL);
3459 EXPECT_EQ(GL_NO_ERROR, CheckError());
3461 // VertexAttribPointer: offset
3462 gl_->VertexAttribPointer(
3463 kAttribIndex, 1, GL_FLOAT, GL_FALSE, kStride,
3464 reinterpret_cast<void*>(offset));
3465 EXPECT_EQ(GL_INVALID_OPERATION, CheckError());
3466 EXPECT_STREQ(kOffsetOverflowMessage, GetLastError().c_str());
3469 TEST_F(GLES2ImplementationTest, TraceBeginCHROMIUM) {
3470 const uint32 kCategoryBucketId = GLES2Implementation::kResultBucketId;
3471 const uint32 kNameBucketId = GLES2Implementation::kResultBucketId + 1;
3472 const std::string category_name = "test category";
3473 const std::string trace_name = "test trace";
3474 const size_t kPaddedString1Size =
3475 transfer_buffer_->RoundToAlignment(category_name.size() + 1);
3476 const size_t kPaddedString2Size =
3477 transfer_buffer_->RoundToAlignment(trace_name.size() + 1);
3479 gl_->TraceBeginCHROMIUM(category_name.c_str(), trace_name.c_str());
3480 EXPECT_EQ(GL_NO_ERROR, CheckError());
3482 struct Cmds {
3483 cmd::SetBucketSize category_size1;
3484 cmd::SetBucketData category_data;
3485 cmd::SetToken set_token1;
3486 cmd::SetBucketSize name_size1;
3487 cmd::SetBucketData name_data;
3488 cmd::SetToken set_token2;
3489 cmds::TraceBeginCHROMIUM trace_call_begin;
3490 cmd::SetBucketSize category_size2;
3491 cmd::SetBucketSize name_size2;
3494 ExpectedMemoryInfo mem1 = GetExpectedMemory(kPaddedString1Size);
3495 ExpectedMemoryInfo mem2 = GetExpectedMemory(kPaddedString2Size);
3497 ASSERT_STREQ(category_name.c_str(), reinterpret_cast<char*>(mem1.ptr));
3498 ASSERT_STREQ(trace_name.c_str(), reinterpret_cast<char*>(mem2.ptr));
3500 Cmds expected;
3501 expected.category_size1.Init(kCategoryBucketId, category_name.size() + 1);
3502 expected.category_data.Init(
3503 kCategoryBucketId, 0, category_name.size() + 1, mem1.id, mem1.offset);
3504 expected.set_token1.Init(GetNextToken());
3505 expected.name_size1.Init(kNameBucketId, trace_name.size() + 1);
3506 expected.name_data.Init(
3507 kNameBucketId, 0, trace_name.size() + 1, mem2.id, mem2.offset);
3508 expected.set_token2.Init(GetNextToken());
3509 expected.trace_call_begin.Init(kCategoryBucketId, kNameBucketId);
3510 expected.category_size2.Init(kCategoryBucketId, 0);
3511 expected.name_size2.Init(kNameBucketId, 0);
3513 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
3516 TEST_F(GLES2ImplementationTest, AllowNestedTracesCHROMIUM) {
3517 const std::string category1_name = "test category 1";
3518 const std::string trace1_name = "test trace 1";
3519 const std::string category2_name = "test category 2";
3520 const std::string trace2_name = "test trace 2";
3522 gl_->TraceBeginCHROMIUM(category1_name.c_str(), trace1_name.c_str());
3523 EXPECT_EQ(GL_NO_ERROR, CheckError());
3525 gl_->TraceBeginCHROMIUM(category2_name.c_str(), trace2_name.c_str());
3526 EXPECT_EQ(GL_NO_ERROR, CheckError());
3528 gl_->TraceEndCHROMIUM();
3529 EXPECT_EQ(GL_NO_ERROR, CheckError());
3531 gl_->TraceEndCHROMIUM();
3532 EXPECT_EQ(GL_NO_ERROR, CheckError());
3534 // No more corresponding begin tracer marker should error.
3535 gl_->TraceEndCHROMIUM();
3536 EXPECT_EQ(GL_INVALID_OPERATION, CheckError());
3539 TEST_F(GLES2ImplementationTest, IsEnabled) {
3540 // If we use a valid enum, its state is cached on client side, so no command
3541 // is actually generated, and this test will fail.
3542 // TODO(zmo): it seems we never need the command. Maybe remove it.
3543 GLenum kCap = 1;
3544 struct Cmds {
3545 cmds::IsEnabled cmd;
3548 Cmds expected;
3549 ExpectedMemoryInfo result1 =
3550 GetExpectedResultMemory(sizeof(cmds::IsEnabled::Result));
3551 expected.cmd.Init(kCap, result1.id, result1.offset);
3553 EXPECT_CALL(*command_buffer(), OnFlush())
3554 .WillOnce(SetMemory(result1.ptr, uint32_t(GL_TRUE)))
3555 .RetiresOnSaturation();
3557 GLboolean result = gl_->IsEnabled(kCap);
3558 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
3559 EXPECT_TRUE(result);
3562 TEST_F(GLES2ImplementationTest, ClientWaitSync) {
3563 const GLuint client_sync_id = 36;
3564 struct Cmds {
3565 cmds::ClientWaitSync cmd;
3568 Cmds expected;
3569 ExpectedMemoryInfo result1 =
3570 GetExpectedResultMemory(sizeof(cmds::ClientWaitSync::Result));
3571 const GLuint64 kTimeout = 0xABCDEF0123456789;
3572 uint32_t v32_0 = 0, v32_1 = 0;
3573 GLES2Util::MapUint64ToTwoUint32(kTimeout, &v32_0, &v32_1);
3574 expected.cmd.Init(client_sync_id, GL_SYNC_FLUSH_COMMANDS_BIT,
3575 v32_0, v32_1, result1.id, result1.offset);
3577 EXPECT_CALL(*command_buffer(), OnFlush())
3578 .WillOnce(SetMemory(result1.ptr, uint32_t(GL_CONDITION_SATISFIED)))
3579 .RetiresOnSaturation();
3581 GLenum result = gl_->ClientWaitSync(
3582 reinterpret_cast<GLsync>(client_sync_id), GL_SYNC_FLUSH_COMMANDS_BIT,
3583 kTimeout);
3584 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
3585 EXPECT_EQ(static_cast<GLenum>(GL_CONDITION_SATISFIED), result);
3588 TEST_F(GLES2ImplementationTest, WaitSync) {
3589 const GLuint kClientSyncId = 36;
3590 struct Cmds {
3591 cmds::WaitSync cmd;
3593 Cmds expected;
3594 const GLuint64 kTimeout = GL_TIMEOUT_IGNORED;
3595 uint32_t v32_0 = 0, v32_1 = 0;
3596 GLES2Util::MapUint64ToTwoUint32(kTimeout, &v32_0, &v32_1);
3597 expected.cmd.Init(kClientSyncId, 0, v32_0, v32_1);
3599 gl_->WaitSync(reinterpret_cast<GLsync>(kClientSyncId), 0, kTimeout);
3600 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
3603 TEST_F(GLES2ImplementationTest, MapBufferRangeUnmapBufferWrite) {
3604 ExpectedMemoryInfo result =
3605 GetExpectedResultMemory(sizeof(cmds::MapBufferRange::Result));
3607 EXPECT_CALL(*command_buffer(), OnFlush())
3608 .WillOnce(SetMemory(result.ptr, uint32_t(1)))
3609 .RetiresOnSaturation();
3611 const GLuint kBufferId = 123;
3612 gl_->BindBuffer(GL_ARRAY_BUFFER, kBufferId);
3614 void* mem = gl_->MapBufferRange(GL_ARRAY_BUFFER, 10, 64, GL_MAP_WRITE_BIT);
3615 EXPECT_TRUE(mem != nullptr);
3617 EXPECT_TRUE(gl_->UnmapBuffer(GL_ARRAY_BUFFER));
3620 TEST_F(GLES2ImplementationTest, MapBufferRangeWriteWithInvalidateBit) {
3621 ExpectedMemoryInfo result =
3622 GetExpectedResultMemory(sizeof(cmds::MapBufferRange::Result));
3624 EXPECT_CALL(*command_buffer(), OnFlush())
3625 .WillOnce(SetMemory(result.ptr, uint32_t(1)))
3626 .RetiresOnSaturation();
3628 const GLuint kBufferId = 123;
3629 gl_->BindBuffer(GL_ARRAY_BUFFER, kBufferId);
3631 GLsizeiptr kSize = 64;
3632 void* mem = gl_->MapBufferRange(
3633 GL_ARRAY_BUFFER, 10, kSize,
3634 GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_RANGE_BIT);
3635 EXPECT_TRUE(mem != nullptr);
3636 std::vector<int8_t> zero(kSize);
3637 memset(&zero[0], 0, kSize);
3638 EXPECT_EQ(0, memcmp(mem, &zero[0], kSize));
3641 TEST_F(GLES2ImplementationTest, MapBufferRangeWriteWithGLError) {
3642 ExpectedMemoryInfo result =
3643 GetExpectedResultMemory(sizeof(cmds::MapBufferRange::Result));
3645 // Return a result of 0 to indicate an GL error.
3646 EXPECT_CALL(*command_buffer(), OnFlush())
3647 .WillOnce(SetMemory(result.ptr, uint32_t(0)))
3648 .RetiresOnSaturation();
3650 const GLuint kBufferId = 123;
3651 gl_->BindBuffer(GL_ARRAY_BUFFER, kBufferId);
3653 void* mem = gl_->MapBufferRange(GL_ARRAY_BUFFER, 10, 64, GL_MAP_WRITE_BIT);
3654 EXPECT_TRUE(mem == nullptr);
3657 TEST_F(GLES2ImplementationTest, MapBufferRangeUnmapBufferRead) {
3658 ExpectedMemoryInfo result =
3659 GetExpectedResultMemory(sizeof(cmds::MapBufferRange::Result));
3661 EXPECT_CALL(*command_buffer(), OnFlush())
3662 .WillOnce(SetMemory(result.ptr, uint32_t(1)))
3663 .RetiresOnSaturation();
3665 const GLuint kBufferId = 123;
3666 gl_->BindBuffer(GL_ARRAY_BUFFER, kBufferId);
3668 void* mem = gl_->MapBufferRange(GL_ARRAY_BUFFER, 10, 64, GL_MAP_READ_BIT);
3669 EXPECT_TRUE(mem != nullptr);
3671 EXPECT_TRUE(gl_->UnmapBuffer(GL_ARRAY_BUFFER));
3674 TEST_F(GLES2ImplementationTest, MapBufferRangeReadWithGLError) {
3675 ExpectedMemoryInfo result =
3676 GetExpectedResultMemory(sizeof(cmds::MapBufferRange::Result));
3678 // Return a result of 0 to indicate an GL error.
3679 EXPECT_CALL(*command_buffer(), OnFlush())
3680 .WillOnce(SetMemory(result.ptr, uint32_t(0)))
3681 .RetiresOnSaturation();
3683 const GLuint kBufferId = 123;
3684 gl_->BindBuffer(GL_ARRAY_BUFFER, kBufferId);
3686 void* mem = gl_->MapBufferRange(GL_ARRAY_BUFFER, 10, 64, GL_MAP_READ_BIT);
3687 EXPECT_TRUE(mem == nullptr);
3690 TEST_F(GLES2ImplementationTest, UnmapBufferFails) {
3691 // No bound buffer.
3692 EXPECT_FALSE(gl_->UnmapBuffer(GL_ARRAY_BUFFER));
3693 EXPECT_EQ(GL_INVALID_OPERATION, CheckError());
3695 const GLuint kBufferId = 123;
3696 gl_->BindBuffer(GL_ARRAY_BUFFER, kBufferId);
3698 // Buffer is unmapped.
3699 EXPECT_FALSE(gl_->UnmapBuffer(GL_ARRAY_BUFFER));
3700 EXPECT_EQ(GL_INVALID_OPERATION, CheckError());
3703 TEST_F(GLES2ImplementationTest, BufferDataUnmapsDataStore) {
3704 ExpectedMemoryInfo result =
3705 GetExpectedResultMemory(sizeof(cmds::MapBufferRange::Result));
3707 EXPECT_CALL(*command_buffer(), OnFlush())
3708 .WillOnce(SetMemory(result.ptr, uint32_t(1)))
3709 .RetiresOnSaturation();
3711 const GLuint kBufferId = 123;
3712 gl_->BindBuffer(GL_ARRAY_BUFFER, kBufferId);
3714 void* mem = gl_->MapBufferRange(GL_ARRAY_BUFFER, 10, 64, GL_MAP_WRITE_BIT);
3715 EXPECT_TRUE(mem != nullptr);
3717 std::vector<uint8_t> data(16);
3718 // BufferData unmaps the data store.
3719 gl_->BufferData(GL_ARRAY_BUFFER, 16, &data[0], GL_STREAM_DRAW);
3721 EXPECT_FALSE(gl_->UnmapBuffer(GL_ARRAY_BUFFER));
3722 EXPECT_EQ(GL_INVALID_OPERATION, CheckError());
3725 TEST_F(GLES2ImplementationTest, DeleteBuffersUnmapsDataStore) {
3726 ExpectedMemoryInfo result =
3727 GetExpectedResultMemory(sizeof(cmds::MapBufferRange::Result));
3729 EXPECT_CALL(*command_buffer(), OnFlush())
3730 .WillOnce(SetMemory(result.ptr, uint32_t(1)))
3731 .RetiresOnSaturation();
3733 const GLuint kBufferId = 123;
3734 gl_->BindBuffer(GL_ARRAY_BUFFER, kBufferId);
3736 void* mem = gl_->MapBufferRange(GL_ARRAY_BUFFER, 10, 64, GL_MAP_WRITE_BIT);
3737 EXPECT_TRUE(mem != nullptr);
3739 std::vector<uint8_t> data(16);
3740 // DeleteBuffers unmaps the data store.
3741 gl_->DeleteBuffers(1, &kBufferId);
3743 EXPECT_FALSE(gl_->UnmapBuffer(GL_ARRAY_BUFFER));
3744 EXPECT_EQ(GL_INVALID_OPERATION, CheckError());
3747 TEST_F(GLES2ImplementationManualInitTest, LoseContextOnOOM) {
3748 ContextInitOptions init_options;
3749 init_options.lose_context_when_out_of_memory = true;
3750 ASSERT_TRUE(Initialize(init_options));
3752 struct Cmds {
3753 cmds::LoseContextCHROMIUM cmd;
3756 GLsizei max = std::numeric_limits<GLsizei>::max();
3757 EXPECT_CALL(*gpu_control_, CreateGpuMemoryBufferImage(max, max, _, _))
3758 .WillOnce(Return(-1));
3759 gl_->CreateGpuMemoryBufferImageCHROMIUM(max, max, GL_RGBA, GL_MAP_CHROMIUM);
3760 // The context should be lost.
3761 Cmds expected;
3762 expected.cmd.Init(GL_GUILTY_CONTEXT_RESET_ARB, GL_UNKNOWN_CONTEXT_RESET_ARB);
3763 EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
3766 TEST_F(GLES2ImplementationManualInitTest, NoLoseContextOnOOM) {
3767 ContextInitOptions init_options;
3768 ASSERT_TRUE(Initialize(init_options));
3770 struct Cmds {
3771 cmds::LoseContextCHROMIUM cmd;
3774 GLsizei max = std::numeric_limits<GLsizei>::max();
3775 EXPECT_CALL(*gpu_control_, CreateGpuMemoryBufferImage(max, max, _, _))
3776 .WillOnce(Return(-1));
3777 gl_->CreateGpuMemoryBufferImageCHROMIUM(max, max, GL_RGBA, GL_MAP_CHROMIUM);
3778 // The context should not be lost.
3779 EXPECT_TRUE(NoCommandsWritten());
3782 TEST_F(GLES2ImplementationManualInitTest, FailInitOnBGRMismatch1) {
3783 ContextInitOptions init_options;
3784 init_options.bind_generates_resource_client = false;
3785 init_options.bind_generates_resource_service = true;
3786 EXPECT_FALSE(Initialize(init_options));
3789 TEST_F(GLES2ImplementationManualInitTest, FailInitOnBGRMismatch2) {
3790 ContextInitOptions init_options;
3791 init_options.bind_generates_resource_client = true;
3792 init_options.bind_generates_resource_service = false;
3793 EXPECT_FALSE(Initialize(init_options));
3796 TEST_F(GLES2ImplementationManualInitTest, FailInitOnTransferBufferFail) {
3797 ContextInitOptions init_options;
3798 init_options.transfer_buffer_initialize_fail = true;
3799 EXPECT_FALSE(Initialize(init_options));
3802 #include "gpu/command_buffer/client/gles2_implementation_unittest_autogen.h"
3804 } // namespace gles2
3805 } // namespace gpu