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"
11 #include <GLES2/gl2ext.h>
12 #include <GLES2/gl2extchromium.h>
13 #include <GLES3/gl3.h>
14 #include "base/compiler_specific.h"
15 #include "gpu/command_buffer/client/client_test_helper.h"
16 #include "gpu/command_buffer/client/program_info_manager.h"
17 #include "gpu/command_buffer/client/transfer_buffer.h"
18 #include "gpu/command_buffer/common/command_buffer.h"
19 #include "testing/gtest/include/gtest/gtest.h"
20 #include "testing/gmock/include/gmock/gmock.h"
22 #if !defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS)
23 #define GLES2_SUPPORT_CLIENT_SIDE_ARRAYS
27 using testing::AtLeast
;
28 using testing::AnyNumber
;
30 using testing::InSequence
;
31 using testing::Invoke
;
33 using testing::Sequence
;
34 using testing::StrictMock
;
36 using testing::Return
;
41 ACTION_P2(SetMemory
, dst
, obj
) {
42 memcpy(dst
, &obj
, sizeof(obj
));
45 ACTION_P3(SetMemoryFromArray
, dst
, array
, size
) {
46 memcpy(dst
, array
, size
);
49 // Used to help set the transfer buffer result to SizedResult of a single value.
51 class SizedResultHelper
{
53 explicit SizedResultHelper(T result
)
54 : size_(sizeof(result
)),
63 // Struct to make it easy to pass a vec4 worth of floats.
65 FourFloats(float _x
, float _y
, float _z
, float _w
)
79 // Struct that holds 7 characters.
85 class MockTransferBuffer
: public TransferBufferInterface
{
87 struct ExpectedMemoryInfo
{
94 CommandBuffer
* command_buffer
,
96 unsigned int result_size
,
97 unsigned int alignment
,
99 : command_buffer_(command_buffer
),
101 result_size_(result_size
),
102 alignment_(alignment
),
103 actual_buffer_index_(0),
104 expected_buffer_index_(0),
106 expected_offset_(result_size
),
107 actual_offset_(result_size
),
108 initialize_fail_(initialize_fail
) {
109 // We have to allocate the buffers here because
110 // we need to know their address before GLES2Implementation::Initialize
112 for (int ii
= 0; ii
< kNumBuffers
; ++ii
) {
113 buffers_
[ii
] = command_buffer_
->CreateTransferBuffer(
114 size_
+ ii
* alignment_
,
116 EXPECT_NE(-1, buffer_ids_
[ii
]);
120 ~MockTransferBuffer() override
{}
122 bool Initialize(unsigned int starting_buffer_size
,
123 unsigned int result_size
,
124 unsigned int /* min_buffer_size */,
125 unsigned int /* max_buffer_size */,
126 unsigned int alignment
,
127 unsigned int size_to_flush
) override
;
128 int GetShmId() override
;
129 void* GetResultBuffer() override
;
130 int GetResultOffset() override
;
131 void Free() override
;
132 bool HaveBuffer() const override
;
133 void* AllocUpTo(unsigned int size
, unsigned int* size_allocated
) override
;
134 void* Alloc(unsigned int size
) override
;
135 RingBuffer::Offset
GetOffset(void* pointer
) const override
;
136 void FreePendingToken(void* p
, unsigned int /* token */) override
;
138 size_t MaxTransferBufferSize() {
139 return size_
- result_size_
;
142 unsigned int RoundToAlignment(unsigned int size
) {
143 return (size
+ alignment_
- 1) & ~(alignment_
- 1);
147 return expected_buffer_index_
== actual_buffer_index_
&&
148 expected_offset_
== actual_offset_
;
151 ExpectedMemoryInfo
GetExpectedMemory(size_t size
) {
152 ExpectedMemoryInfo mem
;
153 mem
.offset
= AllocateExpectedTransferBuffer(size
);
154 mem
.id
= GetExpectedTransferBufferId();
155 mem
.ptr
= static_cast<uint8
*>(
156 GetExpectedTransferAddressFromOffset(mem
.offset
, size
));
160 ExpectedMemoryInfo
GetExpectedResultMemory(size_t size
) {
161 ExpectedMemoryInfo mem
;
162 mem
.offset
= GetExpectedResultBufferOffset();
163 mem
.id
= GetExpectedResultBufferId();
164 mem
.ptr
= static_cast<uint8
*>(
165 GetExpectedTransferAddressFromOffset(mem
.offset
, size
));
170 static const int kNumBuffers
= 2;
172 uint8
* actual_buffer() const {
173 return static_cast<uint8
*>(buffers_
[actual_buffer_index_
]->memory());
176 uint8
* expected_buffer() const {
177 return static_cast<uint8
*>(buffers_
[expected_buffer_index_
]->memory());
180 uint32
AllocateExpectedTransferBuffer(size_t size
) {
181 EXPECT_LE(size
, MaxTransferBufferSize());
183 // Toggle which buffer we get each time to simulate the buffer being
185 expected_buffer_index_
= (expected_buffer_index_
+ 1) % kNumBuffers
;
187 if (expected_offset_
+ size
> size_
) {
188 expected_offset_
= result_size_
;
190 uint32 offset
= expected_offset_
;
191 expected_offset_
+= RoundToAlignment(size
);
193 // Make sure each buffer has a different offset.
194 return offset
+ expected_buffer_index_
* alignment_
;
197 void* GetExpectedTransferAddressFromOffset(uint32 offset
, size_t size
) {
198 EXPECT_GE(offset
, expected_buffer_index_
* alignment_
);
199 EXPECT_LE(offset
+ size
, size_
+ expected_buffer_index_
* alignment_
);
200 return expected_buffer() + offset
;
203 int GetExpectedResultBufferId() {
204 return buffer_ids_
[expected_buffer_index_
];
207 uint32
GetExpectedResultBufferOffset() {
208 return expected_buffer_index_
* alignment_
;
211 int GetExpectedTransferBufferId() {
212 return buffer_ids_
[expected_buffer_index_
];
215 CommandBuffer
* command_buffer_
;
219 int buffer_ids_
[kNumBuffers
];
220 scoped_refptr
<Buffer
> buffers_
[kNumBuffers
];
221 int actual_buffer_index_
;
222 int expected_buffer_index_
;
224 uint32 expected_offset_
;
225 uint32 actual_offset_
;
226 bool initialize_fail_
;
228 DISALLOW_COPY_AND_ASSIGN(MockTransferBuffer
);
231 bool MockTransferBuffer::Initialize(
232 unsigned int starting_buffer_size
,
233 unsigned int result_size
,
234 unsigned int /* min_buffer_size */,
235 unsigned int /* max_buffer_size */,
236 unsigned int alignment
,
237 unsigned int /* size_to_flush */) {
238 // Just check they match.
239 return size_
== starting_buffer_size
&&
240 result_size_
== result_size
&&
241 alignment_
== alignment
&& !initialize_fail_
;
244 int MockTransferBuffer::GetShmId() {
245 return buffer_ids_
[actual_buffer_index_
];
248 void* MockTransferBuffer::GetResultBuffer() {
249 return actual_buffer() + actual_buffer_index_
* alignment_
;
252 int MockTransferBuffer::GetResultOffset() {
253 return actual_buffer_index_
* alignment_
;
256 void MockTransferBuffer::Free() {
260 bool MockTransferBuffer::HaveBuffer() const {
264 void* MockTransferBuffer::AllocUpTo(
265 unsigned int size
, unsigned int* size_allocated
) {
266 EXPECT_TRUE(size_allocated
!= NULL
);
267 EXPECT_TRUE(last_alloc_
== NULL
);
269 // Toggle which buffer we get each time to simulate the buffer being
271 actual_buffer_index_
= (actual_buffer_index_
+ 1) % kNumBuffers
;
273 size
= std::min(static_cast<size_t>(size
), MaxTransferBufferSize());
274 if (actual_offset_
+ size
> size_
) {
275 actual_offset_
= result_size_
;
277 uint32 offset
= actual_offset_
;
278 actual_offset_
+= RoundToAlignment(size
);
279 *size_allocated
= size
;
281 // Make sure each buffer has a different offset.
282 last_alloc_
= actual_buffer() + offset
+ actual_buffer_index_
* alignment_
;
286 void* MockTransferBuffer::Alloc(unsigned int size
) {
287 EXPECT_LE(size
, MaxTransferBufferSize());
288 unsigned int temp
= 0;
289 void* p
= AllocUpTo(size
, &temp
);
290 EXPECT_EQ(temp
, size
);
294 RingBuffer::Offset
MockTransferBuffer::GetOffset(void* pointer
) const {
295 // Make sure each buffer has a different offset.
296 return static_cast<uint8
*>(pointer
) - actual_buffer();
299 void MockTransferBuffer::FreePendingToken(void* p
, unsigned int /* token */) {
300 EXPECT_EQ(last_alloc_
, p
);
304 // API wrapper for Buffers.
305 class GenBuffersAPI
{
307 static void Gen(GLES2Implementation
* gl_impl
, GLsizei n
, GLuint
* ids
) {
308 gl_impl
->GenBuffers(n
, ids
);
311 static void Delete(GLES2Implementation
* gl_impl
,
314 gl_impl
->DeleteBuffers(n
, ids
);
318 // API wrapper for Framebuffers.
319 class GenFramebuffersAPI
{
321 static void Gen(GLES2Implementation
* gl_impl
, GLsizei n
, GLuint
* ids
) {
322 gl_impl
->GenFramebuffers(n
, ids
);
325 static void Delete(GLES2Implementation
* gl_impl
,
328 gl_impl
->DeleteFramebuffers(n
, ids
);
332 // API wrapper for Renderbuffers.
333 class GenRenderbuffersAPI
{
335 static void Gen(GLES2Implementation
* gl_impl
, GLsizei n
, GLuint
* ids
) {
336 gl_impl
->GenRenderbuffers(n
, ids
);
339 static void Delete(GLES2Implementation
* gl_impl
,
342 gl_impl
->DeleteRenderbuffers(n
, ids
);
346 // API wrapper for Textures.
347 class GenTexturesAPI
{
349 static void Gen(GLES2Implementation
* gl_impl
, GLsizei n
, GLuint
* ids
) {
350 gl_impl
->GenTextures(n
, ids
);
353 static void Delete(GLES2Implementation
* gl_impl
,
356 gl_impl
->DeleteTextures(n
, ids
);
360 class GLES2ImplementationTest
: public testing::Test
{
362 static const int kNumTestContexts
= 2;
363 static const uint8 kInitialValue
= 0xBD;
364 static const int32 kNumCommandEntries
= 500;
365 static const int32 kCommandBufferSizeBytes
=
366 kNumCommandEntries
* sizeof(CommandBufferEntry
);
367 static const size_t kTransferBufferSize
= 512;
369 static const GLint kMaxCombinedTextureImageUnits
= 8;
370 static const GLint kMaxCubeMapTextureSize
= 64;
371 static const GLint kMaxFragmentUniformVectors
= 16;
372 static const GLint kMaxRenderbufferSize
= 64;
373 static const GLint kMaxTextureImageUnits
= 8;
374 static const GLint kMaxTextureSize
= 128;
375 static const GLint kMaxVaryingVectors
= 8;
376 static const GLint kMaxVertexAttribs
= 8;
377 static const GLint kMaxVertexTextureImageUnits
= 0;
378 static const GLint kMaxVertexUniformVectors
= 128;
379 static const GLint kNumCompressedTextureFormats
= 0;
380 static const GLint kNumShaderBinaryFormats
= 0;
381 static const GLuint kMaxTransformFeedbackSeparateAttribs
= 4;
382 static const GLuint kMaxUniformBufferBindings
= 36;
383 static const GLuint kStartId
= 1024;
384 static const GLuint kBuffersStartId
=
385 GLES2Implementation::kClientSideArrayId
+ 2 * kNumTestContexts
;
386 static const GLuint kFramebuffersStartId
= 1;
387 static const GLuint kProgramsAndShadersStartId
= 1;
388 static const GLuint kRenderbuffersStartId
= 1;
389 static const GLuint kSamplersStartId
= 1;
390 static const GLuint kTexturesStartId
= 1;
391 static const GLuint kTransformFeedbacksStartId
= 1;
392 static const GLuint kQueriesStartId
= 1;
393 static const GLuint kVertexArraysStartId
= 1;
394 static const GLuint kValuebuffersStartId
= 1;
396 typedef MockTransferBuffer::ExpectedMemoryInfo ExpectedMemoryInfo
;
400 TestContext() : commands_(NULL
), token_(0) {}
402 bool Initialize(ShareGroup
* share_group
,
403 bool bind_generates_resource_client
,
404 bool bind_generates_resource_service
,
405 bool lose_context_when_out_of_memory
,
406 bool transfer_buffer_initialize_fail
) {
407 command_buffer_
.reset(new StrictMock
<MockClientCommandBuffer
>());
408 if (!command_buffer_
->Initialize())
411 transfer_buffer_
.reset(
412 new MockTransferBuffer(command_buffer_
.get(),
414 GLES2Implementation::kStartingOffset
,
415 GLES2Implementation::kAlignment
,
416 transfer_buffer_initialize_fail
));
418 helper_
.reset(new GLES2CmdHelper(command_buffer()));
419 helper_
->Initialize(kCommandBufferSizeBytes
);
421 gpu_control_
.reset(new StrictMock
<MockClientGpuControl
>());
422 Capabilities capabilities
;
423 capabilities
.VisitPrecisions(
424 [](GLenum shader
, GLenum type
,
425 Capabilities::ShaderPrecision
* precision
) {
426 precision
->min_range
= 3;
427 precision
->max_range
= 5;
428 precision
->precision
= 7;
430 capabilities
.max_combined_texture_image_units
=
431 kMaxCombinedTextureImageUnits
;
432 capabilities
.max_cube_map_texture_size
= kMaxCubeMapTextureSize
;
433 capabilities
.max_fragment_uniform_vectors
= kMaxFragmentUniformVectors
;
434 capabilities
.max_renderbuffer_size
= kMaxRenderbufferSize
;
435 capabilities
.max_texture_image_units
= kMaxTextureImageUnits
;
436 capabilities
.max_texture_size
= kMaxTextureSize
;
437 capabilities
.max_varying_vectors
= kMaxVaryingVectors
;
438 capabilities
.max_vertex_attribs
= kMaxVertexAttribs
;
439 capabilities
.max_vertex_texture_image_units
= kMaxVertexTextureImageUnits
;
440 capabilities
.max_vertex_uniform_vectors
= kMaxVertexUniformVectors
;
441 capabilities
.num_compressed_texture_formats
=
442 kNumCompressedTextureFormats
;
443 capabilities
.num_shader_binary_formats
= kNumShaderBinaryFormats
;
444 capabilities
.max_transform_feedback_separate_attribs
=
445 kMaxTransformFeedbackSeparateAttribs
;
446 capabilities
.max_uniform_buffer_bindings
= kMaxUniformBufferBindings
;
447 capabilities
.bind_generates_resource_chromium
=
448 bind_generates_resource_service
? 1 : 0;
449 EXPECT_CALL(*gpu_control_
, GetCapabilities())
450 .WillOnce(testing::Return(capabilities
));
455 const bool support_client_side_arrays
= true;
456 gl_
.reset(new GLES2Implementation(helper_
.get(),
458 transfer_buffer_
.get(),
459 bind_generates_resource_client
,
460 lose_context_when_out_of_memory
,
461 support_client_side_arrays
,
462 gpu_control_
.get()));
464 if (!gl_
->Initialize(kTransferBufferSize
,
467 GLES2Implementation::kNoLimit
))
471 helper_
->CommandBufferHelper::Finish();
472 ::testing::Mock::VerifyAndClearExpectations(gl_
.get());
474 scoped_refptr
<Buffer
> ring_buffer
= helper_
->get_ring_buffer();
475 commands_
= static_cast<CommandBufferEntry
*>(ring_buffer
->memory()) +
476 command_buffer()->GetPutOffset();
478 EXPECT_TRUE(transfer_buffer_
->InSync());
480 ::testing::Mock::VerifyAndClearExpectations(command_buffer());
485 Mock::VerifyAndClear(gl_
.get());
486 EXPECT_CALL(*command_buffer(), OnFlush()).Times(AnyNumber());
487 // For command buffer.
488 EXPECT_CALL(*command_buffer(), DestroyTransferBuffer(_
))
493 MockClientCommandBuffer
* command_buffer() const {
494 return command_buffer_
.get();
497 int GetNextToken() { return ++token_
; }
499 void ClearCommands() {
500 scoped_refptr
<Buffer
> ring_buffer
= helper_
->get_ring_buffer();
501 memset(ring_buffer
->memory(), kInitialValue
, ring_buffer
->size());
504 scoped_ptr
<MockClientCommandBuffer
> command_buffer_
;
505 scoped_ptr
<MockClientGpuControl
> gpu_control_
;
506 scoped_ptr
<GLES2CmdHelper
> helper_
;
507 scoped_ptr
<MockTransferBuffer
> transfer_buffer_
;
508 scoped_ptr
<GLES2Implementation
> gl_
;
509 CommandBufferEntry
* commands_
;
513 GLES2ImplementationTest() : commands_(NULL
) {}
515 void SetUp() override
;
516 void TearDown() override
;
518 bool NoCommandsWritten() {
519 scoped_refptr
<Buffer
> ring_buffer
= helper_
->get_ring_buffer();
520 const uint8
* cmds
= reinterpret_cast<const uint8
*>(ring_buffer
->memory());
521 const uint8
* end
= cmds
+ ring_buffer
->size();
522 for (; cmds
< end
; ++cmds
) {
523 if (*cmds
!= kInitialValue
) {
530 QueryTracker::Query
* GetQuery(GLuint id
) {
531 return gl_
->query_tracker_
->GetQuery(id
);
534 struct ContextInitOptions
{
536 : bind_generates_resource_client(true),
537 bind_generates_resource_service(true),
538 lose_context_when_out_of_memory(false),
539 transfer_buffer_initialize_fail(false) {}
541 bool bind_generates_resource_client
;
542 bool bind_generates_resource_service
;
543 bool lose_context_when_out_of_memory
;
544 bool transfer_buffer_initialize_fail
;
547 bool Initialize(const ContextInitOptions
& init_options
) {
549 share_group_
= new ShareGroup(init_options
.bind_generates_resource_client
);
551 for (int i
= 0; i
< kNumTestContexts
; i
++) {
552 if (!test_contexts_
[i
].Initialize(
554 init_options
.bind_generates_resource_client
,
555 init_options
.bind_generates_resource_service
,
556 init_options
.lose_context_when_out_of_memory
,
557 init_options
.transfer_buffer_initialize_fail
))
561 // Default to test context 0.
562 gpu_control_
= test_contexts_
[0].gpu_control_
.get();
563 helper_
= test_contexts_
[0].helper_
.get();
564 transfer_buffer_
= test_contexts_
[0].transfer_buffer_
.get();
565 gl_
= test_contexts_
[0].gl_
.get();
566 commands_
= test_contexts_
[0].commands_
;
570 MockClientCommandBuffer
* command_buffer() const {
571 return test_contexts_
[0].command_buffer_
.get();
574 int GetNextToken() { return test_contexts_
[0].GetNextToken(); }
576 const void* GetPut() {
577 return helper_
->GetSpace(0);
580 void ClearCommands() {
581 scoped_refptr
<Buffer
> ring_buffer
= helper_
->get_ring_buffer();
582 memset(ring_buffer
->memory(), kInitialValue
, ring_buffer
->size());
585 size_t MaxTransferBufferSize() {
586 return transfer_buffer_
->MaxTransferBufferSize();
589 ExpectedMemoryInfo
GetExpectedMemory(size_t size
) {
590 return transfer_buffer_
->GetExpectedMemory(size
);
593 ExpectedMemoryInfo
GetExpectedResultMemory(size_t size
) {
594 return transfer_buffer_
->GetExpectedResultMemory(size
);
597 // Sets the ProgramInfoManager. The manager will be owned
598 // by the ShareGroup.
599 void SetProgramInfoManager(ProgramInfoManager
* manager
) {
600 gl_
->share_group()->set_program_info_manager(manager
);
604 ExpectedMemoryInfo result
=
605 GetExpectedResultMemory(sizeof(cmds::GetError::Result
));
606 EXPECT_CALL(*command_buffer(), OnFlush())
607 .WillOnce(SetMemory(result
.ptr
, GLuint(GL_NO_ERROR
)))
608 .RetiresOnSaturation();
609 return gl_
->GetError();
612 const std::string
& GetLastError() {
613 return gl_
->GetLastError();
616 bool GetBucketContents(uint32 bucket_id
, std::vector
<int8
>* data
) {
617 return gl_
->GetBucketContents(bucket_id
, data
);
620 TestContext test_contexts_
[kNumTestContexts
];
622 scoped_refptr
<ShareGroup
> share_group_
;
623 MockClientGpuControl
* gpu_control_
;
624 GLES2CmdHelper
* helper_
;
625 MockTransferBuffer
* transfer_buffer_
;
626 GLES2Implementation
* gl_
;
627 CommandBufferEntry
* commands_
;
630 void GLES2ImplementationTest::SetUp() {
631 ContextInitOptions init_options
;
632 ASSERT_TRUE(Initialize(init_options
));
635 void GLES2ImplementationTest::TearDown() {
636 for (int i
= 0; i
< kNumTestContexts
; i
++)
637 test_contexts_
[i
].TearDown();
640 class GLES2ImplementationManualInitTest
: public GLES2ImplementationTest
{
642 void SetUp() override
{}
645 class GLES2ImplementationStrictSharedTest
: public GLES2ImplementationTest
{
647 void SetUp() override
;
649 template <class ResApi
>
650 void FlushGenerationTest() {
651 GLuint id1
, id2
, id3
;
653 // Generate valid id.
654 ResApi::Gen(gl_
, 1, &id1
);
657 // Delete id1 and generate id2. id1 should not be reused.
658 ResApi::Delete(gl_
, 1, &id1
);
659 ResApi::Gen(gl_
, 1, &id2
);
663 // Expect id1 reuse after Flush.
665 ResApi::Gen(gl_
, 1, &id3
);
669 // Ids should not be reused unless the |Deleting| context does a Flush()
670 // AND triggers a lazy release after that.
671 template <class ResApi
>
672 void CrossContextGenerationTest() {
673 GLES2Implementation
* gl1
= test_contexts_
[0].gl_
.get();
674 GLES2Implementation
* gl2
= test_contexts_
[1].gl_
.get();
675 GLuint id1
, id2
, id3
;
677 // Delete, no flush on context 1. No reuse.
678 ResApi::Gen(gl1
, 1, &id1
);
679 ResApi::Delete(gl1
, 1, &id1
);
680 ResApi::Gen(gl1
, 1, &id2
);
683 // Flush context 2. Still no reuse.
685 ResApi::Gen(gl2
, 1, &id3
);
689 // Flush on context 1, but no lazy release. Still no reuse.
691 ResApi::Gen(gl2
, 1, &id3
);
694 // Lazy release triggered by another Delete. Should reuse id1.
695 ResApi::Delete(gl1
, 1, &id2
);
696 ResApi::Gen(gl2
, 1, &id3
);
700 // Same as CrossContextGenerationTest(), but triggers an Auto Flush on
701 // the Delete(). Tests an edge case regression.
702 template <class ResApi
>
703 void CrossContextGenerationAutoFlushTest() {
704 GLES2Implementation
* gl1
= test_contexts_
[0].gl_
.get();
705 GLES2Implementation
* gl2
= test_contexts_
[1].gl_
.get();
706 GLuint id1
, id2
, id3
;
708 // Delete, no flush on context 1. No reuse.
709 // By half filling the buffer, an internal flush is forced on the Delete().
710 ResApi::Gen(gl1
, 1, &id1
);
711 gl1
->helper()->Noop(kNumCommandEntries
/ 2);
712 ResApi::Delete(gl1
, 1, &id1
);
713 ResApi::Gen(gl1
, 1, &id2
);
716 // Flush context 2. Still no reuse.
718 ResApi::Gen(gl2
, 1, &id3
);
722 // Flush on context 1, but no lazy release. Still no reuse.
724 ResApi::Gen(gl2
, 1, &id3
);
727 // Lazy release triggered by another Delete. Should reuse id1.
728 ResApi::Delete(gl1
, 1, &id2
);
729 ResApi::Gen(gl2
, 1, &id3
);
734 void GLES2ImplementationStrictSharedTest::SetUp() {
735 ContextInitOptions init_options
;
736 init_options
.bind_generates_resource_client
= false;
737 init_options
.bind_generates_resource_service
= false;
738 ASSERT_TRUE(Initialize(init_options
));
741 // GCC requires these declarations, but MSVC requires they not be present
743 const uint8
GLES2ImplementationTest::kInitialValue
;
744 const int32
GLES2ImplementationTest::kNumCommandEntries
;
745 const int32
GLES2ImplementationTest::kCommandBufferSizeBytes
;
746 const size_t GLES2ImplementationTest::kTransferBufferSize
;
747 const GLint
GLES2ImplementationTest::kMaxCombinedTextureImageUnits
;
748 const GLint
GLES2ImplementationTest::kMaxCubeMapTextureSize
;
749 const GLint
GLES2ImplementationTest::kMaxFragmentUniformVectors
;
750 const GLint
GLES2ImplementationTest::kMaxRenderbufferSize
;
751 const GLint
GLES2ImplementationTest::kMaxTextureImageUnits
;
752 const GLint
GLES2ImplementationTest::kMaxTextureSize
;
753 const GLint
GLES2ImplementationTest::kMaxVaryingVectors
;
754 const GLint
GLES2ImplementationTest::kMaxVertexAttribs
;
755 const GLint
GLES2ImplementationTest::kMaxVertexTextureImageUnits
;
756 const GLint
GLES2ImplementationTest::kMaxVertexUniformVectors
;
757 const GLint
GLES2ImplementationTest::kNumCompressedTextureFormats
;
758 const GLint
GLES2ImplementationTest::kNumShaderBinaryFormats
;
759 const GLuint
GLES2ImplementationTest::kStartId
;
760 const GLuint
GLES2ImplementationTest::kBuffersStartId
;
761 const GLuint
GLES2ImplementationTest::kFramebuffersStartId
;
762 const GLuint
GLES2ImplementationTest::kProgramsAndShadersStartId
;
763 const GLuint
GLES2ImplementationTest::kRenderbuffersStartId
;
764 const GLuint
GLES2ImplementationTest::kSamplersStartId
;
765 const GLuint
GLES2ImplementationTest::kTexturesStartId
;
766 const GLuint
GLES2ImplementationTest::kTransformFeedbacksStartId
;
767 const GLuint
GLES2ImplementationTest::kQueriesStartId
;
768 const GLuint
GLES2ImplementationTest::kVertexArraysStartId
;
769 const GLuint
GLES2ImplementationTest::kValuebuffersStartId
;
772 TEST_F(GLES2ImplementationTest
, Basic
) {
773 EXPECT_TRUE(gl_
->share_group() != NULL
);
776 TEST_F(GLES2ImplementationTest
, GetBucketContents
) {
777 const uint32 kBucketId
= GLES2Implementation::kResultBucketId
;
778 const uint32 kTestSize
= MaxTransferBufferSize() + 32;
780 scoped_ptr
<uint8
[]> buf(new uint8
[kTestSize
]);
781 uint8
* expected_data
= buf
.get();
782 for (uint32 ii
= 0; ii
< kTestSize
; ++ii
) {
783 expected_data
[ii
] = ii
* 3;
787 cmd::GetBucketStart get_bucket_start
;
788 cmd::SetToken set_token1
;
789 cmd::GetBucketData get_bucket_data
;
790 cmd::SetToken set_token2
;
791 cmd::SetBucketSize set_bucket_size2
;
794 ExpectedMemoryInfo mem1
= GetExpectedMemory(MaxTransferBufferSize());
795 ExpectedMemoryInfo result1
= GetExpectedResultMemory(sizeof(uint32
));
796 ExpectedMemoryInfo mem2
= GetExpectedMemory(
797 kTestSize
- MaxTransferBufferSize());
800 expected
.get_bucket_start
.Init(
801 kBucketId
, result1
.id
, result1
.offset
,
802 MaxTransferBufferSize(), mem1
.id
, mem1
.offset
);
803 expected
.set_token1
.Init(GetNextToken());
804 expected
.get_bucket_data
.Init(
805 kBucketId
, MaxTransferBufferSize(),
806 kTestSize
- MaxTransferBufferSize(), mem2
.id
, mem2
.offset
);
807 expected
.set_bucket_size2
.Init(kBucketId
, 0);
808 expected
.set_token2
.Init(GetNextToken());
810 EXPECT_CALL(*command_buffer(), OnFlush())
812 SetMemory(result1
.ptr
, kTestSize
),
814 mem1
.ptr
, expected_data
, MaxTransferBufferSize())))
815 .WillOnce(SetMemoryFromArray(
816 mem2
.ptr
, expected_data
+ MaxTransferBufferSize(),
817 kTestSize
- MaxTransferBufferSize()))
818 .RetiresOnSaturation();
820 std::vector
<int8
> data
;
821 GetBucketContents(kBucketId
, &data
);
822 EXPECT_EQ(0, memcmp(&expected
, commands_
, sizeof(expected
)));
823 ASSERT_EQ(kTestSize
, data
.size());
824 EXPECT_EQ(0, memcmp(expected_data
, &data
[0], data
.size()));
827 TEST_F(GLES2ImplementationTest
, GetShaderPrecisionFormat
) {
829 cmds::GetShaderPrecisionFormat cmd
;
831 typedef cmds::GetShaderPrecisionFormat::Result Result
;
832 const unsigned kDummyType1
= 3;
833 const unsigned kDummyType2
= 4;
835 // The first call for dummy type 1 should trigger a command buffer request.
836 GLint range1
[2] = {0, 0};
837 GLint precision1
= 0;
839 ExpectedMemoryInfo client_result1
= GetExpectedResultMemory(4);
840 expected1
.cmd
.Init(GL_FRAGMENT_SHADER
, kDummyType1
, client_result1
.id
,
841 client_result1
.offset
);
842 Result server_result1
= {true, 14, 14, 10};
843 EXPECT_CALL(*command_buffer(), OnFlush())
844 .WillOnce(SetMemory(client_result1
.ptr
, server_result1
))
845 .RetiresOnSaturation();
846 gl_
->GetShaderPrecisionFormat(GL_FRAGMENT_SHADER
, kDummyType1
, range1
,
848 const void* commands2
= GetPut();
849 EXPECT_NE(commands_
, commands2
);
850 EXPECT_EQ(0, memcmp(&expected1
, commands_
, sizeof(expected1
)));
851 EXPECT_EQ(range1
[0], 14);
852 EXPECT_EQ(range1
[1], 14);
853 EXPECT_EQ(precision1
, 10);
855 // The second call for dummy type 1 should use the cached value and avoid
856 // triggering a command buffer request, so we do not expect a call to
857 // OnFlush() here. We do expect the results to be correct though.
858 GLint range2
[2] = {0, 0};
859 GLint precision2
= 0;
860 gl_
->GetShaderPrecisionFormat(GL_FRAGMENT_SHADER
, kDummyType1
, range2
,
862 const void* commands3
= GetPut();
863 EXPECT_EQ(commands2
, commands3
);
864 EXPECT_EQ(range2
[0], 14);
865 EXPECT_EQ(range2
[1], 14);
866 EXPECT_EQ(precision2
, 10);
868 // If we then make a request for dummy type 2, we should get another command
869 // buffer request since it hasn't been cached yet.
870 GLint range3
[2] = {0, 0};
871 GLint precision3
= 0;
873 ExpectedMemoryInfo result3
= GetExpectedResultMemory(4);
874 expected3
.cmd
.Init(GL_FRAGMENT_SHADER
, kDummyType2
, result3
.id
,
876 Result result3_source
= {true, 62, 62, 16};
877 EXPECT_CALL(*command_buffer(), OnFlush())
878 .WillOnce(SetMemory(result3
.ptr
, result3_source
))
879 .RetiresOnSaturation();
880 gl_
->GetShaderPrecisionFormat(GL_FRAGMENT_SHADER
, kDummyType2
, range3
,
882 const void* commands4
= GetPut();
883 EXPECT_NE(commands3
, commands4
);
884 EXPECT_EQ(0, memcmp(&expected3
, commands3
, sizeof(expected3
)));
885 EXPECT_EQ(range3
[0], 62);
886 EXPECT_EQ(range3
[1], 62);
887 EXPECT_EQ(precision3
, 16);
889 // Any call for predefined types should use the cached value from the
890 // Capabilities and avoid triggering a command buffer request, so we do not
891 // expect a call to OnFlush() here. We do expect the results to be correct
893 GLint range4
[2] = {0, 0};
894 GLint precision4
= 0;
895 gl_
->GetShaderPrecisionFormat(GL_FRAGMENT_SHADER
, GL_MEDIUM_FLOAT
, range4
,
897 const void* commands5
= GetPut();
898 EXPECT_EQ(commands4
, commands5
);
899 EXPECT_EQ(range4
[0], 3);
900 EXPECT_EQ(range4
[1], 5);
901 EXPECT_EQ(precision4
, 7);
904 TEST_F(GLES2ImplementationTest
, GetShaderSource
) {
905 const uint32 kBucketId
= GLES2Implementation::kResultBucketId
;
906 const GLuint kShaderId
= 456;
907 const Str7 kString
= {"foobar"};
908 const char kBad
= 0x12;
910 cmd::SetBucketSize set_bucket_size1
;
911 cmds::GetShaderSource get_shader_source
;
912 cmd::GetBucketStart get_bucket_start
;
913 cmd::SetToken set_token1
;
914 cmd::SetBucketSize set_bucket_size2
;
917 ExpectedMemoryInfo mem1
= GetExpectedMemory(MaxTransferBufferSize());
918 ExpectedMemoryInfo result1
= GetExpectedResultMemory(sizeof(uint32
));
921 expected
.set_bucket_size1
.Init(kBucketId
, 0);
922 expected
.get_shader_source
.Init(kShaderId
, kBucketId
);
923 expected
.get_bucket_start
.Init(
924 kBucketId
, result1
.id
, result1
.offset
,
925 MaxTransferBufferSize(), mem1
.id
, mem1
.offset
);
926 expected
.set_token1
.Init(GetNextToken());
927 expected
.set_bucket_size2
.Init(kBucketId
, 0);
928 char buf
[sizeof(kString
) + 1];
929 memset(buf
, kBad
, sizeof(buf
));
931 EXPECT_CALL(*command_buffer(), OnFlush())
932 .WillOnce(DoAll(SetMemory(result1
.ptr
, uint32(sizeof(kString
))),
933 SetMemory(mem1
.ptr
, kString
)))
934 .RetiresOnSaturation();
937 gl_
->GetShaderSource(kShaderId
, sizeof(buf
), &length
, buf
);
938 EXPECT_EQ(0, memcmp(&expected
, commands_
, sizeof(expected
)));
939 EXPECT_EQ(sizeof(kString
) - 1, static_cast<size_t>(length
));
940 EXPECT_STREQ(kString
.str
, buf
);
941 EXPECT_EQ(buf
[sizeof(kString
)], kBad
);
944 #if defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS)
946 TEST_F(GLES2ImplementationTest
, DrawArraysClientSideBuffers
) {
947 static const float verts
[][4] = {
948 { 12.0f
, 23.0f
, 34.0f
, 45.0f
, },
949 { 56.0f
, 67.0f
, 78.0f
, 89.0f
, },
950 { 13.0f
, 24.0f
, 35.0f
, 46.0f
, },
953 cmds::EnableVertexAttribArray enable1
;
954 cmds::EnableVertexAttribArray enable2
;
955 cmds::BindBuffer bind_to_emu
;
956 cmds::BufferData set_size
;
957 cmds::BufferSubData copy_data1
;
958 cmd::SetToken set_token1
;
959 cmds::VertexAttribPointer set_pointer1
;
960 cmds::BufferSubData copy_data2
;
961 cmd::SetToken set_token2
;
962 cmds::VertexAttribPointer set_pointer2
;
963 cmds::DrawArrays draw
;
964 cmds::BindBuffer restore
;
966 const GLuint kEmuBufferId
= GLES2Implementation::kClientSideArrayId
;
967 const GLuint kAttribIndex1
= 1;
968 const GLuint kAttribIndex2
= 3;
969 const GLint kNumComponents1
= 3;
970 const GLint kNumComponents2
= 2;
971 const GLsizei kClientStride
= sizeof(verts
[0]);
972 const GLint kFirst
= 1;
973 const GLsizei kCount
= 2;
974 const GLsizei kSize1
=
975 arraysize(verts
) * kNumComponents1
* sizeof(verts
[0][0]);
976 const GLsizei kSize2
=
977 arraysize(verts
) * kNumComponents2
* sizeof(verts
[0][0]);
978 const GLsizei kEmuOffset1
= 0;
979 const GLsizei kEmuOffset2
= kSize1
;
980 const GLsizei kTotalSize
= kSize1
+ kSize2
;
982 ExpectedMemoryInfo mem1
= GetExpectedMemory(kSize1
);
983 ExpectedMemoryInfo mem2
= GetExpectedMemory(kSize2
);
986 expected
.enable1
.Init(kAttribIndex1
);
987 expected
.enable2
.Init(kAttribIndex2
);
988 expected
.bind_to_emu
.Init(GL_ARRAY_BUFFER
, kEmuBufferId
);
989 expected
.set_size
.Init(GL_ARRAY_BUFFER
, kTotalSize
, 0, 0, GL_DYNAMIC_DRAW
);
990 expected
.copy_data1
.Init(
991 GL_ARRAY_BUFFER
, kEmuOffset1
, kSize1
, mem1
.id
, mem1
.offset
);
992 expected
.set_token1
.Init(GetNextToken());
993 expected
.set_pointer1
.Init(
994 kAttribIndex1
, kNumComponents1
, GL_FLOAT
, GL_FALSE
, 0, kEmuOffset1
);
995 expected
.copy_data2
.Init(
996 GL_ARRAY_BUFFER
, kEmuOffset2
, kSize2
, mem2
.id
, mem2
.offset
);
997 expected
.set_token2
.Init(GetNextToken());
998 expected
.set_pointer2
.Init(
999 kAttribIndex2
, kNumComponents2
, GL_FLOAT
, GL_FALSE
, 0, kEmuOffset2
);
1000 expected
.draw
.Init(GL_POINTS
, kFirst
, kCount
);
1001 expected
.restore
.Init(GL_ARRAY_BUFFER
, 0);
1002 gl_
->EnableVertexAttribArray(kAttribIndex1
);
1003 gl_
->EnableVertexAttribArray(kAttribIndex2
);
1004 gl_
->VertexAttribPointer(
1005 kAttribIndex1
, kNumComponents1
, GL_FLOAT
, GL_FALSE
, kClientStride
, verts
);
1006 gl_
->VertexAttribPointer(
1007 kAttribIndex2
, kNumComponents2
, GL_FLOAT
, GL_FALSE
, kClientStride
, verts
);
1008 gl_
->DrawArrays(GL_POINTS
, kFirst
, kCount
);
1009 EXPECT_EQ(0, memcmp(&expected
, commands_
, sizeof(expected
)));
1012 TEST_F(GLES2ImplementationTest
, DrawArraysInstancedANGLEClientSideBuffers
) {
1013 static const float verts
[][4] = {
1014 { 12.0f
, 23.0f
, 34.0f
, 45.0f
, },
1015 { 56.0f
, 67.0f
, 78.0f
, 89.0f
, },
1016 { 13.0f
, 24.0f
, 35.0f
, 46.0f
, },
1019 cmds::EnableVertexAttribArray enable1
;
1020 cmds::EnableVertexAttribArray enable2
;
1021 cmds::VertexAttribDivisorANGLE divisor
;
1022 cmds::BindBuffer bind_to_emu
;
1023 cmds::BufferData set_size
;
1024 cmds::BufferSubData copy_data1
;
1025 cmd::SetToken set_token1
;
1026 cmds::VertexAttribPointer set_pointer1
;
1027 cmds::BufferSubData copy_data2
;
1028 cmd::SetToken set_token2
;
1029 cmds::VertexAttribPointer set_pointer2
;
1030 cmds::DrawArraysInstancedANGLE draw
;
1031 cmds::BindBuffer restore
;
1033 const GLuint kEmuBufferId
= GLES2Implementation::kClientSideArrayId
;
1034 const GLuint kAttribIndex1
= 1;
1035 const GLuint kAttribIndex2
= 3;
1036 const GLint kNumComponents1
= 3;
1037 const GLint kNumComponents2
= 2;
1038 const GLsizei kClientStride
= sizeof(verts
[0]);
1039 const GLint kFirst
= 1;
1040 const GLsizei kCount
= 2;
1041 const GLuint kDivisor
= 1;
1042 const GLsizei kSize1
=
1043 arraysize(verts
) * kNumComponents1
* sizeof(verts
[0][0]);
1044 const GLsizei kSize2
=
1045 1 * kNumComponents2
* sizeof(verts
[0][0]);
1046 const GLsizei kEmuOffset1
= 0;
1047 const GLsizei kEmuOffset2
= kSize1
;
1048 const GLsizei kTotalSize
= kSize1
+ kSize2
;
1050 ExpectedMemoryInfo mem1
= GetExpectedMemory(kSize1
);
1051 ExpectedMemoryInfo mem2
= GetExpectedMemory(kSize2
);
1054 expected
.enable1
.Init(kAttribIndex1
);
1055 expected
.enable2
.Init(kAttribIndex2
);
1056 expected
.divisor
.Init(kAttribIndex2
, kDivisor
);
1057 expected
.bind_to_emu
.Init(GL_ARRAY_BUFFER
, kEmuBufferId
);
1058 expected
.set_size
.Init(GL_ARRAY_BUFFER
, kTotalSize
, 0, 0, GL_DYNAMIC_DRAW
);
1059 expected
.copy_data1
.Init(
1060 GL_ARRAY_BUFFER
, kEmuOffset1
, kSize1
, mem1
.id
, mem1
.offset
);
1061 expected
.set_token1
.Init(GetNextToken());
1062 expected
.set_pointer1
.Init(
1063 kAttribIndex1
, kNumComponents1
, GL_FLOAT
, GL_FALSE
, 0, kEmuOffset1
);
1064 expected
.copy_data2
.Init(
1065 GL_ARRAY_BUFFER
, kEmuOffset2
, kSize2
, mem2
.id
, mem2
.offset
);
1066 expected
.set_token2
.Init(GetNextToken());
1067 expected
.set_pointer2
.Init(
1068 kAttribIndex2
, kNumComponents2
, GL_FLOAT
, GL_FALSE
, 0, kEmuOffset2
);
1069 expected
.draw
.Init(GL_POINTS
, kFirst
, kCount
, 1);
1070 expected
.restore
.Init(GL_ARRAY_BUFFER
, 0);
1071 gl_
->EnableVertexAttribArray(kAttribIndex1
);
1072 gl_
->EnableVertexAttribArray(kAttribIndex2
);
1073 gl_
->VertexAttribPointer(
1074 kAttribIndex1
, kNumComponents1
, GL_FLOAT
, GL_FALSE
, kClientStride
, verts
);
1075 gl_
->VertexAttribPointer(
1076 kAttribIndex2
, kNumComponents2
, GL_FLOAT
, GL_FALSE
, kClientStride
, verts
);
1077 gl_
->VertexAttribDivisorANGLE(kAttribIndex2
, kDivisor
);
1078 gl_
->DrawArraysInstancedANGLE(GL_POINTS
, kFirst
, kCount
, 1);
1079 EXPECT_EQ(0, memcmp(&expected
, commands_
, sizeof(expected
)));
1082 TEST_F(GLES2ImplementationTest
, DrawElementsClientSideBuffers
) {
1083 static const float verts
[][4] = {
1084 { 12.0f
, 23.0f
, 34.0f
, 45.0f
, },
1085 { 56.0f
, 67.0f
, 78.0f
, 89.0f
, },
1086 { 13.0f
, 24.0f
, 35.0f
, 46.0f
, },
1088 static const uint16 indices
[] = {
1092 cmds::EnableVertexAttribArray enable1
;
1093 cmds::EnableVertexAttribArray enable2
;
1094 cmds::BindBuffer bind_to_index_emu
;
1095 cmds::BufferData set_index_size
;
1096 cmds::BufferSubData copy_data0
;
1097 cmd::SetToken set_token0
;
1098 cmds::BindBuffer bind_to_emu
;
1099 cmds::BufferData set_size
;
1100 cmds::BufferSubData copy_data1
;
1101 cmd::SetToken set_token1
;
1102 cmds::VertexAttribPointer set_pointer1
;
1103 cmds::BufferSubData copy_data2
;
1104 cmd::SetToken set_token2
;
1105 cmds::VertexAttribPointer set_pointer2
;
1106 cmds::DrawElements draw
;
1107 cmds::BindBuffer restore
;
1108 cmds::BindBuffer restore_element
;
1110 const GLsizei kIndexSize
= sizeof(indices
);
1111 const GLuint kEmuBufferId
= GLES2Implementation::kClientSideArrayId
;
1112 const GLuint kEmuIndexBufferId
=
1113 GLES2Implementation::kClientSideElementArrayId
;
1114 const GLuint kAttribIndex1
= 1;
1115 const GLuint kAttribIndex2
= 3;
1116 const GLint kNumComponents1
= 3;
1117 const GLint kNumComponents2
= 2;
1118 const GLsizei kClientStride
= sizeof(verts
[0]);
1119 const GLsizei kCount
= 2;
1120 const GLsizei kSize1
=
1121 arraysize(verts
) * kNumComponents1
* sizeof(verts
[0][0]);
1122 const GLsizei kSize2
=
1123 arraysize(verts
) * kNumComponents2
* sizeof(verts
[0][0]);
1124 const GLsizei kEmuOffset1
= 0;
1125 const GLsizei kEmuOffset2
= kSize1
;
1126 const GLsizei kTotalSize
= kSize1
+ kSize2
;
1128 ExpectedMemoryInfo mem1
= GetExpectedMemory(kIndexSize
);
1129 ExpectedMemoryInfo mem2
= GetExpectedMemory(kSize1
);
1130 ExpectedMemoryInfo mem3
= GetExpectedMemory(kSize2
);
1133 expected
.enable1
.Init(kAttribIndex1
);
1134 expected
.enable2
.Init(kAttribIndex2
);
1135 expected
.bind_to_index_emu
.Init(GL_ELEMENT_ARRAY_BUFFER
, kEmuIndexBufferId
);
1136 expected
.set_index_size
.Init(
1137 GL_ELEMENT_ARRAY_BUFFER
, kIndexSize
, 0, 0, GL_DYNAMIC_DRAW
);
1138 expected
.copy_data0
.Init(
1139 GL_ELEMENT_ARRAY_BUFFER
, 0, kIndexSize
, mem1
.id
, mem1
.offset
);
1140 expected
.set_token0
.Init(GetNextToken());
1141 expected
.bind_to_emu
.Init(GL_ARRAY_BUFFER
, kEmuBufferId
);
1142 expected
.set_size
.Init(GL_ARRAY_BUFFER
, kTotalSize
, 0, 0, GL_DYNAMIC_DRAW
);
1143 expected
.copy_data1
.Init(
1144 GL_ARRAY_BUFFER
, kEmuOffset1
, kSize1
, mem2
.id
, mem2
.offset
);
1145 expected
.set_token1
.Init(GetNextToken());
1146 expected
.set_pointer1
.Init(
1147 kAttribIndex1
, kNumComponents1
, GL_FLOAT
, GL_FALSE
, 0, kEmuOffset1
);
1148 expected
.copy_data2
.Init(
1149 GL_ARRAY_BUFFER
, kEmuOffset2
, kSize2
, mem3
.id
, mem3
.offset
);
1150 expected
.set_token2
.Init(GetNextToken());
1151 expected
.set_pointer2
.Init(kAttribIndex2
, kNumComponents2
,
1152 GL_FLOAT
, GL_FALSE
, 0, kEmuOffset2
);
1153 expected
.draw
.Init(GL_POINTS
, kCount
, GL_UNSIGNED_SHORT
, 0);
1154 expected
.restore
.Init(GL_ARRAY_BUFFER
, 0);
1155 expected
.restore_element
.Init(GL_ELEMENT_ARRAY_BUFFER
, 0);
1156 gl_
->EnableVertexAttribArray(kAttribIndex1
);
1157 gl_
->EnableVertexAttribArray(kAttribIndex2
);
1158 gl_
->VertexAttribPointer(kAttribIndex1
, kNumComponents1
,
1159 GL_FLOAT
, GL_FALSE
, kClientStride
, verts
);
1160 gl_
->VertexAttribPointer(kAttribIndex2
, kNumComponents2
,
1161 GL_FLOAT
, GL_FALSE
, kClientStride
, verts
);
1162 gl_
->DrawElements(GL_POINTS
, kCount
, GL_UNSIGNED_SHORT
, indices
);
1163 EXPECT_EQ(0, memcmp(&expected
, commands_
, sizeof(expected
)));
1166 TEST_F(GLES2ImplementationTest
, DrawElementsClientSideBuffersIndexUint
) {
1167 static const float verts
[][4] = {
1168 { 12.0f
, 23.0f
, 34.0f
, 45.0f
, },
1169 { 56.0f
, 67.0f
, 78.0f
, 89.0f
, },
1170 { 13.0f
, 24.0f
, 35.0f
, 46.0f
, },
1172 static const uint32 indices
[] = {
1176 cmds::EnableVertexAttribArray enable1
;
1177 cmds::EnableVertexAttribArray enable2
;
1178 cmds::BindBuffer bind_to_index_emu
;
1179 cmds::BufferData set_index_size
;
1180 cmds::BufferSubData copy_data0
;
1181 cmd::SetToken set_token0
;
1182 cmds::BindBuffer bind_to_emu
;
1183 cmds::BufferData set_size
;
1184 cmds::BufferSubData copy_data1
;
1185 cmd::SetToken set_token1
;
1186 cmds::VertexAttribPointer set_pointer1
;
1187 cmds::BufferSubData copy_data2
;
1188 cmd::SetToken set_token2
;
1189 cmds::VertexAttribPointer set_pointer2
;
1190 cmds::DrawElements draw
;
1191 cmds::BindBuffer restore
;
1192 cmds::BindBuffer restore_element
;
1194 const GLsizei kIndexSize
= sizeof(indices
);
1195 const GLuint kEmuBufferId
= GLES2Implementation::kClientSideArrayId
;
1196 const GLuint kEmuIndexBufferId
=
1197 GLES2Implementation::kClientSideElementArrayId
;
1198 const GLuint kAttribIndex1
= 1;
1199 const GLuint kAttribIndex2
= 3;
1200 const GLint kNumComponents1
= 3;
1201 const GLint kNumComponents2
= 2;
1202 const GLsizei kClientStride
= sizeof(verts
[0]);
1203 const GLsizei kCount
= 2;
1204 const GLsizei kSize1
=
1205 arraysize(verts
) * kNumComponents1
* sizeof(verts
[0][0]);
1206 const GLsizei kSize2
=
1207 arraysize(verts
) * kNumComponents2
* sizeof(verts
[0][0]);
1208 const GLsizei kEmuOffset1
= 0;
1209 const GLsizei kEmuOffset2
= kSize1
;
1210 const GLsizei kTotalSize
= kSize1
+ kSize2
;
1212 ExpectedMemoryInfo mem1
= GetExpectedMemory(kIndexSize
);
1213 ExpectedMemoryInfo mem2
= GetExpectedMemory(kSize1
);
1214 ExpectedMemoryInfo mem3
= GetExpectedMemory(kSize2
);
1217 expected
.enable1
.Init(kAttribIndex1
);
1218 expected
.enable2
.Init(kAttribIndex2
);
1219 expected
.bind_to_index_emu
.Init(GL_ELEMENT_ARRAY_BUFFER
, kEmuIndexBufferId
);
1220 expected
.set_index_size
.Init(
1221 GL_ELEMENT_ARRAY_BUFFER
, kIndexSize
, 0, 0, GL_DYNAMIC_DRAW
);
1222 expected
.copy_data0
.Init(
1223 GL_ELEMENT_ARRAY_BUFFER
, 0, kIndexSize
, mem1
.id
, mem1
.offset
);
1224 expected
.set_token0
.Init(GetNextToken());
1225 expected
.bind_to_emu
.Init(GL_ARRAY_BUFFER
, kEmuBufferId
);
1226 expected
.set_size
.Init(GL_ARRAY_BUFFER
, kTotalSize
, 0, 0, GL_DYNAMIC_DRAW
);
1227 expected
.copy_data1
.Init(
1228 GL_ARRAY_BUFFER
, kEmuOffset1
, kSize1
, mem2
.id
, mem2
.offset
);
1229 expected
.set_token1
.Init(GetNextToken());
1230 expected
.set_pointer1
.Init(
1231 kAttribIndex1
, kNumComponents1
, GL_FLOAT
, GL_FALSE
, 0, kEmuOffset1
);
1232 expected
.copy_data2
.Init(
1233 GL_ARRAY_BUFFER
, kEmuOffset2
, kSize2
, mem3
.id
, mem3
.offset
);
1234 expected
.set_token2
.Init(GetNextToken());
1235 expected
.set_pointer2
.Init(kAttribIndex2
, kNumComponents2
,
1236 GL_FLOAT
, GL_FALSE
, 0, kEmuOffset2
);
1237 expected
.draw
.Init(GL_POINTS
, kCount
, GL_UNSIGNED_INT
, 0);
1238 expected
.restore
.Init(GL_ARRAY_BUFFER
, 0);
1239 expected
.restore_element
.Init(GL_ELEMENT_ARRAY_BUFFER
, 0);
1240 gl_
->EnableVertexAttribArray(kAttribIndex1
);
1241 gl_
->EnableVertexAttribArray(kAttribIndex2
);
1242 gl_
->VertexAttribPointer(kAttribIndex1
, kNumComponents1
,
1243 GL_FLOAT
, GL_FALSE
, kClientStride
, verts
);
1244 gl_
->VertexAttribPointer(kAttribIndex2
, kNumComponents2
,
1245 GL_FLOAT
, GL_FALSE
, kClientStride
, verts
);
1246 gl_
->DrawElements(GL_POINTS
, kCount
, GL_UNSIGNED_INT
, indices
);
1247 EXPECT_EQ(0, memcmp(&expected
, commands_
, sizeof(expected
)));
1250 TEST_F(GLES2ImplementationTest
, DrawElementsClientSideBuffersInvalidIndexUint
) {
1251 static const float verts
[][4] = {
1252 { 12.0f
, 23.0f
, 34.0f
, 45.0f
, },
1253 { 56.0f
, 67.0f
, 78.0f
, 89.0f
, },
1254 { 13.0f
, 24.0f
, 35.0f
, 46.0f
, },
1256 static const uint32 indices
[] = {
1260 const GLuint kAttribIndex1
= 1;
1261 const GLuint kAttribIndex2
= 3;
1262 const GLint kNumComponents1
= 3;
1263 const GLint kNumComponents2
= 2;
1264 const GLsizei kClientStride
= sizeof(verts
[0]);
1265 const GLsizei kCount
= 2;
1267 EXPECT_CALL(*command_buffer(), OnFlush())
1269 .RetiresOnSaturation();
1271 gl_
->EnableVertexAttribArray(kAttribIndex1
);
1272 gl_
->EnableVertexAttribArray(kAttribIndex2
);
1273 gl_
->VertexAttribPointer(kAttribIndex1
, kNumComponents1
,
1274 GL_FLOAT
, GL_FALSE
, kClientStride
, verts
);
1275 gl_
->VertexAttribPointer(kAttribIndex2
, kNumComponents2
,
1276 GL_FLOAT
, GL_FALSE
, kClientStride
, verts
);
1277 gl_
->DrawElements(GL_POINTS
, kCount
, GL_UNSIGNED_INT
, indices
);
1279 EXPECT_EQ(static_cast<GLenum
>(GL_INVALID_OPERATION
), gl_
->GetError());
1282 TEST_F(GLES2ImplementationTest
,
1283 DrawElementsClientSideBuffersServiceSideIndices
) {
1284 static const float verts
[][4] = {
1285 { 12.0f
, 23.0f
, 34.0f
, 45.0f
, },
1286 { 56.0f
, 67.0f
, 78.0f
, 89.0f
, },
1287 { 13.0f
, 24.0f
, 35.0f
, 46.0f
, },
1290 cmds::EnableVertexAttribArray enable1
;
1291 cmds::EnableVertexAttribArray enable2
;
1292 cmds::BindBuffer bind_to_index
;
1293 cmds::GetMaxValueInBufferCHROMIUM get_max
;
1294 cmds::BindBuffer bind_to_emu
;
1295 cmds::BufferData set_size
;
1296 cmds::BufferSubData copy_data1
;
1297 cmd::SetToken set_token1
;
1298 cmds::VertexAttribPointer set_pointer1
;
1299 cmds::BufferSubData copy_data2
;
1300 cmd::SetToken set_token2
;
1301 cmds::VertexAttribPointer set_pointer2
;
1302 cmds::DrawElements draw
;
1303 cmds::BindBuffer restore
;
1305 const GLuint kEmuBufferId
= GLES2Implementation::kClientSideArrayId
;
1306 const GLuint kClientIndexBufferId
= 0x789;
1307 const GLuint kIndexOffset
= 0x40;
1308 const GLuint kMaxIndex
= 2;
1309 const GLuint kAttribIndex1
= 1;
1310 const GLuint kAttribIndex2
= 3;
1311 const GLint kNumComponents1
= 3;
1312 const GLint kNumComponents2
= 2;
1313 const GLsizei kClientStride
= sizeof(verts
[0]);
1314 const GLsizei kCount
= 2;
1315 const GLsizei kSize1
=
1316 arraysize(verts
) * kNumComponents1
* sizeof(verts
[0][0]);
1317 const GLsizei kSize2
=
1318 arraysize(verts
) * kNumComponents2
* sizeof(verts
[0][0]);
1319 const GLsizei kEmuOffset1
= 0;
1320 const GLsizei kEmuOffset2
= kSize1
;
1321 const GLsizei kTotalSize
= kSize1
+ kSize2
;
1323 ExpectedMemoryInfo mem1
= GetExpectedResultMemory(sizeof(uint32
));
1324 ExpectedMemoryInfo mem2
= GetExpectedMemory(kSize1
);
1325 ExpectedMemoryInfo mem3
= GetExpectedMemory(kSize2
);
1329 expected
.enable1
.Init(kAttribIndex1
);
1330 expected
.enable2
.Init(kAttribIndex2
);
1331 expected
.bind_to_index
.Init(GL_ELEMENT_ARRAY_BUFFER
, kClientIndexBufferId
);
1332 expected
.get_max
.Init(kClientIndexBufferId
, kCount
, GL_UNSIGNED_SHORT
,
1333 kIndexOffset
, mem1
.id
, mem1
.offset
);
1334 expected
.bind_to_emu
.Init(GL_ARRAY_BUFFER
, kEmuBufferId
);
1335 expected
.set_size
.Init(GL_ARRAY_BUFFER
, kTotalSize
, 0, 0, GL_DYNAMIC_DRAW
);
1336 expected
.copy_data1
.Init(
1337 GL_ARRAY_BUFFER
, kEmuOffset1
, kSize1
, mem2
.id
, mem2
.offset
);
1338 expected
.set_token1
.Init(GetNextToken());
1339 expected
.set_pointer1
.Init(kAttribIndex1
, kNumComponents1
,
1340 GL_FLOAT
, GL_FALSE
, 0, kEmuOffset1
);
1341 expected
.copy_data2
.Init(
1342 GL_ARRAY_BUFFER
, kEmuOffset2
, kSize2
, mem3
.id
, mem3
.offset
);
1343 expected
.set_token2
.Init(GetNextToken());
1344 expected
.set_pointer2
.Init(kAttribIndex2
, kNumComponents2
,
1345 GL_FLOAT
, GL_FALSE
, 0, kEmuOffset2
);
1346 expected
.draw
.Init(GL_POINTS
, kCount
, GL_UNSIGNED_SHORT
, kIndexOffset
);
1347 expected
.restore
.Init(GL_ARRAY_BUFFER
, 0);
1349 EXPECT_CALL(*command_buffer(), OnFlush())
1350 .WillOnce(SetMemory(mem1
.ptr
,kMaxIndex
))
1351 .RetiresOnSaturation();
1353 gl_
->EnableVertexAttribArray(kAttribIndex1
);
1354 gl_
->EnableVertexAttribArray(kAttribIndex2
);
1355 gl_
->BindBuffer(GL_ELEMENT_ARRAY_BUFFER
, kClientIndexBufferId
);
1356 gl_
->VertexAttribPointer(kAttribIndex1
, kNumComponents1
,
1357 GL_FLOAT
, GL_FALSE
, kClientStride
, verts
);
1358 gl_
->VertexAttribPointer(kAttribIndex2
, kNumComponents2
,
1359 GL_FLOAT
, GL_FALSE
, kClientStride
, verts
);
1360 gl_
->DrawElements(GL_POINTS
, kCount
, GL_UNSIGNED_SHORT
,
1361 reinterpret_cast<const void*>(kIndexOffset
));
1362 EXPECT_EQ(0, memcmp(&expected
, commands_
, sizeof(expected
)));
1365 TEST_F(GLES2ImplementationTest
, DrawElementsInstancedANGLEClientSideBuffers
) {
1366 static const float verts
[][4] = {
1367 { 12.0f
, 23.0f
, 34.0f
, 45.0f
, },
1368 { 56.0f
, 67.0f
, 78.0f
, 89.0f
, },
1369 { 13.0f
, 24.0f
, 35.0f
, 46.0f
, },
1371 static const uint16 indices
[] = {
1375 cmds::EnableVertexAttribArray enable1
;
1376 cmds::EnableVertexAttribArray enable2
;
1377 cmds::VertexAttribDivisorANGLE divisor
;
1378 cmds::BindBuffer bind_to_index_emu
;
1379 cmds::BufferData set_index_size
;
1380 cmds::BufferSubData copy_data0
;
1381 cmd::SetToken set_token0
;
1382 cmds::BindBuffer bind_to_emu
;
1383 cmds::BufferData set_size
;
1384 cmds::BufferSubData copy_data1
;
1385 cmd::SetToken set_token1
;
1386 cmds::VertexAttribPointer set_pointer1
;
1387 cmds::BufferSubData copy_data2
;
1388 cmd::SetToken set_token2
;
1389 cmds::VertexAttribPointer set_pointer2
;
1390 cmds::DrawElementsInstancedANGLE draw
;
1391 cmds::BindBuffer restore
;
1392 cmds::BindBuffer restore_element
;
1394 const GLsizei kIndexSize
= sizeof(indices
);
1395 const GLuint kEmuBufferId
= GLES2Implementation::kClientSideArrayId
;
1396 const GLuint kEmuIndexBufferId
=
1397 GLES2Implementation::kClientSideElementArrayId
;
1398 const GLuint kAttribIndex1
= 1;
1399 const GLuint kAttribIndex2
= 3;
1400 const GLint kNumComponents1
= 3;
1401 const GLint kNumComponents2
= 2;
1402 const GLsizei kClientStride
= sizeof(verts
[0]);
1403 const GLsizei kCount
= 2;
1404 const GLsizei kSize1
=
1405 arraysize(verts
) * kNumComponents1
* sizeof(verts
[0][0]);
1406 const GLsizei kSize2
=
1407 1 * kNumComponents2
* sizeof(verts
[0][0]);
1408 const GLuint kDivisor
= 1;
1409 const GLsizei kEmuOffset1
= 0;
1410 const GLsizei kEmuOffset2
= kSize1
;
1411 const GLsizei kTotalSize
= kSize1
+ kSize2
;
1413 ExpectedMemoryInfo mem1
= GetExpectedMemory(kIndexSize
);
1414 ExpectedMemoryInfo mem2
= GetExpectedMemory(kSize1
);
1415 ExpectedMemoryInfo mem3
= GetExpectedMemory(kSize2
);
1418 expected
.enable1
.Init(kAttribIndex1
);
1419 expected
.enable2
.Init(kAttribIndex2
);
1420 expected
.divisor
.Init(kAttribIndex2
, kDivisor
);
1421 expected
.bind_to_index_emu
.Init(GL_ELEMENT_ARRAY_BUFFER
, kEmuIndexBufferId
);
1422 expected
.set_index_size
.Init(
1423 GL_ELEMENT_ARRAY_BUFFER
, kIndexSize
, 0, 0, GL_DYNAMIC_DRAW
);
1424 expected
.copy_data0
.Init(
1425 GL_ELEMENT_ARRAY_BUFFER
, 0, kIndexSize
, mem1
.id
, mem1
.offset
);
1426 expected
.set_token0
.Init(GetNextToken());
1427 expected
.bind_to_emu
.Init(GL_ARRAY_BUFFER
, kEmuBufferId
);
1428 expected
.set_size
.Init(GL_ARRAY_BUFFER
, kTotalSize
, 0, 0, GL_DYNAMIC_DRAW
);
1429 expected
.copy_data1
.Init(
1430 GL_ARRAY_BUFFER
, kEmuOffset1
, kSize1
, mem2
.id
, mem2
.offset
);
1431 expected
.set_token1
.Init(GetNextToken());
1432 expected
.set_pointer1
.Init(
1433 kAttribIndex1
, kNumComponents1
, GL_FLOAT
, GL_FALSE
, 0, kEmuOffset1
);
1434 expected
.copy_data2
.Init(
1435 GL_ARRAY_BUFFER
, kEmuOffset2
, kSize2
, mem3
.id
, mem3
.offset
);
1436 expected
.set_token2
.Init(GetNextToken());
1437 expected
.set_pointer2
.Init(kAttribIndex2
, kNumComponents2
,
1438 GL_FLOAT
, GL_FALSE
, 0, kEmuOffset2
);
1439 expected
.draw
.Init(GL_POINTS
, kCount
, GL_UNSIGNED_SHORT
, 0, 1);
1440 expected
.restore
.Init(GL_ARRAY_BUFFER
, 0);
1441 expected
.restore_element
.Init(GL_ELEMENT_ARRAY_BUFFER
, 0);
1442 gl_
->EnableVertexAttribArray(kAttribIndex1
);
1443 gl_
->EnableVertexAttribArray(kAttribIndex2
);
1444 gl_
->VertexAttribPointer(kAttribIndex1
, kNumComponents1
,
1445 GL_FLOAT
, GL_FALSE
, kClientStride
, verts
);
1446 gl_
->VertexAttribPointer(kAttribIndex2
, kNumComponents2
,
1447 GL_FLOAT
, GL_FALSE
, kClientStride
, verts
);
1448 gl_
->VertexAttribDivisorANGLE(kAttribIndex2
, kDivisor
);
1449 gl_
->DrawElementsInstancedANGLE(
1450 GL_POINTS
, kCount
, GL_UNSIGNED_SHORT
, indices
, 1);
1451 EXPECT_EQ(0, memcmp(&expected
, commands_
, sizeof(expected
)));
1454 TEST_F(GLES2ImplementationTest
, GetVertexBufferPointerv
) {
1455 static const float verts
[1] = { 0.0f
, };
1456 const GLuint kAttribIndex1
= 1;
1457 const GLuint kAttribIndex2
= 3;
1458 const GLint kNumComponents1
= 3;
1459 const GLint kNumComponents2
= 2;
1460 const GLsizei kStride1
= 12;
1461 const GLsizei kStride2
= 0;
1462 const GLuint kBufferId
= 0x123;
1463 const GLint kOffset2
= 0x456;
1465 // It's all cached on the client side so no get commands are issued.
1467 cmds::BindBuffer bind
;
1468 cmds::VertexAttribPointer set_pointer
;
1472 expected
.bind
.Init(GL_ARRAY_BUFFER
, kBufferId
);
1473 expected
.set_pointer
.Init(kAttribIndex2
, kNumComponents2
, GL_FLOAT
, GL_FALSE
,
1474 kStride2
, kOffset2
);
1476 // Set one client side buffer.
1477 gl_
->VertexAttribPointer(kAttribIndex1
, kNumComponents1
,
1478 GL_FLOAT
, GL_FALSE
, kStride1
, verts
);
1480 gl_
->BindBuffer(GL_ARRAY_BUFFER
, kBufferId
);
1481 gl_
->VertexAttribPointer(kAttribIndex2
, kNumComponents2
,
1482 GL_FLOAT
, GL_FALSE
, kStride2
,
1483 reinterpret_cast<const void*>(kOffset2
));
1484 // now get them both.
1488 gl_
->GetVertexAttribPointerv(
1489 kAttribIndex1
, GL_VERTEX_ATTRIB_ARRAY_POINTER
, &ptr1
);
1490 gl_
->GetVertexAttribPointerv(
1491 kAttribIndex2
, GL_VERTEX_ATTRIB_ARRAY_POINTER
, &ptr2
);
1493 EXPECT_EQ(0, memcmp(&expected
, commands_
, sizeof(expected
)));
1494 EXPECT_TRUE(static_cast<const void*>(&verts
) == ptr1
);
1495 EXPECT_TRUE(ptr2
== reinterpret_cast<void*>(kOffset2
));
1498 TEST_F(GLES2ImplementationTest
, GetVertexAttrib
) {
1499 static const float verts
[1] = { 0.0f
, };
1500 const GLuint kAttribIndex1
= 1;
1501 const GLuint kAttribIndex2
= 3;
1502 const GLint kNumComponents1
= 3;
1503 const GLint kNumComponents2
= 2;
1504 const GLsizei kStride1
= 12;
1505 const GLsizei kStride2
= 0;
1506 const GLuint kBufferId
= 0x123;
1507 const GLint kOffset2
= 0x456;
1509 // Only one set and one get because the client side buffer's info is stored
1510 // on the client side.
1512 cmds::EnableVertexAttribArray enable
;
1513 cmds::BindBuffer bind
;
1514 cmds::VertexAttribPointer set_pointer
;
1515 cmds::GetVertexAttribfv get2
; // for getting the value from attrib1
1518 ExpectedMemoryInfo mem2
= GetExpectedResultMemory(16);
1521 expected
.enable
.Init(kAttribIndex1
);
1522 expected
.bind
.Init(GL_ARRAY_BUFFER
, kBufferId
);
1523 expected
.set_pointer
.Init(kAttribIndex2
, kNumComponents2
, GL_FLOAT
, GL_FALSE
,
1524 kStride2
, kOffset2
);
1525 expected
.get2
.Init(kAttribIndex1
,
1526 GL_CURRENT_VERTEX_ATTRIB
,
1527 mem2
.id
, mem2
.offset
);
1529 FourFloats
current_attrib(1.2f
, 3.4f
, 5.6f
, 7.8f
);
1531 // One call to flush to wait for last call to GetVertexAttribiv
1532 // as others are all cached.
1533 EXPECT_CALL(*command_buffer(), OnFlush())
1534 .WillOnce(SetMemory(
1535 mem2
.ptr
, SizedResultHelper
<FourFloats
>(current_attrib
)))
1536 .RetiresOnSaturation();
1538 gl_
->EnableVertexAttribArray(kAttribIndex1
);
1539 // Set one client side buffer.
1540 gl_
->VertexAttribPointer(kAttribIndex1
, kNumComponents1
,
1541 GL_FLOAT
, GL_FALSE
, kStride1
, verts
);
1543 gl_
->BindBuffer(GL_ARRAY_BUFFER
, kBufferId
);
1544 gl_
->VertexAttribPointer(kAttribIndex2
, kNumComponents2
,
1545 GL_FLOAT
, GL_FALSE
, kStride2
,
1546 reinterpret_cast<const void*>(kOffset2
));
1547 // first get the service side once to see that we make a command
1548 GLint buffer_id
= 0;
1553 GLint normalized
= 1;
1554 float current
[4] = { 0.0f
, };
1556 gl_
->GetVertexAttribiv(
1557 kAttribIndex2
, GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING
, &buffer_id
);
1558 EXPECT_EQ(kBufferId
, static_cast<GLuint
>(buffer_id
));
1559 gl_
->GetVertexAttribiv(
1560 kAttribIndex1
, GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING
, &buffer_id
);
1561 gl_
->GetVertexAttribiv(
1562 kAttribIndex1
, GL_VERTEX_ATTRIB_ARRAY_ENABLED
, &enabled
);
1563 gl_
->GetVertexAttribiv(
1564 kAttribIndex1
, GL_VERTEX_ATTRIB_ARRAY_SIZE
, &size
);
1565 gl_
->GetVertexAttribiv(
1566 kAttribIndex1
, GL_VERTEX_ATTRIB_ARRAY_STRIDE
, &stride
);
1567 gl_
->GetVertexAttribiv(
1568 kAttribIndex1
, GL_VERTEX_ATTRIB_ARRAY_TYPE
, &type
);
1569 gl_
->GetVertexAttribiv(
1570 kAttribIndex1
, GL_VERTEX_ATTRIB_ARRAY_NORMALIZED
, &normalized
);
1571 gl_
->GetVertexAttribfv(
1572 kAttribIndex1
, GL_CURRENT_VERTEX_ATTRIB
, ¤t
[0]);
1574 EXPECT_EQ(0, buffer_id
);
1575 EXPECT_EQ(GL_TRUE
, enabled
);
1576 EXPECT_EQ(kNumComponents1
, size
);
1577 EXPECT_EQ(kStride1
, stride
);
1578 EXPECT_EQ(GL_FLOAT
, type
);
1579 EXPECT_EQ(GL_FALSE
, normalized
);
1580 EXPECT_EQ(0, memcmp(¤t_attrib
, ¤t
, sizeof(current_attrib
)));
1582 EXPECT_EQ(0, memcmp(&expected
, commands_
, sizeof(expected
)));
1585 TEST_F(GLES2ImplementationTest
, ReservedIds
) {
1586 // Only the get error command should be issued.
1592 ExpectedMemoryInfo mem1
= GetExpectedResultMemory(
1593 sizeof(cmds::GetError::Result
));
1595 expected
.get
.Init(mem1
.id
, mem1
.offset
);
1597 // One call to flush to wait for GetError
1598 EXPECT_CALL(*command_buffer(), OnFlush())
1599 .WillOnce(SetMemory(mem1
.ptr
, GLuint(GL_NO_ERROR
)))
1600 .RetiresOnSaturation();
1604 GLES2Implementation::kClientSideArrayId
);
1607 GLES2Implementation::kClientSideElementArrayId
);
1608 GLenum err
= gl_
->GetError();
1609 EXPECT_EQ(static_cast<GLenum
>(GL_INVALID_OPERATION
), err
);
1610 EXPECT_EQ(0, memcmp(&expected
, commands_
, sizeof(expected
)));
1613 #endif // defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS)
1615 TEST_F(GLES2ImplementationTest
, ReadPixels2Reads
) {
1617 cmds::ReadPixels read1
;
1618 cmd::SetToken set_token1
;
1619 cmds::ReadPixels read2
;
1620 cmd::SetToken set_token2
;
1622 const GLint kBytesPerPixel
= 4;
1623 const GLint kWidth
=
1624 (kTransferBufferSize
- GLES2Implementation::kStartingOffset
) /
1626 const GLint kHeight
= 2;
1627 const GLenum kFormat
= GL_RGBA
;
1628 const GLenum kType
= GL_UNSIGNED_BYTE
;
1630 ExpectedMemoryInfo mem1
=
1631 GetExpectedMemory(kWidth
* kHeight
/ 2 * kBytesPerPixel
);
1632 ExpectedMemoryInfo result1
=
1633 GetExpectedResultMemory(sizeof(cmds::ReadPixels::Result
));
1634 ExpectedMemoryInfo mem2
=
1635 GetExpectedMemory(kWidth
* kHeight
/ 2 * kBytesPerPixel
);
1636 ExpectedMemoryInfo result2
=
1637 GetExpectedResultMemory(sizeof(cmds::ReadPixels::Result
));
1640 expected
.read1
.Init(
1641 0, 0, kWidth
, kHeight
/ 2, kFormat
, kType
,
1642 mem1
.id
, mem1
.offset
, result1
.id
, result1
.offset
,
1644 expected
.set_token1
.Init(GetNextToken());
1645 expected
.read2
.Init(
1646 0, kHeight
/ 2, kWidth
, kHeight
/ 2, kFormat
, kType
,
1647 mem2
.id
, mem2
.offset
, result2
.id
, result2
.offset
, false);
1648 expected
.set_token2
.Init(GetNextToken());
1649 scoped_ptr
<int8
[]> buffer(new int8
[kWidth
* kHeight
* kBytesPerPixel
]);
1651 EXPECT_CALL(*command_buffer(), OnFlush())
1652 .WillOnce(SetMemory(result1
.ptr
, static_cast<uint32
>(1)))
1653 .WillOnce(SetMemory(result2
.ptr
, static_cast<uint32
>(1)))
1654 .RetiresOnSaturation();
1656 gl_
->ReadPixels(0, 0, kWidth
, kHeight
, kFormat
, kType
, buffer
.get());
1657 EXPECT_EQ(0, memcmp(&expected
, commands_
, sizeof(expected
)));
1660 TEST_F(GLES2ImplementationTest
, ReadPixelsBadFormatType
) {
1662 cmds::ReadPixels read
;
1663 cmd::SetToken set_token
;
1665 const GLint kBytesPerPixel
= 4;
1666 const GLint kWidth
= 2;
1667 const GLint kHeight
= 2;
1668 const GLenum kFormat
= 0;
1669 const GLenum kType
= 0;
1671 ExpectedMemoryInfo mem1
=
1672 GetExpectedMemory(kWidth
* kHeight
* kBytesPerPixel
);
1673 ExpectedMemoryInfo result1
=
1674 GetExpectedResultMemory(sizeof(cmds::ReadPixels::Result
));
1678 0, 0, kWidth
, kHeight
, kFormat
, kType
,
1679 mem1
.id
, mem1
.offset
, result1
.id
, result1
.offset
, false);
1680 expected
.set_token
.Init(GetNextToken());
1681 scoped_ptr
<int8
[]> buffer(new int8
[kWidth
* kHeight
* kBytesPerPixel
]);
1683 EXPECT_CALL(*command_buffer(), OnFlush())
1685 .RetiresOnSaturation();
1687 gl_
->ReadPixels(0, 0, kWidth
, kHeight
, kFormat
, kType
, buffer
.get());
1690 TEST_F(GLES2ImplementationTest
, FreeUnusedSharedMemory
) {
1692 cmds::BufferSubData buf
;
1693 cmd::SetToken set_token
;
1695 const GLenum kTarget
= GL_ELEMENT_ARRAY_BUFFER
;
1696 const GLintptr kOffset
= 15;
1697 const GLsizeiptr kSize
= 16;
1699 ExpectedMemoryInfo mem1
= GetExpectedMemory(kSize
);
1703 kTarget
, kOffset
, kSize
, mem1
.id
, mem1
.offset
);
1704 expected
.set_token
.Init(GetNextToken());
1706 void* mem
= gl_
->MapBufferSubDataCHROMIUM(
1707 kTarget
, kOffset
, kSize
, GL_WRITE_ONLY
);
1708 ASSERT_TRUE(mem
!= NULL
);
1709 gl_
->UnmapBufferSubDataCHROMIUM(mem
);
1710 EXPECT_CALL(*command_buffer(), DestroyTransferBuffer(_
))
1712 .RetiresOnSaturation();
1713 gl_
->FreeUnusedSharedMemory();
1716 TEST_F(GLES2ImplementationTest
, MapUnmapBufferSubDataCHROMIUM
) {
1718 cmds::BufferSubData buf
;
1719 cmd::SetToken set_token
;
1721 const GLenum kTarget
= GL_ELEMENT_ARRAY_BUFFER
;
1722 const GLintptr kOffset
= 15;
1723 const GLsizeiptr kSize
= 16;
1728 kTarget
, kOffset
, kSize
,
1729 command_buffer()->GetNextFreeTransferBufferId(), offset
);
1730 expected
.set_token
.Init(GetNextToken());
1732 void* mem
= gl_
->MapBufferSubDataCHROMIUM(
1733 kTarget
, kOffset
, kSize
, GL_WRITE_ONLY
);
1734 ASSERT_TRUE(mem
!= NULL
);
1735 gl_
->UnmapBufferSubDataCHROMIUM(mem
);
1736 EXPECT_EQ(0, memcmp(&expected
, commands_
, sizeof(expected
)));
1739 TEST_F(GLES2ImplementationTest
, MapUnmapBufferSubDataCHROMIUMBadArgs
) {
1740 const GLenum kTarget
= GL_ELEMENT_ARRAY_BUFFER
;
1741 const GLintptr kOffset
= 15;
1742 const GLsizeiptr kSize
= 16;
1744 ExpectedMemoryInfo result1
=
1745 GetExpectedResultMemory(sizeof(cmds::GetError::Result
));
1746 ExpectedMemoryInfo result2
=
1747 GetExpectedResultMemory(sizeof(cmds::GetError::Result
));
1748 ExpectedMemoryInfo result3
=
1749 GetExpectedResultMemory(sizeof(cmds::GetError::Result
));
1750 ExpectedMemoryInfo result4
=
1751 GetExpectedResultMemory(sizeof(cmds::GetError::Result
));
1753 // Calls to flush to wait for GetError
1754 EXPECT_CALL(*command_buffer(), OnFlush())
1755 .WillOnce(SetMemory(result1
.ptr
, GLuint(GL_NO_ERROR
)))
1756 .WillOnce(SetMemory(result2
.ptr
, GLuint(GL_NO_ERROR
)))
1757 .WillOnce(SetMemory(result3
.ptr
, GLuint(GL_NO_ERROR
)))
1758 .WillOnce(SetMemory(result4
.ptr
, GLuint(GL_NO_ERROR
)))
1759 .RetiresOnSaturation();
1762 mem
= gl_
->MapBufferSubDataCHROMIUM(kTarget
, -1, kSize
, GL_WRITE_ONLY
);
1763 ASSERT_TRUE(mem
== NULL
);
1764 EXPECT_EQ(static_cast<GLenum
>(GL_INVALID_VALUE
), gl_
->GetError());
1765 mem
= gl_
->MapBufferSubDataCHROMIUM(kTarget
, kOffset
, -1, GL_WRITE_ONLY
);
1766 ASSERT_TRUE(mem
== NULL
);
1767 EXPECT_EQ(static_cast<GLenum
>(GL_INVALID_VALUE
), gl_
->GetError());
1768 mem
= gl_
->MapBufferSubDataCHROMIUM(kTarget
, kOffset
, kSize
, GL_READ_ONLY
);
1769 ASSERT_TRUE(mem
== NULL
);
1770 EXPECT_EQ(static_cast<GLenum
>(GL_INVALID_ENUM
), gl_
->GetError());
1771 const char* kPtr
= "something";
1772 gl_
->UnmapBufferSubDataCHROMIUM(kPtr
);
1773 EXPECT_EQ(static_cast<GLenum
>(GL_INVALID_VALUE
), gl_
->GetError());
1776 TEST_F(GLES2ImplementationTest
, MapUnmapTexSubImage2DCHROMIUM
) {
1778 cmds::TexSubImage2D tex
;
1779 cmd::SetToken set_token
;
1781 const GLint kLevel
= 1;
1782 const GLint kXOffset
= 2;
1783 const GLint kYOffset
= 3;
1784 const GLint kWidth
= 4;
1785 const GLint kHeight
= 5;
1786 const GLenum kFormat
= GL_RGBA
;
1787 const GLenum kType
= GL_UNSIGNED_BYTE
;
1792 GL_TEXTURE_2D
, kLevel
, kXOffset
, kYOffset
, kWidth
, kHeight
, kFormat
,
1794 command_buffer()->GetNextFreeTransferBufferId(), offset
, GL_FALSE
);
1795 expected
.set_token
.Init(GetNextToken());
1797 void* mem
= gl_
->MapTexSubImage2DCHROMIUM(
1807 ASSERT_TRUE(mem
!= NULL
);
1808 gl_
->UnmapTexSubImage2DCHROMIUM(mem
);
1809 EXPECT_EQ(0, memcmp(&expected
, commands_
, sizeof(expected
)));
1812 TEST_F(GLES2ImplementationTest
, MapUnmapTexSubImage2DCHROMIUMBadArgs
) {
1813 const GLint kLevel
= 1;
1814 const GLint kXOffset
= 2;
1815 const GLint kYOffset
= 3;
1816 const GLint kWidth
= 4;
1817 const GLint kHeight
= 5;
1818 const GLenum kFormat
= GL_RGBA
;
1819 const GLenum kType
= GL_UNSIGNED_BYTE
;
1821 ExpectedMemoryInfo result1
=
1822 GetExpectedResultMemory(sizeof(cmds::GetError::Result
));
1823 ExpectedMemoryInfo result2
=
1824 GetExpectedResultMemory(sizeof(cmds::GetError::Result
));
1825 ExpectedMemoryInfo result3
=
1826 GetExpectedResultMemory(sizeof(cmds::GetError::Result
));
1827 ExpectedMemoryInfo result4
=
1828 GetExpectedResultMemory(sizeof(cmds::GetError::Result
));
1829 ExpectedMemoryInfo result5
=
1830 GetExpectedResultMemory(sizeof(cmds::GetError::Result
));
1831 ExpectedMemoryInfo result6
=
1832 GetExpectedResultMemory(sizeof(cmds::GetError::Result
));
1833 ExpectedMemoryInfo result7
=
1834 GetExpectedResultMemory(sizeof(cmds::GetError::Result
));
1836 // Calls to flush to wait for GetError
1837 EXPECT_CALL(*command_buffer(), OnFlush())
1838 .WillOnce(SetMemory(result1
.ptr
, GLuint(GL_NO_ERROR
)))
1839 .WillOnce(SetMemory(result2
.ptr
, GLuint(GL_NO_ERROR
)))
1840 .WillOnce(SetMemory(result3
.ptr
, GLuint(GL_NO_ERROR
)))
1841 .WillOnce(SetMemory(result4
.ptr
, GLuint(GL_NO_ERROR
)))
1842 .WillOnce(SetMemory(result5
.ptr
, GLuint(GL_NO_ERROR
)))
1843 .WillOnce(SetMemory(result6
.ptr
, GLuint(GL_NO_ERROR
)))
1844 .WillOnce(SetMemory(result7
.ptr
, GLuint(GL_NO_ERROR
)))
1845 .RetiresOnSaturation();
1848 mem
= gl_
->MapTexSubImage2DCHROMIUM(
1858 EXPECT_TRUE(mem
== NULL
);
1859 EXPECT_EQ(static_cast<GLenum
>(GL_INVALID_VALUE
), gl_
->GetError());
1860 mem
= gl_
->MapTexSubImage2DCHROMIUM(
1870 EXPECT_TRUE(mem
== NULL
);
1871 EXPECT_EQ(static_cast<GLenum
>(GL_INVALID_VALUE
), gl_
->GetError());
1872 mem
= gl_
->MapTexSubImage2DCHROMIUM(
1882 EXPECT_TRUE(mem
== NULL
);
1883 EXPECT_EQ(static_cast<GLenum
>(GL_INVALID_VALUE
), gl_
->GetError());
1884 mem
= gl_
->MapTexSubImage2DCHROMIUM(
1894 EXPECT_TRUE(mem
== NULL
);
1895 EXPECT_EQ(static_cast<GLenum
>(GL_INVALID_VALUE
), gl_
->GetError());
1896 mem
= gl_
->MapTexSubImage2DCHROMIUM(
1906 EXPECT_TRUE(mem
== NULL
);
1907 EXPECT_EQ(static_cast<GLenum
>(GL_INVALID_VALUE
), gl_
->GetError());
1908 mem
= gl_
->MapTexSubImage2DCHROMIUM(
1918 EXPECT_TRUE(mem
== NULL
);
1919 EXPECT_EQ(static_cast<GLenum
>(GL_INVALID_ENUM
), gl_
->GetError());
1920 const char* kPtr
= "something";
1921 gl_
->UnmapTexSubImage2DCHROMIUM(kPtr
);
1922 EXPECT_EQ(static_cast<GLenum
>(GL_INVALID_VALUE
), gl_
->GetError());
1925 TEST_F(GLES2ImplementationTest
, GetProgramInfoCHROMIUMGoodArgs
) {
1926 const uint32 kBucketId
= GLES2Implementation::kResultBucketId
;
1927 const GLuint kProgramId
= 123;
1928 const char kBad
= 0x12;
1930 const Str7 kString
= {"foobar"};
1933 ExpectedMemoryInfo mem1
=
1934 GetExpectedMemory(MaxTransferBufferSize());
1935 ExpectedMemoryInfo result1
=
1936 GetExpectedResultMemory(sizeof(cmd::GetBucketStart::Result
));
1937 ExpectedMemoryInfo result2
=
1938 GetExpectedResultMemory(sizeof(cmds::GetError::Result
));
1940 memset(buf
, kBad
, sizeof(buf
));
1941 EXPECT_CALL(*command_buffer(), OnFlush())
1942 .WillOnce(DoAll(SetMemory(result1
.ptr
, uint32(sizeof(kString
))),
1943 SetMemory(mem1
.ptr
, kString
)))
1944 .WillOnce(SetMemory(result2
.ptr
, GLuint(GL_NO_ERROR
)))
1945 .RetiresOnSaturation();
1948 cmd::SetBucketSize set_bucket_size1
;
1949 cmds::GetProgramInfoCHROMIUM get_program_info
;
1950 cmd::GetBucketStart get_bucket_start
;
1951 cmd::SetToken set_token1
;
1952 cmd::SetBucketSize set_bucket_size2
;
1955 expected
.set_bucket_size1
.Init(kBucketId
, 0);
1956 expected
.get_program_info
.Init(kProgramId
, kBucketId
);
1957 expected
.get_bucket_start
.Init(
1958 kBucketId
, result1
.id
, result1
.offset
,
1959 MaxTransferBufferSize(), mem1
.id
, mem1
.offset
);
1960 expected
.set_token1
.Init(GetNextToken());
1961 expected
.set_bucket_size2
.Init(kBucketId
, 0);
1962 gl_
->GetProgramInfoCHROMIUM(kProgramId
, sizeof(buf
), &size
, &buf
);
1963 EXPECT_EQ(0, memcmp(&expected
, commands_
, sizeof(expected
)));
1964 EXPECT_EQ(static_cast<GLenum
>(GL_NO_ERROR
), gl_
->GetError());
1965 EXPECT_EQ(sizeof(kString
), static_cast<size_t>(size
));
1966 EXPECT_STREQ(kString
.str
, buf
);
1967 EXPECT_EQ(buf
[sizeof(kString
)], kBad
);
1970 TEST_F(GLES2ImplementationTest
, GetProgramInfoCHROMIUMBadArgs
) {
1971 const uint32 kBucketId
= GLES2Implementation::kResultBucketId
;
1972 const GLuint kProgramId
= 123;
1974 const Str7 kString
= {"foobar"};
1977 ExpectedMemoryInfo mem1
= GetExpectedMemory(MaxTransferBufferSize());
1978 ExpectedMemoryInfo result1
=
1979 GetExpectedResultMemory(sizeof(cmd::GetBucketStart::Result
));
1980 ExpectedMemoryInfo result2
=
1981 GetExpectedResultMemory(sizeof(cmds::GetError::Result
));
1982 ExpectedMemoryInfo result3
=
1983 GetExpectedResultMemory(sizeof(cmds::GetError::Result
));
1984 ExpectedMemoryInfo result4
=
1985 GetExpectedResultMemory(sizeof(cmds::GetError::Result
));
1987 EXPECT_CALL(*command_buffer(), OnFlush())
1988 .WillOnce(DoAll(SetMemory(result1
.ptr
, uint32(sizeof(kString
))),
1989 SetMemory(mem1
.ptr
, kString
)))
1990 .WillOnce(SetMemory(result2
.ptr
, GLuint(GL_NO_ERROR
)))
1991 .WillOnce(SetMemory(result3
.ptr
, GLuint(GL_NO_ERROR
)))
1992 .WillOnce(SetMemory(result4
.ptr
, GLuint(GL_NO_ERROR
)))
1993 .RetiresOnSaturation();
1995 // try bufsize not big enough.
1997 cmd::SetBucketSize set_bucket_size1
;
1998 cmds::GetProgramInfoCHROMIUM get_program_info
;
1999 cmd::GetBucketStart get_bucket_start
;
2000 cmd::SetToken set_token1
;
2001 cmd::SetBucketSize set_bucket_size2
;
2004 expected
.set_bucket_size1
.Init(kBucketId
, 0);
2005 expected
.get_program_info
.Init(kProgramId
, kBucketId
);
2006 expected
.get_bucket_start
.Init(
2007 kBucketId
, result1
.id
, result1
.offset
,
2008 MaxTransferBufferSize(), mem1
.id
, mem1
.offset
);
2009 expected
.set_token1
.Init(GetNextToken());
2010 expected
.set_bucket_size2
.Init(kBucketId
, 0);
2011 gl_
->GetProgramInfoCHROMIUM(kProgramId
, 6, &size
, &buf
);
2012 EXPECT_EQ(0, memcmp(&expected
, commands_
, sizeof(expected
)));
2013 EXPECT_EQ(static_cast<GLenum
>(GL_INVALID_OPERATION
), gl_
->GetError());
2017 gl_
->GetProgramInfoCHROMIUM(kProgramId
, -1, &size
, &buf
);
2018 EXPECT_TRUE(NoCommandsWritten());
2019 EXPECT_EQ(static_cast<GLenum
>(GL_INVALID_VALUE
), gl_
->GetError());
2022 gl_
->GetProgramInfoCHROMIUM(kProgramId
, sizeof(buf
), NULL
, &buf
);
2023 EXPECT_TRUE(NoCommandsWritten());
2024 EXPECT_EQ(static_cast<GLenum
>(GL_INVALID_VALUE
), gl_
->GetError());
2027 TEST_F(GLES2ImplementationTest
, GetUniformBlocksCHROMIUMGoodArgs
) {
2028 const uint32 kBucketId
= GLES2Implementation::kResultBucketId
;
2029 const GLuint kProgramId
= 123;
2030 const char kBad
= 0x12;
2032 const Str7 kString
= {"foobar"};
2035 ExpectedMemoryInfo mem1
=
2036 GetExpectedMemory(MaxTransferBufferSize());
2037 ExpectedMemoryInfo result1
=
2038 GetExpectedResultMemory(sizeof(cmd::GetBucketStart::Result
));
2039 ExpectedMemoryInfo result2
=
2040 GetExpectedResultMemory(sizeof(cmds::GetError::Result
));
2042 memset(buf
, kBad
, sizeof(buf
));
2043 EXPECT_CALL(*command_buffer(), OnFlush())
2044 .WillOnce(DoAll(SetMemory(result1
.ptr
, uint32(sizeof(kString
))),
2045 SetMemory(mem1
.ptr
, kString
)))
2046 .WillOnce(SetMemory(result2
.ptr
, GLuint(GL_NO_ERROR
)))
2047 .RetiresOnSaturation();
2050 cmd::SetBucketSize set_bucket_size1
;
2051 cmds::GetUniformBlocksCHROMIUM get_uniform_blocks
;
2052 cmd::GetBucketStart get_bucket_start
;
2053 cmd::SetToken set_token1
;
2054 cmd::SetBucketSize set_bucket_size2
;
2057 expected
.set_bucket_size1
.Init(kBucketId
, 0);
2058 expected
.get_uniform_blocks
.Init(kProgramId
, kBucketId
);
2059 expected
.get_bucket_start
.Init(
2060 kBucketId
, result1
.id
, result1
.offset
,
2061 MaxTransferBufferSize(), mem1
.id
, mem1
.offset
);
2062 expected
.set_token1
.Init(GetNextToken());
2063 expected
.set_bucket_size2
.Init(kBucketId
, 0);
2064 gl_
->GetUniformBlocksCHROMIUM(kProgramId
, sizeof(buf
), &size
, &buf
);
2065 EXPECT_EQ(0, memcmp(&expected
, commands_
, sizeof(expected
)));
2066 EXPECT_EQ(static_cast<GLenum
>(GL_NO_ERROR
), gl_
->GetError());
2067 EXPECT_EQ(sizeof(kString
), static_cast<size_t>(size
));
2068 EXPECT_STREQ(kString
.str
, buf
);
2069 EXPECT_EQ(buf
[sizeof(kString
)], kBad
);
2072 TEST_F(GLES2ImplementationTest
, GetUniformBlocksCHROMIUMBadArgs
) {
2073 const uint32 kBucketId
= GLES2Implementation::kResultBucketId
;
2074 const GLuint kProgramId
= 123;
2076 const Str7 kString
= {"foobar"};
2079 ExpectedMemoryInfo mem1
= GetExpectedMemory(MaxTransferBufferSize());
2080 ExpectedMemoryInfo result1
=
2081 GetExpectedResultMemory(sizeof(cmd::GetBucketStart::Result
));
2082 ExpectedMemoryInfo result2
=
2083 GetExpectedResultMemory(sizeof(cmds::GetError::Result
));
2084 ExpectedMemoryInfo result3
=
2085 GetExpectedResultMemory(sizeof(cmds::GetError::Result
));
2086 ExpectedMemoryInfo result4
=
2087 GetExpectedResultMemory(sizeof(cmds::GetError::Result
));
2089 EXPECT_CALL(*command_buffer(), OnFlush())
2090 .WillOnce(DoAll(SetMemory(result1
.ptr
, uint32(sizeof(kString
))),
2091 SetMemory(mem1
.ptr
, kString
)))
2092 .WillOnce(SetMemory(result2
.ptr
, GLuint(GL_NO_ERROR
)))
2093 .WillOnce(SetMemory(result3
.ptr
, GLuint(GL_NO_ERROR
)))
2094 .WillOnce(SetMemory(result4
.ptr
, GLuint(GL_NO_ERROR
)))
2095 .RetiresOnSaturation();
2097 // try bufsize not big enough.
2099 cmd::SetBucketSize set_bucket_size1
;
2100 cmds::GetUniformBlocksCHROMIUM get_uniform_blocks
;
2101 cmd::GetBucketStart get_bucket_start
;
2102 cmd::SetToken set_token1
;
2103 cmd::SetBucketSize set_bucket_size2
;
2106 expected
.set_bucket_size1
.Init(kBucketId
, 0);
2107 expected
.get_uniform_blocks
.Init(kProgramId
, kBucketId
);
2108 expected
.get_bucket_start
.Init(
2109 kBucketId
, result1
.id
, result1
.offset
,
2110 MaxTransferBufferSize(), mem1
.id
, mem1
.offset
);
2111 expected
.set_token1
.Init(GetNextToken());
2112 expected
.set_bucket_size2
.Init(kBucketId
, 0);
2113 gl_
->GetUniformBlocksCHROMIUM(kProgramId
, 6, &size
, &buf
);
2114 EXPECT_EQ(0, memcmp(&expected
, commands_
, sizeof(expected
)));
2115 EXPECT_EQ(static_cast<GLenum
>(GL_INVALID_OPERATION
), gl_
->GetError());
2119 gl_
->GetUniformBlocksCHROMIUM(kProgramId
, -1, &size
, &buf
);
2120 EXPECT_TRUE(NoCommandsWritten());
2121 EXPECT_EQ(static_cast<GLenum
>(GL_INVALID_VALUE
), gl_
->GetError());
2124 gl_
->GetUniformBlocksCHROMIUM(kProgramId
, sizeof(buf
), NULL
, &buf
);
2125 EXPECT_TRUE(NoCommandsWritten());
2126 EXPECT_EQ(static_cast<GLenum
>(GL_INVALID_VALUE
), gl_
->GetError());
2129 // Test that things are cached
2130 TEST_F(GLES2ImplementationTest
, GetIntegerCacheRead
) {
2135 const PNameValue pairs
[] = {
2136 {GL_ACTIVE_TEXTURE
, GL_TEXTURE0
, },
2137 {GL_TEXTURE_BINDING_2D
, 0, },
2138 {GL_TEXTURE_BINDING_CUBE_MAP
, 0, },
2139 {GL_TEXTURE_BINDING_EXTERNAL_OES
, 0, },
2140 {GL_FRAMEBUFFER_BINDING
, 0, },
2141 {GL_RENDERBUFFER_BINDING
, 0, },
2142 {GL_ARRAY_BUFFER_BINDING
, 0, },
2143 {GL_ELEMENT_ARRAY_BUFFER_BINDING
, 0, },
2144 {GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS
, kMaxCombinedTextureImageUnits
, },
2145 {GL_MAX_CUBE_MAP_TEXTURE_SIZE
, kMaxCubeMapTextureSize
, },
2146 {GL_MAX_FRAGMENT_UNIFORM_VECTORS
, kMaxFragmentUniformVectors
, },
2147 {GL_MAX_RENDERBUFFER_SIZE
, kMaxRenderbufferSize
, },
2148 {GL_MAX_TEXTURE_IMAGE_UNITS
, kMaxTextureImageUnits
, },
2149 {GL_MAX_TEXTURE_SIZE
, kMaxTextureSize
, },
2150 {GL_MAX_VARYING_VECTORS
, kMaxVaryingVectors
, },
2151 {GL_MAX_VERTEX_ATTRIBS
, kMaxVertexAttribs
, },
2152 {GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS
, kMaxVertexTextureImageUnits
, },
2153 {GL_MAX_VERTEX_UNIFORM_VECTORS
, kMaxVertexUniformVectors
, },
2154 {GL_NUM_COMPRESSED_TEXTURE_FORMATS
, kNumCompressedTextureFormats
, },
2155 {GL_NUM_SHADER_BINARY_FORMATS
, kNumShaderBinaryFormats
, }, };
2156 size_t num_pairs
= sizeof(pairs
) / sizeof(pairs
[0]);
2157 for (size_t ii
= 0; ii
< num_pairs
; ++ii
) {
2158 const PNameValue
& pv
= pairs
[ii
];
2160 gl_
->GetIntegerv(pv
.pname
, &v
);
2161 EXPECT_TRUE(NoCommandsWritten());
2162 EXPECT_EQ(pv
.expected
, v
);
2165 ExpectedMemoryInfo result1
=
2166 GetExpectedResultMemory(sizeof(cmds::GetError::Result
));
2168 EXPECT_CALL(*command_buffer(), OnFlush())
2169 .WillOnce(SetMemory(result1
.ptr
, GLuint(GL_NO_ERROR
)))
2170 .RetiresOnSaturation();
2171 EXPECT_EQ(static_cast<GLenum
>(GL_NO_ERROR
), gl_
->GetError());
2174 TEST_F(GLES2ImplementationTest
, GetIntegerCacheWrite
) {
2179 gl_
->ActiveTexture(GL_TEXTURE4
);
2180 gl_
->BindBuffer(GL_ARRAY_BUFFER
, 2);
2181 gl_
->BindBuffer(GL_ELEMENT_ARRAY_BUFFER
, 3);
2182 gl_
->BindFramebuffer(GL_FRAMEBUFFER
, 4);
2183 gl_
->BindRenderbuffer(GL_RENDERBUFFER
, 5);
2184 gl_
->BindTexture(GL_TEXTURE_2D
, 6);
2185 gl_
->BindTexture(GL_TEXTURE_CUBE_MAP
, 7);
2186 gl_
->BindTexture(GL_TEXTURE_EXTERNAL_OES
, 8);
2188 const PNameValue pairs
[] = {{GL_ACTIVE_TEXTURE
, GL_TEXTURE4
, },
2189 {GL_ARRAY_BUFFER_BINDING
, 2, },
2190 {GL_ELEMENT_ARRAY_BUFFER_BINDING
, 3, },
2191 {GL_FRAMEBUFFER_BINDING
, 4, },
2192 {GL_RENDERBUFFER_BINDING
, 5, },
2193 {GL_TEXTURE_BINDING_2D
, 6, },
2194 {GL_TEXTURE_BINDING_CUBE_MAP
, 7, },
2195 {GL_TEXTURE_BINDING_EXTERNAL_OES
, 8, }, };
2196 size_t num_pairs
= sizeof(pairs
) / sizeof(pairs
[0]);
2197 for (size_t ii
= 0; ii
< num_pairs
; ++ii
) {
2198 const PNameValue
& pv
= pairs
[ii
];
2200 gl_
->GetIntegerv(pv
.pname
, &v
);
2201 EXPECT_EQ(pv
.expected
, v
);
2204 ExpectedMemoryInfo result1
=
2205 GetExpectedResultMemory(sizeof(cmds::GetError::Result
));
2207 EXPECT_CALL(*command_buffer(), OnFlush())
2208 .WillOnce(SetMemory(result1
.ptr
, GLuint(GL_NO_ERROR
)))
2209 .RetiresOnSaturation();
2210 EXPECT_EQ(static_cast<GLenum
>(GL_NO_ERROR
), gl_
->GetError());
2213 static bool CheckRect(
2214 int width
, int height
, GLenum format
, GLenum type
, int alignment
,
2215 bool flip_y
, const uint8
* r1
, const uint8
* r2
) {
2217 uint32 unpadded_row_size
= 0;
2218 uint32 padded_row_size
= 0;
2219 if (!GLES2Util::ComputeImageDataSizes(
2220 width
, height
, 1, format
, type
, alignment
, &size
, &unpadded_row_size
,
2221 &padded_row_size
)) {
2225 int r2_stride
= flip_y
?
2226 -static_cast<int>(padded_row_size
) :
2227 static_cast<int>(padded_row_size
);
2228 r2
= flip_y
? (r2
+ (height
- 1) * padded_row_size
) : r2
;
2230 for (int y
= 0; y
< height
; ++y
) {
2231 if (memcmp(r1
, r2
, unpadded_row_size
) != 0) {
2234 r1
+= padded_row_size
;
2240 ACTION_P8(CheckRectAction
, width
, height
, format
, type
, alignment
, flip_y
,
2242 EXPECT_TRUE(CheckRect(
2243 width
, height
, format
, type
, alignment
, flip_y
, r1
, r2
));
2246 // Test TexImage2D with and without flip_y
2247 TEST_F(GLES2ImplementationTest
, TexImage2D
) {
2249 cmds::TexImage2D tex_image_2d
;
2250 cmd::SetToken set_token
;
2253 cmds::TexImage2D tex_image_2d
;
2254 cmd::SetToken set_token
;
2256 const GLenum kTarget
= GL_TEXTURE_2D
;
2257 const GLint kLevel
= 0;
2258 const GLenum kFormat
= GL_RGB
;
2259 const GLsizei kWidth
= 3;
2260 const GLsizei kHeight
= 4;
2261 const GLint kBorder
= 0;
2262 const GLenum kType
= GL_UNSIGNED_BYTE
;
2263 const GLint kPixelStoreUnpackAlignment
= 4;
2264 static uint8 pixels
[] = {
2265 11, 12, 13, 13, 14, 15, 15, 16, 17, 101, 102, 103,
2266 21, 22, 23, 23, 24, 25, 25, 26, 27, 201, 202, 203,
2267 31, 32, 33, 33, 34, 35, 35, 36, 37, 123, 124, 125,
2268 41, 42, 43, 43, 44, 45, 45, 46, 47,
2271 ExpectedMemoryInfo mem1
= GetExpectedMemory(sizeof(pixels
));
2274 expected
.tex_image_2d
.Init(
2275 kTarget
, kLevel
, kFormat
, kWidth
, kHeight
, kFormat
, kType
,
2276 mem1
.id
, mem1
.offset
);
2277 expected
.set_token
.Init(GetNextToken());
2279 kTarget
, kLevel
, kFormat
, kWidth
, kHeight
, kBorder
, kFormat
, kType
,
2281 EXPECT_EQ(0, memcmp(&expected
, commands_
, sizeof(expected
)));
2282 EXPECT_TRUE(CheckRect(
2283 kWidth
, kHeight
, kFormat
, kType
, kPixelStoreUnpackAlignment
, false,
2287 gl_
->PixelStorei(GL_UNPACK_FLIP_Y_CHROMIUM
, GL_TRUE
);
2289 ExpectedMemoryInfo mem2
= GetExpectedMemory(sizeof(pixels
));
2291 expected2
.tex_image_2d
.Init(
2292 kTarget
, kLevel
, kFormat
, kWidth
, kHeight
, kFormat
, kType
,
2293 mem2
.id
, mem2
.offset
);
2294 expected2
.set_token
.Init(GetNextToken());
2295 const void* commands2
= GetPut();
2297 kTarget
, kLevel
, kFormat
, kWidth
, kHeight
, kBorder
, kFormat
, kType
,
2299 EXPECT_EQ(0, memcmp(&expected2
, commands2
, sizeof(expected2
)));
2300 EXPECT_TRUE(CheckRect(
2301 kWidth
, kHeight
, kFormat
, kType
, kPixelStoreUnpackAlignment
, true,
2305 // Test TexImage2D with 2 writes
2306 TEST_F(GLES2ImplementationTest
, TexImage2D2Writes
) {
2308 cmds::TexImage2D tex_image_2d
;
2309 cmds::TexSubImage2D tex_sub_image_2d1
;
2310 cmd::SetToken set_token1
;
2311 cmds::TexSubImage2D tex_sub_image_2d2
;
2312 cmd::SetToken set_token2
;
2314 const GLenum kTarget
= GL_TEXTURE_2D
;
2315 const GLint kLevel
= 0;
2316 const GLenum kFormat
= GL_RGB
;
2317 const GLint kBorder
= 0;
2318 const GLenum kType
= GL_UNSIGNED_BYTE
;
2319 const GLint kPixelStoreUnpackAlignment
= 4;
2320 const GLsizei kWidth
= 3;
2323 uint32 unpadded_row_size
= 0;
2324 uint32 padded_row_size
= 0;
2325 ASSERT_TRUE(GLES2Util::ComputeImageDataSizes(
2326 kWidth
, 2, 1, kFormat
, kType
, kPixelStoreUnpackAlignment
,
2327 &size
, &unpadded_row_size
, &padded_row_size
));
2328 const GLsizei kHeight
= (MaxTransferBufferSize() / padded_row_size
) * 2;
2329 ASSERT_TRUE(GLES2Util::ComputeImageDataSizes(
2330 kWidth
, kHeight
, 1, kFormat
, kType
, kPixelStoreUnpackAlignment
,
2331 &size
, NULL
, NULL
));
2332 uint32 half_size
= 0;
2333 ASSERT_TRUE(GLES2Util::ComputeImageDataSizes(
2334 kWidth
, kHeight
/ 2, 1, kFormat
, kType
, kPixelStoreUnpackAlignment
,
2335 &half_size
, NULL
, NULL
));
2337 scoped_ptr
<uint8
[]> pixels(new uint8
[size
]);
2338 for (uint32 ii
= 0; ii
< size
; ++ii
) {
2339 pixels
[ii
] = static_cast<uint8
>(ii
);
2342 ExpectedMemoryInfo mem1
= GetExpectedMemory(half_size
);
2343 ExpectedMemoryInfo mem2
= GetExpectedMemory(half_size
);
2346 expected
.tex_image_2d
.Init(
2347 kTarget
, kLevel
, kFormat
, kWidth
, kHeight
, kFormat
, kType
,
2349 expected
.tex_sub_image_2d1
.Init(
2350 kTarget
, kLevel
, 0, 0, kWidth
, kHeight
/ 2, kFormat
, kType
,
2351 mem1
.id
, mem1
.offset
, true);
2352 expected
.set_token1
.Init(GetNextToken());
2353 expected
.tex_sub_image_2d2
.Init(
2354 kTarget
, kLevel
, 0, kHeight
/ 2, kWidth
, kHeight
/ 2, kFormat
, kType
,
2355 mem2
.id
, mem2
.offset
, true);
2356 expected
.set_token2
.Init(GetNextToken());
2358 // TODO(gman): Make it possible to run this test
2359 // EXPECT_CALL(*command_buffer(), OnFlush())
2360 // .WillOnce(CheckRectAction(
2361 // kWidth, kHeight / 2, kFormat, kType, kPixelStoreUnpackAlignment,
2362 // false, pixels.get(),
2363 // GetExpectedTransferAddressFromOffsetAs<uint8>(offset1, half_size)))
2364 // .RetiresOnSaturation();
2367 kTarget
, kLevel
, kFormat
, kWidth
, kHeight
, kBorder
, kFormat
, kType
,
2369 EXPECT_EQ(0, memcmp(&expected
, commands_
, sizeof(expected
)));
2370 EXPECT_TRUE(CheckRect(
2371 kWidth
, kHeight
/ 2, kFormat
, kType
, kPixelStoreUnpackAlignment
, false,
2372 pixels
.get() + kHeight
/ 2 * padded_row_size
, mem2
.ptr
));
2375 gl_
->PixelStorei(GL_UNPACK_FLIP_Y_CHROMIUM
, GL_TRUE
);
2376 const void* commands2
= GetPut();
2377 ExpectedMemoryInfo mem3
= GetExpectedMemory(half_size
);
2378 ExpectedMemoryInfo mem4
= GetExpectedMemory(half_size
);
2379 expected
.tex_image_2d
.Init(
2380 kTarget
, kLevel
, kFormat
, kWidth
, kHeight
, kFormat
, kType
,
2382 expected
.tex_sub_image_2d1
.Init(
2383 kTarget
, kLevel
, 0, kHeight
/ 2, kWidth
, kHeight
/ 2, kFormat
, kType
,
2384 mem3
.id
, mem3
.offset
, true);
2385 expected
.set_token1
.Init(GetNextToken());
2386 expected
.tex_sub_image_2d2
.Init(
2387 kTarget
, kLevel
, 0, 0, kWidth
, kHeight
/ 2, kFormat
, kType
,
2388 mem4
.id
, mem4
.offset
, true);
2389 expected
.set_token2
.Init(GetNextToken());
2391 // TODO(gman): Make it possible to run this test
2392 // EXPECT_CALL(*command_buffer(), OnFlush())
2393 // .WillOnce(CheckRectAction(
2394 // kWidth, kHeight / 2, kFormat, kType, kPixelStoreUnpackAlignment,
2395 // true, pixels.get(),
2396 // GetExpectedTransferAddressFromOffsetAs<uint8>(offset3, half_size)))
2397 // .RetiresOnSaturation();
2400 kTarget
, kLevel
, kFormat
, kWidth
, kHeight
, kBorder
, kFormat
, kType
,
2402 EXPECT_EQ(0, memcmp(&expected
, commands2
, sizeof(expected
)));
2403 EXPECT_TRUE(CheckRect(
2404 kWidth
, kHeight
/ 2, kFormat
, kType
, kPixelStoreUnpackAlignment
, true,
2405 pixels
.get() + kHeight
/ 2 * padded_row_size
, mem4
.ptr
));
2408 // Test TexSubImage2D with GL_PACK_FLIP_Y set and partial multirow transfers
2409 TEST_F(GLES2ImplementationTest
, TexSubImage2DFlipY
) {
2410 const GLsizei kTextureWidth
= MaxTransferBufferSize() / 4;
2411 const GLsizei kTextureHeight
= 7;
2412 const GLsizei kSubImageWidth
= MaxTransferBufferSize() / 8;
2413 const GLsizei kSubImageHeight
= 4;
2414 const GLint kSubImageXOffset
= 1;
2415 const GLint kSubImageYOffset
= 2;
2416 const GLenum kFormat
= GL_RGBA
;
2417 const GLenum kType
= GL_UNSIGNED_BYTE
;
2418 const GLenum kTarget
= GL_TEXTURE_2D
;
2419 const GLint kLevel
= 0;
2420 const GLint kBorder
= 0;
2421 const GLint kPixelStoreUnpackAlignment
= 4;
2424 cmds::PixelStorei pixel_store_i1
;
2425 cmds::TexImage2D tex_image_2d
;
2426 cmds::PixelStorei pixel_store_i2
;
2427 cmds::TexSubImage2D tex_sub_image_2d1
;
2428 cmd::SetToken set_token1
;
2429 cmds::TexSubImage2D tex_sub_image_2d2
;
2430 cmd::SetToken set_token2
;
2433 uint32 sub_2_high_size
= 0;
2434 ASSERT_TRUE(GLES2Util::ComputeImageDataSizes(
2435 kSubImageWidth
, 2, 1, kFormat
, kType
, kPixelStoreUnpackAlignment
,
2436 &sub_2_high_size
, NULL
, NULL
));
2438 ExpectedMemoryInfo mem1
= GetExpectedMemory(sub_2_high_size
);
2439 ExpectedMemoryInfo mem2
= GetExpectedMemory(sub_2_high_size
);
2442 expected
.pixel_store_i1
.Init(GL_UNPACK_ALIGNMENT
, kPixelStoreUnpackAlignment
);
2443 expected
.tex_image_2d
.Init(
2444 kTarget
, kLevel
, kFormat
, kTextureWidth
, kTextureHeight
, kFormat
,
2446 expected
.pixel_store_i2
.Init(GL_UNPACK_FLIP_Y_CHROMIUM
, GL_TRUE
);
2447 expected
.tex_sub_image_2d1
.Init(kTarget
, kLevel
, kSubImageXOffset
,
2448 kSubImageYOffset
+ 2, kSubImageWidth
, 2, kFormat
, kType
,
2449 mem1
.id
, mem1
.offset
, false);
2450 expected
.set_token1
.Init(GetNextToken());
2451 expected
.tex_sub_image_2d2
.Init(kTarget
, kLevel
, kSubImageXOffset
,
2452 kSubImageYOffset
, kSubImageWidth
, 2, kFormat
, kType
,
2453 mem2
.id
, mem2
.offset
, false);
2454 expected
.set_token2
.Init(GetNextToken());
2456 gl_
->PixelStorei(GL_UNPACK_ALIGNMENT
, kPixelStoreUnpackAlignment
);
2458 kTarget
, kLevel
, kFormat
, kTextureWidth
, kTextureHeight
, kBorder
, kFormat
,
2460 gl_
->PixelStorei(GL_UNPACK_FLIP_Y_CHROMIUM
, GL_TRUE
);
2461 scoped_ptr
<uint32
[]> pixels(new uint32
[kSubImageWidth
* kSubImageHeight
]);
2462 for (int y
= 0; y
< kSubImageHeight
; ++y
) {
2463 for (int x
= 0; x
< kSubImageWidth
; ++x
) {
2464 pixels
.get()[kSubImageWidth
* y
+ x
] = x
| (y
<< 16);
2468 GL_TEXTURE_2D
, 0, kSubImageXOffset
, kSubImageYOffset
, kSubImageWidth
,
2469 kSubImageHeight
, GL_RGBA
, GL_UNSIGNED_BYTE
, pixels
.get());
2471 EXPECT_EQ(0, memcmp(&expected
, commands_
, sizeof(expected
)));
2472 EXPECT_TRUE(CheckRect(
2473 kSubImageWidth
, 2, kFormat
, kType
, kPixelStoreUnpackAlignment
, true,
2474 reinterpret_cast<uint8
*>(pixels
.get() + 2 * kSubImageWidth
),
2478 TEST_F(GLES2ImplementationTest
, SubImageUnpack
) {
2479 static const GLint unpack_alignments
[] = { 1, 2, 4, 8 };
2481 static const GLenum kFormat
= GL_RGB
;
2482 static const GLenum kType
= GL_UNSIGNED_BYTE
;
2483 static const GLint kLevel
= 0;
2484 static const GLint kBorder
= 0;
2485 // We're testing using the unpack params to pull a subimage out of a larger
2486 // source of pixels. Here we specify the subimage by its border rows /
2488 static const GLint kSrcWidth
= 33;
2489 static const GLint kSrcSubImageX0
= 11;
2490 static const GLint kSrcSubImageX1
= 20;
2491 static const GLint kSrcSubImageY0
= 18;
2492 static const GLint kSrcSubImageY1
= 23;
2493 static const GLint kSrcSubImageWidth
= kSrcSubImageX1
- kSrcSubImageX0
;
2494 static const GLint kSrcSubImageHeight
= kSrcSubImageY1
- kSrcSubImageY0
;
2496 // these are only used in the texsubimage tests
2497 static const GLint kTexWidth
= 1023;
2498 static const GLint kTexHeight
= 511;
2499 static const GLint kTexSubXOffset
= 419;
2500 static const GLint kTexSubYOffset
= 103;
2503 cmds::PixelStorei pixel_store_i
;
2504 cmds::PixelStorei pixel_store_i2
;
2505 cmds::TexImage2D tex_image_2d
;
2509 cmds::PixelStorei pixel_store_i
;
2510 cmds::PixelStorei pixel_store_i2
;
2511 cmds::TexImage2D tex_image_2d
;
2512 cmds::TexSubImage2D tex_sub_image_2d
;
2513 } texSubImageExpected
;
2516 ASSERT_TRUE(GLES2Util::ComputeImageDataSizes(
2517 kSrcWidth
, kSrcSubImageY1
, 1, kFormat
, kType
, 8, &src_size
, NULL
, NULL
));
2518 scoped_ptr
<uint8
[]> src_pixels
;
2519 src_pixels
.reset(new uint8
[src_size
]);
2520 for (size_t i
= 0; i
< src_size
; ++i
) {
2521 src_pixels
[i
] = static_cast<int8
>(i
);
2524 for (int sub
= 0; sub
< 2; ++sub
) {
2525 for (int flip_y
= 0; flip_y
< 2; ++flip_y
) {
2526 for (size_t a
= 0; a
< arraysize(unpack_alignments
); ++a
) {
2527 GLint alignment
= unpack_alignments
[a
];
2529 uint32 unpadded_row_size
;
2530 uint32 padded_row_size
;
2531 ASSERT_TRUE(GLES2Util::ComputeImageDataSizes(
2532 kSrcSubImageWidth
, kSrcSubImageHeight
, 1, kFormat
, kType
, alignment
,
2533 &size
, &unpadded_row_size
, &padded_row_size
));
2534 ASSERT_TRUE(size
<= MaxTransferBufferSize());
2535 ExpectedMemoryInfo mem
= GetExpectedMemory(size
);
2537 const void* commands
= GetPut();
2538 gl_
->PixelStorei(GL_UNPACK_ALIGNMENT
, alignment
);
2539 gl_
->PixelStorei(GL_UNPACK_ROW_LENGTH_EXT
, kSrcWidth
);
2540 gl_
->PixelStorei(GL_UNPACK_SKIP_PIXELS_EXT
, kSrcSubImageX0
);
2541 gl_
->PixelStorei(GL_UNPACK_SKIP_ROWS_EXT
, kSrcSubImageY0
);
2542 gl_
->PixelStorei(GL_UNPACK_FLIP_Y_CHROMIUM
, flip_y
);
2545 GL_TEXTURE_2D
, kLevel
, kFormat
, kTexWidth
, kTexHeight
, kBorder
,
2546 kFormat
, kType
, NULL
);
2548 GL_TEXTURE_2D
, kLevel
, kTexSubXOffset
, kTexSubYOffset
,
2549 kSrcSubImageWidth
, kSrcSubImageHeight
, kFormat
, kType
,
2551 texSubImageExpected
.pixel_store_i
.Init(
2552 GL_UNPACK_ALIGNMENT
, alignment
);
2553 texSubImageExpected
.pixel_store_i2
.Init(
2554 GL_UNPACK_FLIP_Y_CHROMIUM
, flip_y
);
2555 texSubImageExpected
.tex_image_2d
.Init(
2556 GL_TEXTURE_2D
, kLevel
, kFormat
, kTexWidth
, kTexHeight
,
2557 kFormat
, kType
, 0, 0);
2558 texSubImageExpected
.tex_sub_image_2d
.Init(
2559 GL_TEXTURE_2D
, kLevel
, kTexSubXOffset
, kTexSubYOffset
,
2560 kSrcSubImageWidth
, kSrcSubImageHeight
, kFormat
, kType
, mem
.id
,
2561 mem
.offset
, GL_FALSE
);
2562 EXPECT_EQ(0, memcmp(
2563 &texSubImageExpected
, commands
, sizeof(texSubImageExpected
)));
2566 GL_TEXTURE_2D
, kLevel
, kFormat
,
2567 kSrcSubImageWidth
, kSrcSubImageHeight
, kBorder
, kFormat
, kType
,
2569 texImageExpected
.pixel_store_i
.Init(GL_UNPACK_ALIGNMENT
, alignment
);
2570 texImageExpected
.pixel_store_i2
.Init(
2571 GL_UNPACK_FLIP_Y_CHROMIUM
, flip_y
);
2572 texImageExpected
.tex_image_2d
.Init(
2573 GL_TEXTURE_2D
, kLevel
, kFormat
, kSrcSubImageWidth
,
2574 kSrcSubImageHeight
, kFormat
, kType
, mem
.id
, mem
.offset
);
2575 EXPECT_EQ(0, memcmp(
2576 &texImageExpected
, commands
, sizeof(texImageExpected
)));
2578 uint32 src_padded_row_size
;
2579 ASSERT_TRUE(GLES2Util::ComputeImagePaddedRowSize(
2580 kSrcWidth
, kFormat
, kType
, alignment
, &src_padded_row_size
));
2581 uint32 bytes_per_group
= GLES2Util::ComputeImageGroupSize(
2583 for (int y
= 0; y
< kSrcSubImageHeight
; ++y
) {
2584 GLint src_sub_y
= flip_y
? kSrcSubImageHeight
- y
- 1 : y
;
2585 const uint8
* src_row
= src_pixels
.get() +
2586 (kSrcSubImageY0
+ src_sub_y
) * src_padded_row_size
+
2587 bytes_per_group
* kSrcSubImageX0
;
2588 const uint8
* dst_row
= mem
.ptr
+ y
* padded_row_size
;
2589 EXPECT_EQ(0, memcmp(src_row
, dst_row
, unpadded_row_size
));
2597 // Test texture related calls with invalid arguments.
2598 TEST_F(GLES2ImplementationTest
, TextureInvalidArguments
) {
2600 cmds::TexImage2D tex_image_2d
;
2601 cmd::SetToken set_token
;
2603 const GLenum kTarget
= GL_TEXTURE_2D
;
2604 const GLint kLevel
= 0;
2605 const GLenum kFormat
= GL_RGB
;
2606 const GLsizei kWidth
= 3;
2607 const GLsizei kHeight
= 4;
2608 const GLint kBorder
= 0;
2609 const GLint kInvalidBorder
= 1;
2610 const GLenum kType
= GL_UNSIGNED_BYTE
;
2611 const GLint kPixelStoreUnpackAlignment
= 4;
2612 static uint8 pixels
[] = {
2613 11, 12, 13, 13, 14, 15, 15, 16, 17, 101, 102, 103,
2614 21, 22, 23, 23, 24, 25, 25, 26, 27, 201, 202, 203,
2615 31, 32, 33, 33, 34, 35, 35, 36, 37, 123, 124, 125,
2616 41, 42, 43, 43, 44, 45, 45, 46, 47,
2619 // Verify that something works.
2621 ExpectedMemoryInfo mem1
= GetExpectedMemory(sizeof(pixels
));
2624 expected
.tex_image_2d
.Init(
2625 kTarget
, kLevel
, kFormat
, kWidth
, kHeight
, kFormat
, kType
,
2626 mem1
.id
, mem1
.offset
);
2627 expected
.set_token
.Init(GetNextToken());
2629 kTarget
, kLevel
, kFormat
, kWidth
, kHeight
, kBorder
, kFormat
, kType
,
2631 EXPECT_EQ(0, memcmp(&expected
, commands_
, sizeof(expected
)));
2632 EXPECT_TRUE(CheckRect(
2633 kWidth
, kHeight
, kFormat
, kType
, kPixelStoreUnpackAlignment
, false,
2638 // Use invalid border.
2640 kTarget
, kLevel
, kFormat
, kWidth
, kHeight
, kInvalidBorder
, kFormat
, kType
,
2643 EXPECT_TRUE(NoCommandsWritten());
2644 EXPECT_EQ(GL_INVALID_VALUE
, CheckError());
2648 gl_
->AsyncTexImage2DCHROMIUM(
2649 kTarget
, kLevel
, kFormat
, kWidth
, kHeight
, kInvalidBorder
, kFormat
, kType
,
2652 EXPECT_TRUE(NoCommandsWritten());
2653 EXPECT_EQ(GL_INVALID_VALUE
, CheckError());
2657 // Checking for CompressedTexImage2D argument validation is a bit tricky due
2658 // to (runtime-detected) compression formats. Try to infer the error with an
2660 const GLenum kCompressedFormat
= GL_ETC1_RGB8_OES
;
2661 gl_
->CompressedTexImage2D(
2662 kTarget
, kLevel
, kCompressedFormat
, kWidth
, kHeight
, kBorder
,
2663 arraysize(pixels
), pixels
);
2665 // In the above, kCompressedFormat and arraysize(pixels) are possibly wrong
2666 // values. First ensure that these do not cause failures at the client. If
2667 // this check ever fails, it probably means that client checks more than at
2668 // the time of writing of this test. In this case, more code needs to be
2669 // written for this test.
2670 EXPECT_FALSE(NoCommandsWritten());
2674 // Changing border to invalid border should make the call fail at the client
2676 gl_
->CompressedTexImage2D(
2677 kTarget
, kLevel
, kCompressedFormat
, kWidth
, kHeight
, kInvalidBorder
,
2678 arraysize(pixels
), pixels
);
2679 EXPECT_TRUE(NoCommandsWritten());
2680 EXPECT_EQ(GL_INVALID_VALUE
, CheckError());
2683 TEST_F(GLES2ImplementationTest
, TexImage3DSingleCommand
) {
2685 cmds::TexImage3D tex_image_3d
;
2687 const GLenum kTarget
= GL_TEXTURE_3D
;
2688 const GLint kLevel
= 0;
2689 const GLint kBorder
= 0;
2690 const GLenum kFormat
= GL_RGB
;
2691 const GLenum kType
= GL_UNSIGNED_BYTE
;
2692 const GLint kPixelStoreUnpackAlignment
= 4;
2693 const GLsizei kWidth
= 3;
2694 const GLsizei kDepth
= 2;
2697 uint32 unpadded_row_size
= 0;
2698 uint32 padded_row_size
= 0;
2699 ASSERT_TRUE(GLES2Util::ComputeImageDataSizes(
2700 kWidth
, 2, kDepth
, kFormat
, kType
, kPixelStoreUnpackAlignment
,
2701 &size
, &unpadded_row_size
, &padded_row_size
));
2702 // Makes sure we can just send over the data in one command.
2703 const GLsizei kHeight
= MaxTransferBufferSize() / padded_row_size
/ kDepth
;
2704 ASSERT_TRUE(GLES2Util::ComputeImageDataSizes(
2705 kWidth
, kHeight
, kDepth
, kFormat
, kType
, kPixelStoreUnpackAlignment
,
2706 &size
, NULL
, NULL
));
2708 scoped_ptr
<uint8
[]> pixels(new uint8
[size
]);
2709 for (uint32 ii
= 0; ii
< size
; ++ii
) {
2710 pixels
[ii
] = static_cast<uint8
>(ii
);
2713 ExpectedMemoryInfo mem
= GetExpectedMemory(size
);
2716 expected
.tex_image_3d
.Init(
2717 kTarget
, kLevel
, kFormat
, kWidth
, kHeight
, kDepth
,
2718 kFormat
, kType
, mem
.id
, mem
.offset
);
2721 kTarget
, kLevel
, kFormat
, kWidth
, kHeight
, kDepth
, kBorder
,
2722 kFormat
, kType
, pixels
.get());
2724 EXPECT_EQ(0, memcmp(&expected
, commands_
, sizeof(expected
)));
2725 EXPECT_TRUE(CheckRect(
2726 kWidth
, kHeight
* kDepth
, kFormat
, kType
, kPixelStoreUnpackAlignment
,
2727 false, reinterpret_cast<uint8
*>(pixels
.get()), mem
.ptr
));
2730 TEST_F(GLES2ImplementationTest
, TexImage3DViaTexSubImage3D
) {
2732 cmds::TexImage3D tex_image_3d
;
2733 cmds::TexSubImage3D tex_sub_image_3d1
;
2734 cmd::SetToken set_token
;
2735 cmds::TexSubImage3D tex_sub_image_3d2
;
2737 const GLenum kTarget
= GL_TEXTURE_3D
;
2738 const GLint kLevel
= 0;
2739 const GLint kBorder
= 0;
2740 const GLenum kFormat
= GL_RGB
;
2741 const GLenum kType
= GL_UNSIGNED_BYTE
;
2742 const GLint kPixelStoreUnpackAlignment
= 4;
2743 const GLsizei kWidth
= 3;
2746 uint32 unpadded_row_size
= 0;
2747 uint32 padded_row_size
= 0;
2748 ASSERT_TRUE(GLES2Util::ComputeImageDataSizes(
2749 kWidth
, 2, 1, kFormat
, kType
, kPixelStoreUnpackAlignment
,
2750 &size
, &unpadded_row_size
, &padded_row_size
));
2751 // Makes sure the data is more than one command can hold.
2752 const GLsizei kHeight
= MaxTransferBufferSize() / padded_row_size
+ 3;
2753 ASSERT_TRUE(GLES2Util::ComputeImageDataSizes(
2754 kWidth
, kHeight
, 1, kFormat
, kType
, kPixelStoreUnpackAlignment
,
2755 &size
, NULL
, NULL
));
2756 uint32 first_size
= padded_row_size
* (kHeight
- 3);
2757 uint32 second_size
=
2758 padded_row_size
* 3 - (padded_row_size
- unpadded_row_size
);
2759 EXPECT_EQ(size
, first_size
+ second_size
);
2760 ExpectedMemoryInfo mem1
= GetExpectedMemory(first_size
);
2761 ExpectedMemoryInfo mem2
= GetExpectedMemory(second_size
);
2762 scoped_ptr
<uint8
[]> pixels(new uint8
[size
]);
2763 for (uint32 ii
= 0; ii
< size
; ++ii
) {
2764 pixels
[ii
] = static_cast<uint8
>(ii
);
2768 expected
.tex_image_3d
.Init(
2769 kTarget
, kLevel
, kFormat
, kWidth
, kHeight
, 1, kFormat
, kType
, 0, 0);
2770 expected
.tex_sub_image_3d1
.Init(
2771 kTarget
, kLevel
, 0, 0, 0, kWidth
, kHeight
- 3, 1, kFormat
, kType
,
2772 mem1
.id
, mem1
.offset
, GL_TRUE
);
2773 expected
.tex_sub_image_3d2
.Init(
2774 kTarget
, kLevel
, 0, kHeight
- 3, 0, kWidth
, 3, 1, kFormat
, kType
,
2775 mem2
.id
, mem2
.offset
, GL_TRUE
);
2776 expected
.set_token
.Init(GetNextToken());
2779 kTarget
, kLevel
, kFormat
, kWidth
, kHeight
, 1, kBorder
,
2780 kFormat
, kType
, pixels
.get());
2781 EXPECT_EQ(0, memcmp(&expected
, commands_
, sizeof(expected
)));
2784 // Test TexSubImage3D with 4 writes
2785 TEST_F(GLES2ImplementationTest
, TexSubImage3D4Writes
) {
2787 cmds::TexSubImage3D tex_sub_image_3d1_1
;
2788 cmd::SetToken set_token1
;
2789 cmds::TexSubImage3D tex_sub_image_3d1_2
;
2790 cmd::SetToken set_token2
;
2791 cmds::TexSubImage3D tex_sub_image_3d2_1
;
2792 cmd::SetToken set_token3
;
2793 cmds::TexSubImage3D tex_sub_image_3d2_2
;
2795 const GLenum kTarget
= GL_TEXTURE_3D
;
2796 const GLint kLevel
= 0;
2797 const GLint kXOffset
= 0;
2798 const GLint kYOffset
= 0;
2799 const GLint kZOffset
= 0;
2800 const GLenum kFormat
= GL_RGB
;
2801 const GLenum kType
= GL_UNSIGNED_BYTE
;
2802 const GLint kPixelStoreUnpackAlignment
= 4;
2803 const GLsizei kWidth
= 3;
2804 const GLsizei kDepth
= 2;
2807 uint32 unpadded_row_size
= 0;
2808 uint32 padded_row_size
= 0;
2809 ASSERT_TRUE(GLES2Util::ComputeImageDataSizes(
2810 kWidth
, 2, 1, kFormat
, kType
, kPixelStoreUnpackAlignment
,
2811 &size
, &unpadded_row_size
, &padded_row_size
));
2812 const GLsizei kHeight
= MaxTransferBufferSize() / padded_row_size
+ 2;
2813 ASSERT_TRUE(GLES2Util::ComputeImageDataSizes(
2814 kWidth
, kHeight
, kDepth
, kFormat
, kType
, kPixelStoreUnpackAlignment
,
2815 &size
, NULL
, NULL
));
2816 uint32 first_size
= (kHeight
- 2) * padded_row_size
;
2817 uint32 second_size
= 2 * padded_row_size
;
2818 uint32 third_size
= first_size
;
2819 uint32 fourth_size
= second_size
- (padded_row_size
- unpadded_row_size
);
2820 EXPECT_EQ(size
, first_size
+ second_size
+ third_size
+ fourth_size
);
2822 scoped_ptr
<uint8
[]> pixels(new uint8
[size
]);
2823 for (uint32 ii
= 0; ii
< size
; ++ii
) {
2824 pixels
[ii
] = static_cast<uint8
>(ii
);
2827 ExpectedMemoryInfo mem1_1
= GetExpectedMemory(first_size
);
2828 ExpectedMemoryInfo mem1_2
= GetExpectedMemory(second_size
);
2829 ExpectedMemoryInfo mem2_1
= GetExpectedMemory(third_size
);
2830 ExpectedMemoryInfo mem2_2
= GetExpectedMemory(fourth_size
);
2833 expected
.tex_sub_image_3d1_1
.Init(
2834 kTarget
, kLevel
, kXOffset
, kYOffset
, kZOffset
,
2835 kWidth
, kHeight
- 2, 1, kFormat
, kType
,
2836 mem1_1
.id
, mem1_1
.offset
, GL_FALSE
);
2837 expected
.tex_sub_image_3d1_2
.Init(
2838 kTarget
, kLevel
, kXOffset
, kYOffset
+ kHeight
- 2, kZOffset
,
2839 kWidth
, 2, 1, kFormat
, kType
, mem1_2
.id
, mem1_2
.offset
, GL_FALSE
);
2840 expected
.tex_sub_image_3d2_1
.Init(
2841 kTarget
, kLevel
, kXOffset
, kYOffset
, kZOffset
+ 1,
2842 kWidth
, kHeight
- 2, 1, kFormat
, kType
,
2843 mem2_1
.id
, mem2_1
.offset
, GL_FALSE
);
2844 expected
.tex_sub_image_3d2_2
.Init(
2845 kTarget
, kLevel
, kXOffset
, kYOffset
+ kHeight
- 2, kZOffset
+ 1,
2846 kWidth
, 2, 1, kFormat
, kType
, mem2_2
.id
, mem2_2
.offset
, GL_FALSE
);
2847 expected
.set_token1
.Init(GetNextToken());
2848 expected
.set_token2
.Init(GetNextToken());
2849 expected
.set_token3
.Init(GetNextToken());
2852 kTarget
, kLevel
, kXOffset
, kYOffset
, kZOffset
, kWidth
, kHeight
, kDepth
,
2853 kFormat
, kType
, pixels
.get());
2855 EXPECT_EQ(0, memcmp(&expected
, commands_
, sizeof(expected
)));
2856 uint32 offset_to_last
= first_size
+ second_size
+ third_size
;
2857 EXPECT_TRUE(CheckRect(
2858 kWidth
, 2, kFormat
, kType
, kPixelStoreUnpackAlignment
, false,
2859 reinterpret_cast<uint8
*>(pixels
.get()) + offset_to_last
, mem2_2
.ptr
));
2862 // Binds can not be cached with bind_generates_resource = false because
2863 // our id might not be valid. More specifically if you bind on contextA then
2864 // delete on contextB the resource is still bound on contextA but GetInterger
2865 // won't return an id.
2866 TEST_F(GLES2ImplementationStrictSharedTest
, BindsNotCached
) {
2871 const PNameValue pairs
[] = {{GL_TEXTURE_BINDING_2D
, 1, },
2872 {GL_TEXTURE_BINDING_CUBE_MAP
, 2, },
2873 {GL_TEXTURE_BINDING_EXTERNAL_OES
, 3, },
2874 {GL_FRAMEBUFFER_BINDING
, 4, },
2875 {GL_RENDERBUFFER_BINDING
, 5, },
2876 {GL_ARRAY_BUFFER_BINDING
, 6, },
2877 {GL_ELEMENT_ARRAY_BUFFER_BINDING
, 7, }, };
2878 size_t num_pairs
= sizeof(pairs
) / sizeof(pairs
[0]);
2879 for (size_t ii
= 0; ii
< num_pairs
; ++ii
) {
2880 const PNameValue
& pv
= pairs
[ii
];
2882 ExpectedMemoryInfo result1
=
2883 GetExpectedResultMemory(sizeof(cmds::GetIntegerv::Result
));
2884 EXPECT_CALL(*command_buffer(), OnFlush())
2885 .WillOnce(SetMemory(result1
.ptr
,
2886 SizedResultHelper
<GLuint
>(pv
.expected
)))
2887 .RetiresOnSaturation();
2888 gl_
->GetIntegerv(pv
.pname
, &v
);
2889 EXPECT_EQ(pv
.expected
, v
);
2893 // glGen* Ids must not be reused until glDelete* commands have been
2894 // flushed by glFlush.
2895 TEST_F(GLES2ImplementationStrictSharedTest
, FlushGenerationTestBuffers
) {
2896 FlushGenerationTest
<GenBuffersAPI
>();
2898 TEST_F(GLES2ImplementationStrictSharedTest
, FlushGenerationTestFramebuffers
) {
2899 FlushGenerationTest
<GenFramebuffersAPI
>();
2901 TEST_F(GLES2ImplementationStrictSharedTest
, FlushGenerationTestRenderbuffers
) {
2902 FlushGenerationTest
<GenRenderbuffersAPI
>();
2904 TEST_F(GLES2ImplementationStrictSharedTest
, FlushGenerationTestTextures
) {
2905 FlushGenerationTest
<GenTexturesAPI
>();
2908 // glGen* Ids must not be reused cross-context until glDelete* commands are
2909 // flushed by glFlush, and the Ids are lazily freed after.
2910 TEST_F(GLES2ImplementationStrictSharedTest
, CrossContextGenerationTestBuffers
) {
2911 CrossContextGenerationTest
<GenBuffersAPI
>();
2913 TEST_F(GLES2ImplementationStrictSharedTest
,
2914 CrossContextGenerationTestFramebuffers
) {
2915 CrossContextGenerationTest
<GenFramebuffersAPI
>();
2917 TEST_F(GLES2ImplementationStrictSharedTest
,
2918 CrossContextGenerationTestRenderbuffers
) {
2919 CrossContextGenerationTest
<GenRenderbuffersAPI
>();
2921 TEST_F(GLES2ImplementationStrictSharedTest
,
2922 CrossContextGenerationTestTextures
) {
2923 CrossContextGenerationTest
<GenTexturesAPI
>();
2926 // Test Delete which causes auto flush. Tests a regression case that occurred
2928 TEST_F(GLES2ImplementationStrictSharedTest
,
2929 CrossContextGenerationAutoFlushTestBuffers
) {
2930 CrossContextGenerationAutoFlushTest
<GenBuffersAPI
>();
2932 TEST_F(GLES2ImplementationStrictSharedTest
,
2933 CrossContextGenerationAutoFlushTestFramebuffers
) {
2934 CrossContextGenerationAutoFlushTest
<GenFramebuffersAPI
>();
2936 TEST_F(GLES2ImplementationStrictSharedTest
,
2937 CrossContextGenerationAutoFlushTestRenderbuffers
) {
2938 CrossContextGenerationAutoFlushTest
<GenRenderbuffersAPI
>();
2940 TEST_F(GLES2ImplementationStrictSharedTest
,
2941 CrossContextGenerationAutoFlushTestTextures
) {
2942 CrossContextGenerationAutoFlushTest
<GenTexturesAPI
>();
2945 TEST_F(GLES2ImplementationTest
, GetString
) {
2946 const uint32 kBucketId
= GLES2Implementation::kResultBucketId
;
2947 const Str7 kString
= {"foobar"};
2948 // GL_CHROMIUM_map_sub GL_CHROMIUM_flipy are hard coded into
2949 // GLES2Implementation.
2950 const char* expected_str
=
2952 "GL_CHROMIUM_flipy "
2953 "GL_EXT_unpack_subimage "
2954 "GL_CHROMIUM_map_sub";
2955 const char kBad
= 0x12;
2957 cmd::SetBucketSize set_bucket_size1
;
2958 cmds::GetString get_string
;
2959 cmd::GetBucketStart get_bucket_start
;
2960 cmd::SetToken set_token1
;
2961 cmd::SetBucketSize set_bucket_size2
;
2963 ExpectedMemoryInfo mem1
= GetExpectedMemory(MaxTransferBufferSize());
2964 ExpectedMemoryInfo result1
=
2965 GetExpectedResultMemory(sizeof(cmd::GetBucketStart::Result
));
2967 expected
.set_bucket_size1
.Init(kBucketId
, 0);
2968 expected
.get_string
.Init(GL_EXTENSIONS
, kBucketId
);
2969 expected
.get_bucket_start
.Init(
2970 kBucketId
, result1
.id
, result1
.offset
,
2971 MaxTransferBufferSize(), mem1
.id
, mem1
.offset
);
2972 expected
.set_token1
.Init(GetNextToken());
2973 expected
.set_bucket_size2
.Init(kBucketId
, 0);
2974 char buf
[sizeof(kString
) + 1];
2975 memset(buf
, kBad
, sizeof(buf
));
2977 EXPECT_CALL(*command_buffer(), OnFlush())
2978 .WillOnce(DoAll(SetMemory(result1
.ptr
, uint32(sizeof(kString
))),
2979 SetMemory(mem1
.ptr
, kString
)))
2980 .RetiresOnSaturation();
2982 const GLubyte
* result
= gl_
->GetString(GL_EXTENSIONS
);
2983 EXPECT_EQ(0, memcmp(&expected
, commands_
, sizeof(expected
)));
2984 EXPECT_STREQ(expected_str
, reinterpret_cast<const char*>(result
));
2987 TEST_F(GLES2ImplementationTest
, PixelStoreiGLPackReverseRowOrderANGLE
) {
2988 const uint32 kBucketId
= GLES2Implementation::kResultBucketId
;
2989 const Str7 kString
= {"foobar"};
2991 cmd::SetBucketSize set_bucket_size1
;
2992 cmds::GetString get_string
;
2993 cmd::GetBucketStart get_bucket_start
;
2994 cmd::SetToken set_token1
;
2995 cmd::SetBucketSize set_bucket_size2
;
2996 cmds::PixelStorei pixel_store
;
2999 ExpectedMemoryInfo mem1
= GetExpectedMemory(MaxTransferBufferSize());
3000 ExpectedMemoryInfo result1
=
3001 GetExpectedResultMemory(sizeof(cmd::GetBucketStart::Result
));
3004 expected
.set_bucket_size1
.Init(kBucketId
, 0);
3005 expected
.get_string
.Init(GL_EXTENSIONS
, kBucketId
);
3006 expected
.get_bucket_start
.Init(
3007 kBucketId
, result1
.id
, result1
.offset
,
3008 MaxTransferBufferSize(), mem1
.id
, mem1
.offset
);
3009 expected
.set_token1
.Init(GetNextToken());
3010 expected
.set_bucket_size2
.Init(kBucketId
, 0);
3011 expected
.pixel_store
.Init(GL_PACK_REVERSE_ROW_ORDER_ANGLE
, 1);
3013 EXPECT_CALL(*command_buffer(), OnFlush())
3014 .WillOnce(DoAll(SetMemory(result1
.ptr
, uint32(sizeof(kString
))),
3015 SetMemory(mem1
.ptr
, kString
)))
3016 .RetiresOnSaturation();
3018 gl_
->PixelStorei(GL_PACK_REVERSE_ROW_ORDER_ANGLE
, 1);
3019 EXPECT_EQ(0, memcmp(&expected
, commands_
, sizeof(expected
)));
3022 TEST_F(GLES2ImplementationTest
, CreateProgram
) {
3024 cmds::CreateProgram cmd
;
3028 expected
.cmd
.Init(kProgramsAndShadersStartId
);
3029 GLuint id
= gl_
->CreateProgram();
3030 EXPECT_EQ(0, memcmp(&expected
, commands_
, sizeof(expected
)));
3031 EXPECT_EQ(kProgramsAndShadersStartId
, id
);
3034 TEST_F(GLES2ImplementationTest
, BufferDataLargerThanTransferBuffer
) {
3036 cmds::BufferData set_size
;
3037 cmds::BufferSubData copy_data1
;
3038 cmd::SetToken set_token1
;
3039 cmds::BufferSubData copy_data2
;
3040 cmd::SetToken set_token2
;
3042 const unsigned kUsableSize
=
3043 kTransferBufferSize
- GLES2Implementation::kStartingOffset
;
3044 uint8 buf
[kUsableSize
* 2] = { 0, };
3046 ExpectedMemoryInfo mem1
= GetExpectedMemory(kUsableSize
);
3047 ExpectedMemoryInfo mem2
= GetExpectedMemory(kUsableSize
);
3050 expected
.set_size
.Init(
3051 GL_ARRAY_BUFFER
, arraysize(buf
), 0, 0, GL_DYNAMIC_DRAW
);
3052 expected
.copy_data1
.Init(
3053 GL_ARRAY_BUFFER
, 0, kUsableSize
, mem1
.id
, mem1
.offset
);
3054 expected
.set_token1
.Init(GetNextToken());
3055 expected
.copy_data2
.Init(
3056 GL_ARRAY_BUFFER
, kUsableSize
, kUsableSize
, mem2
.id
, mem2
.offset
);
3057 expected
.set_token2
.Init(GetNextToken());
3058 gl_
->BufferData(GL_ARRAY_BUFFER
, arraysize(buf
), buf
, GL_DYNAMIC_DRAW
);
3059 EXPECT_EQ(0, memcmp(&expected
, commands_
, sizeof(expected
)));
3062 TEST_F(GLES2ImplementationTest
, CapabilitiesAreCached
) {
3063 static const GLenum kStates
[] = {
3068 GL_POLYGON_OFFSET_FILL
,
3069 GL_SAMPLE_ALPHA_TO_COVERAGE
,
3075 cmds::Enable enable_cmd
;
3079 for (size_t ii
= 0; ii
< arraysize(kStates
); ++ii
) {
3080 GLenum state
= kStates
[ii
];
3081 expected
.enable_cmd
.Init(state
);
3082 GLboolean result
= gl_
->IsEnabled(state
);
3083 EXPECT_EQ(static_cast<GLboolean
>(ii
== 0), result
);
3084 EXPECT_TRUE(NoCommandsWritten());
3085 const void* commands
= GetPut();
3088 EXPECT_EQ(0, memcmp(&expected
, commands
, sizeof(expected
)));
3091 result
= gl_
->IsEnabled(state
);
3092 EXPECT_TRUE(result
);
3093 EXPECT_TRUE(NoCommandsWritten());
3097 TEST_F(GLES2ImplementationTest
, BindVertexArrayOES
) {
3099 gl_
->GenVertexArraysOES(1, &id
);
3103 cmds::BindVertexArrayOES cmd
;
3106 expected
.cmd
.Init(id
);
3108 const void* commands
= GetPut();
3109 gl_
->BindVertexArrayOES(id
);
3110 EXPECT_EQ(0, memcmp(&expected
, commands
, sizeof(expected
)));
3112 gl_
->BindVertexArrayOES(id
);
3113 EXPECT_TRUE(NoCommandsWritten());
3116 TEST_F(GLES2ImplementationTest
, BeginEndQueryEXT
) {
3117 // Test GetQueryivEXT returns 0 if no current query.
3119 gl_
->GetQueryivEXT(GL_ANY_SAMPLES_PASSED_EXT
, GL_CURRENT_QUERY_EXT
, ¶m
);
3120 EXPECT_EQ(0, param
);
3122 GLuint expected_ids
[2] = { 1, 2 }; // These must match what's actually genned.
3124 cmds::GenQueriesEXTImmediate gen
;
3127 GenCmds expected_gen_cmds
;
3128 expected_gen_cmds
.gen
.Init(arraysize(expected_ids
), &expected_ids
[0]);
3129 GLuint ids
[arraysize(expected_ids
)] = { 0, };
3130 gl_
->GenQueriesEXT(arraysize(expected_ids
), &ids
[0]);
3131 EXPECT_EQ(0, memcmp(
3132 &expected_gen_cmds
, commands_
, sizeof(expected_gen_cmds
)));
3133 GLuint id1
= ids
[0];
3134 GLuint id2
= ids
[1];
3137 // Test BeginQueryEXT fails if id = 0.
3138 gl_
->BeginQueryEXT(GL_ANY_SAMPLES_PASSED_EXT
, 0);
3139 EXPECT_TRUE(NoCommandsWritten());
3140 EXPECT_EQ(GL_INVALID_OPERATION
, CheckError());
3142 // Test BeginQueryEXT inserts command.
3144 cmds::BeginQueryEXT begin_query
;
3146 BeginCmds expected_begin_cmds
;
3147 const void* commands
= GetPut();
3148 gl_
->BeginQueryEXT(GL_ANY_SAMPLES_PASSED_EXT
, id1
);
3149 QueryTracker::Query
* query
= GetQuery(id1
);
3150 ASSERT_TRUE(query
!= NULL
);
3151 expected_begin_cmds
.begin_query
.Init(
3152 GL_ANY_SAMPLES_PASSED_EXT
, id1
, query
->shm_id(), query
->shm_offset());
3153 EXPECT_EQ(0, memcmp(
3154 &expected_begin_cmds
, commands
, sizeof(expected_begin_cmds
)));
3157 // Test GetQueryivEXT returns id.
3159 gl_
->GetQueryivEXT(GL_ANY_SAMPLES_PASSED_EXT
, GL_CURRENT_QUERY_EXT
, ¶m
);
3160 EXPECT_EQ(id1
, static_cast<GLuint
>(param
));
3162 GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT
, GL_CURRENT_QUERY_EXT
, ¶m
);
3163 EXPECT_EQ(0, param
);
3165 // Test BeginQueryEXT fails if between Begin/End.
3166 gl_
->BeginQueryEXT(GL_ANY_SAMPLES_PASSED_EXT
, id2
);
3167 EXPECT_TRUE(NoCommandsWritten());
3168 EXPECT_EQ(GL_INVALID_OPERATION
, CheckError());
3170 // Test EndQueryEXT fails if target not same as current query.
3172 gl_
->EndQueryEXT(GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT
);
3173 EXPECT_TRUE(NoCommandsWritten());
3174 EXPECT_EQ(GL_INVALID_OPERATION
, CheckError());
3176 // Test EndQueryEXT sends command
3178 cmds::EndQueryEXT end_query
;
3180 EndCmds expected_end_cmds
;
3181 expected_end_cmds
.end_query
.Init(
3182 GL_ANY_SAMPLES_PASSED_EXT
, query
->submit_count());
3183 commands
= GetPut();
3184 gl_
->EndQueryEXT(GL_ANY_SAMPLES_PASSED_EXT
);
3185 EXPECT_EQ(0, memcmp(
3186 &expected_end_cmds
, commands
, sizeof(expected_end_cmds
)));
3188 // Test EndQueryEXT fails if no current query.
3190 gl_
->EndQueryEXT(GL_ANY_SAMPLES_PASSED_EXT
);
3191 EXPECT_TRUE(NoCommandsWritten());
3192 EXPECT_EQ(GL_INVALID_OPERATION
, CheckError());
3194 // Test 2nd Begin/End increments count.
3195 base::subtle::Atomic32 old_submit_count
= query
->submit_count();
3196 gl_
->BeginQueryEXT(GL_ANY_SAMPLES_PASSED_EXT
, id1
);
3197 EXPECT_NE(old_submit_count
, query
->submit_count());
3198 expected_end_cmds
.end_query
.Init(
3199 GL_ANY_SAMPLES_PASSED_EXT
, query
->submit_count());
3200 commands
= GetPut();
3201 gl_
->EndQueryEXT(GL_ANY_SAMPLES_PASSED_EXT
);
3202 EXPECT_EQ(0, memcmp(
3203 &expected_end_cmds
, commands
, sizeof(expected_end_cmds
)));
3205 // Test BeginQueryEXT fails if target changed.
3207 gl_
->BeginQueryEXT(GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT
, id1
);
3208 EXPECT_TRUE(NoCommandsWritten());
3209 EXPECT_EQ(GL_INVALID_OPERATION
, CheckError());
3211 // Test GetQueryObjectuivEXT fails if unused id
3212 GLuint available
= 0xBDu
;
3214 gl_
->GetQueryObjectuivEXT(id2
, GL_QUERY_RESULT_AVAILABLE_EXT
, &available
);
3215 EXPECT_TRUE(NoCommandsWritten());
3216 EXPECT_EQ(0xBDu
, available
);
3217 EXPECT_EQ(GL_INVALID_OPERATION
, CheckError());
3219 // Test GetQueryObjectuivEXT fails if bad id
3221 gl_
->GetQueryObjectuivEXT(4567, GL_QUERY_RESULT_AVAILABLE_EXT
, &available
);
3222 EXPECT_TRUE(NoCommandsWritten());
3223 EXPECT_EQ(0xBDu
, available
);
3224 EXPECT_EQ(GL_INVALID_OPERATION
, CheckError());
3226 // Test GetQueryObjectuivEXT CheckResultsAvailable
3228 gl_
->GetQueryObjectuivEXT(id1
, GL_QUERY_RESULT_AVAILABLE_EXT
, &available
);
3229 EXPECT_EQ(0u, available
);
3232 TEST_F(GLES2ImplementationTest
, ErrorQuery
) {
3234 gl_
->GenQueriesEXT(1, &id
);
3237 // Test BeginQueryEXT does NOT insert commands.
3238 gl_
->BeginQueryEXT(GL_GET_ERROR_QUERY_CHROMIUM
, id
);
3239 EXPECT_TRUE(NoCommandsWritten());
3240 QueryTracker::Query
* query
= GetQuery(id
);
3241 ASSERT_TRUE(query
!= NULL
);
3243 // Test EndQueryEXT sends both begin and end command
3245 cmds::BeginQueryEXT begin_query
;
3246 cmds::EndQueryEXT end_query
;
3248 EndCmds expected_end_cmds
;
3249 expected_end_cmds
.begin_query
.Init(
3250 GL_GET_ERROR_QUERY_CHROMIUM
, id
, query
->shm_id(), query
->shm_offset());
3251 expected_end_cmds
.end_query
.Init(
3252 GL_GET_ERROR_QUERY_CHROMIUM
, query
->submit_count());
3253 const void* commands
= GetPut();
3254 gl_
->EndQueryEXT(GL_GET_ERROR_QUERY_CHROMIUM
);
3255 EXPECT_EQ(0, memcmp(
3256 &expected_end_cmds
, commands
, sizeof(expected_end_cmds
)));
3259 // Check result is not yet available.
3260 GLuint available
= 0xBDu
;
3261 gl_
->GetQueryObjectuivEXT(id
, GL_QUERY_RESULT_AVAILABLE_EXT
, &available
);
3262 EXPECT_TRUE(NoCommandsWritten());
3263 EXPECT_EQ(0u, available
);
3265 // Test no commands are sent if there is a client side error.
3267 // Generate a client side error
3268 gl_
->ActiveTexture(GL_TEXTURE0
- 1);
3270 gl_
->BeginQueryEXT(GL_GET_ERROR_QUERY_CHROMIUM
, id
);
3271 gl_
->EndQueryEXT(GL_GET_ERROR_QUERY_CHROMIUM
);
3272 EXPECT_TRUE(NoCommandsWritten());
3274 // Check result is available.
3275 gl_
->GetQueryObjectuivEXT(id
, GL_QUERY_RESULT_AVAILABLE_EXT
, &available
);
3276 EXPECT_TRUE(NoCommandsWritten());
3277 EXPECT_NE(0u, available
);
3280 GLuint result
= 0xBDu
;
3281 gl_
->GetQueryObjectuivEXT(id
, GL_QUERY_RESULT_EXT
, &result
);
3282 EXPECT_TRUE(NoCommandsWritten());
3283 EXPECT_EQ(static_cast<GLuint
>(GL_INVALID_ENUM
), result
);
3286 #if !defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS)
3287 TEST_F(GLES2ImplementationTest
, VertexArrays
) {
3288 const GLuint kAttribIndex1
= 1;
3289 const GLint kNumComponents1
= 3;
3290 const GLsizei kClientStride
= 12;
3293 gl_
->GenVertexArraysOES(1, &id
);
3296 gl_
->BindVertexArrayOES(id
);
3298 // Test that VertexAttribPointer cannot be called with a bound buffer of 0
3299 // unless the offset is NULL
3300 gl_
->BindBuffer(GL_ARRAY_BUFFER
, 0);
3302 gl_
->VertexAttribPointer(
3303 kAttribIndex1
, kNumComponents1
, GL_FLOAT
, GL_FALSE
, kClientStride
,
3304 reinterpret_cast<const void*>(4));
3305 EXPECT_EQ(GL_INVALID_OPERATION
, CheckError());
3307 gl_
->VertexAttribPointer(
3308 kAttribIndex1
, kNumComponents1
, GL_FLOAT
, GL_FALSE
, kClientStride
, NULL
);
3309 EXPECT_EQ(GL_NO_ERROR
, CheckError());
3313 TEST_F(GLES2ImplementationTest
, Disable
) {
3318 expected
.cmd
.Init(GL_DITHER
); // Note: DITHER defaults to enabled.
3320 gl_
->Disable(GL_DITHER
);
3321 EXPECT_EQ(0, memcmp(&expected
, commands_
, sizeof(expected
)));
3322 // Check it's cached and not called again.
3324 gl_
->Disable(GL_DITHER
);
3325 EXPECT_TRUE(NoCommandsWritten());
3328 TEST_F(GLES2ImplementationTest
, Enable
) {
3333 expected
.cmd
.Init(GL_BLEND
); // Note: BLEND defaults to disabled.
3335 gl_
->Enable(GL_BLEND
);
3336 EXPECT_EQ(0, memcmp(&expected
, commands_
, sizeof(expected
)));
3337 // Check it's cached and not called again.
3339 gl_
->Enable(GL_BLEND
);
3340 EXPECT_TRUE(NoCommandsWritten());
3343 TEST_F(GLES2ImplementationTest
, ConsumeTextureCHROMIUM
) {
3345 cmds::ConsumeTextureCHROMIUMImmediate cmd
;
3349 Mailbox mailbox
= Mailbox::Generate();
3351 expected
.cmd
.Init(GL_TEXTURE_2D
, mailbox
.name
);
3352 gl_
->ConsumeTextureCHROMIUM(GL_TEXTURE_2D
, mailbox
.name
);
3353 EXPECT_EQ(0, memcmp(&expected
, commands_
, sizeof(expected
)));
3356 TEST_F(GLES2ImplementationTest
, CreateAndConsumeTextureCHROMIUM
) {
3358 cmds::CreateAndConsumeTextureCHROMIUMImmediate cmd
;
3362 Mailbox mailbox
= Mailbox::Generate();
3364 expected
.cmd
.Init(GL_TEXTURE_2D
, kTexturesStartId
, mailbox
.name
);
3365 GLuint id
= gl_
->CreateAndConsumeTextureCHROMIUM(GL_TEXTURE_2D
, mailbox
.name
);
3366 EXPECT_EQ(0, memcmp(&expected
, commands_
, sizeof(expected
)));
3367 EXPECT_EQ(kTexturesStartId
, id
);
3370 TEST_F(GLES2ImplementationTest
, ProduceTextureCHROMIUM
) {
3372 cmds::ProduceTextureCHROMIUMImmediate cmd
;
3376 Mailbox mailbox
= Mailbox::Generate();
3378 expected
.cmd
.Init(GL_TEXTURE_2D
, mailbox
.name
);
3379 gl_
->ProduceTextureCHROMIUM(GL_TEXTURE_2D
, mailbox
.name
);
3380 EXPECT_EQ(0, memcmp(&expected
, commands_
, sizeof(expected
)));
3383 TEST_F(GLES2ImplementationTest
, ProduceTextureDirectCHROMIUM
) {
3385 cmds::ProduceTextureDirectCHROMIUMImmediate cmd
;
3389 Mailbox mailbox
= Mailbox::Generate();
3391 expected
.cmd
.Init(kTexturesStartId
, GL_TEXTURE_2D
, mailbox
.name
);
3392 gl_
->ProduceTextureDirectCHROMIUM(
3393 kTexturesStartId
, GL_TEXTURE_2D
, mailbox
.name
);
3394 EXPECT_EQ(0, memcmp(&expected
, commands_
, sizeof(expected
)));
3397 TEST_F(GLES2ImplementationTest
, LimitSizeAndOffsetTo32Bit
) {
3400 if (sizeof(size
) <= 4 || sizeof(offset
) <= 4)
3402 // The below two casts should be no-op, as we return early if
3403 // it's 32-bit system.
3404 int64 value64
= 0x100000000;
3405 size
= static_cast<GLsizeiptr
>(value64
);
3406 offset
= static_cast<GLintptr
>(value64
);
3408 const char kSizeOverflowMessage
[] = "size more than 32-bit";
3409 const char kOffsetOverflowMessage
[] = "offset more than 32-bit";
3411 const GLfloat buf
[] = { 1.0, 1.0, 1.0, 1.0 };
3412 const GLubyte indices
[] = { 0 };
3414 const GLuint kClientArrayBufferId
= 0x789;
3415 const GLuint kClientElementArrayBufferId
= 0x790;
3416 gl_
->BindBuffer(GL_ARRAY_BUFFER
, kClientArrayBufferId
);
3417 gl_
->BindBuffer(GL_ELEMENT_ARRAY_BUFFER
, kClientElementArrayBufferId
);
3418 EXPECT_EQ(GL_NO_ERROR
, CheckError());
3420 // Call BufferData() should succeed with legal paramaters.
3421 gl_
->BufferData(GL_ARRAY_BUFFER
, sizeof(buf
), buf
, GL_DYNAMIC_DRAW
);
3423 GL_ELEMENT_ARRAY_BUFFER
, sizeof(indices
), indices
, GL_DYNAMIC_DRAW
);
3424 EXPECT_EQ(GL_NO_ERROR
, CheckError());
3427 gl_
->BufferData(GL_ARRAY_BUFFER
, size
, buf
, GL_DYNAMIC_DRAW
);
3428 EXPECT_EQ(GL_INVALID_OPERATION
, CheckError());
3429 EXPECT_STREQ(kSizeOverflowMessage
, GetLastError().c_str());
3431 // Call BufferSubData() should succeed with legal paramaters.
3432 gl_
->BufferSubData(GL_ARRAY_BUFFER
, 0, sizeof(buf
[0]), buf
);
3433 EXPECT_EQ(GL_NO_ERROR
, CheckError());
3435 // BufferSubData: offset
3436 gl_
->BufferSubData(GL_ARRAY_BUFFER
, offset
, 1, buf
);
3437 EXPECT_EQ(GL_INVALID_OPERATION
, CheckError());
3438 EXPECT_STREQ(kOffsetOverflowMessage
, GetLastError().c_str());
3440 // BufferSubData: size
3441 EXPECT_EQ(GL_NO_ERROR
, CheckError());
3442 gl_
->BufferSubData(GL_ARRAY_BUFFER
, 0, size
, buf
);
3443 EXPECT_EQ(GL_INVALID_OPERATION
, CheckError());
3444 EXPECT_STREQ(kSizeOverflowMessage
, GetLastError().c_str());
3446 // Call MapBufferSubDataCHROMIUM() should succeed with legal paramaters.
3448 gl_
->MapBufferSubDataCHROMIUM(GL_ARRAY_BUFFER
, 0, 1, GL_WRITE_ONLY
);
3449 EXPECT_TRUE(NULL
!= mem
);
3450 EXPECT_EQ(GL_NO_ERROR
, CheckError());
3451 gl_
->UnmapBufferSubDataCHROMIUM(mem
);
3453 // MapBufferSubDataCHROMIUM: offset
3454 EXPECT_TRUE(NULL
== gl_
->MapBufferSubDataCHROMIUM(
3455 GL_ARRAY_BUFFER
, offset
, 1, GL_WRITE_ONLY
));
3456 EXPECT_EQ(GL_INVALID_OPERATION
, CheckError());
3457 EXPECT_STREQ(kOffsetOverflowMessage
, GetLastError().c_str());
3459 // MapBufferSubDataCHROMIUM: size
3460 EXPECT_EQ(GL_NO_ERROR
, CheckError());
3461 EXPECT_TRUE(NULL
== gl_
->MapBufferSubDataCHROMIUM(
3462 GL_ARRAY_BUFFER
, 0, size
, GL_WRITE_ONLY
));
3463 EXPECT_EQ(GL_INVALID_OPERATION
, CheckError());
3464 EXPECT_STREQ(kSizeOverflowMessage
, GetLastError().c_str());
3466 // Call DrawElements() should succeed with legal paramaters.
3467 gl_
->DrawElements(GL_POINTS
, 1, GL_UNSIGNED_BYTE
, NULL
);
3468 EXPECT_EQ(GL_NO_ERROR
, CheckError());
3470 // DrawElements: offset
3472 GL_POINTS
, 1, GL_UNSIGNED_BYTE
, reinterpret_cast<void*>(offset
));
3473 EXPECT_EQ(GL_INVALID_OPERATION
, CheckError());
3474 EXPECT_STREQ(kOffsetOverflowMessage
, GetLastError().c_str());
3476 // Call DrawElementsInstancedANGLE() should succeed with legal paramaters.
3477 gl_
->DrawElementsInstancedANGLE(GL_POINTS
, 1, GL_UNSIGNED_BYTE
, NULL
, 1);
3478 EXPECT_EQ(GL_NO_ERROR
, CheckError());
3480 // DrawElementsInstancedANGLE: offset
3481 gl_
->DrawElementsInstancedANGLE(
3482 GL_POINTS
, 1, GL_UNSIGNED_BYTE
, reinterpret_cast<void*>(offset
), 1);
3483 EXPECT_EQ(GL_INVALID_OPERATION
, CheckError());
3484 EXPECT_STREQ(kOffsetOverflowMessage
, GetLastError().c_str());
3486 // Call VertexAttribPointer() should succeed with legal paramaters.
3487 const GLuint kAttribIndex
= 1;
3488 const GLsizei kStride
= 4;
3489 gl_
->VertexAttribPointer(
3490 kAttribIndex
, 1, GL_FLOAT
, GL_FALSE
, kStride
, NULL
);
3491 EXPECT_EQ(GL_NO_ERROR
, CheckError());
3493 // VertexAttribPointer: offset
3494 gl_
->VertexAttribPointer(
3495 kAttribIndex
, 1, GL_FLOAT
, GL_FALSE
, kStride
,
3496 reinterpret_cast<void*>(offset
));
3497 EXPECT_EQ(GL_INVALID_OPERATION
, CheckError());
3498 EXPECT_STREQ(kOffsetOverflowMessage
, GetLastError().c_str());
3501 TEST_F(GLES2ImplementationTest
, TraceBeginCHROMIUM
) {
3502 const uint32 kCategoryBucketId
= GLES2Implementation::kResultBucketId
;
3503 const uint32 kNameBucketId
= GLES2Implementation::kResultBucketId
+ 1;
3504 const std::string category_name
= "test category";
3505 const std::string trace_name
= "test trace";
3506 const size_t kPaddedString1Size
=
3507 transfer_buffer_
->RoundToAlignment(category_name
.size() + 1);
3508 const size_t kPaddedString2Size
=
3509 transfer_buffer_
->RoundToAlignment(trace_name
.size() + 1);
3511 gl_
->TraceBeginCHROMIUM(category_name
.c_str(), trace_name
.c_str());
3512 EXPECT_EQ(GL_NO_ERROR
, CheckError());
3515 cmd::SetBucketSize category_size1
;
3516 cmd::SetBucketData category_data
;
3517 cmd::SetToken set_token1
;
3518 cmd::SetBucketSize name_size1
;
3519 cmd::SetBucketData name_data
;
3520 cmd::SetToken set_token2
;
3521 cmds::TraceBeginCHROMIUM trace_call_begin
;
3522 cmd::SetBucketSize category_size2
;
3523 cmd::SetBucketSize name_size2
;
3526 ExpectedMemoryInfo mem1
= GetExpectedMemory(kPaddedString1Size
);
3527 ExpectedMemoryInfo mem2
= GetExpectedMemory(kPaddedString2Size
);
3529 ASSERT_STREQ(category_name
.c_str(), reinterpret_cast<char*>(mem1
.ptr
));
3530 ASSERT_STREQ(trace_name
.c_str(), reinterpret_cast<char*>(mem2
.ptr
));
3533 expected
.category_size1
.Init(kCategoryBucketId
, category_name
.size() + 1);
3534 expected
.category_data
.Init(
3535 kCategoryBucketId
, 0, category_name
.size() + 1, mem1
.id
, mem1
.offset
);
3536 expected
.set_token1
.Init(GetNextToken());
3537 expected
.name_size1
.Init(kNameBucketId
, trace_name
.size() + 1);
3538 expected
.name_data
.Init(
3539 kNameBucketId
, 0, trace_name
.size() + 1, mem2
.id
, mem2
.offset
);
3540 expected
.set_token2
.Init(GetNextToken());
3541 expected
.trace_call_begin
.Init(kCategoryBucketId
, kNameBucketId
);
3542 expected
.category_size2
.Init(kCategoryBucketId
, 0);
3543 expected
.name_size2
.Init(kNameBucketId
, 0);
3545 EXPECT_EQ(0, memcmp(&expected
, commands_
, sizeof(expected
)));
3548 TEST_F(GLES2ImplementationTest
, AllowNestedTracesCHROMIUM
) {
3549 const std::string category1_name
= "test category 1";
3550 const std::string trace1_name
= "test trace 1";
3551 const std::string category2_name
= "test category 2";
3552 const std::string trace2_name
= "test trace 2";
3554 gl_
->TraceBeginCHROMIUM(category1_name
.c_str(), trace1_name
.c_str());
3555 EXPECT_EQ(GL_NO_ERROR
, CheckError());
3557 gl_
->TraceBeginCHROMIUM(category2_name
.c_str(), trace2_name
.c_str());
3558 EXPECT_EQ(GL_NO_ERROR
, CheckError());
3560 gl_
->TraceEndCHROMIUM();
3561 EXPECT_EQ(GL_NO_ERROR
, CheckError());
3563 gl_
->TraceEndCHROMIUM();
3564 EXPECT_EQ(GL_NO_ERROR
, CheckError());
3566 // No more corresponding begin tracer marker should error.
3567 gl_
->TraceEndCHROMIUM();
3568 EXPECT_EQ(GL_INVALID_OPERATION
, CheckError());
3571 TEST_F(GLES2ImplementationTest
, IsEnabled
) {
3572 // If we use a valid enum, its state is cached on client side, so no command
3573 // is actually generated, and this test will fail.
3574 // TODO(zmo): it seems we never need the command. Maybe remove it.
3577 cmds::IsEnabled cmd
;
3581 ExpectedMemoryInfo result1
=
3582 GetExpectedResultMemory(sizeof(cmds::IsEnabled::Result
));
3583 expected
.cmd
.Init(kCap
, result1
.id
, result1
.offset
);
3585 EXPECT_CALL(*command_buffer(), OnFlush())
3586 .WillOnce(SetMemory(result1
.ptr
, uint32_t(GL_TRUE
)))
3587 .RetiresOnSaturation();
3589 GLboolean result
= gl_
->IsEnabled(kCap
);
3590 EXPECT_EQ(0, memcmp(&expected
, commands_
, sizeof(expected
)));
3591 EXPECT_TRUE(result
);
3594 TEST_F(GLES2ImplementationTest
, ClientWaitSync
) {
3595 const GLuint client_sync_id
= 36;
3597 cmds::ClientWaitSync cmd
;
3601 ExpectedMemoryInfo result1
=
3602 GetExpectedResultMemory(sizeof(cmds::ClientWaitSync::Result
));
3603 const GLuint64 kTimeout
= 0xABCDEF0123456789;
3604 uint32_t v32_0
= 0, v32_1
= 0;
3605 GLES2Util::MapUint64ToTwoUint32(kTimeout
, &v32_0
, &v32_1
);
3606 expected
.cmd
.Init(client_sync_id
, GL_SYNC_FLUSH_COMMANDS_BIT
,
3607 v32_0
, v32_1
, result1
.id
, result1
.offset
);
3609 EXPECT_CALL(*command_buffer(), OnFlush())
3610 .WillOnce(SetMemory(result1
.ptr
, uint32_t(GL_CONDITION_SATISFIED
)))
3611 .RetiresOnSaturation();
3613 GLenum result
= gl_
->ClientWaitSync(
3614 reinterpret_cast<GLsync
>(client_sync_id
), GL_SYNC_FLUSH_COMMANDS_BIT
,
3616 EXPECT_EQ(0, memcmp(&expected
, commands_
, sizeof(expected
)));
3617 EXPECT_EQ(static_cast<GLenum
>(GL_CONDITION_SATISFIED
), result
);
3620 TEST_F(GLES2ImplementationTest
, WaitSync
) {
3621 const GLuint kClientSyncId
= 36;
3626 const GLuint64 kTimeout
= GL_TIMEOUT_IGNORED
;
3627 uint32_t v32_0
= 0, v32_1
= 0;
3628 GLES2Util::MapUint64ToTwoUint32(kTimeout
, &v32_0
, &v32_1
);
3629 expected
.cmd
.Init(kClientSyncId
, 0, v32_0
, v32_1
);
3631 gl_
->WaitSync(reinterpret_cast<GLsync
>(kClientSyncId
), 0, kTimeout
);
3632 EXPECT_EQ(0, memcmp(&expected
, commands_
, sizeof(expected
)));
3635 TEST_F(GLES2ImplementationManualInitTest
, LoseContextOnOOM
) {
3636 ContextInitOptions init_options
;
3637 init_options
.lose_context_when_out_of_memory
= true;
3638 ASSERT_TRUE(Initialize(init_options
));
3641 cmds::LoseContextCHROMIUM cmd
;
3644 GLsizei max
= std::numeric_limits
<GLsizei
>::max();
3645 EXPECT_CALL(*gpu_control_
, CreateGpuMemoryBufferImage(max
, max
, _
, _
))
3646 .WillOnce(Return(-1));
3647 gl_
->CreateGpuMemoryBufferImageCHROMIUM(max
, max
, GL_RGBA
, GL_MAP_CHROMIUM
);
3648 // The context should be lost.
3650 expected
.cmd
.Init(GL_GUILTY_CONTEXT_RESET_ARB
, GL_UNKNOWN_CONTEXT_RESET_ARB
);
3651 EXPECT_EQ(0, memcmp(&expected
, commands_
, sizeof(expected
)));
3654 TEST_F(GLES2ImplementationManualInitTest
, NoLoseContextOnOOM
) {
3655 ContextInitOptions init_options
;
3656 ASSERT_TRUE(Initialize(init_options
));
3659 cmds::LoseContextCHROMIUM cmd
;
3662 GLsizei max
= std::numeric_limits
<GLsizei
>::max();
3663 EXPECT_CALL(*gpu_control_
, CreateGpuMemoryBufferImage(max
, max
, _
, _
))
3664 .WillOnce(Return(-1));
3665 gl_
->CreateGpuMemoryBufferImageCHROMIUM(max
, max
, GL_RGBA
, GL_MAP_CHROMIUM
);
3666 // The context should not be lost.
3667 EXPECT_TRUE(NoCommandsWritten());
3670 TEST_F(GLES2ImplementationManualInitTest
, FailInitOnBGRMismatch1
) {
3671 ContextInitOptions init_options
;
3672 init_options
.bind_generates_resource_client
= false;
3673 init_options
.bind_generates_resource_service
= true;
3674 EXPECT_FALSE(Initialize(init_options
));
3677 TEST_F(GLES2ImplementationManualInitTest
, FailInitOnBGRMismatch2
) {
3678 ContextInitOptions init_options
;
3679 init_options
.bind_generates_resource_client
= true;
3680 init_options
.bind_generates_resource_service
= false;
3681 EXPECT_FALSE(Initialize(init_options
));
3684 TEST_F(GLES2ImplementationManualInitTest
, FailInitOnTransferBufferFail
) {
3685 ContextInitOptions init_options
;
3686 init_options
.transfer_buffer_initialize_fail
= true;
3687 EXPECT_FALSE(Initialize(init_options
));
3690 #include "gpu/command_buffer/client/gles2_implementation_unittest_autogen.h"
3692 } // namespace gles2