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 QueryTracker
* GetQueryTracker() {
548 return gl_
->query_tracker_
.get();
551 struct ContextInitOptions
{
553 : bind_generates_resource_client(true),
554 bind_generates_resource_service(true),
555 lose_context_when_out_of_memory(false),
556 transfer_buffer_initialize_fail(false),
558 occlusion_query_boolean(true),
559 timer_queries(true) {}
561 bool bind_generates_resource_client
;
562 bool bind_generates_resource_service
;
563 bool lose_context_when_out_of_memory
;
564 bool transfer_buffer_initialize_fail
;
566 bool occlusion_query_boolean
;
570 bool Initialize(const ContextInitOptions
& init_options
) {
572 share_group_
= new ShareGroup(init_options
.bind_generates_resource_client
);
574 for (int i
= 0; i
< kNumTestContexts
; i
++) {
575 if (!test_contexts_
[i
].Initialize(
577 init_options
.bind_generates_resource_client
,
578 init_options
.bind_generates_resource_service
,
579 init_options
.lose_context_when_out_of_memory
,
580 init_options
.transfer_buffer_initialize_fail
,
581 init_options
.sync_query
,
582 init_options
.occlusion_query_boolean
,
583 init_options
.timer_queries
))
587 // Default to test context 0.
588 gpu_control_
= test_contexts_
[0].gpu_control_
.get();
589 helper_
= test_contexts_
[0].helper_
.get();
590 transfer_buffer_
= test_contexts_
[0].transfer_buffer_
.get();
591 gl_
= test_contexts_
[0].gl_
.get();
592 commands_
= test_contexts_
[0].commands_
;
596 MockClientCommandBuffer
* command_buffer() const {
597 return test_contexts_
[0].command_buffer_
.get();
600 int GetNextToken() { return test_contexts_
[0].GetNextToken(); }
602 const void* GetPut() {
603 return helper_
->GetSpace(0);
606 void ClearCommands() {
607 scoped_refptr
<Buffer
> ring_buffer
= helper_
->get_ring_buffer();
608 memset(ring_buffer
->memory(), kInitialValue
, ring_buffer
->size());
611 size_t MaxTransferBufferSize() {
612 return transfer_buffer_
->MaxTransferBufferSize();
615 void SetMappedMemoryLimit(size_t limit
) {
616 gl_
->mapped_memory_
->set_max_allocated_bytes(limit
);
619 ExpectedMemoryInfo
GetExpectedMemory(size_t size
) {
620 return transfer_buffer_
->GetExpectedMemory(size
);
623 ExpectedMemoryInfo
GetExpectedResultMemory(size_t size
) {
624 return transfer_buffer_
->GetExpectedResultMemory(size
);
627 ExpectedMemoryInfo
GetExpectedMappedMemory(size_t size
) {
628 ExpectedMemoryInfo mem
;
630 // Temporarily allocate memory and expect that memory block to be reused.
631 mem
.ptr
= static_cast<uint8
*>(gl_
->mapped_memory_
->Alloc(size
,
634 gl_
->mapped_memory_
->Free(mem
.ptr
);
639 // Sets the ProgramInfoManager. The manager will be owned
640 // by the ShareGroup.
641 void SetProgramInfoManager(ProgramInfoManager
* manager
) {
642 gl_
->share_group()->set_program_info_manager(manager
);
646 ExpectedMemoryInfo result
=
647 GetExpectedResultMemory(sizeof(cmds::GetError::Result
));
648 EXPECT_CALL(*command_buffer(), OnFlush())
649 .WillOnce(SetMemory(result
.ptr
, GLuint(GL_NO_ERROR
)))
650 .RetiresOnSaturation();
651 return gl_
->GetError();
654 const std::string
& GetLastError() {
655 return gl_
->GetLastError();
658 bool GetBucketContents(uint32 bucket_id
, std::vector
<int8
>* data
) {
659 return gl_
->GetBucketContents(bucket_id
, data
);
662 TestContext test_contexts_
[kNumTestContexts
];
664 scoped_refptr
<ShareGroup
> share_group_
;
665 MockClientGpuControl
* gpu_control_
;
666 GLES2CmdHelper
* helper_
;
667 MockTransferBuffer
* transfer_buffer_
;
668 GLES2Implementation
* gl_
;
669 CommandBufferEntry
* commands_
;
672 void GLES2ImplementationTest::SetUp() {
673 ContextInitOptions init_options
;
674 ASSERT_TRUE(Initialize(init_options
));
677 void GLES2ImplementationTest::TearDown() {
678 for (int i
= 0; i
< kNumTestContexts
; i
++)
679 test_contexts_
[i
].TearDown();
682 class GLES2ImplementationManualInitTest
: public GLES2ImplementationTest
{
684 void SetUp() override
{}
687 class GLES2ImplementationStrictSharedTest
: public GLES2ImplementationTest
{
689 void SetUp() override
;
691 template <class ResApi
>
692 void FlushGenerationTest() {
693 GLuint id1
, id2
, id3
;
695 // Generate valid id.
696 ResApi::Gen(gl_
, 1, &id1
);
699 // Delete id1 and generate id2. id1 should not be reused.
700 ResApi::Delete(gl_
, 1, &id1
);
701 ResApi::Gen(gl_
, 1, &id2
);
705 // Expect id1 reuse after Flush.
707 ResApi::Gen(gl_
, 1, &id3
);
711 // Ids should not be reused unless the |Deleting| context does a Flush()
712 // AND triggers a lazy release after that.
713 template <class ResApi
>
714 void CrossContextGenerationTest() {
715 GLES2Implementation
* gl1
= test_contexts_
[0].gl_
.get();
716 GLES2Implementation
* gl2
= test_contexts_
[1].gl_
.get();
717 GLuint id1
, id2
, id3
;
719 // Delete, no flush on context 1. No reuse.
720 ResApi::Gen(gl1
, 1, &id1
);
721 ResApi::Delete(gl1
, 1, &id1
);
722 ResApi::Gen(gl1
, 1, &id2
);
725 // Flush context 2. Still no reuse.
727 ResApi::Gen(gl2
, 1, &id3
);
731 // Flush on context 1, but no lazy release. Still no reuse.
733 ResApi::Gen(gl2
, 1, &id3
);
736 // Lazy release triggered by another Delete. Should reuse id1.
737 ResApi::Delete(gl1
, 1, &id2
);
738 ResApi::Gen(gl2
, 1, &id3
);
742 // Same as CrossContextGenerationTest(), but triggers an Auto Flush on
743 // the Delete(). Tests an edge case regression.
744 template <class ResApi
>
745 void CrossContextGenerationAutoFlushTest() {
746 GLES2Implementation
* gl1
= test_contexts_
[0].gl_
.get();
747 GLES2Implementation
* gl2
= test_contexts_
[1].gl_
.get();
748 GLuint id1
, id2
, id3
;
750 // Delete, no flush on context 1. No reuse.
751 // By half filling the buffer, an internal flush is forced on the Delete().
752 ResApi::Gen(gl1
, 1, &id1
);
753 gl1
->helper()->Noop(kNumCommandEntries
/ 2);
754 ResApi::Delete(gl1
, 1, &id1
);
755 ResApi::Gen(gl1
, 1, &id2
);
758 // Flush context 2. Still no reuse.
760 ResApi::Gen(gl2
, 1, &id3
);
764 // Flush on context 1, but no lazy release. Still no reuse.
766 ResApi::Gen(gl2
, 1, &id3
);
769 // Lazy release triggered by another Delete. Should reuse id1.
770 ResApi::Delete(gl1
, 1, &id2
);
771 ResApi::Gen(gl2
, 1, &id3
);
776 void GLES2ImplementationStrictSharedTest::SetUp() {
777 ContextInitOptions init_options
;
778 init_options
.bind_generates_resource_client
= false;
779 init_options
.bind_generates_resource_service
= false;
780 ASSERT_TRUE(Initialize(init_options
));
783 // GCC requires these declarations, but MSVC requires they not be present
785 const uint8
GLES2ImplementationTest::kInitialValue
;
786 const int32
GLES2ImplementationTest::kNumCommandEntries
;
787 const int32
GLES2ImplementationTest::kCommandBufferSizeBytes
;
788 const size_t GLES2ImplementationTest::kTransferBufferSize
;
789 const GLint
GLES2ImplementationTest::kMaxCombinedTextureImageUnits
;
790 const GLint
GLES2ImplementationTest::kMaxCubeMapTextureSize
;
791 const GLint
GLES2ImplementationTest::kMaxFragmentUniformVectors
;
792 const GLint
GLES2ImplementationTest::kMaxRenderbufferSize
;
793 const GLint
GLES2ImplementationTest::kMaxTextureImageUnits
;
794 const GLint
GLES2ImplementationTest::kMaxTextureSize
;
795 const GLint
GLES2ImplementationTest::kMaxVaryingVectors
;
796 const GLint
GLES2ImplementationTest::kMaxVertexAttribs
;
797 const GLint
GLES2ImplementationTest::kMaxVertexTextureImageUnits
;
798 const GLint
GLES2ImplementationTest::kMaxVertexUniformVectors
;
799 const GLint
GLES2ImplementationTest::kNumCompressedTextureFormats
;
800 const GLint
GLES2ImplementationTest::kNumShaderBinaryFormats
;
801 const GLuint
GLES2ImplementationTest::kStartId
;
802 const GLuint
GLES2ImplementationTest::kBuffersStartId
;
803 const GLuint
GLES2ImplementationTest::kFramebuffersStartId
;
804 const GLuint
GLES2ImplementationTest::kProgramsAndShadersStartId
;
805 const GLuint
GLES2ImplementationTest::kRenderbuffersStartId
;
806 const GLuint
GLES2ImplementationTest::kSamplersStartId
;
807 const GLuint
GLES2ImplementationTest::kTexturesStartId
;
808 const GLuint
GLES2ImplementationTest::kTransformFeedbacksStartId
;
809 const GLuint
GLES2ImplementationTest::kQueriesStartId
;
810 const GLuint
GLES2ImplementationTest::kVertexArraysStartId
;
811 const GLuint
GLES2ImplementationTest::kValuebuffersStartId
;
814 TEST_F(GLES2ImplementationTest
, Basic
) {
815 EXPECT_TRUE(gl_
->share_group() != NULL
);
818 TEST_F(GLES2ImplementationTest
, GetBucketContents
) {
819 const uint32 kBucketId
= GLES2Implementation::kResultBucketId
;
820 const uint32 kTestSize
= MaxTransferBufferSize() + 32;
822 scoped_ptr
<uint8
[]> buf(new uint8
[kTestSize
]);
823 uint8
* expected_data
= buf
.get();
824 for (uint32 ii
= 0; ii
< kTestSize
; ++ii
) {
825 expected_data
[ii
] = ii
* 3;
829 cmd::GetBucketStart get_bucket_start
;
830 cmd::SetToken set_token1
;
831 cmd::GetBucketData get_bucket_data
;
832 cmd::SetToken set_token2
;
833 cmd::SetBucketSize set_bucket_size2
;
836 ExpectedMemoryInfo mem1
= GetExpectedMemory(MaxTransferBufferSize());
837 ExpectedMemoryInfo result1
= GetExpectedResultMemory(sizeof(uint32
));
838 ExpectedMemoryInfo mem2
= GetExpectedMemory(
839 kTestSize
- MaxTransferBufferSize());
842 expected
.get_bucket_start
.Init(
843 kBucketId
, result1
.id
, result1
.offset
,
844 MaxTransferBufferSize(), mem1
.id
, mem1
.offset
);
845 expected
.set_token1
.Init(GetNextToken());
846 expected
.get_bucket_data
.Init(
847 kBucketId
, MaxTransferBufferSize(),
848 kTestSize
- MaxTransferBufferSize(), mem2
.id
, mem2
.offset
);
849 expected
.set_bucket_size2
.Init(kBucketId
, 0);
850 expected
.set_token2
.Init(GetNextToken());
852 EXPECT_CALL(*command_buffer(), OnFlush())
854 SetMemory(result1
.ptr
, kTestSize
),
856 mem1
.ptr
, expected_data
, MaxTransferBufferSize())))
857 .WillOnce(SetMemoryFromArray(
858 mem2
.ptr
, expected_data
+ MaxTransferBufferSize(),
859 kTestSize
- MaxTransferBufferSize()))
860 .RetiresOnSaturation();
862 std::vector
<int8
> data
;
863 GetBucketContents(kBucketId
, &data
);
864 EXPECT_EQ(0, memcmp(&expected
, commands_
, sizeof(expected
)));
865 ASSERT_EQ(kTestSize
, data
.size());
866 EXPECT_EQ(0, memcmp(expected_data
, &data
[0], data
.size()));
869 TEST_F(GLES2ImplementationTest
, GetShaderPrecisionFormat
) {
871 cmds::GetShaderPrecisionFormat cmd
;
873 typedef cmds::GetShaderPrecisionFormat::Result Result
;
874 const unsigned kDummyType1
= 3;
875 const unsigned kDummyType2
= 4;
877 // The first call for dummy type 1 should trigger a command buffer request.
878 GLint range1
[2] = {0, 0};
879 GLint precision1
= 0;
881 ExpectedMemoryInfo client_result1
= GetExpectedResultMemory(4);
882 expected1
.cmd
.Init(GL_FRAGMENT_SHADER
, kDummyType1
, client_result1
.id
,
883 client_result1
.offset
);
884 Result server_result1
= {true, 14, 14, 10};
885 EXPECT_CALL(*command_buffer(), OnFlush())
886 .WillOnce(SetMemory(client_result1
.ptr
, server_result1
))
887 .RetiresOnSaturation();
888 gl_
->GetShaderPrecisionFormat(GL_FRAGMENT_SHADER
, kDummyType1
, range1
,
890 const void* commands2
= GetPut();
891 EXPECT_NE(commands_
, commands2
);
892 EXPECT_EQ(0, memcmp(&expected1
, commands_
, sizeof(expected1
)));
893 EXPECT_EQ(range1
[0], 14);
894 EXPECT_EQ(range1
[1], 14);
895 EXPECT_EQ(precision1
, 10);
897 // The second call for dummy type 1 should use the cached value and avoid
898 // triggering a command buffer request, so we do not expect a call to
899 // OnFlush() here. We do expect the results to be correct though.
900 GLint range2
[2] = {0, 0};
901 GLint precision2
= 0;
902 gl_
->GetShaderPrecisionFormat(GL_FRAGMENT_SHADER
, kDummyType1
, range2
,
904 const void* commands3
= GetPut();
905 EXPECT_EQ(commands2
, commands3
);
906 EXPECT_EQ(range2
[0], 14);
907 EXPECT_EQ(range2
[1], 14);
908 EXPECT_EQ(precision2
, 10);
910 // If we then make a request for dummy type 2, we should get another command
911 // buffer request since it hasn't been cached yet.
912 GLint range3
[2] = {0, 0};
913 GLint precision3
= 0;
915 ExpectedMemoryInfo result3
= GetExpectedResultMemory(4);
916 expected3
.cmd
.Init(GL_FRAGMENT_SHADER
, kDummyType2
, result3
.id
,
918 Result result3_source
= {true, 62, 62, 16};
919 EXPECT_CALL(*command_buffer(), OnFlush())
920 .WillOnce(SetMemory(result3
.ptr
, result3_source
))
921 .RetiresOnSaturation();
922 gl_
->GetShaderPrecisionFormat(GL_FRAGMENT_SHADER
, kDummyType2
, range3
,
924 const void* commands4
= GetPut();
925 EXPECT_NE(commands3
, commands4
);
926 EXPECT_EQ(0, memcmp(&expected3
, commands3
, sizeof(expected3
)));
927 EXPECT_EQ(range3
[0], 62);
928 EXPECT_EQ(range3
[1], 62);
929 EXPECT_EQ(precision3
, 16);
931 // Any call for predefined types should use the cached value from the
932 // Capabilities and avoid triggering a command buffer request, so we do not
933 // expect a call to OnFlush() here. We do expect the results to be correct
935 GLint range4
[2] = {0, 0};
936 GLint precision4
= 0;
937 gl_
->GetShaderPrecisionFormat(GL_FRAGMENT_SHADER
, GL_MEDIUM_FLOAT
, range4
,
939 const void* commands5
= GetPut();
940 EXPECT_EQ(commands4
, commands5
);
941 EXPECT_EQ(range4
[0], 3);
942 EXPECT_EQ(range4
[1], 5);
943 EXPECT_EQ(precision4
, 7);
946 TEST_F(GLES2ImplementationTest
, GetShaderSource
) {
947 const uint32 kBucketId
= GLES2Implementation::kResultBucketId
;
948 const GLuint kShaderId
= 456;
949 const Str7 kString
= {"foobar"};
950 const char kBad
= 0x12;
952 cmd::SetBucketSize set_bucket_size1
;
953 cmds::GetShaderSource get_shader_source
;
954 cmd::GetBucketStart get_bucket_start
;
955 cmd::SetToken set_token1
;
956 cmd::SetBucketSize set_bucket_size2
;
959 ExpectedMemoryInfo mem1
= GetExpectedMemory(MaxTransferBufferSize());
960 ExpectedMemoryInfo result1
= GetExpectedResultMemory(sizeof(uint32
));
963 expected
.set_bucket_size1
.Init(kBucketId
, 0);
964 expected
.get_shader_source
.Init(kShaderId
, kBucketId
);
965 expected
.get_bucket_start
.Init(
966 kBucketId
, result1
.id
, result1
.offset
,
967 MaxTransferBufferSize(), mem1
.id
, mem1
.offset
);
968 expected
.set_token1
.Init(GetNextToken());
969 expected
.set_bucket_size2
.Init(kBucketId
, 0);
970 char buf
[sizeof(kString
) + 1];
971 memset(buf
, kBad
, sizeof(buf
));
973 EXPECT_CALL(*command_buffer(), OnFlush())
974 .WillOnce(DoAll(SetMemory(result1
.ptr
, uint32(sizeof(kString
))),
975 SetMemory(mem1
.ptr
, kString
)))
976 .RetiresOnSaturation();
979 gl_
->GetShaderSource(kShaderId
, sizeof(buf
), &length
, buf
);
980 EXPECT_EQ(0, memcmp(&expected
, commands_
, sizeof(expected
)));
981 EXPECT_EQ(sizeof(kString
) - 1, static_cast<size_t>(length
));
982 EXPECT_STREQ(kString
.str
, buf
);
983 EXPECT_EQ(buf
[sizeof(kString
)], kBad
);
986 #if defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS)
988 TEST_F(GLES2ImplementationTest
, DrawArraysClientSideBuffers
) {
989 static const float verts
[][4] = {
990 { 12.0f
, 23.0f
, 34.0f
, 45.0f
, },
991 { 56.0f
, 67.0f
, 78.0f
, 89.0f
, },
992 { 13.0f
, 24.0f
, 35.0f
, 46.0f
, },
995 cmds::EnableVertexAttribArray enable1
;
996 cmds::EnableVertexAttribArray enable2
;
997 cmds::BindBuffer bind_to_emu
;
998 cmds::BufferData set_size
;
999 cmds::BufferSubData copy_data1
;
1000 cmd::SetToken set_token1
;
1001 cmds::VertexAttribPointer set_pointer1
;
1002 cmds::BufferSubData copy_data2
;
1003 cmd::SetToken set_token2
;
1004 cmds::VertexAttribPointer set_pointer2
;
1005 cmds::DrawArrays draw
;
1006 cmds::BindBuffer restore
;
1008 const GLuint kEmuBufferId
= GLES2Implementation::kClientSideArrayId
;
1009 const GLuint kAttribIndex1
= 1;
1010 const GLuint kAttribIndex2
= 3;
1011 const GLint kNumComponents1
= 3;
1012 const GLint kNumComponents2
= 2;
1013 const GLsizei kClientStride
= sizeof(verts
[0]);
1014 const GLint kFirst
= 1;
1015 const GLsizei kCount
= 2;
1016 const GLsizei kSize1
=
1017 arraysize(verts
) * kNumComponents1
* sizeof(verts
[0][0]);
1018 const GLsizei kSize2
=
1019 arraysize(verts
) * kNumComponents2
* sizeof(verts
[0][0]);
1020 const GLsizei kEmuOffset1
= 0;
1021 const GLsizei kEmuOffset2
= kSize1
;
1022 const GLsizei kTotalSize
= kSize1
+ kSize2
;
1024 ExpectedMemoryInfo mem1
= GetExpectedMemory(kSize1
);
1025 ExpectedMemoryInfo mem2
= GetExpectedMemory(kSize2
);
1028 expected
.enable1
.Init(kAttribIndex1
);
1029 expected
.enable2
.Init(kAttribIndex2
);
1030 expected
.bind_to_emu
.Init(GL_ARRAY_BUFFER
, kEmuBufferId
);
1031 expected
.set_size
.Init(GL_ARRAY_BUFFER
, kTotalSize
, 0, 0, GL_DYNAMIC_DRAW
);
1032 expected
.copy_data1
.Init(
1033 GL_ARRAY_BUFFER
, kEmuOffset1
, kSize1
, mem1
.id
, mem1
.offset
);
1034 expected
.set_token1
.Init(GetNextToken());
1035 expected
.set_pointer1
.Init(
1036 kAttribIndex1
, kNumComponents1
, GL_FLOAT
, GL_FALSE
, 0, kEmuOffset1
);
1037 expected
.copy_data2
.Init(
1038 GL_ARRAY_BUFFER
, kEmuOffset2
, kSize2
, mem2
.id
, mem2
.offset
);
1039 expected
.set_token2
.Init(GetNextToken());
1040 expected
.set_pointer2
.Init(
1041 kAttribIndex2
, kNumComponents2
, GL_FLOAT
, GL_FALSE
, 0, kEmuOffset2
);
1042 expected
.draw
.Init(GL_POINTS
, kFirst
, kCount
);
1043 expected
.restore
.Init(GL_ARRAY_BUFFER
, 0);
1044 gl_
->EnableVertexAttribArray(kAttribIndex1
);
1045 gl_
->EnableVertexAttribArray(kAttribIndex2
);
1046 gl_
->VertexAttribPointer(
1047 kAttribIndex1
, kNumComponents1
, GL_FLOAT
, GL_FALSE
, kClientStride
, verts
);
1048 gl_
->VertexAttribPointer(
1049 kAttribIndex2
, kNumComponents2
, GL_FLOAT
, GL_FALSE
, kClientStride
, verts
);
1050 gl_
->DrawArrays(GL_POINTS
, kFirst
, kCount
);
1051 EXPECT_EQ(0, memcmp(&expected
, commands_
, sizeof(expected
)));
1054 TEST_F(GLES2ImplementationTest
, DrawArraysInstancedANGLEClientSideBuffers
) {
1055 static const float verts
[][4] = {
1056 { 12.0f
, 23.0f
, 34.0f
, 45.0f
, },
1057 { 56.0f
, 67.0f
, 78.0f
, 89.0f
, },
1058 { 13.0f
, 24.0f
, 35.0f
, 46.0f
, },
1061 cmds::EnableVertexAttribArray enable1
;
1062 cmds::EnableVertexAttribArray enable2
;
1063 cmds::VertexAttribDivisorANGLE divisor
;
1064 cmds::BindBuffer bind_to_emu
;
1065 cmds::BufferData set_size
;
1066 cmds::BufferSubData copy_data1
;
1067 cmd::SetToken set_token1
;
1068 cmds::VertexAttribPointer set_pointer1
;
1069 cmds::BufferSubData copy_data2
;
1070 cmd::SetToken set_token2
;
1071 cmds::VertexAttribPointer set_pointer2
;
1072 cmds::DrawArraysInstancedANGLE draw
;
1073 cmds::BindBuffer restore
;
1075 const GLuint kEmuBufferId
= GLES2Implementation::kClientSideArrayId
;
1076 const GLuint kAttribIndex1
= 1;
1077 const GLuint kAttribIndex2
= 3;
1078 const GLint kNumComponents1
= 3;
1079 const GLint kNumComponents2
= 2;
1080 const GLsizei kClientStride
= sizeof(verts
[0]);
1081 const GLint kFirst
= 1;
1082 const GLsizei kCount
= 2;
1083 const GLuint kDivisor
= 1;
1084 const GLsizei kSize1
=
1085 arraysize(verts
) * kNumComponents1
* sizeof(verts
[0][0]);
1086 const GLsizei kSize2
=
1087 1 * kNumComponents2
* sizeof(verts
[0][0]);
1088 const GLsizei kEmuOffset1
= 0;
1089 const GLsizei kEmuOffset2
= kSize1
;
1090 const GLsizei kTotalSize
= kSize1
+ kSize2
;
1092 ExpectedMemoryInfo mem1
= GetExpectedMemory(kSize1
);
1093 ExpectedMemoryInfo mem2
= GetExpectedMemory(kSize2
);
1096 expected
.enable1
.Init(kAttribIndex1
);
1097 expected
.enable2
.Init(kAttribIndex2
);
1098 expected
.divisor
.Init(kAttribIndex2
, kDivisor
);
1099 expected
.bind_to_emu
.Init(GL_ARRAY_BUFFER
, kEmuBufferId
);
1100 expected
.set_size
.Init(GL_ARRAY_BUFFER
, kTotalSize
, 0, 0, GL_DYNAMIC_DRAW
);
1101 expected
.copy_data1
.Init(
1102 GL_ARRAY_BUFFER
, kEmuOffset1
, kSize1
, mem1
.id
, mem1
.offset
);
1103 expected
.set_token1
.Init(GetNextToken());
1104 expected
.set_pointer1
.Init(
1105 kAttribIndex1
, kNumComponents1
, GL_FLOAT
, GL_FALSE
, 0, kEmuOffset1
);
1106 expected
.copy_data2
.Init(
1107 GL_ARRAY_BUFFER
, kEmuOffset2
, kSize2
, mem2
.id
, mem2
.offset
);
1108 expected
.set_token2
.Init(GetNextToken());
1109 expected
.set_pointer2
.Init(
1110 kAttribIndex2
, kNumComponents2
, GL_FLOAT
, GL_FALSE
, 0, kEmuOffset2
);
1111 expected
.draw
.Init(GL_POINTS
, kFirst
, kCount
, 1);
1112 expected
.restore
.Init(GL_ARRAY_BUFFER
, 0);
1113 gl_
->EnableVertexAttribArray(kAttribIndex1
);
1114 gl_
->EnableVertexAttribArray(kAttribIndex2
);
1115 gl_
->VertexAttribPointer(
1116 kAttribIndex1
, kNumComponents1
, GL_FLOAT
, GL_FALSE
, kClientStride
, verts
);
1117 gl_
->VertexAttribPointer(
1118 kAttribIndex2
, kNumComponents2
, GL_FLOAT
, GL_FALSE
, kClientStride
, verts
);
1119 gl_
->VertexAttribDivisorANGLE(kAttribIndex2
, kDivisor
);
1120 gl_
->DrawArraysInstancedANGLE(GL_POINTS
, kFirst
, kCount
, 1);
1121 EXPECT_EQ(0, memcmp(&expected
, commands_
, sizeof(expected
)));
1124 TEST_F(GLES2ImplementationTest
, DrawElementsClientSideBuffers
) {
1125 static const float verts
[][4] = {
1126 { 12.0f
, 23.0f
, 34.0f
, 45.0f
, },
1127 { 56.0f
, 67.0f
, 78.0f
, 89.0f
, },
1128 { 13.0f
, 24.0f
, 35.0f
, 46.0f
, },
1130 static const uint16 indices
[] = {
1134 cmds::EnableVertexAttribArray enable1
;
1135 cmds::EnableVertexAttribArray enable2
;
1136 cmds::BindBuffer bind_to_index_emu
;
1137 cmds::BufferData set_index_size
;
1138 cmds::BufferSubData copy_data0
;
1139 cmd::SetToken set_token0
;
1140 cmds::BindBuffer bind_to_emu
;
1141 cmds::BufferData set_size
;
1142 cmds::BufferSubData copy_data1
;
1143 cmd::SetToken set_token1
;
1144 cmds::VertexAttribPointer set_pointer1
;
1145 cmds::BufferSubData copy_data2
;
1146 cmd::SetToken set_token2
;
1147 cmds::VertexAttribPointer set_pointer2
;
1148 cmds::DrawElements draw
;
1149 cmds::BindBuffer restore
;
1150 cmds::BindBuffer restore_element
;
1152 const GLsizei kIndexSize
= sizeof(indices
);
1153 const GLuint kEmuBufferId
= GLES2Implementation::kClientSideArrayId
;
1154 const GLuint kEmuIndexBufferId
=
1155 GLES2Implementation::kClientSideElementArrayId
;
1156 const GLuint kAttribIndex1
= 1;
1157 const GLuint kAttribIndex2
= 3;
1158 const GLint kNumComponents1
= 3;
1159 const GLint kNumComponents2
= 2;
1160 const GLsizei kClientStride
= sizeof(verts
[0]);
1161 const GLsizei kCount
= 2;
1162 const GLsizei kSize1
=
1163 arraysize(verts
) * kNumComponents1
* sizeof(verts
[0][0]);
1164 const GLsizei kSize2
=
1165 arraysize(verts
) * kNumComponents2
* sizeof(verts
[0][0]);
1166 const GLsizei kEmuOffset1
= 0;
1167 const GLsizei kEmuOffset2
= kSize1
;
1168 const GLsizei kTotalSize
= kSize1
+ kSize2
;
1170 ExpectedMemoryInfo mem1
= GetExpectedMemory(kIndexSize
);
1171 ExpectedMemoryInfo mem2
= GetExpectedMemory(kSize1
);
1172 ExpectedMemoryInfo mem3
= GetExpectedMemory(kSize2
);
1175 expected
.enable1
.Init(kAttribIndex1
);
1176 expected
.enable2
.Init(kAttribIndex2
);
1177 expected
.bind_to_index_emu
.Init(GL_ELEMENT_ARRAY_BUFFER
, kEmuIndexBufferId
);
1178 expected
.set_index_size
.Init(
1179 GL_ELEMENT_ARRAY_BUFFER
, kIndexSize
, 0, 0, GL_DYNAMIC_DRAW
);
1180 expected
.copy_data0
.Init(
1181 GL_ELEMENT_ARRAY_BUFFER
, 0, kIndexSize
, mem1
.id
, mem1
.offset
);
1182 expected
.set_token0
.Init(GetNextToken());
1183 expected
.bind_to_emu
.Init(GL_ARRAY_BUFFER
, kEmuBufferId
);
1184 expected
.set_size
.Init(GL_ARRAY_BUFFER
, kTotalSize
, 0, 0, GL_DYNAMIC_DRAW
);
1185 expected
.copy_data1
.Init(
1186 GL_ARRAY_BUFFER
, kEmuOffset1
, kSize1
, mem2
.id
, mem2
.offset
);
1187 expected
.set_token1
.Init(GetNextToken());
1188 expected
.set_pointer1
.Init(
1189 kAttribIndex1
, kNumComponents1
, GL_FLOAT
, GL_FALSE
, 0, kEmuOffset1
);
1190 expected
.copy_data2
.Init(
1191 GL_ARRAY_BUFFER
, kEmuOffset2
, kSize2
, mem3
.id
, mem3
.offset
);
1192 expected
.set_token2
.Init(GetNextToken());
1193 expected
.set_pointer2
.Init(kAttribIndex2
, kNumComponents2
,
1194 GL_FLOAT
, GL_FALSE
, 0, kEmuOffset2
);
1195 expected
.draw
.Init(GL_POINTS
, kCount
, GL_UNSIGNED_SHORT
, 0);
1196 expected
.restore
.Init(GL_ARRAY_BUFFER
, 0);
1197 expected
.restore_element
.Init(GL_ELEMENT_ARRAY_BUFFER
, 0);
1198 gl_
->EnableVertexAttribArray(kAttribIndex1
);
1199 gl_
->EnableVertexAttribArray(kAttribIndex2
);
1200 gl_
->VertexAttribPointer(kAttribIndex1
, kNumComponents1
,
1201 GL_FLOAT
, GL_FALSE
, kClientStride
, verts
);
1202 gl_
->VertexAttribPointer(kAttribIndex2
, kNumComponents2
,
1203 GL_FLOAT
, GL_FALSE
, kClientStride
, verts
);
1204 gl_
->DrawElements(GL_POINTS
, kCount
, GL_UNSIGNED_SHORT
, indices
);
1205 EXPECT_EQ(0, memcmp(&expected
, commands_
, sizeof(expected
)));
1208 TEST_F(GLES2ImplementationTest
, DrawElementsClientSideBuffersIndexUint
) {
1209 static const float verts
[][4] = {
1210 { 12.0f
, 23.0f
, 34.0f
, 45.0f
, },
1211 { 56.0f
, 67.0f
, 78.0f
, 89.0f
, },
1212 { 13.0f
, 24.0f
, 35.0f
, 46.0f
, },
1214 static const uint32 indices
[] = {
1218 cmds::EnableVertexAttribArray enable1
;
1219 cmds::EnableVertexAttribArray enable2
;
1220 cmds::BindBuffer bind_to_index_emu
;
1221 cmds::BufferData set_index_size
;
1222 cmds::BufferSubData copy_data0
;
1223 cmd::SetToken set_token0
;
1224 cmds::BindBuffer bind_to_emu
;
1225 cmds::BufferData set_size
;
1226 cmds::BufferSubData copy_data1
;
1227 cmd::SetToken set_token1
;
1228 cmds::VertexAttribPointer set_pointer1
;
1229 cmds::BufferSubData copy_data2
;
1230 cmd::SetToken set_token2
;
1231 cmds::VertexAttribPointer set_pointer2
;
1232 cmds::DrawElements draw
;
1233 cmds::BindBuffer restore
;
1234 cmds::BindBuffer restore_element
;
1236 const GLsizei kIndexSize
= sizeof(indices
);
1237 const GLuint kEmuBufferId
= GLES2Implementation::kClientSideArrayId
;
1238 const GLuint kEmuIndexBufferId
=
1239 GLES2Implementation::kClientSideElementArrayId
;
1240 const GLuint kAttribIndex1
= 1;
1241 const GLuint kAttribIndex2
= 3;
1242 const GLint kNumComponents1
= 3;
1243 const GLint kNumComponents2
= 2;
1244 const GLsizei kClientStride
= sizeof(verts
[0]);
1245 const GLsizei kCount
= 2;
1246 const GLsizei kSize1
=
1247 arraysize(verts
) * kNumComponents1
* sizeof(verts
[0][0]);
1248 const GLsizei kSize2
=
1249 arraysize(verts
) * kNumComponents2
* sizeof(verts
[0][0]);
1250 const GLsizei kEmuOffset1
= 0;
1251 const GLsizei kEmuOffset2
= kSize1
;
1252 const GLsizei kTotalSize
= kSize1
+ kSize2
;
1254 ExpectedMemoryInfo mem1
= GetExpectedMemory(kIndexSize
);
1255 ExpectedMemoryInfo mem2
= GetExpectedMemory(kSize1
);
1256 ExpectedMemoryInfo mem3
= GetExpectedMemory(kSize2
);
1259 expected
.enable1
.Init(kAttribIndex1
);
1260 expected
.enable2
.Init(kAttribIndex2
);
1261 expected
.bind_to_index_emu
.Init(GL_ELEMENT_ARRAY_BUFFER
, kEmuIndexBufferId
);
1262 expected
.set_index_size
.Init(
1263 GL_ELEMENT_ARRAY_BUFFER
, kIndexSize
, 0, 0, GL_DYNAMIC_DRAW
);
1264 expected
.copy_data0
.Init(
1265 GL_ELEMENT_ARRAY_BUFFER
, 0, kIndexSize
, mem1
.id
, mem1
.offset
);
1266 expected
.set_token0
.Init(GetNextToken());
1267 expected
.bind_to_emu
.Init(GL_ARRAY_BUFFER
, kEmuBufferId
);
1268 expected
.set_size
.Init(GL_ARRAY_BUFFER
, kTotalSize
, 0, 0, GL_DYNAMIC_DRAW
);
1269 expected
.copy_data1
.Init(
1270 GL_ARRAY_BUFFER
, kEmuOffset1
, kSize1
, mem2
.id
, mem2
.offset
);
1271 expected
.set_token1
.Init(GetNextToken());
1272 expected
.set_pointer1
.Init(
1273 kAttribIndex1
, kNumComponents1
, GL_FLOAT
, GL_FALSE
, 0, kEmuOffset1
);
1274 expected
.copy_data2
.Init(
1275 GL_ARRAY_BUFFER
, kEmuOffset2
, kSize2
, mem3
.id
, mem3
.offset
);
1276 expected
.set_token2
.Init(GetNextToken());
1277 expected
.set_pointer2
.Init(kAttribIndex2
, kNumComponents2
,
1278 GL_FLOAT
, GL_FALSE
, 0, kEmuOffset2
);
1279 expected
.draw
.Init(GL_POINTS
, kCount
, GL_UNSIGNED_INT
, 0);
1280 expected
.restore
.Init(GL_ARRAY_BUFFER
, 0);
1281 expected
.restore_element
.Init(GL_ELEMENT_ARRAY_BUFFER
, 0);
1282 gl_
->EnableVertexAttribArray(kAttribIndex1
);
1283 gl_
->EnableVertexAttribArray(kAttribIndex2
);
1284 gl_
->VertexAttribPointer(kAttribIndex1
, kNumComponents1
,
1285 GL_FLOAT
, GL_FALSE
, kClientStride
, verts
);
1286 gl_
->VertexAttribPointer(kAttribIndex2
, kNumComponents2
,
1287 GL_FLOAT
, GL_FALSE
, kClientStride
, verts
);
1288 gl_
->DrawElements(GL_POINTS
, kCount
, GL_UNSIGNED_INT
, indices
);
1289 EXPECT_EQ(0, memcmp(&expected
, commands_
, sizeof(expected
)));
1292 TEST_F(GLES2ImplementationTest
, DrawElementsClientSideBuffersInvalidIndexUint
) {
1293 static const float verts
[][4] = {
1294 { 12.0f
, 23.0f
, 34.0f
, 45.0f
, },
1295 { 56.0f
, 67.0f
, 78.0f
, 89.0f
, },
1296 { 13.0f
, 24.0f
, 35.0f
, 46.0f
, },
1298 static const uint32 indices
[] = {
1302 const GLuint kAttribIndex1
= 1;
1303 const GLuint kAttribIndex2
= 3;
1304 const GLint kNumComponents1
= 3;
1305 const GLint kNumComponents2
= 2;
1306 const GLsizei kClientStride
= sizeof(verts
[0]);
1307 const GLsizei kCount
= 2;
1309 EXPECT_CALL(*command_buffer(), OnFlush())
1311 .RetiresOnSaturation();
1313 gl_
->EnableVertexAttribArray(kAttribIndex1
);
1314 gl_
->EnableVertexAttribArray(kAttribIndex2
);
1315 gl_
->VertexAttribPointer(kAttribIndex1
, kNumComponents1
,
1316 GL_FLOAT
, GL_FALSE
, kClientStride
, verts
);
1317 gl_
->VertexAttribPointer(kAttribIndex2
, kNumComponents2
,
1318 GL_FLOAT
, GL_FALSE
, kClientStride
, verts
);
1319 gl_
->DrawElements(GL_POINTS
, kCount
, GL_UNSIGNED_INT
, indices
);
1321 EXPECT_EQ(static_cast<GLenum
>(GL_INVALID_OPERATION
), gl_
->GetError());
1324 TEST_F(GLES2ImplementationTest
,
1325 DrawElementsClientSideBuffersServiceSideIndices
) {
1326 static const float verts
[][4] = {
1327 { 12.0f
, 23.0f
, 34.0f
, 45.0f
, },
1328 { 56.0f
, 67.0f
, 78.0f
, 89.0f
, },
1329 { 13.0f
, 24.0f
, 35.0f
, 46.0f
, },
1332 cmds::EnableVertexAttribArray enable1
;
1333 cmds::EnableVertexAttribArray enable2
;
1334 cmds::BindBuffer bind_to_index
;
1335 cmds::GetMaxValueInBufferCHROMIUM get_max
;
1336 cmds::BindBuffer bind_to_emu
;
1337 cmds::BufferData set_size
;
1338 cmds::BufferSubData copy_data1
;
1339 cmd::SetToken set_token1
;
1340 cmds::VertexAttribPointer set_pointer1
;
1341 cmds::BufferSubData copy_data2
;
1342 cmd::SetToken set_token2
;
1343 cmds::VertexAttribPointer set_pointer2
;
1344 cmds::DrawElements draw
;
1345 cmds::BindBuffer restore
;
1347 const GLuint kEmuBufferId
= GLES2Implementation::kClientSideArrayId
;
1348 const GLuint kClientIndexBufferId
= 0x789;
1349 const GLuint kIndexOffset
= 0x40;
1350 const GLuint kMaxIndex
= 2;
1351 const GLuint kAttribIndex1
= 1;
1352 const GLuint kAttribIndex2
= 3;
1353 const GLint kNumComponents1
= 3;
1354 const GLint kNumComponents2
= 2;
1355 const GLsizei kClientStride
= sizeof(verts
[0]);
1356 const GLsizei kCount
= 2;
1357 const GLsizei kSize1
=
1358 arraysize(verts
) * kNumComponents1
* sizeof(verts
[0][0]);
1359 const GLsizei kSize2
=
1360 arraysize(verts
) * kNumComponents2
* sizeof(verts
[0][0]);
1361 const GLsizei kEmuOffset1
= 0;
1362 const GLsizei kEmuOffset2
= kSize1
;
1363 const GLsizei kTotalSize
= kSize1
+ kSize2
;
1365 ExpectedMemoryInfo mem1
= GetExpectedResultMemory(sizeof(uint32
));
1366 ExpectedMemoryInfo mem2
= GetExpectedMemory(kSize1
);
1367 ExpectedMemoryInfo mem3
= GetExpectedMemory(kSize2
);
1371 expected
.enable1
.Init(kAttribIndex1
);
1372 expected
.enable2
.Init(kAttribIndex2
);
1373 expected
.bind_to_index
.Init(GL_ELEMENT_ARRAY_BUFFER
, kClientIndexBufferId
);
1374 expected
.get_max
.Init(kClientIndexBufferId
, kCount
, GL_UNSIGNED_SHORT
,
1375 kIndexOffset
, mem1
.id
, mem1
.offset
);
1376 expected
.bind_to_emu
.Init(GL_ARRAY_BUFFER
, kEmuBufferId
);
1377 expected
.set_size
.Init(GL_ARRAY_BUFFER
, kTotalSize
, 0, 0, GL_DYNAMIC_DRAW
);
1378 expected
.copy_data1
.Init(
1379 GL_ARRAY_BUFFER
, kEmuOffset1
, kSize1
, mem2
.id
, mem2
.offset
);
1380 expected
.set_token1
.Init(GetNextToken());
1381 expected
.set_pointer1
.Init(kAttribIndex1
, kNumComponents1
,
1382 GL_FLOAT
, GL_FALSE
, 0, kEmuOffset1
);
1383 expected
.copy_data2
.Init(
1384 GL_ARRAY_BUFFER
, kEmuOffset2
, kSize2
, mem3
.id
, mem3
.offset
);
1385 expected
.set_token2
.Init(GetNextToken());
1386 expected
.set_pointer2
.Init(kAttribIndex2
, kNumComponents2
,
1387 GL_FLOAT
, GL_FALSE
, 0, kEmuOffset2
);
1388 expected
.draw
.Init(GL_POINTS
, kCount
, GL_UNSIGNED_SHORT
, kIndexOffset
);
1389 expected
.restore
.Init(GL_ARRAY_BUFFER
, 0);
1391 EXPECT_CALL(*command_buffer(), OnFlush())
1392 .WillOnce(SetMemory(mem1
.ptr
,kMaxIndex
))
1393 .RetiresOnSaturation();
1395 gl_
->EnableVertexAttribArray(kAttribIndex1
);
1396 gl_
->EnableVertexAttribArray(kAttribIndex2
);
1397 gl_
->BindBuffer(GL_ELEMENT_ARRAY_BUFFER
, kClientIndexBufferId
);
1398 gl_
->VertexAttribPointer(kAttribIndex1
, kNumComponents1
,
1399 GL_FLOAT
, GL_FALSE
, kClientStride
, verts
);
1400 gl_
->VertexAttribPointer(kAttribIndex2
, kNumComponents2
,
1401 GL_FLOAT
, GL_FALSE
, kClientStride
, verts
);
1402 gl_
->DrawElements(GL_POINTS
, kCount
, GL_UNSIGNED_SHORT
,
1403 reinterpret_cast<const void*>(kIndexOffset
));
1404 EXPECT_EQ(0, memcmp(&expected
, commands_
, sizeof(expected
)));
1407 TEST_F(GLES2ImplementationTest
, DrawElementsInstancedANGLEClientSideBuffers
) {
1408 static const float verts
[][4] = {
1409 { 12.0f
, 23.0f
, 34.0f
, 45.0f
, },
1410 { 56.0f
, 67.0f
, 78.0f
, 89.0f
, },
1411 { 13.0f
, 24.0f
, 35.0f
, 46.0f
, },
1413 static const uint16 indices
[] = {
1417 cmds::EnableVertexAttribArray enable1
;
1418 cmds::EnableVertexAttribArray enable2
;
1419 cmds::VertexAttribDivisorANGLE divisor
;
1420 cmds::BindBuffer bind_to_index_emu
;
1421 cmds::BufferData set_index_size
;
1422 cmds::BufferSubData copy_data0
;
1423 cmd::SetToken set_token0
;
1424 cmds::BindBuffer bind_to_emu
;
1425 cmds::BufferData set_size
;
1426 cmds::BufferSubData copy_data1
;
1427 cmd::SetToken set_token1
;
1428 cmds::VertexAttribPointer set_pointer1
;
1429 cmds::BufferSubData copy_data2
;
1430 cmd::SetToken set_token2
;
1431 cmds::VertexAttribPointer set_pointer2
;
1432 cmds::DrawElementsInstancedANGLE draw
;
1433 cmds::BindBuffer restore
;
1434 cmds::BindBuffer restore_element
;
1436 const GLsizei kIndexSize
= sizeof(indices
);
1437 const GLuint kEmuBufferId
= GLES2Implementation::kClientSideArrayId
;
1438 const GLuint kEmuIndexBufferId
=
1439 GLES2Implementation::kClientSideElementArrayId
;
1440 const GLuint kAttribIndex1
= 1;
1441 const GLuint kAttribIndex2
= 3;
1442 const GLint kNumComponents1
= 3;
1443 const GLint kNumComponents2
= 2;
1444 const GLsizei kClientStride
= sizeof(verts
[0]);
1445 const GLsizei kCount
= 2;
1446 const GLsizei kSize1
=
1447 arraysize(verts
) * kNumComponents1
* sizeof(verts
[0][0]);
1448 const GLsizei kSize2
=
1449 1 * kNumComponents2
* sizeof(verts
[0][0]);
1450 const GLuint kDivisor
= 1;
1451 const GLsizei kEmuOffset1
= 0;
1452 const GLsizei kEmuOffset2
= kSize1
;
1453 const GLsizei kTotalSize
= kSize1
+ kSize2
;
1455 ExpectedMemoryInfo mem1
= GetExpectedMemory(kIndexSize
);
1456 ExpectedMemoryInfo mem2
= GetExpectedMemory(kSize1
);
1457 ExpectedMemoryInfo mem3
= GetExpectedMemory(kSize2
);
1460 expected
.enable1
.Init(kAttribIndex1
);
1461 expected
.enable2
.Init(kAttribIndex2
);
1462 expected
.divisor
.Init(kAttribIndex2
, kDivisor
);
1463 expected
.bind_to_index_emu
.Init(GL_ELEMENT_ARRAY_BUFFER
, kEmuIndexBufferId
);
1464 expected
.set_index_size
.Init(
1465 GL_ELEMENT_ARRAY_BUFFER
, kIndexSize
, 0, 0, GL_DYNAMIC_DRAW
);
1466 expected
.copy_data0
.Init(
1467 GL_ELEMENT_ARRAY_BUFFER
, 0, kIndexSize
, mem1
.id
, mem1
.offset
);
1468 expected
.set_token0
.Init(GetNextToken());
1469 expected
.bind_to_emu
.Init(GL_ARRAY_BUFFER
, kEmuBufferId
);
1470 expected
.set_size
.Init(GL_ARRAY_BUFFER
, kTotalSize
, 0, 0, GL_DYNAMIC_DRAW
);
1471 expected
.copy_data1
.Init(
1472 GL_ARRAY_BUFFER
, kEmuOffset1
, kSize1
, mem2
.id
, mem2
.offset
);
1473 expected
.set_token1
.Init(GetNextToken());
1474 expected
.set_pointer1
.Init(
1475 kAttribIndex1
, kNumComponents1
, GL_FLOAT
, GL_FALSE
, 0, kEmuOffset1
);
1476 expected
.copy_data2
.Init(
1477 GL_ARRAY_BUFFER
, kEmuOffset2
, kSize2
, mem3
.id
, mem3
.offset
);
1478 expected
.set_token2
.Init(GetNextToken());
1479 expected
.set_pointer2
.Init(kAttribIndex2
, kNumComponents2
,
1480 GL_FLOAT
, GL_FALSE
, 0, kEmuOffset2
);
1481 expected
.draw
.Init(GL_POINTS
, kCount
, GL_UNSIGNED_SHORT
, 0, 1);
1482 expected
.restore
.Init(GL_ARRAY_BUFFER
, 0);
1483 expected
.restore_element
.Init(GL_ELEMENT_ARRAY_BUFFER
, 0);
1484 gl_
->EnableVertexAttribArray(kAttribIndex1
);
1485 gl_
->EnableVertexAttribArray(kAttribIndex2
);
1486 gl_
->VertexAttribPointer(kAttribIndex1
, kNumComponents1
,
1487 GL_FLOAT
, GL_FALSE
, kClientStride
, verts
);
1488 gl_
->VertexAttribPointer(kAttribIndex2
, kNumComponents2
,
1489 GL_FLOAT
, GL_FALSE
, kClientStride
, verts
);
1490 gl_
->VertexAttribDivisorANGLE(kAttribIndex2
, kDivisor
);
1491 gl_
->DrawElementsInstancedANGLE(
1492 GL_POINTS
, kCount
, GL_UNSIGNED_SHORT
, indices
, 1);
1493 EXPECT_EQ(0, memcmp(&expected
, commands_
, sizeof(expected
)));
1496 TEST_F(GLES2ImplementationTest
, GetVertexBufferPointerv
) {
1497 static const float verts
[1] = { 0.0f
, };
1498 const GLuint kAttribIndex1
= 1;
1499 const GLuint kAttribIndex2
= 3;
1500 const GLint kNumComponents1
= 3;
1501 const GLint kNumComponents2
= 2;
1502 const GLsizei kStride1
= 12;
1503 const GLsizei kStride2
= 0;
1504 const GLuint kBufferId
= 0x123;
1505 const GLint kOffset2
= 0x456;
1507 // It's all cached on the client side so no get commands are issued.
1509 cmds::BindBuffer bind
;
1510 cmds::VertexAttribPointer set_pointer
;
1514 expected
.bind
.Init(GL_ARRAY_BUFFER
, kBufferId
);
1515 expected
.set_pointer
.Init(kAttribIndex2
, kNumComponents2
, GL_FLOAT
, GL_FALSE
,
1516 kStride2
, kOffset2
);
1518 // Set one client side buffer.
1519 gl_
->VertexAttribPointer(kAttribIndex1
, kNumComponents1
,
1520 GL_FLOAT
, GL_FALSE
, kStride1
, verts
);
1522 gl_
->BindBuffer(GL_ARRAY_BUFFER
, kBufferId
);
1523 gl_
->VertexAttribPointer(kAttribIndex2
, kNumComponents2
,
1524 GL_FLOAT
, GL_FALSE
, kStride2
,
1525 reinterpret_cast<const void*>(kOffset2
));
1526 // now get them both.
1530 gl_
->GetVertexAttribPointerv(
1531 kAttribIndex1
, GL_VERTEX_ATTRIB_ARRAY_POINTER
, &ptr1
);
1532 gl_
->GetVertexAttribPointerv(
1533 kAttribIndex2
, GL_VERTEX_ATTRIB_ARRAY_POINTER
, &ptr2
);
1535 EXPECT_EQ(0, memcmp(&expected
, commands_
, sizeof(expected
)));
1536 EXPECT_TRUE(static_cast<const void*>(&verts
) == ptr1
);
1537 EXPECT_TRUE(ptr2
== reinterpret_cast<void*>(kOffset2
));
1540 TEST_F(GLES2ImplementationTest
, GetVertexAttrib
) {
1541 static const float verts
[1] = { 0.0f
, };
1542 const GLuint kAttribIndex1
= 1;
1543 const GLuint kAttribIndex2
= 3;
1544 const GLint kNumComponents1
= 3;
1545 const GLint kNumComponents2
= 2;
1546 const GLsizei kStride1
= 12;
1547 const GLsizei kStride2
= 0;
1548 const GLuint kBufferId
= 0x123;
1549 const GLint kOffset2
= 0x456;
1551 // Only one set and one get because the client side buffer's info is stored
1552 // on the client side.
1554 cmds::EnableVertexAttribArray enable
;
1555 cmds::BindBuffer bind
;
1556 cmds::VertexAttribPointer set_pointer
;
1557 cmds::GetVertexAttribfv get2
; // for getting the value from attrib1
1560 ExpectedMemoryInfo mem2
= GetExpectedResultMemory(16);
1563 expected
.enable
.Init(kAttribIndex1
);
1564 expected
.bind
.Init(GL_ARRAY_BUFFER
, kBufferId
);
1565 expected
.set_pointer
.Init(kAttribIndex2
, kNumComponents2
, GL_FLOAT
, GL_FALSE
,
1566 kStride2
, kOffset2
);
1567 expected
.get2
.Init(kAttribIndex1
,
1568 GL_CURRENT_VERTEX_ATTRIB
,
1569 mem2
.id
, mem2
.offset
);
1571 FourFloats
current_attrib(1.2f
, 3.4f
, 5.6f
, 7.8f
);
1573 // One call to flush to wait for last call to GetVertexAttribiv
1574 // as others are all cached.
1575 EXPECT_CALL(*command_buffer(), OnFlush())
1576 .WillOnce(SetMemory(
1577 mem2
.ptr
, SizedResultHelper
<FourFloats
>(current_attrib
)))
1578 .RetiresOnSaturation();
1580 gl_
->EnableVertexAttribArray(kAttribIndex1
);
1581 // Set one client side buffer.
1582 gl_
->VertexAttribPointer(kAttribIndex1
, kNumComponents1
,
1583 GL_FLOAT
, GL_FALSE
, kStride1
, verts
);
1585 gl_
->BindBuffer(GL_ARRAY_BUFFER
, kBufferId
);
1586 gl_
->VertexAttribPointer(kAttribIndex2
, kNumComponents2
,
1587 GL_FLOAT
, GL_FALSE
, kStride2
,
1588 reinterpret_cast<const void*>(kOffset2
));
1589 // first get the service side once to see that we make a command
1590 GLint buffer_id
= 0;
1595 GLint normalized
= 1;
1596 float current
[4] = { 0.0f
, };
1598 gl_
->GetVertexAttribiv(
1599 kAttribIndex2
, GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING
, &buffer_id
);
1600 EXPECT_EQ(kBufferId
, static_cast<GLuint
>(buffer_id
));
1601 gl_
->GetVertexAttribiv(
1602 kAttribIndex1
, GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING
, &buffer_id
);
1603 gl_
->GetVertexAttribiv(
1604 kAttribIndex1
, GL_VERTEX_ATTRIB_ARRAY_ENABLED
, &enabled
);
1605 gl_
->GetVertexAttribiv(
1606 kAttribIndex1
, GL_VERTEX_ATTRIB_ARRAY_SIZE
, &size
);
1607 gl_
->GetVertexAttribiv(
1608 kAttribIndex1
, GL_VERTEX_ATTRIB_ARRAY_STRIDE
, &stride
);
1609 gl_
->GetVertexAttribiv(
1610 kAttribIndex1
, GL_VERTEX_ATTRIB_ARRAY_TYPE
, &type
);
1611 gl_
->GetVertexAttribiv(
1612 kAttribIndex1
, GL_VERTEX_ATTRIB_ARRAY_NORMALIZED
, &normalized
);
1613 gl_
->GetVertexAttribfv(
1614 kAttribIndex1
, GL_CURRENT_VERTEX_ATTRIB
, ¤t
[0]);
1616 EXPECT_EQ(0, buffer_id
);
1617 EXPECT_EQ(GL_TRUE
, enabled
);
1618 EXPECT_EQ(kNumComponents1
, size
);
1619 EXPECT_EQ(kStride1
, stride
);
1620 EXPECT_EQ(GL_FLOAT
, type
);
1621 EXPECT_EQ(GL_FALSE
, normalized
);
1622 EXPECT_EQ(0, memcmp(¤t_attrib
, ¤t
, sizeof(current_attrib
)));
1624 EXPECT_EQ(0, memcmp(&expected
, commands_
, sizeof(expected
)));
1627 TEST_F(GLES2ImplementationTest
, ReservedIds
) {
1628 // Only the get error command should be issued.
1634 ExpectedMemoryInfo mem1
= GetExpectedResultMemory(
1635 sizeof(cmds::GetError::Result
));
1637 expected
.get
.Init(mem1
.id
, mem1
.offset
);
1639 // One call to flush to wait for GetError
1640 EXPECT_CALL(*command_buffer(), OnFlush())
1641 .WillOnce(SetMemory(mem1
.ptr
, GLuint(GL_NO_ERROR
)))
1642 .RetiresOnSaturation();
1646 GLES2Implementation::kClientSideArrayId
);
1649 GLES2Implementation::kClientSideElementArrayId
);
1650 GLenum err
= gl_
->GetError();
1651 EXPECT_EQ(static_cast<GLenum
>(GL_INVALID_OPERATION
), err
);
1652 EXPECT_EQ(0, memcmp(&expected
, commands_
, sizeof(expected
)));
1655 #endif // defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS)
1657 TEST_F(GLES2ImplementationTest
, ReadPixels2Reads
) {
1659 cmds::ReadPixels read1
;
1660 cmd::SetToken set_token1
;
1661 cmds::ReadPixels read2
;
1662 cmd::SetToken set_token2
;
1664 const GLint kBytesPerPixel
= 4;
1665 const GLint kWidth
=
1666 (kTransferBufferSize
- GLES2Implementation::kStartingOffset
) /
1668 const GLint kHeight
= 2;
1669 const GLenum kFormat
= GL_RGBA
;
1670 const GLenum kType
= GL_UNSIGNED_BYTE
;
1672 ExpectedMemoryInfo mem1
=
1673 GetExpectedMemory(kWidth
* kHeight
/ 2 * kBytesPerPixel
);
1674 ExpectedMemoryInfo result1
=
1675 GetExpectedResultMemory(sizeof(cmds::ReadPixels::Result
));
1676 ExpectedMemoryInfo mem2
=
1677 GetExpectedMemory(kWidth
* kHeight
/ 2 * kBytesPerPixel
);
1678 ExpectedMemoryInfo result2
=
1679 GetExpectedResultMemory(sizeof(cmds::ReadPixels::Result
));
1682 expected
.read1
.Init(
1683 0, 0, kWidth
, kHeight
/ 2, kFormat
, kType
,
1684 mem1
.id
, mem1
.offset
, result1
.id
, result1
.offset
,
1686 expected
.set_token1
.Init(GetNextToken());
1687 expected
.read2
.Init(
1688 0, kHeight
/ 2, kWidth
, kHeight
/ 2, kFormat
, kType
,
1689 mem2
.id
, mem2
.offset
, result2
.id
, result2
.offset
, false);
1690 expected
.set_token2
.Init(GetNextToken());
1691 scoped_ptr
<int8
[]> buffer(new int8
[kWidth
* kHeight
* kBytesPerPixel
]);
1693 EXPECT_CALL(*command_buffer(), OnFlush())
1694 .WillOnce(SetMemory(result1
.ptr
, static_cast<uint32
>(1)))
1695 .WillOnce(SetMemory(result2
.ptr
, static_cast<uint32
>(1)))
1696 .RetiresOnSaturation();
1698 gl_
->ReadPixels(0, 0, kWidth
, kHeight
, kFormat
, kType
, buffer
.get());
1699 EXPECT_EQ(0, memcmp(&expected
, commands_
, sizeof(expected
)));
1702 TEST_F(GLES2ImplementationTest
, ReadPixelsBadFormatType
) {
1704 cmds::ReadPixels read
;
1705 cmd::SetToken set_token
;
1707 const GLint kBytesPerPixel
= 4;
1708 const GLint kWidth
= 2;
1709 const GLint kHeight
= 2;
1710 const GLenum kFormat
= 0;
1711 const GLenum kType
= 0;
1713 ExpectedMemoryInfo mem1
=
1714 GetExpectedMemory(kWidth
* kHeight
* kBytesPerPixel
);
1715 ExpectedMemoryInfo result1
=
1716 GetExpectedResultMemory(sizeof(cmds::ReadPixels::Result
));
1720 0, 0, kWidth
, kHeight
, kFormat
, kType
,
1721 mem1
.id
, mem1
.offset
, result1
.id
, result1
.offset
, false);
1722 expected
.set_token
.Init(GetNextToken());
1723 scoped_ptr
<int8
[]> buffer(new int8
[kWidth
* kHeight
* kBytesPerPixel
]);
1725 EXPECT_CALL(*command_buffer(), OnFlush())
1727 .RetiresOnSaturation();
1729 gl_
->ReadPixels(0, 0, kWidth
, kHeight
, kFormat
, kType
, buffer
.get());
1732 TEST_F(GLES2ImplementationTest
, FreeUnusedSharedMemory
) {
1734 cmds::BufferSubData buf
;
1735 cmd::SetToken set_token
;
1737 const GLenum kTarget
= GL_ELEMENT_ARRAY_BUFFER
;
1738 const GLintptr kOffset
= 15;
1739 const GLsizeiptr kSize
= 16;
1741 ExpectedMemoryInfo mem1
= GetExpectedMemory(kSize
);
1745 kTarget
, kOffset
, kSize
, mem1
.id
, mem1
.offset
);
1746 expected
.set_token
.Init(GetNextToken());
1748 void* mem
= gl_
->MapBufferSubDataCHROMIUM(
1749 kTarget
, kOffset
, kSize
, GL_WRITE_ONLY
);
1750 ASSERT_TRUE(mem
!= NULL
);
1751 gl_
->UnmapBufferSubDataCHROMIUM(mem
);
1752 EXPECT_CALL(*command_buffer(), DestroyTransferBuffer(_
))
1754 .RetiresOnSaturation();
1755 gl_
->FreeUnusedSharedMemory();
1758 TEST_F(GLES2ImplementationTest
, MapUnmapBufferSubDataCHROMIUM
) {
1760 cmds::BufferSubData buf
;
1761 cmd::SetToken set_token
;
1763 const GLenum kTarget
= GL_ELEMENT_ARRAY_BUFFER
;
1764 const GLintptr kOffset
= 15;
1765 const GLsizeiptr kSize
= 16;
1770 kTarget
, kOffset
, kSize
,
1771 command_buffer()->GetNextFreeTransferBufferId(), offset
);
1772 expected
.set_token
.Init(GetNextToken());
1774 void* mem
= gl_
->MapBufferSubDataCHROMIUM(
1775 kTarget
, kOffset
, kSize
, GL_WRITE_ONLY
);
1776 ASSERT_TRUE(mem
!= NULL
);
1777 gl_
->UnmapBufferSubDataCHROMIUM(mem
);
1778 EXPECT_EQ(0, memcmp(&expected
, commands_
, sizeof(expected
)));
1781 TEST_F(GLES2ImplementationTest
, MapUnmapBufferSubDataCHROMIUMBadArgs
) {
1782 const GLenum kTarget
= GL_ELEMENT_ARRAY_BUFFER
;
1783 const GLintptr kOffset
= 15;
1784 const GLsizeiptr kSize
= 16;
1786 ExpectedMemoryInfo result1
=
1787 GetExpectedResultMemory(sizeof(cmds::GetError::Result
));
1788 ExpectedMemoryInfo result2
=
1789 GetExpectedResultMemory(sizeof(cmds::GetError::Result
));
1790 ExpectedMemoryInfo result3
=
1791 GetExpectedResultMemory(sizeof(cmds::GetError::Result
));
1792 ExpectedMemoryInfo result4
=
1793 GetExpectedResultMemory(sizeof(cmds::GetError::Result
));
1795 // Calls to flush to wait for GetError
1796 EXPECT_CALL(*command_buffer(), OnFlush())
1797 .WillOnce(SetMemory(result1
.ptr
, GLuint(GL_NO_ERROR
)))
1798 .WillOnce(SetMemory(result2
.ptr
, GLuint(GL_NO_ERROR
)))
1799 .WillOnce(SetMemory(result3
.ptr
, GLuint(GL_NO_ERROR
)))
1800 .WillOnce(SetMemory(result4
.ptr
, GLuint(GL_NO_ERROR
)))
1801 .RetiresOnSaturation();
1804 mem
= gl_
->MapBufferSubDataCHROMIUM(kTarget
, -1, kSize
, GL_WRITE_ONLY
);
1805 ASSERT_TRUE(mem
== NULL
);
1806 EXPECT_EQ(static_cast<GLenum
>(GL_INVALID_VALUE
), gl_
->GetError());
1807 mem
= gl_
->MapBufferSubDataCHROMIUM(kTarget
, kOffset
, -1, GL_WRITE_ONLY
);
1808 ASSERT_TRUE(mem
== NULL
);
1809 EXPECT_EQ(static_cast<GLenum
>(GL_INVALID_VALUE
), gl_
->GetError());
1810 mem
= gl_
->MapBufferSubDataCHROMIUM(kTarget
, kOffset
, kSize
, GL_READ_ONLY
);
1811 ASSERT_TRUE(mem
== NULL
);
1812 EXPECT_EQ(static_cast<GLenum
>(GL_INVALID_ENUM
), gl_
->GetError());
1813 const char* kPtr
= "something";
1814 gl_
->UnmapBufferSubDataCHROMIUM(kPtr
);
1815 EXPECT_EQ(static_cast<GLenum
>(GL_INVALID_VALUE
), gl_
->GetError());
1818 TEST_F(GLES2ImplementationTest
, MapUnmapTexSubImage2DCHROMIUM
) {
1820 cmds::TexSubImage2D tex
;
1821 cmd::SetToken set_token
;
1823 const GLint kLevel
= 1;
1824 const GLint kXOffset
= 2;
1825 const GLint kYOffset
= 3;
1826 const GLint kWidth
= 4;
1827 const GLint kHeight
= 5;
1828 const GLenum kFormat
= GL_RGBA
;
1829 const GLenum kType
= GL_UNSIGNED_BYTE
;
1834 GL_TEXTURE_2D
, kLevel
, kXOffset
, kYOffset
, kWidth
, kHeight
, kFormat
,
1836 command_buffer()->GetNextFreeTransferBufferId(), offset
, GL_FALSE
);
1837 expected
.set_token
.Init(GetNextToken());
1839 void* mem
= gl_
->MapTexSubImage2DCHROMIUM(
1849 ASSERT_TRUE(mem
!= NULL
);
1850 gl_
->UnmapTexSubImage2DCHROMIUM(mem
);
1851 EXPECT_EQ(0, memcmp(&expected
, commands_
, sizeof(expected
)));
1854 TEST_F(GLES2ImplementationTest
, MapUnmapTexSubImage2DCHROMIUMBadArgs
) {
1855 const GLint kLevel
= 1;
1856 const GLint kXOffset
= 2;
1857 const GLint kYOffset
= 3;
1858 const GLint kWidth
= 4;
1859 const GLint kHeight
= 5;
1860 const GLenum kFormat
= GL_RGBA
;
1861 const GLenum kType
= GL_UNSIGNED_BYTE
;
1863 ExpectedMemoryInfo result1
=
1864 GetExpectedResultMemory(sizeof(cmds::GetError::Result
));
1865 ExpectedMemoryInfo result2
=
1866 GetExpectedResultMemory(sizeof(cmds::GetError::Result
));
1867 ExpectedMemoryInfo result3
=
1868 GetExpectedResultMemory(sizeof(cmds::GetError::Result
));
1869 ExpectedMemoryInfo result4
=
1870 GetExpectedResultMemory(sizeof(cmds::GetError::Result
));
1871 ExpectedMemoryInfo result5
=
1872 GetExpectedResultMemory(sizeof(cmds::GetError::Result
));
1873 ExpectedMemoryInfo result6
=
1874 GetExpectedResultMemory(sizeof(cmds::GetError::Result
));
1875 ExpectedMemoryInfo result7
=
1876 GetExpectedResultMemory(sizeof(cmds::GetError::Result
));
1878 // Calls to flush to wait for GetError
1879 EXPECT_CALL(*command_buffer(), OnFlush())
1880 .WillOnce(SetMemory(result1
.ptr
, GLuint(GL_NO_ERROR
)))
1881 .WillOnce(SetMemory(result2
.ptr
, GLuint(GL_NO_ERROR
)))
1882 .WillOnce(SetMemory(result3
.ptr
, GLuint(GL_NO_ERROR
)))
1883 .WillOnce(SetMemory(result4
.ptr
, GLuint(GL_NO_ERROR
)))
1884 .WillOnce(SetMemory(result5
.ptr
, GLuint(GL_NO_ERROR
)))
1885 .WillOnce(SetMemory(result6
.ptr
, GLuint(GL_NO_ERROR
)))
1886 .WillOnce(SetMemory(result7
.ptr
, GLuint(GL_NO_ERROR
)))
1887 .RetiresOnSaturation();
1890 mem
= gl_
->MapTexSubImage2DCHROMIUM(
1900 EXPECT_TRUE(mem
== NULL
);
1901 EXPECT_EQ(static_cast<GLenum
>(GL_INVALID_VALUE
), gl_
->GetError());
1902 mem
= gl_
->MapTexSubImage2DCHROMIUM(
1912 EXPECT_TRUE(mem
== NULL
);
1913 EXPECT_EQ(static_cast<GLenum
>(GL_INVALID_VALUE
), gl_
->GetError());
1914 mem
= gl_
->MapTexSubImage2DCHROMIUM(
1924 EXPECT_TRUE(mem
== NULL
);
1925 EXPECT_EQ(static_cast<GLenum
>(GL_INVALID_VALUE
), gl_
->GetError());
1926 mem
= gl_
->MapTexSubImage2DCHROMIUM(
1936 EXPECT_TRUE(mem
== NULL
);
1937 EXPECT_EQ(static_cast<GLenum
>(GL_INVALID_VALUE
), gl_
->GetError());
1938 mem
= gl_
->MapTexSubImage2DCHROMIUM(
1948 EXPECT_TRUE(mem
== NULL
);
1949 EXPECT_EQ(static_cast<GLenum
>(GL_INVALID_VALUE
), gl_
->GetError());
1950 mem
= gl_
->MapTexSubImage2DCHROMIUM(
1960 EXPECT_TRUE(mem
== NULL
);
1961 EXPECT_EQ(static_cast<GLenum
>(GL_INVALID_ENUM
), gl_
->GetError());
1962 const char* kPtr
= "something";
1963 gl_
->UnmapTexSubImage2DCHROMIUM(kPtr
);
1964 EXPECT_EQ(static_cast<GLenum
>(GL_INVALID_VALUE
), gl_
->GetError());
1967 TEST_F(GLES2ImplementationTest
, GetProgramInfoCHROMIUMGoodArgs
) {
1968 const uint32 kBucketId
= GLES2Implementation::kResultBucketId
;
1969 const GLuint kProgramId
= 123;
1970 const char kBad
= 0x12;
1972 const Str7 kString
= {"foobar"};
1975 ExpectedMemoryInfo mem1
=
1976 GetExpectedMemory(MaxTransferBufferSize());
1977 ExpectedMemoryInfo result1
=
1978 GetExpectedResultMemory(sizeof(cmd::GetBucketStart::Result
));
1979 ExpectedMemoryInfo result2
=
1980 GetExpectedResultMemory(sizeof(cmds::GetError::Result
));
1982 memset(buf
, kBad
, sizeof(buf
));
1983 EXPECT_CALL(*command_buffer(), OnFlush())
1984 .WillOnce(DoAll(SetMemory(result1
.ptr
, uint32(sizeof(kString
))),
1985 SetMemory(mem1
.ptr
, kString
)))
1986 .WillOnce(SetMemory(result2
.ptr
, GLuint(GL_NO_ERROR
)))
1987 .RetiresOnSaturation();
1990 cmd::SetBucketSize set_bucket_size1
;
1991 cmds::GetProgramInfoCHROMIUM get_program_info
;
1992 cmd::GetBucketStart get_bucket_start
;
1993 cmd::SetToken set_token1
;
1994 cmd::SetBucketSize set_bucket_size2
;
1997 expected
.set_bucket_size1
.Init(kBucketId
, 0);
1998 expected
.get_program_info
.Init(kProgramId
, kBucketId
);
1999 expected
.get_bucket_start
.Init(
2000 kBucketId
, result1
.id
, result1
.offset
,
2001 MaxTransferBufferSize(), mem1
.id
, mem1
.offset
);
2002 expected
.set_token1
.Init(GetNextToken());
2003 expected
.set_bucket_size2
.Init(kBucketId
, 0);
2004 gl_
->GetProgramInfoCHROMIUM(kProgramId
, sizeof(buf
), &size
, &buf
);
2005 EXPECT_EQ(0, memcmp(&expected
, commands_
, sizeof(expected
)));
2006 EXPECT_EQ(static_cast<GLenum
>(GL_NO_ERROR
), gl_
->GetError());
2007 EXPECT_EQ(sizeof(kString
), static_cast<size_t>(size
));
2008 EXPECT_STREQ(kString
.str
, buf
);
2009 EXPECT_EQ(buf
[sizeof(kString
)], kBad
);
2012 TEST_F(GLES2ImplementationTest
, GetProgramInfoCHROMIUMBadArgs
) {
2013 const uint32 kBucketId
= GLES2Implementation::kResultBucketId
;
2014 const GLuint kProgramId
= 123;
2016 const Str7 kString
= {"foobar"};
2019 ExpectedMemoryInfo mem1
= GetExpectedMemory(MaxTransferBufferSize());
2020 ExpectedMemoryInfo result1
=
2021 GetExpectedResultMemory(sizeof(cmd::GetBucketStart::Result
));
2022 ExpectedMemoryInfo result2
=
2023 GetExpectedResultMemory(sizeof(cmds::GetError::Result
));
2024 ExpectedMemoryInfo result3
=
2025 GetExpectedResultMemory(sizeof(cmds::GetError::Result
));
2026 ExpectedMemoryInfo result4
=
2027 GetExpectedResultMemory(sizeof(cmds::GetError::Result
));
2029 EXPECT_CALL(*command_buffer(), OnFlush())
2030 .WillOnce(DoAll(SetMemory(result1
.ptr
, uint32(sizeof(kString
))),
2031 SetMemory(mem1
.ptr
, kString
)))
2032 .WillOnce(SetMemory(result2
.ptr
, GLuint(GL_NO_ERROR
)))
2033 .WillOnce(SetMemory(result3
.ptr
, GLuint(GL_NO_ERROR
)))
2034 .WillOnce(SetMemory(result4
.ptr
, GLuint(GL_NO_ERROR
)))
2035 .RetiresOnSaturation();
2037 // try bufsize not big enough.
2039 cmd::SetBucketSize set_bucket_size1
;
2040 cmds::GetProgramInfoCHROMIUM get_program_info
;
2041 cmd::GetBucketStart get_bucket_start
;
2042 cmd::SetToken set_token1
;
2043 cmd::SetBucketSize set_bucket_size2
;
2046 expected
.set_bucket_size1
.Init(kBucketId
, 0);
2047 expected
.get_program_info
.Init(kProgramId
, kBucketId
);
2048 expected
.get_bucket_start
.Init(
2049 kBucketId
, result1
.id
, result1
.offset
,
2050 MaxTransferBufferSize(), mem1
.id
, mem1
.offset
);
2051 expected
.set_token1
.Init(GetNextToken());
2052 expected
.set_bucket_size2
.Init(kBucketId
, 0);
2053 gl_
->GetProgramInfoCHROMIUM(kProgramId
, 6, &size
, &buf
);
2054 EXPECT_EQ(0, memcmp(&expected
, commands_
, sizeof(expected
)));
2055 EXPECT_EQ(static_cast<GLenum
>(GL_INVALID_OPERATION
), gl_
->GetError());
2059 gl_
->GetProgramInfoCHROMIUM(kProgramId
, -1, &size
, &buf
);
2060 EXPECT_TRUE(NoCommandsWritten());
2061 EXPECT_EQ(static_cast<GLenum
>(GL_INVALID_VALUE
), gl_
->GetError());
2064 gl_
->GetProgramInfoCHROMIUM(kProgramId
, sizeof(buf
), NULL
, &buf
);
2065 EXPECT_TRUE(NoCommandsWritten());
2066 EXPECT_EQ(static_cast<GLenum
>(GL_INVALID_VALUE
), gl_
->GetError());
2069 TEST_F(GLES2ImplementationTest
, GetUniformBlocksCHROMIUMGoodArgs
) {
2070 const uint32 kBucketId
= GLES2Implementation::kResultBucketId
;
2071 const GLuint kProgramId
= 123;
2072 const char kBad
= 0x12;
2074 const Str7 kString
= {"foobar"};
2077 ExpectedMemoryInfo mem1
=
2078 GetExpectedMemory(MaxTransferBufferSize());
2079 ExpectedMemoryInfo result1
=
2080 GetExpectedResultMemory(sizeof(cmd::GetBucketStart::Result
));
2081 ExpectedMemoryInfo result2
=
2082 GetExpectedResultMemory(sizeof(cmds::GetError::Result
));
2084 memset(buf
, kBad
, sizeof(buf
));
2085 EXPECT_CALL(*command_buffer(), OnFlush())
2086 .WillOnce(DoAll(SetMemory(result1
.ptr
, uint32(sizeof(kString
))),
2087 SetMemory(mem1
.ptr
, kString
)))
2088 .WillOnce(SetMemory(result2
.ptr
, GLuint(GL_NO_ERROR
)))
2089 .RetiresOnSaturation();
2092 cmd::SetBucketSize set_bucket_size1
;
2093 cmds::GetUniformBlocksCHROMIUM get_uniform_blocks
;
2094 cmd::GetBucketStart get_bucket_start
;
2095 cmd::SetToken set_token1
;
2096 cmd::SetBucketSize set_bucket_size2
;
2099 expected
.set_bucket_size1
.Init(kBucketId
, 0);
2100 expected
.get_uniform_blocks
.Init(kProgramId
, kBucketId
);
2101 expected
.get_bucket_start
.Init(
2102 kBucketId
, result1
.id
, result1
.offset
,
2103 MaxTransferBufferSize(), mem1
.id
, mem1
.offset
);
2104 expected
.set_token1
.Init(GetNextToken());
2105 expected
.set_bucket_size2
.Init(kBucketId
, 0);
2106 gl_
->GetUniformBlocksCHROMIUM(kProgramId
, sizeof(buf
), &size
, &buf
);
2107 EXPECT_EQ(0, memcmp(&expected
, commands_
, sizeof(expected
)));
2108 EXPECT_EQ(static_cast<GLenum
>(GL_NO_ERROR
), gl_
->GetError());
2109 EXPECT_EQ(sizeof(kString
), static_cast<size_t>(size
));
2110 EXPECT_STREQ(kString
.str
, buf
);
2111 EXPECT_EQ(buf
[sizeof(kString
)], kBad
);
2114 TEST_F(GLES2ImplementationTest
, GetUniformBlocksCHROMIUMBadArgs
) {
2115 const uint32 kBucketId
= GLES2Implementation::kResultBucketId
;
2116 const GLuint kProgramId
= 123;
2118 const Str7 kString
= {"foobar"};
2121 ExpectedMemoryInfo mem1
= GetExpectedMemory(MaxTransferBufferSize());
2122 ExpectedMemoryInfo result1
=
2123 GetExpectedResultMemory(sizeof(cmd::GetBucketStart::Result
));
2124 ExpectedMemoryInfo result2
=
2125 GetExpectedResultMemory(sizeof(cmds::GetError::Result
));
2126 ExpectedMemoryInfo result3
=
2127 GetExpectedResultMemory(sizeof(cmds::GetError::Result
));
2128 ExpectedMemoryInfo result4
=
2129 GetExpectedResultMemory(sizeof(cmds::GetError::Result
));
2131 EXPECT_CALL(*command_buffer(), OnFlush())
2132 .WillOnce(DoAll(SetMemory(result1
.ptr
, uint32(sizeof(kString
))),
2133 SetMemory(mem1
.ptr
, kString
)))
2134 .WillOnce(SetMemory(result2
.ptr
, GLuint(GL_NO_ERROR
)))
2135 .WillOnce(SetMemory(result3
.ptr
, GLuint(GL_NO_ERROR
)))
2136 .WillOnce(SetMemory(result4
.ptr
, GLuint(GL_NO_ERROR
)))
2137 .RetiresOnSaturation();
2139 // try bufsize not big enough.
2141 cmd::SetBucketSize set_bucket_size1
;
2142 cmds::GetUniformBlocksCHROMIUM get_uniform_blocks
;
2143 cmd::GetBucketStart get_bucket_start
;
2144 cmd::SetToken set_token1
;
2145 cmd::SetBucketSize set_bucket_size2
;
2148 expected
.set_bucket_size1
.Init(kBucketId
, 0);
2149 expected
.get_uniform_blocks
.Init(kProgramId
, kBucketId
);
2150 expected
.get_bucket_start
.Init(
2151 kBucketId
, result1
.id
, result1
.offset
,
2152 MaxTransferBufferSize(), mem1
.id
, mem1
.offset
);
2153 expected
.set_token1
.Init(GetNextToken());
2154 expected
.set_bucket_size2
.Init(kBucketId
, 0);
2155 gl_
->GetUniformBlocksCHROMIUM(kProgramId
, 6, &size
, &buf
);
2156 EXPECT_EQ(0, memcmp(&expected
, commands_
, sizeof(expected
)));
2157 EXPECT_EQ(static_cast<GLenum
>(GL_INVALID_OPERATION
), gl_
->GetError());
2161 gl_
->GetUniformBlocksCHROMIUM(kProgramId
, -1, &size
, &buf
);
2162 EXPECT_TRUE(NoCommandsWritten());
2163 EXPECT_EQ(static_cast<GLenum
>(GL_INVALID_VALUE
), gl_
->GetError());
2166 gl_
->GetUniformBlocksCHROMIUM(kProgramId
, sizeof(buf
), NULL
, &buf
);
2167 EXPECT_TRUE(NoCommandsWritten());
2168 EXPECT_EQ(static_cast<GLenum
>(GL_INVALID_VALUE
), gl_
->GetError());
2171 // Test that things are cached
2172 TEST_F(GLES2ImplementationTest
, GetIntegerCacheRead
) {
2177 const PNameValue pairs
[] = {
2178 {GL_ACTIVE_TEXTURE
, GL_TEXTURE0
, },
2179 {GL_TEXTURE_BINDING_2D
, 0, },
2180 {GL_TEXTURE_BINDING_CUBE_MAP
, 0, },
2181 {GL_TEXTURE_BINDING_EXTERNAL_OES
, 0, },
2182 {GL_FRAMEBUFFER_BINDING
, 0, },
2183 {GL_RENDERBUFFER_BINDING
, 0, },
2184 {GL_ARRAY_BUFFER_BINDING
, 0, },
2185 {GL_ELEMENT_ARRAY_BUFFER_BINDING
, 0, },
2186 {GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS
, kMaxCombinedTextureImageUnits
, },
2187 {GL_MAX_CUBE_MAP_TEXTURE_SIZE
, kMaxCubeMapTextureSize
, },
2188 {GL_MAX_FRAGMENT_UNIFORM_VECTORS
, kMaxFragmentUniformVectors
, },
2189 {GL_MAX_RENDERBUFFER_SIZE
, kMaxRenderbufferSize
, },
2190 {GL_MAX_TEXTURE_IMAGE_UNITS
, kMaxTextureImageUnits
, },
2191 {GL_MAX_TEXTURE_SIZE
, kMaxTextureSize
, },
2192 {GL_MAX_VARYING_VECTORS
, kMaxVaryingVectors
, },
2193 {GL_MAX_VERTEX_ATTRIBS
, kMaxVertexAttribs
, },
2194 {GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS
, kMaxVertexTextureImageUnits
, },
2195 {GL_MAX_VERTEX_UNIFORM_VECTORS
, kMaxVertexUniformVectors
, },
2196 {GL_NUM_COMPRESSED_TEXTURE_FORMATS
, kNumCompressedTextureFormats
, },
2197 {GL_NUM_SHADER_BINARY_FORMATS
, kNumShaderBinaryFormats
, }, };
2198 size_t num_pairs
= sizeof(pairs
) / sizeof(pairs
[0]);
2199 for (size_t ii
= 0; ii
< num_pairs
; ++ii
) {
2200 const PNameValue
& pv
= pairs
[ii
];
2202 gl_
->GetIntegerv(pv
.pname
, &v
);
2203 EXPECT_TRUE(NoCommandsWritten());
2204 EXPECT_EQ(pv
.expected
, v
);
2207 ExpectedMemoryInfo result1
=
2208 GetExpectedResultMemory(sizeof(cmds::GetError::Result
));
2210 EXPECT_CALL(*command_buffer(), OnFlush())
2211 .WillOnce(SetMemory(result1
.ptr
, GLuint(GL_NO_ERROR
)))
2212 .RetiresOnSaturation();
2213 EXPECT_EQ(static_cast<GLenum
>(GL_NO_ERROR
), gl_
->GetError());
2216 TEST_F(GLES2ImplementationTest
, GetIntegerDisjointValue
) {
2217 ExpectedMemoryInfo mem
= GetExpectedMappedMemory(sizeof(DisjointValueSync
));
2218 gl_
->SetDisjointValueSyncCHROMIUM();
2219 ASSERT_EQ(mem
.id
, GetQueryTracker()->DisjointCountSyncShmID());
2220 ASSERT_EQ(mem
.offset
, GetQueryTracker()->DisjointCountSyncShmOffset());
2221 DisjointValueSync
* disjoint_sync
=
2222 reinterpret_cast<DisjointValueSync
*>(mem
.ptr
);
2225 GLint disjoint_value
= -1;
2226 gl_
->GetIntegerv(GL_GPU_DISJOINT_EXT
, &disjoint_value
);
2227 EXPECT_TRUE(NoCommandsWritten());
2228 EXPECT_EQ(0, disjoint_value
);
2230 // After setting disjoint, it should be true.
2231 disjoint_value
= -1;
2232 disjoint_sync
->SetDisjointCount(1);
2233 gl_
->GetIntegerv(GL_GPU_DISJOINT_EXT
, &disjoint_value
);
2234 EXPECT_TRUE(NoCommandsWritten());
2235 EXPECT_EQ(1, disjoint_value
);
2237 // After checking disjoint, it should be false again.
2238 disjoint_value
= -1;
2239 gl_
->GetIntegerv(GL_GPU_DISJOINT_EXT
, &disjoint_value
);
2240 EXPECT_TRUE(NoCommandsWritten());
2241 EXPECT_EQ(0, disjoint_value
);
2243 // Check for errors.
2244 ExpectedMemoryInfo result1
=
2245 GetExpectedResultMemory(sizeof(cmds::GetError::Result
));
2246 EXPECT_CALL(*command_buffer(), OnFlush())
2247 .WillOnce(SetMemory(result1
.ptr
, GLuint(GL_NO_ERROR
)))
2248 .RetiresOnSaturation();
2249 EXPECT_EQ(static_cast<GLenum
>(GL_NO_ERROR
), gl_
->GetError());
2252 TEST_F(GLES2ImplementationTest
, GetIntegerCacheWrite
) {
2257 gl_
->ActiveTexture(GL_TEXTURE4
);
2258 gl_
->BindBuffer(GL_ARRAY_BUFFER
, 2);
2259 gl_
->BindBuffer(GL_ELEMENT_ARRAY_BUFFER
, 3);
2260 gl_
->BindFramebuffer(GL_FRAMEBUFFER
, 4);
2261 gl_
->BindRenderbuffer(GL_RENDERBUFFER
, 5);
2262 gl_
->BindTexture(GL_TEXTURE_2D
, 6);
2263 gl_
->BindTexture(GL_TEXTURE_CUBE_MAP
, 7);
2264 gl_
->BindTexture(GL_TEXTURE_EXTERNAL_OES
, 8);
2266 const PNameValue pairs
[] = {{GL_ACTIVE_TEXTURE
, GL_TEXTURE4
, },
2267 {GL_ARRAY_BUFFER_BINDING
, 2, },
2268 {GL_ELEMENT_ARRAY_BUFFER_BINDING
, 3, },
2269 {GL_FRAMEBUFFER_BINDING
, 4, },
2270 {GL_RENDERBUFFER_BINDING
, 5, },
2271 {GL_TEXTURE_BINDING_2D
, 6, },
2272 {GL_TEXTURE_BINDING_CUBE_MAP
, 7, },
2273 {GL_TEXTURE_BINDING_EXTERNAL_OES
, 8, }, };
2274 size_t num_pairs
= sizeof(pairs
) / sizeof(pairs
[0]);
2275 for (size_t ii
= 0; ii
< num_pairs
; ++ii
) {
2276 const PNameValue
& pv
= pairs
[ii
];
2278 gl_
->GetIntegerv(pv
.pname
, &v
);
2279 EXPECT_EQ(pv
.expected
, v
);
2282 ExpectedMemoryInfo result1
=
2283 GetExpectedResultMemory(sizeof(cmds::GetError::Result
));
2285 EXPECT_CALL(*command_buffer(), OnFlush())
2286 .WillOnce(SetMemory(result1
.ptr
, GLuint(GL_NO_ERROR
)))
2287 .RetiresOnSaturation();
2288 EXPECT_EQ(static_cast<GLenum
>(GL_NO_ERROR
), gl_
->GetError());
2291 static bool CheckRect(
2292 int width
, int height
, GLenum format
, GLenum type
, int alignment
,
2293 const uint8
* r1
, const uint8
* r2
) {
2295 uint32 unpadded_row_size
= 0;
2296 uint32 padded_row_size
= 0;
2297 if (!GLES2Util::ComputeImageDataSizes(
2298 width
, height
, 1, format
, type
, alignment
, &size
, &unpadded_row_size
,
2299 &padded_row_size
)) {
2303 int r2_stride
= static_cast<int>(padded_row_size
);
2305 for (int y
= 0; y
< height
; ++y
) {
2306 if (memcmp(r1
, r2
, unpadded_row_size
) != 0) {
2309 r1
+= padded_row_size
;
2315 ACTION_P7(CheckRectAction
, width
, height
, format
, type
, alignment
, r1
, r2
) {
2316 EXPECT_TRUE(CheckRect(
2317 width
, height
, format
, type
, alignment
, r1
, r2
));
2320 TEST_F(GLES2ImplementationTest
, TexImage2D
) {
2322 cmds::TexImage2D tex_image_2d
;
2323 cmd::SetToken set_token
;
2326 cmds::TexImage2D tex_image_2d
;
2327 cmd::SetToken set_token
;
2329 const GLenum kTarget
= GL_TEXTURE_2D
;
2330 const GLint kLevel
= 0;
2331 const GLenum kFormat
= GL_RGB
;
2332 const GLsizei kWidth
= 3;
2333 const GLsizei kHeight
= 4;
2334 const GLint kBorder
= 0;
2335 const GLenum kType
= GL_UNSIGNED_BYTE
;
2336 const GLint kPixelStoreUnpackAlignment
= 4;
2337 static uint8 pixels
[] = {
2338 11, 12, 13, 13, 14, 15, 15, 16, 17, 101, 102, 103,
2339 21, 22, 23, 23, 24, 25, 25, 26, 27, 201, 202, 203,
2340 31, 32, 33, 33, 34, 35, 35, 36, 37, 123, 124, 125,
2341 41, 42, 43, 43, 44, 45, 45, 46, 47,
2344 ExpectedMemoryInfo mem1
= GetExpectedMemory(sizeof(pixels
));
2347 expected
.tex_image_2d
.Init(
2348 kTarget
, kLevel
, kFormat
, kWidth
, kHeight
, kFormat
, kType
,
2349 mem1
.id
, mem1
.offset
);
2350 expected
.set_token
.Init(GetNextToken());
2352 kTarget
, kLevel
, kFormat
, kWidth
, kHeight
, kBorder
, kFormat
, kType
,
2354 EXPECT_EQ(0, memcmp(&expected
, commands_
, sizeof(expected
)));
2355 EXPECT_TRUE(CheckRect(
2356 kWidth
, kHeight
, kFormat
, kType
, kPixelStoreUnpackAlignment
,
2360 TEST_F(GLES2ImplementationTest
, TexImage2DViaMappedMem
) {
2362 cmds::TexImage2D tex_image_2d
;
2363 cmd::SetToken set_token
;
2365 const GLenum kTarget
= GL_TEXTURE_2D
;
2366 const GLint kLevel
= 0;
2367 const GLenum kFormat
= GL_RGB
;
2368 const GLsizei kWidth
= 3;
2369 const GLint kBorder
= 0;
2370 const GLenum kType
= GL_UNSIGNED_BYTE
;
2371 const GLint kPixelStoreUnpackAlignment
= 4;
2374 uint32 unpadded_row_size
= 0;
2375 uint32 padded_row_size
= 0;
2376 ASSERT_TRUE(GLES2Util::ComputeImageDataSizes(
2377 kWidth
, 2, 1, kFormat
, kType
, kPixelStoreUnpackAlignment
,
2378 &size
, &unpadded_row_size
, &padded_row_size
));
2379 const GLsizei kMaxHeight
= (MaxTransferBufferSize() / padded_row_size
) * 2;
2380 const GLsizei kHeight
= kMaxHeight
* 2;
2381 ASSERT_TRUE(GLES2Util::ComputeImageDataSizes(
2382 kWidth
, kHeight
, 1, kFormat
, kType
, kPixelStoreUnpackAlignment
,
2383 &size
, &unpadded_row_size
, &padded_row_size
));
2385 scoped_ptr
<uint8
[]> pixels(new uint8
[size
]);
2386 for (uint32 ii
= 0; ii
< size
; ++ii
) {
2387 pixels
[ii
] = static_cast<uint8
>(ii
);
2390 ExpectedMemoryInfo mem1
= GetExpectedMappedMemory(size
);
2393 expected
.tex_image_2d
.Init(
2394 kTarget
, kLevel
, kFormat
, kWidth
, kHeight
, kFormat
, kType
,
2395 mem1
.id
, mem1
.offset
);
2396 expected
.set_token
.Init(GetNextToken());
2398 kTarget
, kLevel
, kFormat
, kWidth
, kHeight
, kBorder
, kFormat
, kType
,
2400 EXPECT_EQ(0, memcmp(&expected
, commands_
, sizeof(expected
)));
2401 EXPECT_TRUE(CheckRect(
2402 kWidth
, kHeight
, kFormat
, kType
, kPixelStoreUnpackAlignment
,
2403 pixels
.get(), mem1
.ptr
));
2406 // Test TexImage2D with 2 writes
2407 TEST_F(GLES2ImplementationTest
, TexImage2DViaTexSubImage2D
) {
2408 // Set limit to 1 to effectively disable mapped memory.
2409 SetMappedMemoryLimit(1);
2412 cmds::TexImage2D tex_image_2d
;
2413 cmds::TexSubImage2D tex_sub_image_2d1
;
2414 cmd::SetToken set_token1
;
2415 cmds::TexSubImage2D tex_sub_image_2d2
;
2416 cmd::SetToken set_token2
;
2418 const GLenum kTarget
= GL_TEXTURE_2D
;
2419 const GLint kLevel
= 0;
2420 const GLenum kFormat
= GL_RGB
;
2421 const GLint kBorder
= 0;
2422 const GLenum kType
= GL_UNSIGNED_BYTE
;
2423 const GLint kPixelStoreUnpackAlignment
= 4;
2424 const GLsizei kWidth
= 3;
2427 uint32 unpadded_row_size
= 0;
2428 uint32 padded_row_size
= 0;
2429 ASSERT_TRUE(GLES2Util::ComputeImageDataSizes(
2430 kWidth
, 2, 1, kFormat
, kType
, kPixelStoreUnpackAlignment
,
2431 &size
, &unpadded_row_size
, &padded_row_size
));
2432 const GLsizei kHeight
= (MaxTransferBufferSize() / padded_row_size
) * 2;
2433 ASSERT_TRUE(GLES2Util::ComputeImageDataSizes(
2434 kWidth
, kHeight
, 1, kFormat
, kType
, kPixelStoreUnpackAlignment
,
2435 &size
, NULL
, NULL
));
2436 uint32 half_size
= 0;
2437 ASSERT_TRUE(GLES2Util::ComputeImageDataSizes(
2438 kWidth
, kHeight
/ 2, 1, kFormat
, kType
, kPixelStoreUnpackAlignment
,
2439 &half_size
, NULL
, NULL
));
2441 scoped_ptr
<uint8
[]> pixels(new uint8
[size
]);
2442 for (uint32 ii
= 0; ii
< size
; ++ii
) {
2443 pixels
[ii
] = static_cast<uint8
>(ii
);
2446 ExpectedMemoryInfo mem1
= GetExpectedMemory(half_size
);
2447 ExpectedMemoryInfo mem2
= GetExpectedMemory(half_size
);
2450 expected
.tex_image_2d
.Init(
2451 kTarget
, kLevel
, kFormat
, kWidth
, kHeight
, kFormat
, kType
,
2453 expected
.tex_sub_image_2d1
.Init(
2454 kTarget
, kLevel
, 0, 0, kWidth
, kHeight
/ 2, kFormat
, kType
,
2455 mem1
.id
, mem1
.offset
, true);
2456 expected
.set_token1
.Init(GetNextToken());
2457 expected
.tex_sub_image_2d2
.Init(
2458 kTarget
, kLevel
, 0, kHeight
/ 2, kWidth
, kHeight
/ 2, kFormat
, kType
,
2459 mem2
.id
, mem2
.offset
, true);
2460 expected
.set_token2
.Init(GetNextToken());
2462 // TODO(gman): Make it possible to run this test
2463 // EXPECT_CALL(*command_buffer(), OnFlush())
2464 // .WillOnce(CheckRectAction(
2465 // kWidth, kHeight / 2, kFormat, kType, kPixelStoreUnpackAlignment,
2466 // false, pixels.get(),
2467 // GetExpectedTransferAddressFromOffsetAs<uint8>(offset1, half_size)))
2468 // .RetiresOnSaturation();
2471 kTarget
, kLevel
, kFormat
, kWidth
, kHeight
, kBorder
, kFormat
, kType
,
2473 EXPECT_EQ(0, memcmp(&expected
, commands_
, sizeof(expected
)));
2474 EXPECT_TRUE(CheckRect(
2475 kWidth
, kHeight
/ 2, kFormat
, kType
, kPixelStoreUnpackAlignment
,
2476 pixels
.get() + kHeight
/ 2 * padded_row_size
, mem2
.ptr
));
2479 TEST_F(GLES2ImplementationTest
, SubImageUnpack
) {
2480 static const GLint unpack_alignments
[] = { 1, 2, 4, 8 };
2482 static const GLenum kFormat
= GL_RGB
;
2483 static const GLenum kType
= GL_UNSIGNED_BYTE
;
2484 static const GLint kLevel
= 0;
2485 static const GLint kBorder
= 0;
2486 // We're testing using the unpack params to pull a subimage out of a larger
2487 // source of pixels. Here we specify the subimage by its border rows /
2489 static const GLint kSrcWidth
= 33;
2490 static const GLint kSrcSubImageX0
= 11;
2491 static const GLint kSrcSubImageX1
= 20;
2492 static const GLint kSrcSubImageY0
= 18;
2493 static const GLint kSrcSubImageY1
= 23;
2494 static const GLint kSrcSubImageWidth
= kSrcSubImageX1
- kSrcSubImageX0
;
2495 static const GLint kSrcSubImageHeight
= kSrcSubImageY1
- kSrcSubImageY0
;
2497 // these are only used in the texsubimage tests
2498 static const GLint kTexWidth
= 1023;
2499 static const GLint kTexHeight
= 511;
2500 static const GLint kTexSubXOffset
= 419;
2501 static const GLint kTexSubYOffset
= 103;
2504 cmds::PixelStorei pixel_store_i
;
2505 cmds::TexImage2D tex_image_2d
;
2509 cmds::PixelStorei pixel_store_i
;
2510 cmds::TexImage2D tex_image_2d
;
2511 cmds::TexSubImage2D tex_sub_image_2d
;
2512 } texSubImageExpected
;
2515 ASSERT_TRUE(GLES2Util::ComputeImageDataSizes(
2516 kSrcWidth
, kSrcSubImageY1
, 1, kFormat
, kType
, 8, &src_size
, NULL
, NULL
));
2517 scoped_ptr
<uint8
[]> src_pixels
;
2518 src_pixels
.reset(new uint8
[src_size
]);
2519 for (size_t i
= 0; i
< src_size
; ++i
) {
2520 src_pixels
[i
] = static_cast<int8
>(i
);
2523 for (int sub
= 0; sub
< 2; ++sub
) {
2524 for (size_t a
= 0; a
< arraysize(unpack_alignments
); ++a
) {
2525 GLint alignment
= unpack_alignments
[a
];
2527 uint32 unpadded_row_size
;
2528 uint32 padded_row_size
;
2529 ASSERT_TRUE(GLES2Util::ComputeImageDataSizes(
2530 kSrcSubImageWidth
, kSrcSubImageHeight
, 1, kFormat
, kType
, alignment
,
2531 &size
, &unpadded_row_size
, &padded_row_size
));
2532 ASSERT_TRUE(size
<= MaxTransferBufferSize());
2533 ExpectedMemoryInfo mem
= GetExpectedMemory(size
);
2535 const void* commands
= GetPut();
2536 gl_
->PixelStorei(GL_UNPACK_ALIGNMENT
, alignment
);
2537 gl_
->PixelStorei(GL_UNPACK_ROW_LENGTH_EXT
, kSrcWidth
);
2538 gl_
->PixelStorei(GL_UNPACK_SKIP_PIXELS_EXT
, kSrcSubImageX0
);
2539 gl_
->PixelStorei(GL_UNPACK_SKIP_ROWS_EXT
, kSrcSubImageY0
);
2542 GL_TEXTURE_2D
, kLevel
, kFormat
, kTexWidth
, kTexHeight
, kBorder
,
2543 kFormat
, kType
, NULL
);
2545 GL_TEXTURE_2D
, kLevel
, kTexSubXOffset
, kTexSubYOffset
,
2546 kSrcSubImageWidth
, kSrcSubImageHeight
, kFormat
, kType
,
2548 texSubImageExpected
.pixel_store_i
.Init(
2549 GL_UNPACK_ALIGNMENT
, alignment
);
2550 texSubImageExpected
.tex_image_2d
.Init(
2551 GL_TEXTURE_2D
, kLevel
, kFormat
, kTexWidth
, kTexHeight
,
2552 kFormat
, kType
, 0, 0);
2553 texSubImageExpected
.tex_sub_image_2d
.Init(
2554 GL_TEXTURE_2D
, kLevel
, kTexSubXOffset
, kTexSubYOffset
,
2555 kSrcSubImageWidth
, kSrcSubImageHeight
, kFormat
, kType
, mem
.id
,
2556 mem
.offset
, GL_FALSE
);
2557 EXPECT_EQ(0, memcmp(
2558 &texSubImageExpected
, commands
, sizeof(texSubImageExpected
)));
2561 GL_TEXTURE_2D
, kLevel
, kFormat
,
2562 kSrcSubImageWidth
, kSrcSubImageHeight
, kBorder
, kFormat
, kType
,
2564 texImageExpected
.pixel_store_i
.Init(GL_UNPACK_ALIGNMENT
, alignment
);
2565 texImageExpected
.tex_image_2d
.Init(
2566 GL_TEXTURE_2D
, kLevel
, kFormat
, kSrcSubImageWidth
,
2567 kSrcSubImageHeight
, kFormat
, kType
, mem
.id
, mem
.offset
);
2568 EXPECT_EQ(0, memcmp(
2569 &texImageExpected
, commands
, sizeof(texImageExpected
)));
2571 uint32 src_padded_row_size
;
2572 ASSERT_TRUE(GLES2Util::ComputeImagePaddedRowSize(
2573 kSrcWidth
, kFormat
, kType
, alignment
, &src_padded_row_size
));
2574 uint32 bytes_per_group
= GLES2Util::ComputeImageGroupSize(
2576 for (int y
= 0; y
< kSrcSubImageHeight
; ++y
) {
2577 const uint8
* src_row
= src_pixels
.get() +
2578 (kSrcSubImageY0
+ y
) * src_padded_row_size
+
2579 bytes_per_group
* kSrcSubImageX0
;
2580 const uint8
* dst_row
= mem
.ptr
+ y
* padded_row_size
;
2581 EXPECT_EQ(0, memcmp(src_row
, dst_row
, unpadded_row_size
));
2588 // Test texture related calls with invalid arguments.
2589 TEST_F(GLES2ImplementationTest
, TextureInvalidArguments
) {
2591 cmds::TexImage2D tex_image_2d
;
2592 cmd::SetToken set_token
;
2594 const GLenum kTarget
= GL_TEXTURE_2D
;
2595 const GLint kLevel
= 0;
2596 const GLenum kFormat
= GL_RGB
;
2597 const GLsizei kWidth
= 3;
2598 const GLsizei kHeight
= 4;
2599 const GLint kBorder
= 0;
2600 const GLint kInvalidBorder
= 1;
2601 const GLenum kType
= GL_UNSIGNED_BYTE
;
2602 const GLint kPixelStoreUnpackAlignment
= 4;
2603 static uint8 pixels
[] = {
2604 11, 12, 13, 13, 14, 15, 15, 16, 17, 101, 102, 103,
2605 21, 22, 23, 23, 24, 25, 25, 26, 27, 201, 202, 203,
2606 31, 32, 33, 33, 34, 35, 35, 36, 37, 123, 124, 125,
2607 41, 42, 43, 43, 44, 45, 45, 46, 47,
2610 // Verify that something works.
2612 ExpectedMemoryInfo mem1
= GetExpectedMemory(sizeof(pixels
));
2615 expected
.tex_image_2d
.Init(
2616 kTarget
, kLevel
, kFormat
, kWidth
, kHeight
, kFormat
, kType
,
2617 mem1
.id
, mem1
.offset
);
2618 expected
.set_token
.Init(GetNextToken());
2620 kTarget
, kLevel
, kFormat
, kWidth
, kHeight
, kBorder
, kFormat
, kType
,
2622 EXPECT_EQ(0, memcmp(&expected
, commands_
, sizeof(expected
)));
2623 EXPECT_TRUE(CheckRect(
2624 kWidth
, kHeight
, kFormat
, kType
, kPixelStoreUnpackAlignment
,
2629 // Use invalid border.
2631 kTarget
, kLevel
, kFormat
, kWidth
, kHeight
, kInvalidBorder
, kFormat
, kType
,
2634 EXPECT_TRUE(NoCommandsWritten());
2635 EXPECT_EQ(GL_INVALID_VALUE
, CheckError());
2639 gl_
->AsyncTexImage2DCHROMIUM(
2640 kTarget
, kLevel
, kFormat
, kWidth
, kHeight
, kInvalidBorder
, kFormat
, kType
,
2643 EXPECT_TRUE(NoCommandsWritten());
2644 EXPECT_EQ(GL_INVALID_VALUE
, CheckError());
2648 // Checking for CompressedTexImage2D argument validation is a bit tricky due
2649 // to (runtime-detected) compression formats. Try to infer the error with an
2651 const GLenum kCompressedFormat
= GL_ETC1_RGB8_OES
;
2652 gl_
->CompressedTexImage2D(
2653 kTarget
, kLevel
, kCompressedFormat
, kWidth
, kHeight
, kBorder
,
2654 arraysize(pixels
), pixels
);
2656 // In the above, kCompressedFormat and arraysize(pixels) are possibly wrong
2657 // values. First ensure that these do not cause failures at the client. If
2658 // this check ever fails, it probably means that client checks more than at
2659 // the time of writing of this test. In this case, more code needs to be
2660 // written for this test.
2661 EXPECT_FALSE(NoCommandsWritten());
2665 // Changing border to invalid border should make the call fail at the client
2667 gl_
->CompressedTexImage2D(
2668 kTarget
, kLevel
, kCompressedFormat
, kWidth
, kHeight
, kInvalidBorder
,
2669 arraysize(pixels
), pixels
);
2670 EXPECT_TRUE(NoCommandsWritten());
2671 EXPECT_EQ(GL_INVALID_VALUE
, CheckError());
2674 TEST_F(GLES2ImplementationTest
, TexImage3DSingleCommand
) {
2676 cmds::TexImage3D tex_image_3d
;
2678 const GLenum kTarget
= GL_TEXTURE_3D
;
2679 const GLint kLevel
= 0;
2680 const GLint kBorder
= 0;
2681 const GLenum kFormat
= GL_RGB
;
2682 const GLenum kType
= GL_UNSIGNED_BYTE
;
2683 const GLint kPixelStoreUnpackAlignment
= 4;
2684 const GLsizei kWidth
= 3;
2685 const GLsizei kDepth
= 2;
2688 uint32 unpadded_row_size
= 0;
2689 uint32 padded_row_size
= 0;
2690 ASSERT_TRUE(GLES2Util::ComputeImageDataSizes(
2691 kWidth
, 2, kDepth
, kFormat
, kType
, kPixelStoreUnpackAlignment
,
2692 &size
, &unpadded_row_size
, &padded_row_size
));
2693 // Makes sure we can just send over the data in one command.
2694 const GLsizei kHeight
= MaxTransferBufferSize() / padded_row_size
/ kDepth
;
2695 ASSERT_TRUE(GLES2Util::ComputeImageDataSizes(
2696 kWidth
, kHeight
, kDepth
, kFormat
, kType
, kPixelStoreUnpackAlignment
,
2697 &size
, NULL
, NULL
));
2699 scoped_ptr
<uint8
[]> pixels(new uint8
[size
]);
2700 for (uint32 ii
= 0; ii
< size
; ++ii
) {
2701 pixels
[ii
] = static_cast<uint8
>(ii
);
2704 ExpectedMemoryInfo mem
= GetExpectedMemory(size
);
2707 expected
.tex_image_3d
.Init(
2708 kTarget
, kLevel
, kFormat
, kWidth
, kHeight
, kDepth
,
2709 kFormat
, kType
, mem
.id
, mem
.offset
);
2712 kTarget
, kLevel
, kFormat
, kWidth
, kHeight
, kDepth
, kBorder
,
2713 kFormat
, kType
, pixels
.get());
2715 EXPECT_EQ(0, memcmp(&expected
, commands_
, sizeof(expected
)));
2716 EXPECT_TRUE(CheckRect(
2717 kWidth
, kHeight
* kDepth
, kFormat
, kType
, kPixelStoreUnpackAlignment
,
2718 reinterpret_cast<uint8
*>(pixels
.get()), mem
.ptr
));
2721 TEST_F(GLES2ImplementationTest
, TexImage3DViaMappedMem
) {
2723 cmds::TexImage3D tex_image_3d
;
2725 const GLenum kTarget
= GL_TEXTURE_3D
;
2726 const GLint kLevel
= 0;
2727 const GLint kBorder
= 0;
2728 const GLenum kFormat
= GL_RGB
;
2729 const GLenum kType
= GL_UNSIGNED_BYTE
;
2730 const GLint kPixelStoreUnpackAlignment
= 4;
2731 const GLsizei kWidth
= 3;
2732 const GLsizei kDepth
= 2;
2735 uint32 unpadded_row_size
= 0;
2736 uint32 padded_row_size
= 0;
2737 ASSERT_TRUE(GLES2Util::ComputeImageDataSizes(
2738 kWidth
, 2, kDepth
, kFormat
, kType
, kPixelStoreUnpackAlignment
,
2739 &size
, &unpadded_row_size
, &padded_row_size
));
2740 // Makes sure we can just send over the data in one command.
2741 const GLsizei kMaxHeight
= MaxTransferBufferSize() / padded_row_size
/ kDepth
;
2742 const GLsizei kHeight
= kMaxHeight
* 2;
2743 ASSERT_TRUE(GLES2Util::ComputeImageDataSizes(
2744 kWidth
, kHeight
, kDepth
, kFormat
, kType
, kPixelStoreUnpackAlignment
,
2745 &size
, NULL
, NULL
));
2747 scoped_ptr
<uint8
[]> pixels(new uint8
[size
]);
2748 for (uint32 ii
= 0; ii
< size
; ++ii
) {
2749 pixels
[ii
] = static_cast<uint8
>(ii
);
2752 ExpectedMemoryInfo mem
= GetExpectedMappedMemory(size
);
2755 expected
.tex_image_3d
.Init(
2756 kTarget
, kLevel
, kFormat
, kWidth
, kHeight
, kDepth
,
2757 kFormat
, kType
, mem
.id
, mem
.offset
);
2760 kTarget
, kLevel
, kFormat
, kWidth
, kHeight
, kDepth
, kBorder
,
2761 kFormat
, kType
, pixels
.get());
2763 EXPECT_EQ(0, memcmp(&expected
, commands_
, sizeof(expected
)));
2764 EXPECT_TRUE(CheckRect(
2765 kWidth
, kHeight
* kDepth
, kFormat
, kType
, kPixelStoreUnpackAlignment
,
2766 reinterpret_cast<uint8
*>(pixels
.get()), mem
.ptr
));
2769 TEST_F(GLES2ImplementationTest
, TexImage3DViaTexSubImage3D
) {
2770 // Set limit to 1 to effectively disable mapped memory.
2771 SetMappedMemoryLimit(1);
2774 cmds::TexImage3D tex_image_3d
;
2775 cmds::TexSubImage3D tex_sub_image_3d1
;
2776 cmd::SetToken set_token
;
2777 cmds::TexSubImage3D tex_sub_image_3d2
;
2779 const GLenum kTarget
= GL_TEXTURE_3D
;
2780 const GLint kLevel
= 0;
2781 const GLint kBorder
= 0;
2782 const GLenum kFormat
= GL_RGB
;
2783 const GLenum kType
= GL_UNSIGNED_BYTE
;
2784 const GLint kPixelStoreUnpackAlignment
= 4;
2785 const GLsizei kWidth
= 3;
2788 uint32 unpadded_row_size
= 0;
2789 uint32 padded_row_size
= 0;
2790 ASSERT_TRUE(GLES2Util::ComputeImageDataSizes(
2791 kWidth
, 2, 1, kFormat
, kType
, kPixelStoreUnpackAlignment
,
2792 &size
, &unpadded_row_size
, &padded_row_size
));
2793 // Makes sure the data is more than one command can hold.
2794 const GLsizei kHeight
= MaxTransferBufferSize() / padded_row_size
+ 3;
2795 ASSERT_TRUE(GLES2Util::ComputeImageDataSizes(
2796 kWidth
, kHeight
, 1, kFormat
, kType
, kPixelStoreUnpackAlignment
,
2797 &size
, NULL
, NULL
));
2798 uint32 first_size
= padded_row_size
* (kHeight
- 3);
2799 uint32 second_size
=
2800 padded_row_size
* 3 - (padded_row_size
- unpadded_row_size
);
2801 EXPECT_EQ(size
, first_size
+ second_size
);
2802 ExpectedMemoryInfo mem1
= GetExpectedMemory(first_size
);
2803 ExpectedMemoryInfo mem2
= GetExpectedMemory(second_size
);
2804 scoped_ptr
<uint8
[]> pixels(new uint8
[size
]);
2805 for (uint32 ii
= 0; ii
< size
; ++ii
) {
2806 pixels
[ii
] = static_cast<uint8
>(ii
);
2810 expected
.tex_image_3d
.Init(
2811 kTarget
, kLevel
, kFormat
, kWidth
, kHeight
, 1, kFormat
, kType
, 0, 0);
2812 expected
.tex_sub_image_3d1
.Init(
2813 kTarget
, kLevel
, 0, 0, 0, kWidth
, kHeight
- 3, 1, kFormat
, kType
,
2814 mem1
.id
, mem1
.offset
, GL_TRUE
);
2815 expected
.tex_sub_image_3d2
.Init(
2816 kTarget
, kLevel
, 0, kHeight
- 3, 0, kWidth
, 3, 1, kFormat
, kType
,
2817 mem2
.id
, mem2
.offset
, GL_TRUE
);
2818 expected
.set_token
.Init(GetNextToken());
2821 kTarget
, kLevel
, kFormat
, kWidth
, kHeight
, 1, kBorder
,
2822 kFormat
, kType
, pixels
.get());
2823 EXPECT_EQ(0, memcmp(&expected
, commands_
, sizeof(expected
)));
2826 // Test TexSubImage3D with 4 writes
2827 TEST_F(GLES2ImplementationTest
, TexSubImage3D4Writes
) {
2829 cmds::TexSubImage3D tex_sub_image_3d1_1
;
2830 cmd::SetToken set_token1
;
2831 cmds::TexSubImage3D tex_sub_image_3d1_2
;
2832 cmd::SetToken set_token2
;
2833 cmds::TexSubImage3D tex_sub_image_3d2_1
;
2834 cmd::SetToken set_token3
;
2835 cmds::TexSubImage3D tex_sub_image_3d2_2
;
2837 const GLenum kTarget
= GL_TEXTURE_3D
;
2838 const GLint kLevel
= 0;
2839 const GLint kXOffset
= 0;
2840 const GLint kYOffset
= 0;
2841 const GLint kZOffset
= 0;
2842 const GLenum kFormat
= GL_RGB
;
2843 const GLenum kType
= GL_UNSIGNED_BYTE
;
2844 const GLint kPixelStoreUnpackAlignment
= 4;
2845 const GLsizei kWidth
= 3;
2846 const GLsizei kDepth
= 2;
2849 uint32 unpadded_row_size
= 0;
2850 uint32 padded_row_size
= 0;
2851 ASSERT_TRUE(GLES2Util::ComputeImageDataSizes(
2852 kWidth
, 2, 1, kFormat
, kType
, kPixelStoreUnpackAlignment
,
2853 &size
, &unpadded_row_size
, &padded_row_size
));
2854 const GLsizei kHeight
= MaxTransferBufferSize() / padded_row_size
+ 2;
2855 ASSERT_TRUE(GLES2Util::ComputeImageDataSizes(
2856 kWidth
, kHeight
, kDepth
, kFormat
, kType
, kPixelStoreUnpackAlignment
,
2857 &size
, NULL
, NULL
));
2858 uint32 first_size
= (kHeight
- 2) * padded_row_size
;
2859 uint32 second_size
= 2 * padded_row_size
;
2860 uint32 third_size
= first_size
;
2861 uint32 fourth_size
= second_size
- (padded_row_size
- unpadded_row_size
);
2862 EXPECT_EQ(size
, first_size
+ second_size
+ third_size
+ fourth_size
);
2864 scoped_ptr
<uint8
[]> pixels(new uint8
[size
]);
2865 for (uint32 ii
= 0; ii
< size
; ++ii
) {
2866 pixels
[ii
] = static_cast<uint8
>(ii
);
2869 ExpectedMemoryInfo mem1_1
= GetExpectedMemory(first_size
);
2870 ExpectedMemoryInfo mem1_2
= GetExpectedMemory(second_size
);
2871 ExpectedMemoryInfo mem2_1
= GetExpectedMemory(third_size
);
2872 ExpectedMemoryInfo mem2_2
= GetExpectedMemory(fourth_size
);
2875 expected
.tex_sub_image_3d1_1
.Init(
2876 kTarget
, kLevel
, kXOffset
, kYOffset
, kZOffset
,
2877 kWidth
, kHeight
- 2, 1, kFormat
, kType
,
2878 mem1_1
.id
, mem1_1
.offset
, GL_FALSE
);
2879 expected
.tex_sub_image_3d1_2
.Init(
2880 kTarget
, kLevel
, kXOffset
, kYOffset
+ kHeight
- 2, kZOffset
,
2881 kWidth
, 2, 1, kFormat
, kType
, mem1_2
.id
, mem1_2
.offset
, GL_FALSE
);
2882 expected
.tex_sub_image_3d2_1
.Init(
2883 kTarget
, kLevel
, kXOffset
, kYOffset
, kZOffset
+ 1,
2884 kWidth
, kHeight
- 2, 1, kFormat
, kType
,
2885 mem2_1
.id
, mem2_1
.offset
, GL_FALSE
);
2886 expected
.tex_sub_image_3d2_2
.Init(
2887 kTarget
, kLevel
, kXOffset
, kYOffset
+ kHeight
- 2, kZOffset
+ 1,
2888 kWidth
, 2, 1, kFormat
, kType
, mem2_2
.id
, mem2_2
.offset
, GL_FALSE
);
2889 expected
.set_token1
.Init(GetNextToken());
2890 expected
.set_token2
.Init(GetNextToken());
2891 expected
.set_token3
.Init(GetNextToken());
2894 kTarget
, kLevel
, kXOffset
, kYOffset
, kZOffset
, kWidth
, kHeight
, kDepth
,
2895 kFormat
, kType
, pixels
.get());
2897 EXPECT_EQ(0, memcmp(&expected
, commands_
, sizeof(expected
)));
2898 uint32 offset_to_last
= first_size
+ second_size
+ third_size
;
2899 EXPECT_TRUE(CheckRect(
2900 kWidth
, 2, kFormat
, kType
, kPixelStoreUnpackAlignment
,
2901 reinterpret_cast<uint8
*>(pixels
.get()) + offset_to_last
, mem2_2
.ptr
));
2904 // glGen* Ids must not be reused until glDelete* commands have been
2905 // flushed by glFlush.
2906 TEST_F(GLES2ImplementationStrictSharedTest
, FlushGenerationTestBuffers
) {
2907 FlushGenerationTest
<GenBuffersAPI
>();
2909 TEST_F(GLES2ImplementationStrictSharedTest
, FlushGenerationTestFramebuffers
) {
2910 FlushGenerationTest
<GenFramebuffersAPI
>();
2912 TEST_F(GLES2ImplementationStrictSharedTest
, FlushGenerationTestRenderbuffers
) {
2913 FlushGenerationTest
<GenRenderbuffersAPI
>();
2915 TEST_F(GLES2ImplementationStrictSharedTest
, FlushGenerationTestTextures
) {
2916 FlushGenerationTest
<GenTexturesAPI
>();
2919 // glGen* Ids must not be reused cross-context until glDelete* commands are
2920 // flushed by glFlush, and the Ids are lazily freed after.
2921 TEST_F(GLES2ImplementationStrictSharedTest
, CrossContextGenerationTestBuffers
) {
2922 CrossContextGenerationTest
<GenBuffersAPI
>();
2924 TEST_F(GLES2ImplementationStrictSharedTest
,
2925 CrossContextGenerationTestFramebuffers
) {
2926 CrossContextGenerationTest
<GenFramebuffersAPI
>();
2928 TEST_F(GLES2ImplementationStrictSharedTest
,
2929 CrossContextGenerationTestRenderbuffers
) {
2930 CrossContextGenerationTest
<GenRenderbuffersAPI
>();
2932 TEST_F(GLES2ImplementationStrictSharedTest
,
2933 CrossContextGenerationTestTextures
) {
2934 CrossContextGenerationTest
<GenTexturesAPI
>();
2937 // Test Delete which causes auto flush. Tests a regression case that occurred
2939 TEST_F(GLES2ImplementationStrictSharedTest
,
2940 CrossContextGenerationAutoFlushTestBuffers
) {
2941 CrossContextGenerationAutoFlushTest
<GenBuffersAPI
>();
2943 TEST_F(GLES2ImplementationStrictSharedTest
,
2944 CrossContextGenerationAutoFlushTestFramebuffers
) {
2945 CrossContextGenerationAutoFlushTest
<GenFramebuffersAPI
>();
2947 TEST_F(GLES2ImplementationStrictSharedTest
,
2948 CrossContextGenerationAutoFlushTestRenderbuffers
) {
2949 CrossContextGenerationAutoFlushTest
<GenRenderbuffersAPI
>();
2951 TEST_F(GLES2ImplementationStrictSharedTest
,
2952 CrossContextGenerationAutoFlushTestTextures
) {
2953 CrossContextGenerationAutoFlushTest
<GenTexturesAPI
>();
2956 TEST_F(GLES2ImplementationTest
, GetString
) {
2957 const uint32 kBucketId
= GLES2Implementation::kResultBucketId
;
2958 const Str7 kString
= {"foobar"};
2959 // GL_CHROMIUM_map_sub is hard coded into GLES2Implementation.
2960 const char* expected_str
=
2962 "GL_EXT_unpack_subimage "
2963 "GL_CHROMIUM_map_sub";
2964 const char kBad
= 0x12;
2966 cmd::SetBucketSize set_bucket_size1
;
2967 cmds::GetString get_string
;
2968 cmd::GetBucketStart get_bucket_start
;
2969 cmd::SetToken set_token1
;
2970 cmd::SetBucketSize set_bucket_size2
;
2972 ExpectedMemoryInfo mem1
= GetExpectedMemory(MaxTransferBufferSize());
2973 ExpectedMemoryInfo result1
=
2974 GetExpectedResultMemory(sizeof(cmd::GetBucketStart::Result
));
2976 expected
.set_bucket_size1
.Init(kBucketId
, 0);
2977 expected
.get_string
.Init(GL_EXTENSIONS
, kBucketId
);
2978 expected
.get_bucket_start
.Init(
2979 kBucketId
, result1
.id
, result1
.offset
,
2980 MaxTransferBufferSize(), mem1
.id
, mem1
.offset
);
2981 expected
.set_token1
.Init(GetNextToken());
2982 expected
.set_bucket_size2
.Init(kBucketId
, 0);
2983 char buf
[sizeof(kString
) + 1];
2984 memset(buf
, kBad
, sizeof(buf
));
2986 EXPECT_CALL(*command_buffer(), OnFlush())
2987 .WillOnce(DoAll(SetMemory(result1
.ptr
, uint32(sizeof(kString
))),
2988 SetMemory(mem1
.ptr
, kString
)))
2989 .RetiresOnSaturation();
2991 const GLubyte
* result
= gl_
->GetString(GL_EXTENSIONS
);
2992 EXPECT_EQ(0, memcmp(&expected
, commands_
, sizeof(expected
)));
2993 EXPECT_STREQ(expected_str
, reinterpret_cast<const char*>(result
));
2996 TEST_F(GLES2ImplementationTest
, PixelStoreiGLPackReverseRowOrderANGLE
) {
2997 const uint32 kBucketId
= GLES2Implementation::kResultBucketId
;
2998 const Str7 kString
= {"foobar"};
3000 cmd::SetBucketSize set_bucket_size1
;
3001 cmds::GetString get_string
;
3002 cmd::GetBucketStart get_bucket_start
;
3003 cmd::SetToken set_token1
;
3004 cmd::SetBucketSize set_bucket_size2
;
3005 cmds::PixelStorei pixel_store
;
3008 ExpectedMemoryInfo mem1
= GetExpectedMemory(MaxTransferBufferSize());
3009 ExpectedMemoryInfo result1
=
3010 GetExpectedResultMemory(sizeof(cmd::GetBucketStart::Result
));
3013 expected
.set_bucket_size1
.Init(kBucketId
, 0);
3014 expected
.get_string
.Init(GL_EXTENSIONS
, kBucketId
);
3015 expected
.get_bucket_start
.Init(
3016 kBucketId
, result1
.id
, result1
.offset
,
3017 MaxTransferBufferSize(), mem1
.id
, mem1
.offset
);
3018 expected
.set_token1
.Init(GetNextToken());
3019 expected
.set_bucket_size2
.Init(kBucketId
, 0);
3020 expected
.pixel_store
.Init(GL_PACK_REVERSE_ROW_ORDER_ANGLE
, 1);
3022 EXPECT_CALL(*command_buffer(), OnFlush())
3023 .WillOnce(DoAll(SetMemory(result1
.ptr
, uint32(sizeof(kString
))),
3024 SetMemory(mem1
.ptr
, kString
)))
3025 .RetiresOnSaturation();
3027 gl_
->PixelStorei(GL_PACK_REVERSE_ROW_ORDER_ANGLE
, 1);
3028 EXPECT_EQ(0, memcmp(&expected
, commands_
, sizeof(expected
)));
3031 TEST_F(GLES2ImplementationTest
, CreateProgram
) {
3033 cmds::CreateProgram cmd
;
3037 expected
.cmd
.Init(kProgramsAndShadersStartId
);
3038 GLuint id
= gl_
->CreateProgram();
3039 EXPECT_EQ(0, memcmp(&expected
, commands_
, sizeof(expected
)));
3040 EXPECT_EQ(kProgramsAndShadersStartId
, id
);
3043 TEST_F(GLES2ImplementationTest
, BufferDataLargerThanTransferBuffer
) {
3045 cmds::BufferData set_size
;
3046 cmds::BufferSubData copy_data1
;
3047 cmd::SetToken set_token1
;
3048 cmds::BufferSubData copy_data2
;
3049 cmd::SetToken set_token2
;
3051 const unsigned kUsableSize
=
3052 kTransferBufferSize
- GLES2Implementation::kStartingOffset
;
3053 uint8 buf
[kUsableSize
* 2] = { 0, };
3055 ExpectedMemoryInfo mem1
= GetExpectedMemory(kUsableSize
);
3056 ExpectedMemoryInfo mem2
= GetExpectedMemory(kUsableSize
);
3059 expected
.set_size
.Init(
3060 GL_ARRAY_BUFFER
, arraysize(buf
), 0, 0, GL_DYNAMIC_DRAW
);
3061 expected
.copy_data1
.Init(
3062 GL_ARRAY_BUFFER
, 0, kUsableSize
, mem1
.id
, mem1
.offset
);
3063 expected
.set_token1
.Init(GetNextToken());
3064 expected
.copy_data2
.Init(
3065 GL_ARRAY_BUFFER
, kUsableSize
, kUsableSize
, mem2
.id
, mem2
.offset
);
3066 expected
.set_token2
.Init(GetNextToken());
3067 gl_
->BufferData(GL_ARRAY_BUFFER
, arraysize(buf
), buf
, GL_DYNAMIC_DRAW
);
3068 EXPECT_EQ(0, memcmp(&expected
, commands_
, sizeof(expected
)));
3071 TEST_F(GLES2ImplementationTest
, CapabilitiesAreCached
) {
3072 static const GLenum kStates
[] = {
3077 GL_POLYGON_OFFSET_FILL
,
3078 GL_SAMPLE_ALPHA_TO_COVERAGE
,
3084 cmds::Enable enable_cmd
;
3088 for (size_t ii
= 0; ii
< arraysize(kStates
); ++ii
) {
3089 GLenum state
= kStates
[ii
];
3090 expected
.enable_cmd
.Init(state
);
3091 GLboolean result
= gl_
->IsEnabled(state
);
3092 EXPECT_EQ(static_cast<GLboolean
>(ii
== 0), result
);
3093 EXPECT_TRUE(NoCommandsWritten());
3094 const void* commands
= GetPut();
3097 EXPECT_EQ(0, memcmp(&expected
, commands
, sizeof(expected
)));
3100 result
= gl_
->IsEnabled(state
);
3101 EXPECT_TRUE(result
);
3102 EXPECT_TRUE(NoCommandsWritten());
3106 TEST_F(GLES2ImplementationTest
, BindVertexArrayOES
) {
3108 gl_
->GenVertexArraysOES(1, &id
);
3112 cmds::BindVertexArrayOES cmd
;
3115 expected
.cmd
.Init(id
);
3117 const void* commands
= GetPut();
3118 gl_
->BindVertexArrayOES(id
);
3119 EXPECT_EQ(0, memcmp(&expected
, commands
, sizeof(expected
)));
3121 gl_
->BindVertexArrayOES(id
);
3122 EXPECT_TRUE(NoCommandsWritten());
3125 TEST_F(GLES2ImplementationTest
, BeginEndQueryEXT
) {
3126 // Test GetQueryivEXT returns 0 if no current query.
3128 gl_
->GetQueryivEXT(GL_ANY_SAMPLES_PASSED_EXT
, GL_CURRENT_QUERY_EXT
, ¶m
);
3129 EXPECT_EQ(0, param
);
3131 GLuint expected_ids
[2] = { 1, 2 }; // These must match what's actually genned.
3133 cmds::GenQueriesEXTImmediate gen
;
3136 GenCmds expected_gen_cmds
;
3137 expected_gen_cmds
.gen
.Init(arraysize(expected_ids
), &expected_ids
[0]);
3138 GLuint ids
[arraysize(expected_ids
)] = { 0, };
3139 gl_
->GenQueriesEXT(arraysize(expected_ids
), &ids
[0]);
3140 EXPECT_EQ(0, memcmp(
3141 &expected_gen_cmds
, commands_
, sizeof(expected_gen_cmds
)));
3142 GLuint id1
= ids
[0];
3143 GLuint id2
= ids
[1];
3146 // Test BeginQueryEXT fails if id = 0.
3147 gl_
->BeginQueryEXT(GL_ANY_SAMPLES_PASSED_EXT
, 0);
3148 EXPECT_TRUE(NoCommandsWritten());
3149 EXPECT_EQ(GL_INVALID_OPERATION
, CheckError());
3151 // Test BeginQueryEXT inserts command.
3153 cmds::BeginQueryEXT begin_query
;
3155 BeginCmds expected_begin_cmds
;
3156 const void* commands
= GetPut();
3157 gl_
->BeginQueryEXT(GL_ANY_SAMPLES_PASSED_EXT
, id1
);
3158 QueryTracker::Query
* query
= GetQuery(id1
);
3159 ASSERT_TRUE(query
!= NULL
);
3160 expected_begin_cmds
.begin_query
.Init(
3161 GL_ANY_SAMPLES_PASSED_EXT
, id1
, query
->shm_id(), query
->shm_offset());
3162 EXPECT_EQ(0, memcmp(
3163 &expected_begin_cmds
, commands
, sizeof(expected_begin_cmds
)));
3166 // Test GetQueryivEXT returns id.
3168 gl_
->GetQueryivEXT(GL_ANY_SAMPLES_PASSED_EXT
, GL_CURRENT_QUERY_EXT
, ¶m
);
3169 EXPECT_EQ(id1
, static_cast<GLuint
>(param
));
3171 GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT
, GL_CURRENT_QUERY_EXT
, ¶m
);
3172 EXPECT_EQ(0, param
);
3174 // Test BeginQueryEXT fails if between Begin/End.
3175 gl_
->BeginQueryEXT(GL_ANY_SAMPLES_PASSED_EXT
, id2
);
3176 EXPECT_TRUE(NoCommandsWritten());
3177 EXPECT_EQ(GL_INVALID_OPERATION
, CheckError());
3179 // Test EndQueryEXT fails if target not same as current query.
3181 gl_
->EndQueryEXT(GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT
);
3182 EXPECT_TRUE(NoCommandsWritten());
3183 EXPECT_EQ(GL_INVALID_OPERATION
, CheckError());
3185 // Test EndQueryEXT sends command
3187 cmds::EndQueryEXT end_query
;
3189 EndCmds expected_end_cmds
;
3190 expected_end_cmds
.end_query
.Init(
3191 GL_ANY_SAMPLES_PASSED_EXT
, query
->submit_count());
3192 commands
= GetPut();
3193 gl_
->EndQueryEXT(GL_ANY_SAMPLES_PASSED_EXT
);
3194 EXPECT_EQ(0, memcmp(
3195 &expected_end_cmds
, commands
, sizeof(expected_end_cmds
)));
3197 // Test EndQueryEXT fails if no current query.
3199 gl_
->EndQueryEXT(GL_ANY_SAMPLES_PASSED_EXT
);
3200 EXPECT_TRUE(NoCommandsWritten());
3201 EXPECT_EQ(GL_INVALID_OPERATION
, CheckError());
3203 // Test 2nd Begin/End increments count.
3204 base::subtle::Atomic32 old_submit_count
= query
->submit_count();
3205 gl_
->BeginQueryEXT(GL_ANY_SAMPLES_PASSED_EXT
, id1
);
3206 EXPECT_NE(old_submit_count
, query
->submit_count());
3207 expected_end_cmds
.end_query
.Init(
3208 GL_ANY_SAMPLES_PASSED_EXT
, query
->submit_count());
3209 commands
= GetPut();
3210 gl_
->EndQueryEXT(GL_ANY_SAMPLES_PASSED_EXT
);
3211 EXPECT_EQ(0, memcmp(
3212 &expected_end_cmds
, commands
, sizeof(expected_end_cmds
)));
3214 // Test BeginQueryEXT fails if target changed.
3216 gl_
->BeginQueryEXT(GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT
, id1
);
3217 EXPECT_TRUE(NoCommandsWritten());
3218 EXPECT_EQ(GL_INVALID_OPERATION
, CheckError());
3220 // Test GetQueryObjectuivEXT fails if unused id
3221 GLuint available
= 0xBDu
;
3223 gl_
->GetQueryObjectuivEXT(id2
, GL_QUERY_RESULT_AVAILABLE_EXT
, &available
);
3224 EXPECT_TRUE(NoCommandsWritten());
3225 EXPECT_EQ(0xBDu
, available
);
3226 EXPECT_EQ(GL_INVALID_OPERATION
, CheckError());
3228 // Test GetQueryObjectuivEXT fails if bad id
3230 gl_
->GetQueryObjectuivEXT(4567, GL_QUERY_RESULT_AVAILABLE_EXT
, &available
);
3231 EXPECT_TRUE(NoCommandsWritten());
3232 EXPECT_EQ(0xBDu
, available
);
3233 EXPECT_EQ(GL_INVALID_OPERATION
, CheckError());
3235 // Test GetQueryObjectuivEXT CheckResultsAvailable
3237 gl_
->GetQueryObjectuivEXT(id1
, GL_QUERY_RESULT_AVAILABLE_EXT
, &available
);
3238 EXPECT_EQ(0u, available
);
3240 // Test GetQueryObjectui64vEXT fails if unused id
3241 GLuint64 available2
= 0xBDu
;
3243 gl_
->GetQueryObjectui64vEXT(id2
, GL_QUERY_RESULT_AVAILABLE_EXT
, &available2
);
3244 EXPECT_TRUE(NoCommandsWritten());
3245 EXPECT_EQ(0xBDu
, available2
);
3246 EXPECT_EQ(GL_INVALID_OPERATION
, CheckError());
3248 // Test GetQueryObjectui64vEXT fails if bad id
3250 gl_
->GetQueryObjectui64vEXT(4567, GL_QUERY_RESULT_AVAILABLE_EXT
, &available2
);
3251 EXPECT_TRUE(NoCommandsWritten());
3252 EXPECT_EQ(0xBDu
, available2
);
3253 EXPECT_EQ(GL_INVALID_OPERATION
, CheckError());
3255 // Test GetQueryObjectui64vEXT CheckResultsAvailable
3257 gl_
->GetQueryObjectui64vEXT(id1
, GL_QUERY_RESULT_AVAILABLE_EXT
, &available2
);
3258 EXPECT_EQ(0u, available2
);
3261 TEST_F(GLES2ImplementationManualInitTest
, BadQueryTargets
) {
3262 ContextInitOptions init_options
;
3263 init_options
.sync_query
= false;
3264 init_options
.occlusion_query_boolean
= false;
3265 init_options
.timer_queries
= false;
3266 ASSERT_TRUE(Initialize(init_options
));
3269 gl_
->GenQueriesEXT(1, &id
);
3272 gl_
->BeginQueryEXT(GL_COMMANDS_COMPLETED_CHROMIUM
, id
);
3273 EXPECT_EQ(GL_INVALID_OPERATION
, CheckError());
3274 EXPECT_EQ(nullptr, GetQuery(id
));
3276 gl_
->BeginQueryEXT(GL_ANY_SAMPLES_PASSED
, id
);
3277 EXPECT_EQ(GL_INVALID_OPERATION
, CheckError());
3278 EXPECT_EQ(nullptr, GetQuery(id
));
3280 gl_
->BeginQueryEXT(GL_ANY_SAMPLES_PASSED_CONSERVATIVE
, id
);
3281 EXPECT_EQ(GL_INVALID_OPERATION
, CheckError());
3282 EXPECT_EQ(nullptr, GetQuery(id
));
3284 gl_
->BeginQueryEXT(GL_TIME_ELAPSED_EXT
, id
);
3285 EXPECT_EQ(GL_INVALID_OPERATION
, CheckError());
3286 EXPECT_EQ(nullptr, GetQuery(id
));
3288 gl_
->BeginQueryEXT(0x123, id
);
3289 EXPECT_EQ(GL_INVALID_ENUM
, CheckError());
3290 EXPECT_EQ(nullptr, GetQuery(id
));
3292 gl_
->QueryCounterEXT(id
, GL_TIMESTAMP_EXT
);
3293 EXPECT_EQ(GL_INVALID_OPERATION
, CheckError());
3294 EXPECT_EQ(nullptr, GetQuery(id
));
3296 gl_
->QueryCounterEXT(id
, 0x123);
3297 EXPECT_EQ(GL_INVALID_ENUM
, CheckError());
3298 EXPECT_EQ(nullptr, GetQuery(id
));
3301 TEST_F(GLES2ImplementationTest
, SetDisjointSync
) {
3302 struct SetDisjointSyncCmd
{
3303 cmds::SetDisjointValueSyncCHROMIUM disjoint_sync
;
3305 SetDisjointSyncCmd expected_disjoint_sync_cmd
;
3306 const void* commands
= GetPut();
3307 gl_
->SetDisjointValueSyncCHROMIUM();
3308 expected_disjoint_sync_cmd
.disjoint_sync
.Init(
3309 GetQueryTracker()->DisjointCountSyncShmID(),
3310 GetQueryTracker()->DisjointCountSyncShmOffset());
3312 EXPECT_EQ(0, memcmp(&expected_disjoint_sync_cmd
, commands
,
3313 sizeof(expected_disjoint_sync_cmd
)));
3316 TEST_F(GLES2ImplementationTest
, QueryCounterEXT
) {
3317 GLuint expected_ids
[2] = { 1, 2 }; // These must match what's actually genned.
3319 cmds::GenQueriesEXTImmediate gen
;
3322 GenCmds expected_gen_cmds
;
3323 expected_gen_cmds
.gen
.Init(arraysize(expected_ids
), &expected_ids
[0]);
3324 GLuint ids
[arraysize(expected_ids
)] = { 0, };
3325 gl_
->GenQueriesEXT(arraysize(expected_ids
), &ids
[0]);
3326 EXPECT_EQ(0, memcmp(
3327 &expected_gen_cmds
, commands_
, sizeof(expected_gen_cmds
)));
3328 GLuint id1
= ids
[0];
3329 GLuint id2
= ids
[1];
3332 // Make sure disjoint value is synchronized already.
3333 gl_
->SetDisjointValueSyncCHROMIUM();
3336 // Test QueryCounterEXT fails if id = 0.
3337 gl_
->QueryCounterEXT(0, GL_TIMESTAMP_EXT
);
3338 EXPECT_TRUE(NoCommandsWritten());
3339 EXPECT_EQ(GL_INVALID_OPERATION
, CheckError());
3341 // Test QueryCounterEXT fails if target is unknown.
3343 gl_
->QueryCounterEXT(id1
, GL_TIME_ELAPSED_EXT
);
3344 EXPECT_TRUE(NoCommandsWritten());
3345 EXPECT_EQ(GL_INVALID_ENUM
, CheckError());
3347 // Test QueryCounterEXT inserts command.
3348 struct QueryCounterCmds
{
3349 cmds::QueryCounterEXT query_counter
;
3351 QueryCounterCmds expected_query_counter_cmds
;
3352 const void* commands
= GetPut();
3353 gl_
->QueryCounterEXT(id1
, GL_TIMESTAMP_EXT
);
3354 EXPECT_EQ(GL_NO_ERROR
, CheckError());
3355 QueryTracker::Query
* query
= GetQuery(id1
);
3356 ASSERT_TRUE(query
!= NULL
);
3357 expected_query_counter_cmds
.query_counter
.Init(
3358 GL_TIMESTAMP_EXT
, id1
, query
->shm_id(), query
->shm_offset(),
3359 query
->submit_count());
3360 EXPECT_EQ(0, memcmp(&expected_query_counter_cmds
, commands
,
3361 sizeof(expected_query_counter_cmds
)));
3364 // Test 2nd QueryCounterEXT succeeds.
3365 commands
= GetPut();
3366 gl_
->QueryCounterEXT(id2
, GL_TIMESTAMP_EXT
);
3367 EXPECT_EQ(GL_NO_ERROR
, CheckError());
3368 QueryTracker::Query
* query2
= GetQuery(id2
);
3369 ASSERT_TRUE(query2
!= NULL
);
3370 expected_query_counter_cmds
.query_counter
.Init(
3371 GL_TIMESTAMP_EXT
, id2
, query2
->shm_id(), query2
->shm_offset(),
3372 query2
->submit_count());
3373 EXPECT_EQ(0, memcmp(&expected_query_counter_cmds
, commands
,
3374 sizeof(expected_query_counter_cmds
)));
3377 // Test QueryCounterEXT increments count.
3378 base::subtle::Atomic32 old_submit_count
= query
->submit_count();
3379 commands
= GetPut();
3380 gl_
->QueryCounterEXT(id1
, GL_TIMESTAMP_EXT
);
3381 EXPECT_EQ(GL_NO_ERROR
, CheckError());
3382 EXPECT_NE(old_submit_count
, query
->submit_count());
3383 expected_query_counter_cmds
.query_counter
.Init(
3384 GL_TIMESTAMP_EXT
, id1
, query
->shm_id(), query
->shm_offset(),
3385 query
->submit_count());
3386 EXPECT_EQ(0, memcmp(&expected_query_counter_cmds
, commands
,
3387 sizeof(expected_query_counter_cmds
)));
3390 // Test GetQueryObjectuivEXT CheckResultsAvailable
3391 GLuint available
= 0xBDu
;
3393 gl_
->GetQueryObjectuivEXT(id1
, GL_QUERY_RESULT_AVAILABLE_EXT
, &available
);
3394 EXPECT_EQ(0u, available
);
3396 // Test GetQueryObjectui64vEXT CheckResultsAvailable
3397 GLuint64 available2
= 0xBDu
;
3399 gl_
->GetQueryObjectui64vEXT(id1
, GL_QUERY_RESULT_AVAILABLE_EXT
, &available2
);
3400 EXPECT_EQ(0u, available2
);
3403 TEST_F(GLES2ImplementationTest
, ErrorQuery
) {
3405 gl_
->GenQueriesEXT(1, &id
);
3408 // Test BeginQueryEXT does NOT insert commands.
3409 gl_
->BeginQueryEXT(GL_GET_ERROR_QUERY_CHROMIUM
, id
);
3410 EXPECT_TRUE(NoCommandsWritten());
3411 QueryTracker::Query
* query
= GetQuery(id
);
3412 ASSERT_TRUE(query
!= NULL
);
3414 // Test EndQueryEXT sends both begin and end command
3416 cmds::BeginQueryEXT begin_query
;
3417 cmds::EndQueryEXT end_query
;
3419 EndCmds expected_end_cmds
;
3420 expected_end_cmds
.begin_query
.Init(
3421 GL_GET_ERROR_QUERY_CHROMIUM
, id
, query
->shm_id(), query
->shm_offset());
3422 expected_end_cmds
.end_query
.Init(
3423 GL_GET_ERROR_QUERY_CHROMIUM
, query
->submit_count());
3424 const void* commands
= GetPut();
3425 gl_
->EndQueryEXT(GL_GET_ERROR_QUERY_CHROMIUM
);
3426 EXPECT_EQ(0, memcmp(
3427 &expected_end_cmds
, commands
, sizeof(expected_end_cmds
)));
3430 // Check result is not yet available.
3431 GLuint available
= 0xBDu
;
3432 gl_
->GetQueryObjectuivEXT(id
, GL_QUERY_RESULT_AVAILABLE_EXT
, &available
);
3433 EXPECT_TRUE(NoCommandsWritten());
3434 EXPECT_EQ(0u, available
);
3436 // Test no commands are sent if there is a client side error.
3438 // Generate a client side error
3439 gl_
->ActiveTexture(GL_TEXTURE0
- 1);
3441 gl_
->BeginQueryEXT(GL_GET_ERROR_QUERY_CHROMIUM
, id
);
3442 gl_
->EndQueryEXT(GL_GET_ERROR_QUERY_CHROMIUM
);
3443 EXPECT_TRUE(NoCommandsWritten());
3445 // Check result is available.
3446 gl_
->GetQueryObjectuivEXT(id
, GL_QUERY_RESULT_AVAILABLE_EXT
, &available
);
3447 EXPECT_TRUE(NoCommandsWritten());
3448 EXPECT_NE(0u, available
);
3451 GLuint result
= 0xBDu
;
3452 gl_
->GetQueryObjectuivEXT(id
, GL_QUERY_RESULT_EXT
, &result
);
3453 EXPECT_TRUE(NoCommandsWritten());
3454 EXPECT_EQ(static_cast<GLuint
>(GL_INVALID_ENUM
), result
);
3457 #if !defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS)
3458 TEST_F(GLES2ImplementationTest
, VertexArrays
) {
3459 const GLuint kAttribIndex1
= 1;
3460 const GLint kNumComponents1
= 3;
3461 const GLsizei kClientStride
= 12;
3464 gl_
->GenVertexArraysOES(1, &id
);
3467 gl_
->BindVertexArrayOES(id
);
3469 // Test that VertexAttribPointer cannot be called with a bound buffer of 0
3470 // unless the offset is NULL
3471 gl_
->BindBuffer(GL_ARRAY_BUFFER
, 0);
3473 gl_
->VertexAttribPointer(
3474 kAttribIndex1
, kNumComponents1
, GL_FLOAT
, GL_FALSE
, kClientStride
,
3475 reinterpret_cast<const void*>(4));
3476 EXPECT_EQ(GL_INVALID_OPERATION
, CheckError());
3478 gl_
->VertexAttribPointer(
3479 kAttribIndex1
, kNumComponents1
, GL_FLOAT
, GL_FALSE
, kClientStride
, NULL
);
3480 EXPECT_EQ(GL_NO_ERROR
, CheckError());
3484 TEST_F(GLES2ImplementationTest
, Disable
) {
3489 expected
.cmd
.Init(GL_DITHER
); // Note: DITHER defaults to enabled.
3491 gl_
->Disable(GL_DITHER
);
3492 EXPECT_EQ(0, memcmp(&expected
, commands_
, sizeof(expected
)));
3493 // Check it's cached and not called again.
3495 gl_
->Disable(GL_DITHER
);
3496 EXPECT_TRUE(NoCommandsWritten());
3499 TEST_F(GLES2ImplementationTest
, Enable
) {
3504 expected
.cmd
.Init(GL_BLEND
); // Note: BLEND defaults to disabled.
3506 gl_
->Enable(GL_BLEND
);
3507 EXPECT_EQ(0, memcmp(&expected
, commands_
, sizeof(expected
)));
3508 // Check it's cached and not called again.
3510 gl_
->Enable(GL_BLEND
);
3511 EXPECT_TRUE(NoCommandsWritten());
3514 TEST_F(GLES2ImplementationTest
, ConsumeTextureCHROMIUM
) {
3516 cmds::ConsumeTextureCHROMIUMImmediate cmd
;
3520 Mailbox mailbox
= Mailbox::Generate();
3522 expected
.cmd
.Init(GL_TEXTURE_2D
, mailbox
.name
);
3523 gl_
->ConsumeTextureCHROMIUM(GL_TEXTURE_2D
, mailbox
.name
);
3524 EXPECT_EQ(0, memcmp(&expected
, commands_
, sizeof(expected
)));
3527 TEST_F(GLES2ImplementationTest
, CreateAndConsumeTextureCHROMIUM
) {
3529 cmds::CreateAndConsumeTextureCHROMIUMImmediate cmd
;
3533 Mailbox mailbox
= Mailbox::Generate();
3535 expected
.cmd
.Init(GL_TEXTURE_2D
, kTexturesStartId
, mailbox
.name
);
3536 GLuint id
= gl_
->CreateAndConsumeTextureCHROMIUM(GL_TEXTURE_2D
, mailbox
.name
);
3537 EXPECT_EQ(0, memcmp(&expected
, commands_
, sizeof(expected
)));
3538 EXPECT_EQ(kTexturesStartId
, id
);
3541 TEST_F(GLES2ImplementationTest
, ProduceTextureCHROMIUM
) {
3543 cmds::ProduceTextureCHROMIUMImmediate cmd
;
3547 Mailbox mailbox
= Mailbox::Generate();
3549 expected
.cmd
.Init(GL_TEXTURE_2D
, mailbox
.name
);
3550 gl_
->ProduceTextureCHROMIUM(GL_TEXTURE_2D
, mailbox
.name
);
3551 EXPECT_EQ(0, memcmp(&expected
, commands_
, sizeof(expected
)));
3554 TEST_F(GLES2ImplementationTest
, ProduceTextureDirectCHROMIUM
) {
3556 cmds::ProduceTextureDirectCHROMIUMImmediate cmd
;
3560 Mailbox mailbox
= Mailbox::Generate();
3562 expected
.cmd
.Init(kTexturesStartId
, GL_TEXTURE_2D
, mailbox
.name
);
3563 gl_
->ProduceTextureDirectCHROMIUM(
3564 kTexturesStartId
, GL_TEXTURE_2D
, mailbox
.name
);
3565 EXPECT_EQ(0, memcmp(&expected
, commands_
, sizeof(expected
)));
3568 TEST_F(GLES2ImplementationTest
, LimitSizeAndOffsetTo32Bit
) {
3571 if (sizeof(size
) <= 4 || sizeof(offset
) <= 4)
3573 // The below two casts should be no-op, as we return early if
3574 // it's 32-bit system.
3575 int64 value64
= 0x100000000;
3576 size
= static_cast<GLsizeiptr
>(value64
);
3577 offset
= static_cast<GLintptr
>(value64
);
3579 const char kSizeOverflowMessage
[] = "size more than 32-bit";
3580 const char kOffsetOverflowMessage
[] = "offset more than 32-bit";
3582 const GLfloat buf
[] = { 1.0, 1.0, 1.0, 1.0 };
3583 const GLubyte indices
[] = { 0 };
3585 const GLuint kClientArrayBufferId
= 0x789;
3586 const GLuint kClientElementArrayBufferId
= 0x790;
3587 gl_
->BindBuffer(GL_ARRAY_BUFFER
, kClientArrayBufferId
);
3588 gl_
->BindBuffer(GL_ELEMENT_ARRAY_BUFFER
, kClientElementArrayBufferId
);
3589 EXPECT_EQ(GL_NO_ERROR
, CheckError());
3591 // Call BufferData() should succeed with legal paramaters.
3592 gl_
->BufferData(GL_ARRAY_BUFFER
, sizeof(buf
), buf
, GL_DYNAMIC_DRAW
);
3594 GL_ELEMENT_ARRAY_BUFFER
, sizeof(indices
), indices
, GL_DYNAMIC_DRAW
);
3595 EXPECT_EQ(GL_NO_ERROR
, CheckError());
3598 gl_
->BufferData(GL_ARRAY_BUFFER
, size
, buf
, GL_DYNAMIC_DRAW
);
3599 EXPECT_EQ(GL_INVALID_OPERATION
, CheckError());
3600 EXPECT_STREQ(kSizeOverflowMessage
, GetLastError().c_str());
3602 // Call BufferSubData() should succeed with legal paramaters.
3603 gl_
->BufferSubData(GL_ARRAY_BUFFER
, 0, sizeof(buf
[0]), buf
);
3604 EXPECT_EQ(GL_NO_ERROR
, CheckError());
3606 // BufferSubData: offset
3607 gl_
->BufferSubData(GL_ARRAY_BUFFER
, offset
, 1, buf
);
3608 EXPECT_EQ(GL_INVALID_OPERATION
, CheckError());
3609 EXPECT_STREQ(kOffsetOverflowMessage
, GetLastError().c_str());
3611 // BufferSubData: size
3612 EXPECT_EQ(GL_NO_ERROR
, CheckError());
3613 gl_
->BufferSubData(GL_ARRAY_BUFFER
, 0, size
, buf
);
3614 EXPECT_EQ(GL_INVALID_OPERATION
, CheckError());
3615 EXPECT_STREQ(kSizeOverflowMessage
, GetLastError().c_str());
3617 // Call MapBufferSubDataCHROMIUM() should succeed with legal paramaters.
3619 gl_
->MapBufferSubDataCHROMIUM(GL_ARRAY_BUFFER
, 0, 1, GL_WRITE_ONLY
);
3620 EXPECT_TRUE(NULL
!= mem
);
3621 EXPECT_EQ(GL_NO_ERROR
, CheckError());
3622 gl_
->UnmapBufferSubDataCHROMIUM(mem
);
3624 // MapBufferSubDataCHROMIUM: offset
3625 EXPECT_TRUE(NULL
== gl_
->MapBufferSubDataCHROMIUM(
3626 GL_ARRAY_BUFFER
, offset
, 1, GL_WRITE_ONLY
));
3627 EXPECT_EQ(GL_INVALID_OPERATION
, CheckError());
3628 EXPECT_STREQ(kOffsetOverflowMessage
, GetLastError().c_str());
3630 // MapBufferSubDataCHROMIUM: size
3631 EXPECT_EQ(GL_NO_ERROR
, CheckError());
3632 EXPECT_TRUE(NULL
== gl_
->MapBufferSubDataCHROMIUM(
3633 GL_ARRAY_BUFFER
, 0, size
, GL_WRITE_ONLY
));
3634 EXPECT_EQ(GL_INVALID_OPERATION
, CheckError());
3635 EXPECT_STREQ(kSizeOverflowMessage
, GetLastError().c_str());
3637 // Call DrawElements() should succeed with legal paramaters.
3638 gl_
->DrawElements(GL_POINTS
, 1, GL_UNSIGNED_BYTE
, NULL
);
3639 EXPECT_EQ(GL_NO_ERROR
, CheckError());
3641 // DrawElements: offset
3643 GL_POINTS
, 1, GL_UNSIGNED_BYTE
, reinterpret_cast<void*>(offset
));
3644 EXPECT_EQ(GL_INVALID_OPERATION
, CheckError());
3645 EXPECT_STREQ(kOffsetOverflowMessage
, GetLastError().c_str());
3647 // Call DrawElementsInstancedANGLE() should succeed with legal paramaters.
3648 gl_
->DrawElementsInstancedANGLE(GL_POINTS
, 1, GL_UNSIGNED_BYTE
, NULL
, 1);
3649 EXPECT_EQ(GL_NO_ERROR
, CheckError());
3651 // DrawElementsInstancedANGLE: offset
3652 gl_
->DrawElementsInstancedANGLE(
3653 GL_POINTS
, 1, GL_UNSIGNED_BYTE
, reinterpret_cast<void*>(offset
), 1);
3654 EXPECT_EQ(GL_INVALID_OPERATION
, CheckError());
3655 EXPECT_STREQ(kOffsetOverflowMessage
, GetLastError().c_str());
3657 // Call VertexAttribPointer() should succeed with legal paramaters.
3658 const GLuint kAttribIndex
= 1;
3659 const GLsizei kStride
= 4;
3660 gl_
->VertexAttribPointer(
3661 kAttribIndex
, 1, GL_FLOAT
, GL_FALSE
, kStride
, NULL
);
3662 EXPECT_EQ(GL_NO_ERROR
, CheckError());
3664 // VertexAttribPointer: offset
3665 gl_
->VertexAttribPointer(
3666 kAttribIndex
, 1, GL_FLOAT
, GL_FALSE
, kStride
,
3667 reinterpret_cast<void*>(offset
));
3668 EXPECT_EQ(GL_INVALID_OPERATION
, CheckError());
3669 EXPECT_STREQ(kOffsetOverflowMessage
, GetLastError().c_str());
3672 TEST_F(GLES2ImplementationTest
, TraceBeginCHROMIUM
) {
3673 const uint32 kCategoryBucketId
= GLES2Implementation::kResultBucketId
;
3674 const uint32 kNameBucketId
= GLES2Implementation::kResultBucketId
+ 1;
3675 const std::string category_name
= "test category";
3676 const std::string trace_name
= "test trace";
3677 const size_t kPaddedString1Size
=
3678 transfer_buffer_
->RoundToAlignment(category_name
.size() + 1);
3679 const size_t kPaddedString2Size
=
3680 transfer_buffer_
->RoundToAlignment(trace_name
.size() + 1);
3682 gl_
->TraceBeginCHROMIUM(category_name
.c_str(), trace_name
.c_str());
3683 EXPECT_EQ(GL_NO_ERROR
, CheckError());
3686 cmd::SetBucketSize category_size1
;
3687 cmd::SetBucketData category_data
;
3688 cmd::SetToken set_token1
;
3689 cmd::SetBucketSize name_size1
;
3690 cmd::SetBucketData name_data
;
3691 cmd::SetToken set_token2
;
3692 cmds::TraceBeginCHROMIUM trace_call_begin
;
3693 cmd::SetBucketSize category_size2
;
3694 cmd::SetBucketSize name_size2
;
3697 ExpectedMemoryInfo mem1
= GetExpectedMemory(kPaddedString1Size
);
3698 ExpectedMemoryInfo mem2
= GetExpectedMemory(kPaddedString2Size
);
3700 ASSERT_STREQ(category_name
.c_str(), reinterpret_cast<char*>(mem1
.ptr
));
3701 ASSERT_STREQ(trace_name
.c_str(), reinterpret_cast<char*>(mem2
.ptr
));
3704 expected
.category_size1
.Init(kCategoryBucketId
, category_name
.size() + 1);
3705 expected
.category_data
.Init(
3706 kCategoryBucketId
, 0, category_name
.size() + 1, mem1
.id
, mem1
.offset
);
3707 expected
.set_token1
.Init(GetNextToken());
3708 expected
.name_size1
.Init(kNameBucketId
, trace_name
.size() + 1);
3709 expected
.name_data
.Init(
3710 kNameBucketId
, 0, trace_name
.size() + 1, mem2
.id
, mem2
.offset
);
3711 expected
.set_token2
.Init(GetNextToken());
3712 expected
.trace_call_begin
.Init(kCategoryBucketId
, kNameBucketId
);
3713 expected
.category_size2
.Init(kCategoryBucketId
, 0);
3714 expected
.name_size2
.Init(kNameBucketId
, 0);
3716 EXPECT_EQ(0, memcmp(&expected
, commands_
, sizeof(expected
)));
3719 TEST_F(GLES2ImplementationTest
, AllowNestedTracesCHROMIUM
) {
3720 const std::string category1_name
= "test category 1";
3721 const std::string trace1_name
= "test trace 1";
3722 const std::string category2_name
= "test category 2";
3723 const std::string trace2_name
= "test trace 2";
3725 gl_
->TraceBeginCHROMIUM(category1_name
.c_str(), trace1_name
.c_str());
3726 EXPECT_EQ(GL_NO_ERROR
, CheckError());
3728 gl_
->TraceBeginCHROMIUM(category2_name
.c_str(), trace2_name
.c_str());
3729 EXPECT_EQ(GL_NO_ERROR
, CheckError());
3731 gl_
->TraceEndCHROMIUM();
3732 EXPECT_EQ(GL_NO_ERROR
, CheckError());
3734 gl_
->TraceEndCHROMIUM();
3735 EXPECT_EQ(GL_NO_ERROR
, CheckError());
3737 // No more corresponding begin tracer marker should error.
3738 gl_
->TraceEndCHROMIUM();
3739 EXPECT_EQ(GL_INVALID_OPERATION
, CheckError());
3742 TEST_F(GLES2ImplementationTest
, IsEnabled
) {
3743 // If we use a valid enum, its state is cached on client side, so no command
3744 // is actually generated, and this test will fail.
3745 // TODO(zmo): it seems we never need the command. Maybe remove it.
3748 cmds::IsEnabled cmd
;
3752 ExpectedMemoryInfo result1
=
3753 GetExpectedResultMemory(sizeof(cmds::IsEnabled::Result
));
3754 expected
.cmd
.Init(kCap
, result1
.id
, result1
.offset
);
3756 EXPECT_CALL(*command_buffer(), OnFlush())
3757 .WillOnce(SetMemory(result1
.ptr
, uint32_t(GL_TRUE
)))
3758 .RetiresOnSaturation();
3760 GLboolean result
= gl_
->IsEnabled(kCap
);
3761 EXPECT_EQ(0, memcmp(&expected
, commands_
, sizeof(expected
)));
3762 EXPECT_TRUE(result
);
3765 TEST_F(GLES2ImplementationTest
, ClientWaitSync
) {
3766 const GLuint client_sync_id
= 36;
3768 cmds::ClientWaitSync cmd
;
3772 ExpectedMemoryInfo result1
=
3773 GetExpectedResultMemory(sizeof(cmds::ClientWaitSync::Result
));
3774 const GLuint64 kTimeout
= 0xABCDEF0123456789;
3775 uint32_t v32_0
= 0, v32_1
= 0;
3776 GLES2Util::MapUint64ToTwoUint32(kTimeout
, &v32_0
, &v32_1
);
3777 expected
.cmd
.Init(client_sync_id
, GL_SYNC_FLUSH_COMMANDS_BIT
,
3778 v32_0
, v32_1
, result1
.id
, result1
.offset
);
3780 EXPECT_CALL(*command_buffer(), OnFlush())
3781 .WillOnce(SetMemory(result1
.ptr
, uint32_t(GL_CONDITION_SATISFIED
)))
3782 .RetiresOnSaturation();
3784 GLenum result
= gl_
->ClientWaitSync(
3785 reinterpret_cast<GLsync
>(client_sync_id
), GL_SYNC_FLUSH_COMMANDS_BIT
,
3787 EXPECT_EQ(0, memcmp(&expected
, commands_
, sizeof(expected
)));
3788 EXPECT_EQ(static_cast<GLenum
>(GL_CONDITION_SATISFIED
), result
);
3791 TEST_F(GLES2ImplementationTest
, WaitSync
) {
3792 const GLuint kClientSyncId
= 36;
3797 const GLuint64 kTimeout
= GL_TIMEOUT_IGNORED
;
3798 uint32_t v32_0
= 0, v32_1
= 0;
3799 GLES2Util::MapUint64ToTwoUint32(kTimeout
, &v32_0
, &v32_1
);
3800 expected
.cmd
.Init(kClientSyncId
, 0, v32_0
, v32_1
);
3802 gl_
->WaitSync(reinterpret_cast<GLsync
>(kClientSyncId
), 0, kTimeout
);
3803 EXPECT_EQ(0, memcmp(&expected
, commands_
, sizeof(expected
)));
3806 TEST_F(GLES2ImplementationTest
, MapBufferRangeUnmapBufferWrite
) {
3807 ExpectedMemoryInfo result
=
3808 GetExpectedResultMemory(sizeof(cmds::MapBufferRange::Result
));
3810 EXPECT_CALL(*command_buffer(), OnFlush())
3811 .WillOnce(SetMemory(result
.ptr
, uint32_t(1)))
3812 .RetiresOnSaturation();
3814 const GLuint kBufferId
= 123;
3815 gl_
->BindBuffer(GL_ARRAY_BUFFER
, kBufferId
);
3817 void* mem
= gl_
->MapBufferRange(GL_ARRAY_BUFFER
, 10, 64, GL_MAP_WRITE_BIT
);
3818 EXPECT_TRUE(mem
!= nullptr);
3820 EXPECT_TRUE(gl_
->UnmapBuffer(GL_ARRAY_BUFFER
));
3823 TEST_F(GLES2ImplementationTest
, MapBufferRangeWriteWithInvalidateBit
) {
3824 ExpectedMemoryInfo result
=
3825 GetExpectedResultMemory(sizeof(cmds::MapBufferRange::Result
));
3827 EXPECT_CALL(*command_buffer(), OnFlush())
3828 .WillOnce(SetMemory(result
.ptr
, uint32_t(1)))
3829 .RetiresOnSaturation();
3831 const GLuint kBufferId
= 123;
3832 gl_
->BindBuffer(GL_ARRAY_BUFFER
, kBufferId
);
3834 GLsizeiptr kSize
= 64;
3835 void* mem
= gl_
->MapBufferRange(
3836 GL_ARRAY_BUFFER
, 10, kSize
,
3837 GL_MAP_WRITE_BIT
| GL_MAP_INVALIDATE_RANGE_BIT
);
3838 EXPECT_TRUE(mem
!= nullptr);
3839 std::vector
<int8_t> zero(kSize
);
3840 memset(&zero
[0], 0, kSize
);
3841 EXPECT_EQ(0, memcmp(mem
, &zero
[0], kSize
));
3844 TEST_F(GLES2ImplementationTest
, MapBufferRangeWriteWithGLError
) {
3845 ExpectedMemoryInfo result
=
3846 GetExpectedResultMemory(sizeof(cmds::MapBufferRange::Result
));
3848 // Return a result of 0 to indicate an GL error.
3849 EXPECT_CALL(*command_buffer(), OnFlush())
3850 .WillOnce(SetMemory(result
.ptr
, uint32_t(0)))
3851 .RetiresOnSaturation();
3853 const GLuint kBufferId
= 123;
3854 gl_
->BindBuffer(GL_ARRAY_BUFFER
, kBufferId
);
3856 void* mem
= gl_
->MapBufferRange(GL_ARRAY_BUFFER
, 10, 64, GL_MAP_WRITE_BIT
);
3857 EXPECT_TRUE(mem
== nullptr);
3860 TEST_F(GLES2ImplementationTest
, MapBufferRangeUnmapBufferRead
) {
3861 ExpectedMemoryInfo result
=
3862 GetExpectedResultMemory(sizeof(cmds::MapBufferRange::Result
));
3864 EXPECT_CALL(*command_buffer(), OnFlush())
3865 .WillOnce(SetMemory(result
.ptr
, uint32_t(1)))
3866 .RetiresOnSaturation();
3868 const GLuint kBufferId
= 123;
3869 gl_
->BindBuffer(GL_ARRAY_BUFFER
, kBufferId
);
3871 void* mem
= gl_
->MapBufferRange(GL_ARRAY_BUFFER
, 10, 64, GL_MAP_READ_BIT
);
3872 EXPECT_TRUE(mem
!= nullptr);
3874 EXPECT_TRUE(gl_
->UnmapBuffer(GL_ARRAY_BUFFER
));
3877 TEST_F(GLES2ImplementationTest
, MapBufferRangeReadWithGLError
) {
3878 ExpectedMemoryInfo result
=
3879 GetExpectedResultMemory(sizeof(cmds::MapBufferRange::Result
));
3881 // Return a result of 0 to indicate an GL error.
3882 EXPECT_CALL(*command_buffer(), OnFlush())
3883 .WillOnce(SetMemory(result
.ptr
, uint32_t(0)))
3884 .RetiresOnSaturation();
3886 const GLuint kBufferId
= 123;
3887 gl_
->BindBuffer(GL_ARRAY_BUFFER
, kBufferId
);
3889 void* mem
= gl_
->MapBufferRange(GL_ARRAY_BUFFER
, 10, 64, GL_MAP_READ_BIT
);
3890 EXPECT_TRUE(mem
== nullptr);
3893 TEST_F(GLES2ImplementationTest
, UnmapBufferFails
) {
3895 EXPECT_FALSE(gl_
->UnmapBuffer(GL_ARRAY_BUFFER
));
3896 EXPECT_EQ(GL_INVALID_OPERATION
, CheckError());
3898 const GLuint kBufferId
= 123;
3899 gl_
->BindBuffer(GL_ARRAY_BUFFER
, kBufferId
);
3901 // Buffer is unmapped.
3902 EXPECT_FALSE(gl_
->UnmapBuffer(GL_ARRAY_BUFFER
));
3903 EXPECT_EQ(GL_INVALID_OPERATION
, CheckError());
3906 TEST_F(GLES2ImplementationTest
, BufferDataUnmapsDataStore
) {
3907 ExpectedMemoryInfo result
=
3908 GetExpectedResultMemory(sizeof(cmds::MapBufferRange::Result
));
3910 EXPECT_CALL(*command_buffer(), OnFlush())
3911 .WillOnce(SetMemory(result
.ptr
, uint32_t(1)))
3912 .RetiresOnSaturation();
3914 const GLuint kBufferId
= 123;
3915 gl_
->BindBuffer(GL_ARRAY_BUFFER
, kBufferId
);
3917 void* mem
= gl_
->MapBufferRange(GL_ARRAY_BUFFER
, 10, 64, GL_MAP_WRITE_BIT
);
3918 EXPECT_TRUE(mem
!= nullptr);
3920 std::vector
<uint8_t> data(16);
3921 // BufferData unmaps the data store.
3922 gl_
->BufferData(GL_ARRAY_BUFFER
, 16, &data
[0], GL_STREAM_DRAW
);
3924 EXPECT_FALSE(gl_
->UnmapBuffer(GL_ARRAY_BUFFER
));
3925 EXPECT_EQ(GL_INVALID_OPERATION
, CheckError());
3928 TEST_F(GLES2ImplementationTest
, DeleteBuffersUnmapsDataStore
) {
3929 ExpectedMemoryInfo result
=
3930 GetExpectedResultMemory(sizeof(cmds::MapBufferRange::Result
));
3932 EXPECT_CALL(*command_buffer(), OnFlush())
3933 .WillOnce(SetMemory(result
.ptr
, uint32_t(1)))
3934 .RetiresOnSaturation();
3936 const GLuint kBufferId
= 123;
3937 gl_
->BindBuffer(GL_ARRAY_BUFFER
, kBufferId
);
3939 void* mem
= gl_
->MapBufferRange(GL_ARRAY_BUFFER
, 10, 64, GL_MAP_WRITE_BIT
);
3940 EXPECT_TRUE(mem
!= nullptr);
3942 std::vector
<uint8_t> data(16);
3943 // DeleteBuffers unmaps the data store.
3944 gl_
->DeleteBuffers(1, &kBufferId
);
3946 EXPECT_FALSE(gl_
->UnmapBuffer(GL_ARRAY_BUFFER
));
3947 EXPECT_EQ(GL_INVALID_OPERATION
, CheckError());
3950 TEST_F(GLES2ImplementationTest
, GetInternalformativ
) {
3951 const GLint kNumSampleCounts
= 8;
3953 cmds::GetInternalformativ cmd
;
3955 typedef cmds::GetInternalformativ::Result::Type ResultType
;
3956 ResultType result
= 0;
3958 ExpectedMemoryInfo result1
=
3959 GetExpectedResultMemory(sizeof(uint32_t) + sizeof(ResultType
));
3960 expected
.cmd
.Init(123, GL_RGBA8
, GL_NUM_SAMPLE_COUNTS
,
3961 result1
.id
, result1
.offset
);
3962 EXPECT_CALL(*command_buffer(), OnFlush())
3963 .WillOnce(SetMemory(result1
.ptr
,
3964 SizedResultHelper
<ResultType
>(kNumSampleCounts
)))
3965 .RetiresOnSaturation();
3966 gl_
->GetInternalformativ(123, GL_RGBA8
, GL_NUM_SAMPLE_COUNTS
, 1, &result
);
3967 EXPECT_EQ(0, memcmp(&expected
, commands_
, sizeof(expected
)));
3968 EXPECT_EQ(static_cast<ResultType
>(kNumSampleCounts
), result
);
3971 TEST_F(GLES2ImplementationManualInitTest
, LoseContextOnOOM
) {
3972 ContextInitOptions init_options
;
3973 init_options
.lose_context_when_out_of_memory
= true;
3974 ASSERT_TRUE(Initialize(init_options
));
3977 cmds::LoseContextCHROMIUM cmd
;
3980 GLsizei max
= std::numeric_limits
<GLsizei
>::max();
3981 EXPECT_CALL(*gpu_control_
, CreateGpuMemoryBufferImage(max
, max
, _
, _
))
3982 .WillOnce(Return(-1));
3983 gl_
->CreateGpuMemoryBufferImageCHROMIUM(max
, max
, GL_RGBA
, GL_MAP_CHROMIUM
);
3984 // The context should be lost.
3986 expected
.cmd
.Init(GL_GUILTY_CONTEXT_RESET_ARB
, GL_UNKNOWN_CONTEXT_RESET_ARB
);
3987 EXPECT_EQ(0, memcmp(&expected
, commands_
, sizeof(expected
)));
3990 TEST_F(GLES2ImplementationManualInitTest
, NoLoseContextOnOOM
) {
3991 ContextInitOptions init_options
;
3992 ASSERT_TRUE(Initialize(init_options
));
3995 cmds::LoseContextCHROMIUM cmd
;
3998 GLsizei max
= std::numeric_limits
<GLsizei
>::max();
3999 EXPECT_CALL(*gpu_control_
, CreateGpuMemoryBufferImage(max
, max
, _
, _
))
4000 .WillOnce(Return(-1));
4001 gl_
->CreateGpuMemoryBufferImageCHROMIUM(max
, max
, GL_RGBA
, GL_MAP_CHROMIUM
);
4002 // The context should not be lost.
4003 EXPECT_TRUE(NoCommandsWritten());
4006 TEST_F(GLES2ImplementationManualInitTest
, FailInitOnBGRMismatch1
) {
4007 ContextInitOptions init_options
;
4008 init_options
.bind_generates_resource_client
= false;
4009 init_options
.bind_generates_resource_service
= true;
4010 EXPECT_FALSE(Initialize(init_options
));
4013 TEST_F(GLES2ImplementationManualInitTest
, FailInitOnBGRMismatch2
) {
4014 ContextInitOptions init_options
;
4015 init_options
.bind_generates_resource_client
= true;
4016 init_options
.bind_generates_resource_service
= false;
4017 EXPECT_FALSE(Initialize(init_options
));
4020 TEST_F(GLES2ImplementationManualInitTest
, FailInitOnTransferBufferFail
) {
4021 ContextInitOptions init_options
;
4022 init_options
.transfer_buffer_initialize_fail
= true;
4023 EXPECT_FALSE(Initialize(init_options
));
4026 #include "gpu/command_buffer/client/gles2_implementation_unittest_autogen.h"
4028 } // namespace gles2