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