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
= 1;
385 static const GLuint kFramebuffersStartId
= 1;
386 static const GLuint kProgramsAndShadersStartId
= 1;
387 static const GLuint kRenderbuffersStartId
= 1;
388 static const GLuint kSamplersStartId
= 1;
389 static const GLuint kTexturesStartId
= 1;
390 static const GLuint kTransformFeedbacksStartId
= 1;
391 static const GLuint kQueriesStartId
= 1;
392 static const GLuint kVertexArraysStartId
= 1;
393 static const GLuint kValuebuffersStartId
= 1;
395 typedef MockTransferBuffer::ExpectedMemoryInfo ExpectedMemoryInfo
;
399 TestContext() : commands_(NULL
), token_(0) {}
401 bool Initialize(ShareGroup
* share_group
,
402 bool bind_generates_resource_client
,
403 bool bind_generates_resource_service
,
404 bool lose_context_when_out_of_memory
,
405 bool transfer_buffer_initialize_fail
) {
406 command_buffer_
.reset(new StrictMock
<MockClientCommandBuffer
>());
407 if (!command_buffer_
->Initialize())
410 transfer_buffer_
.reset(
411 new MockTransferBuffer(command_buffer_
.get(),
413 GLES2Implementation::kStartingOffset
,
414 GLES2Implementation::kAlignment
,
415 transfer_buffer_initialize_fail
));
417 helper_
.reset(new GLES2CmdHelper(command_buffer()));
418 helper_
->Initialize(kCommandBufferSizeBytes
);
420 gpu_control_
.reset(new StrictMock
<MockClientGpuControl
>());
421 Capabilities capabilities
;
422 capabilities
.VisitPrecisions(
423 [](GLenum shader
, GLenum type
,
424 Capabilities::ShaderPrecision
* precision
) {
425 precision
->min_range
= 3;
426 precision
->max_range
= 5;
427 precision
->precision
= 7;
429 capabilities
.max_combined_texture_image_units
=
430 kMaxCombinedTextureImageUnits
;
431 capabilities
.max_cube_map_texture_size
= kMaxCubeMapTextureSize
;
432 capabilities
.max_fragment_uniform_vectors
= kMaxFragmentUniformVectors
;
433 capabilities
.max_renderbuffer_size
= kMaxRenderbufferSize
;
434 capabilities
.max_texture_image_units
= kMaxTextureImageUnits
;
435 capabilities
.max_texture_size
= kMaxTextureSize
;
436 capabilities
.max_varying_vectors
= kMaxVaryingVectors
;
437 capabilities
.max_vertex_attribs
= kMaxVertexAttribs
;
438 capabilities
.max_vertex_texture_image_units
= kMaxVertexTextureImageUnits
;
439 capabilities
.max_vertex_uniform_vectors
= kMaxVertexUniformVectors
;
440 capabilities
.num_compressed_texture_formats
=
441 kNumCompressedTextureFormats
;
442 capabilities
.num_shader_binary_formats
= kNumShaderBinaryFormats
;
443 capabilities
.max_transform_feedback_separate_attribs
=
444 kMaxTransformFeedbackSeparateAttribs
;
445 capabilities
.max_uniform_buffer_bindings
= kMaxUniformBufferBindings
;
446 capabilities
.bind_generates_resource_chromium
=
447 bind_generates_resource_service
? 1 : 0;
448 EXPECT_CALL(*gpu_control_
, GetCapabilities())
449 .WillOnce(testing::Return(capabilities
));
454 const bool support_client_side_arrays
= true;
455 gl_
.reset(new GLES2Implementation(helper_
.get(),
457 transfer_buffer_
.get(),
458 bind_generates_resource_client
,
459 lose_context_when_out_of_memory
,
460 support_client_side_arrays
,
461 gpu_control_
.get()));
463 if (!gl_
->Initialize(kTransferBufferSize
,
466 GLES2Implementation::kNoLimit
))
470 helper_
->CommandBufferHelper::Finish();
471 ::testing::Mock::VerifyAndClearExpectations(gl_
.get());
473 scoped_refptr
<Buffer
> ring_buffer
= helper_
->get_ring_buffer();
474 commands_
= static_cast<CommandBufferEntry
*>(ring_buffer
->memory()) +
475 command_buffer()->GetPutOffset();
477 EXPECT_TRUE(transfer_buffer_
->InSync());
479 ::testing::Mock::VerifyAndClearExpectations(command_buffer());
484 Mock::VerifyAndClear(gl_
.get());
485 EXPECT_CALL(*command_buffer(), OnFlush()).Times(AnyNumber());
486 // For command buffer.
487 EXPECT_CALL(*command_buffer(), DestroyTransferBuffer(_
))
492 MockClientCommandBuffer
* command_buffer() const {
493 return command_buffer_
.get();
496 int GetNextToken() { return ++token_
; }
498 void ClearCommands() {
499 scoped_refptr
<Buffer
> ring_buffer
= helper_
->get_ring_buffer();
500 memset(ring_buffer
->memory(), kInitialValue
, ring_buffer
->size());
503 scoped_ptr
<MockClientCommandBuffer
> command_buffer_
;
504 scoped_ptr
<MockClientGpuControl
> gpu_control_
;
505 scoped_ptr
<GLES2CmdHelper
> helper_
;
506 scoped_ptr
<MockTransferBuffer
> transfer_buffer_
;
507 scoped_ptr
<GLES2Implementation
> gl_
;
508 CommandBufferEntry
* commands_
;
512 GLES2ImplementationTest() : commands_(NULL
) {}
514 void SetUp() override
;
515 void TearDown() override
;
517 bool NoCommandsWritten() {
518 scoped_refptr
<Buffer
> ring_buffer
= helper_
->get_ring_buffer();
519 const uint8
* cmds
= reinterpret_cast<const uint8
*>(ring_buffer
->memory());
520 const uint8
* end
= cmds
+ ring_buffer
->size();
521 for (; cmds
< end
; ++cmds
) {
522 if (*cmds
!= kInitialValue
) {
529 QueryTracker::Query
* GetQuery(GLuint id
) {
530 return gl_
->query_tracker_
->GetQuery(id
);
533 struct ContextInitOptions
{
535 : bind_generates_resource_client(true),
536 bind_generates_resource_service(true),
537 lose_context_when_out_of_memory(false),
538 transfer_buffer_initialize_fail(false) {}
540 bool bind_generates_resource_client
;
541 bool bind_generates_resource_service
;
542 bool lose_context_when_out_of_memory
;
543 bool transfer_buffer_initialize_fail
;
546 bool Initialize(const ContextInitOptions
& init_options
) {
548 share_group_
= new ShareGroup(init_options
.bind_generates_resource_client
);
550 for (int i
= 0; i
< kNumTestContexts
; i
++) {
551 if (!test_contexts_
[i
].Initialize(
553 init_options
.bind_generates_resource_client
,
554 init_options
.bind_generates_resource_service
,
555 init_options
.lose_context_when_out_of_memory
,
556 init_options
.transfer_buffer_initialize_fail
))
560 // Default to test context 0.
561 gpu_control_
= test_contexts_
[0].gpu_control_
.get();
562 helper_
= test_contexts_
[0].helper_
.get();
563 transfer_buffer_
= test_contexts_
[0].transfer_buffer_
.get();
564 gl_
= test_contexts_
[0].gl_
.get();
565 commands_
= test_contexts_
[0].commands_
;
569 MockClientCommandBuffer
* command_buffer() const {
570 return test_contexts_
[0].command_buffer_
.get();
573 int GetNextToken() { return test_contexts_
[0].GetNextToken(); }
575 const void* GetPut() {
576 return helper_
->GetSpace(0);
579 void ClearCommands() {
580 scoped_refptr
<Buffer
> ring_buffer
= helper_
->get_ring_buffer();
581 memset(ring_buffer
->memory(), kInitialValue
, ring_buffer
->size());
584 size_t MaxTransferBufferSize() {
585 return transfer_buffer_
->MaxTransferBufferSize();
588 ExpectedMemoryInfo
GetExpectedMemory(size_t size
) {
589 return transfer_buffer_
->GetExpectedMemory(size
);
592 ExpectedMemoryInfo
GetExpectedResultMemory(size_t size
) {
593 return transfer_buffer_
->GetExpectedResultMemory(size
);
596 // Sets the ProgramInfoManager. The manager will be owned
597 // by the ShareGroup.
598 void SetProgramInfoManager(ProgramInfoManager
* manager
) {
599 gl_
->share_group()->set_program_info_manager(manager
);
603 ExpectedMemoryInfo result
=
604 GetExpectedResultMemory(sizeof(cmds::GetError::Result
));
605 EXPECT_CALL(*command_buffer(), OnFlush())
606 .WillOnce(SetMemory(result
.ptr
, GLuint(GL_NO_ERROR
)))
607 .RetiresOnSaturation();
608 return gl_
->GetError();
611 const std::string
& GetLastError() {
612 return gl_
->GetLastError();
615 bool GetBucketContents(uint32 bucket_id
, std::vector
<int8
>* data
) {
616 return gl_
->GetBucketContents(bucket_id
, data
);
619 TestContext test_contexts_
[kNumTestContexts
];
621 scoped_refptr
<ShareGroup
> share_group_
;
622 MockClientGpuControl
* gpu_control_
;
623 GLES2CmdHelper
* helper_
;
624 MockTransferBuffer
* transfer_buffer_
;
625 GLES2Implementation
* gl_
;
626 CommandBufferEntry
* commands_
;
629 void GLES2ImplementationTest::SetUp() {
630 ContextInitOptions init_options
;
631 ASSERT_TRUE(Initialize(init_options
));
634 void GLES2ImplementationTest::TearDown() {
635 for (int i
= 0; i
< kNumTestContexts
; i
++)
636 test_contexts_
[i
].TearDown();
639 class GLES2ImplementationManualInitTest
: public GLES2ImplementationTest
{
641 void SetUp() override
{}
644 class GLES2ImplementationStrictSharedTest
: public GLES2ImplementationTest
{
646 void SetUp() override
;
648 template <class ResApi
>
649 void FlushGenerationTest() {
650 GLuint id1
, id2
, id3
;
652 // Generate valid id.
653 ResApi::Gen(gl_
, 1, &id1
);
656 // Delete id1 and generate id2. id1 should not be reused.
657 ResApi::Delete(gl_
, 1, &id1
);
658 ResApi::Gen(gl_
, 1, &id2
);
662 // Expect id1 reuse after Flush.
664 ResApi::Gen(gl_
, 1, &id3
);
668 // Ids should not be reused unless the |Deleting| context does a Flush()
669 // AND triggers a lazy release after that.
670 template <class ResApi
>
671 void CrossContextGenerationTest() {
672 GLES2Implementation
* gl1
= test_contexts_
[0].gl_
.get();
673 GLES2Implementation
* gl2
= test_contexts_
[1].gl_
.get();
674 GLuint id1
, id2
, id3
;
676 // Delete, no flush on context 1. No reuse.
677 ResApi::Gen(gl1
, 1, &id1
);
678 ResApi::Delete(gl1
, 1, &id1
);
679 ResApi::Gen(gl1
, 1, &id2
);
682 // Flush context 2. Still no reuse.
684 ResApi::Gen(gl2
, 1, &id3
);
688 // Flush on context 1, but no lazy release. Still no reuse.
690 ResApi::Gen(gl2
, 1, &id3
);
693 // Lazy release triggered by another Delete. Should reuse id1.
694 ResApi::Delete(gl1
, 1, &id2
);
695 ResApi::Gen(gl2
, 1, &id3
);
699 // Same as CrossContextGenerationTest(), but triggers an Auto Flush on
700 // the Delete(). Tests an edge case regression.
701 template <class ResApi
>
702 void CrossContextGenerationAutoFlushTest() {
703 GLES2Implementation
* gl1
= test_contexts_
[0].gl_
.get();
704 GLES2Implementation
* gl2
= test_contexts_
[1].gl_
.get();
705 GLuint id1
, id2
, id3
;
707 // Delete, no flush on context 1. No reuse.
708 // By half filling the buffer, an internal flush is forced on the Delete().
709 ResApi::Gen(gl1
, 1, &id1
);
710 gl1
->helper()->Noop(kNumCommandEntries
/ 2);
711 ResApi::Delete(gl1
, 1, &id1
);
712 ResApi::Gen(gl1
, 1, &id2
);
715 // Flush context 2. Still no reuse.
717 ResApi::Gen(gl2
, 1, &id3
);
721 // Flush on context 1, but no lazy release. Still no reuse.
723 ResApi::Gen(gl2
, 1, &id3
);
726 // Lazy release triggered by another Delete. Should reuse id1.
727 ResApi::Delete(gl1
, 1, &id2
);
728 ResApi::Gen(gl2
, 1, &id3
);
733 void GLES2ImplementationStrictSharedTest::SetUp() {
734 ContextInitOptions init_options
;
735 init_options
.bind_generates_resource_client
= false;
736 init_options
.bind_generates_resource_service
= false;
737 ASSERT_TRUE(Initialize(init_options
));
740 // GCC requires these declarations, but MSVC requires they not be present
742 const uint8
GLES2ImplementationTest::kInitialValue
;
743 const int32
GLES2ImplementationTest::kNumCommandEntries
;
744 const int32
GLES2ImplementationTest::kCommandBufferSizeBytes
;
745 const size_t GLES2ImplementationTest::kTransferBufferSize
;
746 const GLint
GLES2ImplementationTest::kMaxCombinedTextureImageUnits
;
747 const GLint
GLES2ImplementationTest::kMaxCubeMapTextureSize
;
748 const GLint
GLES2ImplementationTest::kMaxFragmentUniformVectors
;
749 const GLint
GLES2ImplementationTest::kMaxRenderbufferSize
;
750 const GLint
GLES2ImplementationTest::kMaxTextureImageUnits
;
751 const GLint
GLES2ImplementationTest::kMaxTextureSize
;
752 const GLint
GLES2ImplementationTest::kMaxVaryingVectors
;
753 const GLint
GLES2ImplementationTest::kMaxVertexAttribs
;
754 const GLint
GLES2ImplementationTest::kMaxVertexTextureImageUnits
;
755 const GLint
GLES2ImplementationTest::kMaxVertexUniformVectors
;
756 const GLint
GLES2ImplementationTest::kNumCompressedTextureFormats
;
757 const GLint
GLES2ImplementationTest::kNumShaderBinaryFormats
;
758 const GLuint
GLES2ImplementationTest::kStartId
;
759 const GLuint
GLES2ImplementationTest::kBuffersStartId
;
760 const GLuint
GLES2ImplementationTest::kFramebuffersStartId
;
761 const GLuint
GLES2ImplementationTest::kProgramsAndShadersStartId
;
762 const GLuint
GLES2ImplementationTest::kRenderbuffersStartId
;
763 const GLuint
GLES2ImplementationTest::kSamplersStartId
;
764 const GLuint
GLES2ImplementationTest::kTexturesStartId
;
765 const GLuint
GLES2ImplementationTest::kTransformFeedbacksStartId
;
766 const GLuint
GLES2ImplementationTest::kQueriesStartId
;
767 const GLuint
GLES2ImplementationTest::kVertexArraysStartId
;
768 const GLuint
GLES2ImplementationTest::kValuebuffersStartId
;
771 TEST_F(GLES2ImplementationTest
, Basic
) {
772 EXPECT_TRUE(gl_
->share_group() != NULL
);
775 TEST_F(GLES2ImplementationTest
, GetBucketContents
) {
776 const uint32 kBucketId
= GLES2Implementation::kResultBucketId
;
777 const uint32 kTestSize
= MaxTransferBufferSize() + 32;
779 scoped_ptr
<uint8
[]> buf(new uint8
[kTestSize
]);
780 uint8
* expected_data
= buf
.get();
781 for (uint32 ii
= 0; ii
< kTestSize
; ++ii
) {
782 expected_data
[ii
] = ii
* 3;
786 cmd::GetBucketStart get_bucket_start
;
787 cmd::SetToken set_token1
;
788 cmd::GetBucketData get_bucket_data
;
789 cmd::SetToken set_token2
;
790 cmd::SetBucketSize set_bucket_size2
;
793 ExpectedMemoryInfo mem1
= GetExpectedMemory(MaxTransferBufferSize());
794 ExpectedMemoryInfo result1
= GetExpectedResultMemory(sizeof(uint32
));
795 ExpectedMemoryInfo mem2
= GetExpectedMemory(
796 kTestSize
- MaxTransferBufferSize());
799 expected
.get_bucket_start
.Init(
800 kBucketId
, result1
.id
, result1
.offset
,
801 MaxTransferBufferSize(), mem1
.id
, mem1
.offset
);
802 expected
.set_token1
.Init(GetNextToken());
803 expected
.get_bucket_data
.Init(
804 kBucketId
, MaxTransferBufferSize(),
805 kTestSize
- MaxTransferBufferSize(), mem2
.id
, mem2
.offset
);
806 expected
.set_bucket_size2
.Init(kBucketId
, 0);
807 expected
.set_token2
.Init(GetNextToken());
809 EXPECT_CALL(*command_buffer(), OnFlush())
811 SetMemory(result1
.ptr
, kTestSize
),
813 mem1
.ptr
, expected_data
, MaxTransferBufferSize())))
814 .WillOnce(SetMemoryFromArray(
815 mem2
.ptr
, expected_data
+ MaxTransferBufferSize(),
816 kTestSize
- MaxTransferBufferSize()))
817 .RetiresOnSaturation();
819 std::vector
<int8
> data
;
820 GetBucketContents(kBucketId
, &data
);
821 EXPECT_EQ(0, memcmp(&expected
, commands_
, sizeof(expected
)));
822 ASSERT_EQ(kTestSize
, data
.size());
823 EXPECT_EQ(0, memcmp(expected_data
, &data
[0], data
.size()));
826 TEST_F(GLES2ImplementationTest
, GetShaderPrecisionFormat
) {
828 cmds::GetShaderPrecisionFormat cmd
;
830 typedef cmds::GetShaderPrecisionFormat::Result Result
;
831 const unsigned kDummyType1
= 3;
832 const unsigned kDummyType2
= 4;
834 // The first call for dummy type 1 should trigger a command buffer request.
835 GLint range1
[2] = {0, 0};
836 GLint precision1
= 0;
838 ExpectedMemoryInfo client_result1
= GetExpectedResultMemory(4);
839 expected1
.cmd
.Init(GL_FRAGMENT_SHADER
, kDummyType1
, client_result1
.id
,
840 client_result1
.offset
);
841 Result server_result1
= {true, 14, 14, 10};
842 EXPECT_CALL(*command_buffer(), OnFlush())
843 .WillOnce(SetMemory(client_result1
.ptr
, server_result1
))
844 .RetiresOnSaturation();
845 gl_
->GetShaderPrecisionFormat(GL_FRAGMENT_SHADER
, kDummyType1
, range1
,
847 const void* commands2
= GetPut();
848 EXPECT_NE(commands_
, commands2
);
849 EXPECT_EQ(0, memcmp(&expected1
, commands_
, sizeof(expected1
)));
850 EXPECT_EQ(range1
[0], 14);
851 EXPECT_EQ(range1
[1], 14);
852 EXPECT_EQ(precision1
, 10);
854 // The second call for dummy type 1 should use the cached value and avoid
855 // triggering a command buffer request, so we do not expect a call to
856 // OnFlush() here. We do expect the results to be correct though.
857 GLint range2
[2] = {0, 0};
858 GLint precision2
= 0;
859 gl_
->GetShaderPrecisionFormat(GL_FRAGMENT_SHADER
, kDummyType1
, range2
,
861 const void* commands3
= GetPut();
862 EXPECT_EQ(commands2
, commands3
);
863 EXPECT_EQ(range2
[0], 14);
864 EXPECT_EQ(range2
[1], 14);
865 EXPECT_EQ(precision2
, 10);
867 // If we then make a request for dummy type 2, we should get another command
868 // buffer request since it hasn't been cached yet.
869 GLint range3
[2] = {0, 0};
870 GLint precision3
= 0;
872 ExpectedMemoryInfo result3
= GetExpectedResultMemory(4);
873 expected3
.cmd
.Init(GL_FRAGMENT_SHADER
, kDummyType2
, result3
.id
,
875 Result result3_source
= {true, 62, 62, 16};
876 EXPECT_CALL(*command_buffer(), OnFlush())
877 .WillOnce(SetMemory(result3
.ptr
, result3_source
))
878 .RetiresOnSaturation();
879 gl_
->GetShaderPrecisionFormat(GL_FRAGMENT_SHADER
, kDummyType2
, range3
,
881 const void* commands4
= GetPut();
882 EXPECT_NE(commands3
, commands4
);
883 EXPECT_EQ(0, memcmp(&expected3
, commands3
, sizeof(expected3
)));
884 EXPECT_EQ(range3
[0], 62);
885 EXPECT_EQ(range3
[1], 62);
886 EXPECT_EQ(precision3
, 16);
888 // Any call for predefined types should use the cached value from the
889 // Capabilities and avoid triggering a command buffer request, so we do not
890 // expect a call to OnFlush() here. We do expect the results to be correct
892 GLint range4
[2] = {0, 0};
893 GLint precision4
= 0;
894 gl_
->GetShaderPrecisionFormat(GL_FRAGMENT_SHADER
, GL_MEDIUM_FLOAT
, range4
,
896 const void* commands5
= GetPut();
897 EXPECT_EQ(commands4
, commands5
);
898 EXPECT_EQ(range4
[0], 3);
899 EXPECT_EQ(range4
[1], 5);
900 EXPECT_EQ(precision4
, 7);
903 TEST_F(GLES2ImplementationTest
, GetShaderSource
) {
904 const uint32 kBucketId
= GLES2Implementation::kResultBucketId
;
905 const GLuint kShaderId
= 456;
906 const Str7 kString
= {"foobar"};
907 const char kBad
= 0x12;
909 cmd::SetBucketSize set_bucket_size1
;
910 cmds::GetShaderSource get_shader_source
;
911 cmd::GetBucketStart get_bucket_start
;
912 cmd::SetToken set_token1
;
913 cmd::SetBucketSize set_bucket_size2
;
916 ExpectedMemoryInfo mem1
= GetExpectedMemory(MaxTransferBufferSize());
917 ExpectedMemoryInfo result1
= GetExpectedResultMemory(sizeof(uint32
));
920 expected
.set_bucket_size1
.Init(kBucketId
, 0);
921 expected
.get_shader_source
.Init(kShaderId
, kBucketId
);
922 expected
.get_bucket_start
.Init(
923 kBucketId
, result1
.id
, result1
.offset
,
924 MaxTransferBufferSize(), mem1
.id
, mem1
.offset
);
925 expected
.set_token1
.Init(GetNextToken());
926 expected
.set_bucket_size2
.Init(kBucketId
, 0);
927 char buf
[sizeof(kString
) + 1];
928 memset(buf
, kBad
, sizeof(buf
));
930 EXPECT_CALL(*command_buffer(), OnFlush())
931 .WillOnce(DoAll(SetMemory(result1
.ptr
, uint32(sizeof(kString
))),
932 SetMemory(mem1
.ptr
, kString
)))
933 .RetiresOnSaturation();
936 gl_
->GetShaderSource(kShaderId
, sizeof(buf
), &length
, buf
);
937 EXPECT_EQ(0, memcmp(&expected
, commands_
, sizeof(expected
)));
938 EXPECT_EQ(sizeof(kString
) - 1, static_cast<size_t>(length
));
939 EXPECT_STREQ(kString
.str
, buf
);
940 EXPECT_EQ(buf
[sizeof(kString
)], kBad
);
943 #if defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS)
945 TEST_F(GLES2ImplementationTest
, DrawArraysClientSideBuffers
) {
946 static const float verts
[][4] = {
947 { 12.0f
, 23.0f
, 34.0f
, 45.0f
, },
948 { 56.0f
, 67.0f
, 78.0f
, 89.0f
, },
949 { 13.0f
, 24.0f
, 35.0f
, 46.0f
, },
952 cmds::EnableVertexAttribArray enable1
;
953 cmds::EnableVertexAttribArray enable2
;
954 cmds::BindBuffer bind_to_emu
;
955 cmds::BufferData set_size
;
956 cmds::BufferSubData copy_data1
;
957 cmd::SetToken set_token1
;
958 cmds::VertexAttribPointer set_pointer1
;
959 cmds::BufferSubData copy_data2
;
960 cmd::SetToken set_token2
;
961 cmds::VertexAttribPointer set_pointer2
;
962 cmds::DrawArrays draw
;
963 cmds::BindBuffer restore
;
965 const GLuint kEmuBufferId
= GLES2Implementation::kClientSideArrayId
;
966 const GLuint kAttribIndex1
= 1;
967 const GLuint kAttribIndex2
= 3;
968 const GLint kNumComponents1
= 3;
969 const GLint kNumComponents2
= 2;
970 const GLsizei kClientStride
= sizeof(verts
[0]);
971 const GLint kFirst
= 1;
972 const GLsizei kCount
= 2;
973 const GLsizei kSize1
=
974 arraysize(verts
) * kNumComponents1
* sizeof(verts
[0][0]);
975 const GLsizei kSize2
=
976 arraysize(verts
) * kNumComponents2
* sizeof(verts
[0][0]);
977 const GLsizei kEmuOffset1
= 0;
978 const GLsizei kEmuOffset2
= kSize1
;
979 const GLsizei kTotalSize
= kSize1
+ kSize2
;
981 ExpectedMemoryInfo mem1
= GetExpectedMemory(kSize1
);
982 ExpectedMemoryInfo mem2
= GetExpectedMemory(kSize2
);
985 expected
.enable1
.Init(kAttribIndex1
);
986 expected
.enable2
.Init(kAttribIndex2
);
987 expected
.bind_to_emu
.Init(GL_ARRAY_BUFFER
, kEmuBufferId
);
988 expected
.set_size
.Init(GL_ARRAY_BUFFER
, kTotalSize
, 0, 0, GL_DYNAMIC_DRAW
);
989 expected
.copy_data1
.Init(
990 GL_ARRAY_BUFFER
, kEmuOffset1
, kSize1
, mem1
.id
, mem1
.offset
);
991 expected
.set_token1
.Init(GetNextToken());
992 expected
.set_pointer1
.Init(
993 kAttribIndex1
, kNumComponents1
, GL_FLOAT
, GL_FALSE
, 0, kEmuOffset1
);
994 expected
.copy_data2
.Init(
995 GL_ARRAY_BUFFER
, kEmuOffset2
, kSize2
, mem2
.id
, mem2
.offset
);
996 expected
.set_token2
.Init(GetNextToken());
997 expected
.set_pointer2
.Init(
998 kAttribIndex2
, kNumComponents2
, GL_FLOAT
, GL_FALSE
, 0, kEmuOffset2
);
999 expected
.draw
.Init(GL_POINTS
, kFirst
, kCount
);
1000 expected
.restore
.Init(GL_ARRAY_BUFFER
, 0);
1001 gl_
->EnableVertexAttribArray(kAttribIndex1
);
1002 gl_
->EnableVertexAttribArray(kAttribIndex2
);
1003 gl_
->VertexAttribPointer(
1004 kAttribIndex1
, kNumComponents1
, GL_FLOAT
, GL_FALSE
, kClientStride
, verts
);
1005 gl_
->VertexAttribPointer(
1006 kAttribIndex2
, kNumComponents2
, GL_FLOAT
, GL_FALSE
, kClientStride
, verts
);
1007 gl_
->DrawArrays(GL_POINTS
, kFirst
, kCount
);
1008 EXPECT_EQ(0, memcmp(&expected
, commands_
, sizeof(expected
)));
1011 TEST_F(GLES2ImplementationTest
, DrawArraysInstancedANGLEClientSideBuffers
) {
1012 static const float verts
[][4] = {
1013 { 12.0f
, 23.0f
, 34.0f
, 45.0f
, },
1014 { 56.0f
, 67.0f
, 78.0f
, 89.0f
, },
1015 { 13.0f
, 24.0f
, 35.0f
, 46.0f
, },
1018 cmds::EnableVertexAttribArray enable1
;
1019 cmds::EnableVertexAttribArray enable2
;
1020 cmds::VertexAttribDivisorANGLE divisor
;
1021 cmds::BindBuffer bind_to_emu
;
1022 cmds::BufferData set_size
;
1023 cmds::BufferSubData copy_data1
;
1024 cmd::SetToken set_token1
;
1025 cmds::VertexAttribPointer set_pointer1
;
1026 cmds::BufferSubData copy_data2
;
1027 cmd::SetToken set_token2
;
1028 cmds::VertexAttribPointer set_pointer2
;
1029 cmds::DrawArraysInstancedANGLE draw
;
1030 cmds::BindBuffer restore
;
1032 const GLuint kEmuBufferId
= GLES2Implementation::kClientSideArrayId
;
1033 const GLuint kAttribIndex1
= 1;
1034 const GLuint kAttribIndex2
= 3;
1035 const GLint kNumComponents1
= 3;
1036 const GLint kNumComponents2
= 2;
1037 const GLsizei kClientStride
= sizeof(verts
[0]);
1038 const GLint kFirst
= 1;
1039 const GLsizei kCount
= 2;
1040 const GLuint kDivisor
= 1;
1041 const GLsizei kSize1
=
1042 arraysize(verts
) * kNumComponents1
* sizeof(verts
[0][0]);
1043 const GLsizei kSize2
=
1044 1 * kNumComponents2
* sizeof(verts
[0][0]);
1045 const GLsizei kEmuOffset1
= 0;
1046 const GLsizei kEmuOffset2
= kSize1
;
1047 const GLsizei kTotalSize
= kSize1
+ kSize2
;
1049 ExpectedMemoryInfo mem1
= GetExpectedMemory(kSize1
);
1050 ExpectedMemoryInfo mem2
= GetExpectedMemory(kSize2
);
1053 expected
.enable1
.Init(kAttribIndex1
);
1054 expected
.enable2
.Init(kAttribIndex2
);
1055 expected
.divisor
.Init(kAttribIndex2
, kDivisor
);
1056 expected
.bind_to_emu
.Init(GL_ARRAY_BUFFER
, kEmuBufferId
);
1057 expected
.set_size
.Init(GL_ARRAY_BUFFER
, kTotalSize
, 0, 0, GL_DYNAMIC_DRAW
);
1058 expected
.copy_data1
.Init(
1059 GL_ARRAY_BUFFER
, kEmuOffset1
, kSize1
, mem1
.id
, mem1
.offset
);
1060 expected
.set_token1
.Init(GetNextToken());
1061 expected
.set_pointer1
.Init(
1062 kAttribIndex1
, kNumComponents1
, GL_FLOAT
, GL_FALSE
, 0, kEmuOffset1
);
1063 expected
.copy_data2
.Init(
1064 GL_ARRAY_BUFFER
, kEmuOffset2
, kSize2
, mem2
.id
, mem2
.offset
);
1065 expected
.set_token2
.Init(GetNextToken());
1066 expected
.set_pointer2
.Init(
1067 kAttribIndex2
, kNumComponents2
, GL_FLOAT
, GL_FALSE
, 0, kEmuOffset2
);
1068 expected
.draw
.Init(GL_POINTS
, kFirst
, kCount
, 1);
1069 expected
.restore
.Init(GL_ARRAY_BUFFER
, 0);
1070 gl_
->EnableVertexAttribArray(kAttribIndex1
);
1071 gl_
->EnableVertexAttribArray(kAttribIndex2
);
1072 gl_
->VertexAttribPointer(
1073 kAttribIndex1
, kNumComponents1
, GL_FLOAT
, GL_FALSE
, kClientStride
, verts
);
1074 gl_
->VertexAttribPointer(
1075 kAttribIndex2
, kNumComponents2
, GL_FLOAT
, GL_FALSE
, kClientStride
, verts
);
1076 gl_
->VertexAttribDivisorANGLE(kAttribIndex2
, kDivisor
);
1077 gl_
->DrawArraysInstancedANGLE(GL_POINTS
, kFirst
, kCount
, 1);
1078 EXPECT_EQ(0, memcmp(&expected
, commands_
, sizeof(expected
)));
1081 TEST_F(GLES2ImplementationTest
, DrawElementsClientSideBuffers
) {
1082 static const float verts
[][4] = {
1083 { 12.0f
, 23.0f
, 34.0f
, 45.0f
, },
1084 { 56.0f
, 67.0f
, 78.0f
, 89.0f
, },
1085 { 13.0f
, 24.0f
, 35.0f
, 46.0f
, },
1087 static const uint16 indices
[] = {
1091 cmds::EnableVertexAttribArray enable1
;
1092 cmds::EnableVertexAttribArray enable2
;
1093 cmds::BindBuffer bind_to_index_emu
;
1094 cmds::BufferData set_index_size
;
1095 cmds::BufferSubData copy_data0
;
1096 cmd::SetToken set_token0
;
1097 cmds::BindBuffer bind_to_emu
;
1098 cmds::BufferData set_size
;
1099 cmds::BufferSubData copy_data1
;
1100 cmd::SetToken set_token1
;
1101 cmds::VertexAttribPointer set_pointer1
;
1102 cmds::BufferSubData copy_data2
;
1103 cmd::SetToken set_token2
;
1104 cmds::VertexAttribPointer set_pointer2
;
1105 cmds::DrawElements draw
;
1106 cmds::BindBuffer restore
;
1107 cmds::BindBuffer restore_element
;
1109 const GLsizei kIndexSize
= sizeof(indices
);
1110 const GLuint kEmuBufferId
= GLES2Implementation::kClientSideArrayId
;
1111 const GLuint kEmuIndexBufferId
=
1112 GLES2Implementation::kClientSideElementArrayId
;
1113 const GLuint kAttribIndex1
= 1;
1114 const GLuint kAttribIndex2
= 3;
1115 const GLint kNumComponents1
= 3;
1116 const GLint kNumComponents2
= 2;
1117 const GLsizei kClientStride
= sizeof(verts
[0]);
1118 const GLsizei kCount
= 2;
1119 const GLsizei kSize1
=
1120 arraysize(verts
) * kNumComponents1
* sizeof(verts
[0][0]);
1121 const GLsizei kSize2
=
1122 arraysize(verts
) * kNumComponents2
* sizeof(verts
[0][0]);
1123 const GLsizei kEmuOffset1
= 0;
1124 const GLsizei kEmuOffset2
= kSize1
;
1125 const GLsizei kTotalSize
= kSize1
+ kSize2
;
1127 ExpectedMemoryInfo mem1
= GetExpectedMemory(kIndexSize
);
1128 ExpectedMemoryInfo mem2
= GetExpectedMemory(kSize1
);
1129 ExpectedMemoryInfo mem3
= GetExpectedMemory(kSize2
);
1132 expected
.enable1
.Init(kAttribIndex1
);
1133 expected
.enable2
.Init(kAttribIndex2
);
1134 expected
.bind_to_index_emu
.Init(GL_ELEMENT_ARRAY_BUFFER
, kEmuIndexBufferId
);
1135 expected
.set_index_size
.Init(
1136 GL_ELEMENT_ARRAY_BUFFER
, kIndexSize
, 0, 0, GL_DYNAMIC_DRAW
);
1137 expected
.copy_data0
.Init(
1138 GL_ELEMENT_ARRAY_BUFFER
, 0, kIndexSize
, mem1
.id
, mem1
.offset
);
1139 expected
.set_token0
.Init(GetNextToken());
1140 expected
.bind_to_emu
.Init(GL_ARRAY_BUFFER
, kEmuBufferId
);
1141 expected
.set_size
.Init(GL_ARRAY_BUFFER
, kTotalSize
, 0, 0, GL_DYNAMIC_DRAW
);
1142 expected
.copy_data1
.Init(
1143 GL_ARRAY_BUFFER
, kEmuOffset1
, kSize1
, mem2
.id
, mem2
.offset
);
1144 expected
.set_token1
.Init(GetNextToken());
1145 expected
.set_pointer1
.Init(
1146 kAttribIndex1
, kNumComponents1
, GL_FLOAT
, GL_FALSE
, 0, kEmuOffset1
);
1147 expected
.copy_data2
.Init(
1148 GL_ARRAY_BUFFER
, kEmuOffset2
, kSize2
, mem3
.id
, mem3
.offset
);
1149 expected
.set_token2
.Init(GetNextToken());
1150 expected
.set_pointer2
.Init(kAttribIndex2
, kNumComponents2
,
1151 GL_FLOAT
, GL_FALSE
, 0, kEmuOffset2
);
1152 expected
.draw
.Init(GL_POINTS
, kCount
, GL_UNSIGNED_SHORT
, 0);
1153 expected
.restore
.Init(GL_ARRAY_BUFFER
, 0);
1154 expected
.restore_element
.Init(GL_ELEMENT_ARRAY_BUFFER
, 0);
1155 gl_
->EnableVertexAttribArray(kAttribIndex1
);
1156 gl_
->EnableVertexAttribArray(kAttribIndex2
);
1157 gl_
->VertexAttribPointer(kAttribIndex1
, kNumComponents1
,
1158 GL_FLOAT
, GL_FALSE
, kClientStride
, verts
);
1159 gl_
->VertexAttribPointer(kAttribIndex2
, kNumComponents2
,
1160 GL_FLOAT
, GL_FALSE
, kClientStride
, verts
);
1161 gl_
->DrawElements(GL_POINTS
, kCount
, GL_UNSIGNED_SHORT
, indices
);
1162 EXPECT_EQ(0, memcmp(&expected
, commands_
, sizeof(expected
)));
1165 TEST_F(GLES2ImplementationTest
, DrawElementsClientSideBuffersIndexUint
) {
1166 static const float verts
[][4] = {
1167 { 12.0f
, 23.0f
, 34.0f
, 45.0f
, },
1168 { 56.0f
, 67.0f
, 78.0f
, 89.0f
, },
1169 { 13.0f
, 24.0f
, 35.0f
, 46.0f
, },
1171 static const uint32 indices
[] = {
1175 cmds::EnableVertexAttribArray enable1
;
1176 cmds::EnableVertexAttribArray enable2
;
1177 cmds::BindBuffer bind_to_index_emu
;
1178 cmds::BufferData set_index_size
;
1179 cmds::BufferSubData copy_data0
;
1180 cmd::SetToken set_token0
;
1181 cmds::BindBuffer bind_to_emu
;
1182 cmds::BufferData set_size
;
1183 cmds::BufferSubData copy_data1
;
1184 cmd::SetToken set_token1
;
1185 cmds::VertexAttribPointer set_pointer1
;
1186 cmds::BufferSubData copy_data2
;
1187 cmd::SetToken set_token2
;
1188 cmds::VertexAttribPointer set_pointer2
;
1189 cmds::DrawElements draw
;
1190 cmds::BindBuffer restore
;
1191 cmds::BindBuffer restore_element
;
1193 const GLsizei kIndexSize
= sizeof(indices
);
1194 const GLuint kEmuBufferId
= GLES2Implementation::kClientSideArrayId
;
1195 const GLuint kEmuIndexBufferId
=
1196 GLES2Implementation::kClientSideElementArrayId
;
1197 const GLuint kAttribIndex1
= 1;
1198 const GLuint kAttribIndex2
= 3;
1199 const GLint kNumComponents1
= 3;
1200 const GLint kNumComponents2
= 2;
1201 const GLsizei kClientStride
= sizeof(verts
[0]);
1202 const GLsizei kCount
= 2;
1203 const GLsizei kSize1
=
1204 arraysize(verts
) * kNumComponents1
* sizeof(verts
[0][0]);
1205 const GLsizei kSize2
=
1206 arraysize(verts
) * kNumComponents2
* sizeof(verts
[0][0]);
1207 const GLsizei kEmuOffset1
= 0;
1208 const GLsizei kEmuOffset2
= kSize1
;
1209 const GLsizei kTotalSize
= kSize1
+ kSize2
;
1211 ExpectedMemoryInfo mem1
= GetExpectedMemory(kIndexSize
);
1212 ExpectedMemoryInfo mem2
= GetExpectedMemory(kSize1
);
1213 ExpectedMemoryInfo mem3
= GetExpectedMemory(kSize2
);
1216 expected
.enable1
.Init(kAttribIndex1
);
1217 expected
.enable2
.Init(kAttribIndex2
);
1218 expected
.bind_to_index_emu
.Init(GL_ELEMENT_ARRAY_BUFFER
, kEmuIndexBufferId
);
1219 expected
.set_index_size
.Init(
1220 GL_ELEMENT_ARRAY_BUFFER
, kIndexSize
, 0, 0, GL_DYNAMIC_DRAW
);
1221 expected
.copy_data0
.Init(
1222 GL_ELEMENT_ARRAY_BUFFER
, 0, kIndexSize
, mem1
.id
, mem1
.offset
);
1223 expected
.set_token0
.Init(GetNextToken());
1224 expected
.bind_to_emu
.Init(GL_ARRAY_BUFFER
, kEmuBufferId
);
1225 expected
.set_size
.Init(GL_ARRAY_BUFFER
, kTotalSize
, 0, 0, GL_DYNAMIC_DRAW
);
1226 expected
.copy_data1
.Init(
1227 GL_ARRAY_BUFFER
, kEmuOffset1
, kSize1
, mem2
.id
, mem2
.offset
);
1228 expected
.set_token1
.Init(GetNextToken());
1229 expected
.set_pointer1
.Init(
1230 kAttribIndex1
, kNumComponents1
, GL_FLOAT
, GL_FALSE
, 0, kEmuOffset1
);
1231 expected
.copy_data2
.Init(
1232 GL_ARRAY_BUFFER
, kEmuOffset2
, kSize2
, mem3
.id
, mem3
.offset
);
1233 expected
.set_token2
.Init(GetNextToken());
1234 expected
.set_pointer2
.Init(kAttribIndex2
, kNumComponents2
,
1235 GL_FLOAT
, GL_FALSE
, 0, kEmuOffset2
);
1236 expected
.draw
.Init(GL_POINTS
, kCount
, GL_UNSIGNED_INT
, 0);
1237 expected
.restore
.Init(GL_ARRAY_BUFFER
, 0);
1238 expected
.restore_element
.Init(GL_ELEMENT_ARRAY_BUFFER
, 0);
1239 gl_
->EnableVertexAttribArray(kAttribIndex1
);
1240 gl_
->EnableVertexAttribArray(kAttribIndex2
);
1241 gl_
->VertexAttribPointer(kAttribIndex1
, kNumComponents1
,
1242 GL_FLOAT
, GL_FALSE
, kClientStride
, verts
);
1243 gl_
->VertexAttribPointer(kAttribIndex2
, kNumComponents2
,
1244 GL_FLOAT
, GL_FALSE
, kClientStride
, verts
);
1245 gl_
->DrawElements(GL_POINTS
, kCount
, GL_UNSIGNED_INT
, indices
);
1246 EXPECT_EQ(0, memcmp(&expected
, commands_
, sizeof(expected
)));
1249 TEST_F(GLES2ImplementationTest
, DrawElementsClientSideBuffersInvalidIndexUint
) {
1250 static const float verts
[][4] = {
1251 { 12.0f
, 23.0f
, 34.0f
, 45.0f
, },
1252 { 56.0f
, 67.0f
, 78.0f
, 89.0f
, },
1253 { 13.0f
, 24.0f
, 35.0f
, 46.0f
, },
1255 static const uint32 indices
[] = {
1259 const GLuint kAttribIndex1
= 1;
1260 const GLuint kAttribIndex2
= 3;
1261 const GLint kNumComponents1
= 3;
1262 const GLint kNumComponents2
= 2;
1263 const GLsizei kClientStride
= sizeof(verts
[0]);
1264 const GLsizei kCount
= 2;
1266 EXPECT_CALL(*command_buffer(), OnFlush())
1268 .RetiresOnSaturation();
1270 gl_
->EnableVertexAttribArray(kAttribIndex1
);
1271 gl_
->EnableVertexAttribArray(kAttribIndex2
);
1272 gl_
->VertexAttribPointer(kAttribIndex1
, kNumComponents1
,
1273 GL_FLOAT
, GL_FALSE
, kClientStride
, verts
);
1274 gl_
->VertexAttribPointer(kAttribIndex2
, kNumComponents2
,
1275 GL_FLOAT
, GL_FALSE
, kClientStride
, verts
);
1276 gl_
->DrawElements(GL_POINTS
, kCount
, GL_UNSIGNED_INT
, indices
);
1278 EXPECT_EQ(static_cast<GLenum
>(GL_INVALID_OPERATION
), gl_
->GetError());
1281 TEST_F(GLES2ImplementationTest
,
1282 DrawElementsClientSideBuffersServiceSideIndices
) {
1283 static const float verts
[][4] = {
1284 { 12.0f
, 23.0f
, 34.0f
, 45.0f
, },
1285 { 56.0f
, 67.0f
, 78.0f
, 89.0f
, },
1286 { 13.0f
, 24.0f
, 35.0f
, 46.0f
, },
1289 cmds::EnableVertexAttribArray enable1
;
1290 cmds::EnableVertexAttribArray enable2
;
1291 cmds::BindBuffer bind_to_index
;
1292 cmds::GetMaxValueInBufferCHROMIUM get_max
;
1293 cmds::BindBuffer bind_to_emu
;
1294 cmds::BufferData set_size
;
1295 cmds::BufferSubData copy_data1
;
1296 cmd::SetToken set_token1
;
1297 cmds::VertexAttribPointer set_pointer1
;
1298 cmds::BufferSubData copy_data2
;
1299 cmd::SetToken set_token2
;
1300 cmds::VertexAttribPointer set_pointer2
;
1301 cmds::DrawElements draw
;
1302 cmds::BindBuffer restore
;
1304 const GLuint kEmuBufferId
= GLES2Implementation::kClientSideArrayId
;
1305 const GLuint kClientIndexBufferId
= 0x789;
1306 const GLuint kIndexOffset
= 0x40;
1307 const GLuint kMaxIndex
= 2;
1308 const GLuint kAttribIndex1
= 1;
1309 const GLuint kAttribIndex2
= 3;
1310 const GLint kNumComponents1
= 3;
1311 const GLint kNumComponents2
= 2;
1312 const GLsizei kClientStride
= sizeof(verts
[0]);
1313 const GLsizei kCount
= 2;
1314 const GLsizei kSize1
=
1315 arraysize(verts
) * kNumComponents1
* sizeof(verts
[0][0]);
1316 const GLsizei kSize2
=
1317 arraysize(verts
) * kNumComponents2
* sizeof(verts
[0][0]);
1318 const GLsizei kEmuOffset1
= 0;
1319 const GLsizei kEmuOffset2
= kSize1
;
1320 const GLsizei kTotalSize
= kSize1
+ kSize2
;
1322 ExpectedMemoryInfo mem1
= GetExpectedResultMemory(sizeof(uint32
));
1323 ExpectedMemoryInfo mem2
= GetExpectedMemory(kSize1
);
1324 ExpectedMemoryInfo mem3
= GetExpectedMemory(kSize2
);
1328 expected
.enable1
.Init(kAttribIndex1
);
1329 expected
.enable2
.Init(kAttribIndex2
);
1330 expected
.bind_to_index
.Init(GL_ELEMENT_ARRAY_BUFFER
, kClientIndexBufferId
);
1331 expected
.get_max
.Init(kClientIndexBufferId
, kCount
, GL_UNSIGNED_SHORT
,
1332 kIndexOffset
, mem1
.id
, mem1
.offset
);
1333 expected
.bind_to_emu
.Init(GL_ARRAY_BUFFER
, kEmuBufferId
);
1334 expected
.set_size
.Init(GL_ARRAY_BUFFER
, kTotalSize
, 0, 0, GL_DYNAMIC_DRAW
);
1335 expected
.copy_data1
.Init(
1336 GL_ARRAY_BUFFER
, kEmuOffset1
, kSize1
, mem2
.id
, mem2
.offset
);
1337 expected
.set_token1
.Init(GetNextToken());
1338 expected
.set_pointer1
.Init(kAttribIndex1
, kNumComponents1
,
1339 GL_FLOAT
, GL_FALSE
, 0, kEmuOffset1
);
1340 expected
.copy_data2
.Init(
1341 GL_ARRAY_BUFFER
, kEmuOffset2
, kSize2
, mem3
.id
, mem3
.offset
);
1342 expected
.set_token2
.Init(GetNextToken());
1343 expected
.set_pointer2
.Init(kAttribIndex2
, kNumComponents2
,
1344 GL_FLOAT
, GL_FALSE
, 0, kEmuOffset2
);
1345 expected
.draw
.Init(GL_POINTS
, kCount
, GL_UNSIGNED_SHORT
, kIndexOffset
);
1346 expected
.restore
.Init(GL_ARRAY_BUFFER
, 0);
1348 EXPECT_CALL(*command_buffer(), OnFlush())
1349 .WillOnce(SetMemory(mem1
.ptr
,kMaxIndex
))
1350 .RetiresOnSaturation();
1352 gl_
->EnableVertexAttribArray(kAttribIndex1
);
1353 gl_
->EnableVertexAttribArray(kAttribIndex2
);
1354 gl_
->BindBuffer(GL_ELEMENT_ARRAY_BUFFER
, kClientIndexBufferId
);
1355 gl_
->VertexAttribPointer(kAttribIndex1
, kNumComponents1
,
1356 GL_FLOAT
, GL_FALSE
, kClientStride
, verts
);
1357 gl_
->VertexAttribPointer(kAttribIndex2
, kNumComponents2
,
1358 GL_FLOAT
, GL_FALSE
, kClientStride
, verts
);
1359 gl_
->DrawElements(GL_POINTS
, kCount
, GL_UNSIGNED_SHORT
,
1360 reinterpret_cast<const void*>(kIndexOffset
));
1361 EXPECT_EQ(0, memcmp(&expected
, commands_
, sizeof(expected
)));
1364 TEST_F(GLES2ImplementationTest
, DrawElementsInstancedANGLEClientSideBuffers
) {
1365 static const float verts
[][4] = {
1366 { 12.0f
, 23.0f
, 34.0f
, 45.0f
, },
1367 { 56.0f
, 67.0f
, 78.0f
, 89.0f
, },
1368 { 13.0f
, 24.0f
, 35.0f
, 46.0f
, },
1370 static const uint16 indices
[] = {
1374 cmds::EnableVertexAttribArray enable1
;
1375 cmds::EnableVertexAttribArray enable2
;
1376 cmds::VertexAttribDivisorANGLE divisor
;
1377 cmds::BindBuffer bind_to_index_emu
;
1378 cmds::BufferData set_index_size
;
1379 cmds::BufferSubData copy_data0
;
1380 cmd::SetToken set_token0
;
1381 cmds::BindBuffer bind_to_emu
;
1382 cmds::BufferData set_size
;
1383 cmds::BufferSubData copy_data1
;
1384 cmd::SetToken set_token1
;
1385 cmds::VertexAttribPointer set_pointer1
;
1386 cmds::BufferSubData copy_data2
;
1387 cmd::SetToken set_token2
;
1388 cmds::VertexAttribPointer set_pointer2
;
1389 cmds::DrawElementsInstancedANGLE draw
;
1390 cmds::BindBuffer restore
;
1391 cmds::BindBuffer restore_element
;
1393 const GLsizei kIndexSize
= sizeof(indices
);
1394 const GLuint kEmuBufferId
= GLES2Implementation::kClientSideArrayId
;
1395 const GLuint kEmuIndexBufferId
=
1396 GLES2Implementation::kClientSideElementArrayId
;
1397 const GLuint kAttribIndex1
= 1;
1398 const GLuint kAttribIndex2
= 3;
1399 const GLint kNumComponents1
= 3;
1400 const GLint kNumComponents2
= 2;
1401 const GLsizei kClientStride
= sizeof(verts
[0]);
1402 const GLsizei kCount
= 2;
1403 const GLsizei kSize1
=
1404 arraysize(verts
) * kNumComponents1
* sizeof(verts
[0][0]);
1405 const GLsizei kSize2
=
1406 1 * kNumComponents2
* sizeof(verts
[0][0]);
1407 const GLuint kDivisor
= 1;
1408 const GLsizei kEmuOffset1
= 0;
1409 const GLsizei kEmuOffset2
= kSize1
;
1410 const GLsizei kTotalSize
= kSize1
+ kSize2
;
1412 ExpectedMemoryInfo mem1
= GetExpectedMemory(kIndexSize
);
1413 ExpectedMemoryInfo mem2
= GetExpectedMemory(kSize1
);
1414 ExpectedMemoryInfo mem3
= GetExpectedMemory(kSize2
);
1417 expected
.enable1
.Init(kAttribIndex1
);
1418 expected
.enable2
.Init(kAttribIndex2
);
1419 expected
.divisor
.Init(kAttribIndex2
, kDivisor
);
1420 expected
.bind_to_index_emu
.Init(GL_ELEMENT_ARRAY_BUFFER
, kEmuIndexBufferId
);
1421 expected
.set_index_size
.Init(
1422 GL_ELEMENT_ARRAY_BUFFER
, kIndexSize
, 0, 0, GL_DYNAMIC_DRAW
);
1423 expected
.copy_data0
.Init(
1424 GL_ELEMENT_ARRAY_BUFFER
, 0, kIndexSize
, mem1
.id
, mem1
.offset
);
1425 expected
.set_token0
.Init(GetNextToken());
1426 expected
.bind_to_emu
.Init(GL_ARRAY_BUFFER
, kEmuBufferId
);
1427 expected
.set_size
.Init(GL_ARRAY_BUFFER
, kTotalSize
, 0, 0, GL_DYNAMIC_DRAW
);
1428 expected
.copy_data1
.Init(
1429 GL_ARRAY_BUFFER
, kEmuOffset1
, kSize1
, mem2
.id
, mem2
.offset
);
1430 expected
.set_token1
.Init(GetNextToken());
1431 expected
.set_pointer1
.Init(
1432 kAttribIndex1
, kNumComponents1
, GL_FLOAT
, GL_FALSE
, 0, kEmuOffset1
);
1433 expected
.copy_data2
.Init(
1434 GL_ARRAY_BUFFER
, kEmuOffset2
, kSize2
, mem3
.id
, mem3
.offset
);
1435 expected
.set_token2
.Init(GetNextToken());
1436 expected
.set_pointer2
.Init(kAttribIndex2
, kNumComponents2
,
1437 GL_FLOAT
, GL_FALSE
, 0, kEmuOffset2
);
1438 expected
.draw
.Init(GL_POINTS
, kCount
, GL_UNSIGNED_SHORT
, 0, 1);
1439 expected
.restore
.Init(GL_ARRAY_BUFFER
, 0);
1440 expected
.restore_element
.Init(GL_ELEMENT_ARRAY_BUFFER
, 0);
1441 gl_
->EnableVertexAttribArray(kAttribIndex1
);
1442 gl_
->EnableVertexAttribArray(kAttribIndex2
);
1443 gl_
->VertexAttribPointer(kAttribIndex1
, kNumComponents1
,
1444 GL_FLOAT
, GL_FALSE
, kClientStride
, verts
);
1445 gl_
->VertexAttribPointer(kAttribIndex2
, kNumComponents2
,
1446 GL_FLOAT
, GL_FALSE
, kClientStride
, verts
);
1447 gl_
->VertexAttribDivisorANGLE(kAttribIndex2
, kDivisor
);
1448 gl_
->DrawElementsInstancedANGLE(
1449 GL_POINTS
, kCount
, GL_UNSIGNED_SHORT
, indices
, 1);
1450 EXPECT_EQ(0, memcmp(&expected
, commands_
, sizeof(expected
)));
1453 TEST_F(GLES2ImplementationTest
, GetVertexBufferPointerv
) {
1454 static const float verts
[1] = { 0.0f
, };
1455 const GLuint kAttribIndex1
= 1;
1456 const GLuint kAttribIndex2
= 3;
1457 const GLint kNumComponents1
= 3;
1458 const GLint kNumComponents2
= 2;
1459 const GLsizei kStride1
= 12;
1460 const GLsizei kStride2
= 0;
1461 const GLuint kBufferId
= 0x123;
1462 const GLint kOffset2
= 0x456;
1464 // It's all cached on the client side so no get commands are issued.
1466 cmds::BindBuffer bind
;
1467 cmds::VertexAttribPointer set_pointer
;
1471 expected
.bind
.Init(GL_ARRAY_BUFFER
, kBufferId
);
1472 expected
.set_pointer
.Init(kAttribIndex2
, kNumComponents2
, GL_FLOAT
, GL_FALSE
,
1473 kStride2
, kOffset2
);
1475 // Set one client side buffer.
1476 gl_
->VertexAttribPointer(kAttribIndex1
, kNumComponents1
,
1477 GL_FLOAT
, GL_FALSE
, kStride1
, verts
);
1479 gl_
->BindBuffer(GL_ARRAY_BUFFER
, kBufferId
);
1480 gl_
->VertexAttribPointer(kAttribIndex2
, kNumComponents2
,
1481 GL_FLOAT
, GL_FALSE
, kStride2
,
1482 reinterpret_cast<const void*>(kOffset2
));
1483 // now get them both.
1487 gl_
->GetVertexAttribPointerv(
1488 kAttribIndex1
, GL_VERTEX_ATTRIB_ARRAY_POINTER
, &ptr1
);
1489 gl_
->GetVertexAttribPointerv(
1490 kAttribIndex2
, GL_VERTEX_ATTRIB_ARRAY_POINTER
, &ptr2
);
1492 EXPECT_EQ(0, memcmp(&expected
, commands_
, sizeof(expected
)));
1493 EXPECT_TRUE(static_cast<const void*>(&verts
) == ptr1
);
1494 EXPECT_TRUE(ptr2
== reinterpret_cast<void*>(kOffset2
));
1497 TEST_F(GLES2ImplementationTest
, GetVertexAttrib
) {
1498 static const float verts
[1] = { 0.0f
, };
1499 const GLuint kAttribIndex1
= 1;
1500 const GLuint kAttribIndex2
= 3;
1501 const GLint kNumComponents1
= 3;
1502 const GLint kNumComponents2
= 2;
1503 const GLsizei kStride1
= 12;
1504 const GLsizei kStride2
= 0;
1505 const GLuint kBufferId
= 0x123;
1506 const GLint kOffset2
= 0x456;
1508 // Only one set and one get because the client side buffer's info is stored
1509 // on the client side.
1511 cmds::EnableVertexAttribArray enable
;
1512 cmds::BindBuffer bind
;
1513 cmds::VertexAttribPointer set_pointer
;
1514 cmds::GetVertexAttribfv get2
; // for getting the value from attrib1
1517 ExpectedMemoryInfo mem2
= GetExpectedResultMemory(16);
1520 expected
.enable
.Init(kAttribIndex1
);
1521 expected
.bind
.Init(GL_ARRAY_BUFFER
, kBufferId
);
1522 expected
.set_pointer
.Init(kAttribIndex2
, kNumComponents2
, GL_FLOAT
, GL_FALSE
,
1523 kStride2
, kOffset2
);
1524 expected
.get2
.Init(kAttribIndex1
,
1525 GL_CURRENT_VERTEX_ATTRIB
,
1526 mem2
.id
, mem2
.offset
);
1528 FourFloats
current_attrib(1.2f
, 3.4f
, 5.6f
, 7.8f
);
1530 // One call to flush to wait for last call to GetVertexAttribiv
1531 // as others are all cached.
1532 EXPECT_CALL(*command_buffer(), OnFlush())
1533 .WillOnce(SetMemory(
1534 mem2
.ptr
, SizedResultHelper
<FourFloats
>(current_attrib
)))
1535 .RetiresOnSaturation();
1537 gl_
->EnableVertexAttribArray(kAttribIndex1
);
1538 // Set one client side buffer.
1539 gl_
->VertexAttribPointer(kAttribIndex1
, kNumComponents1
,
1540 GL_FLOAT
, GL_FALSE
, kStride1
, verts
);
1542 gl_
->BindBuffer(GL_ARRAY_BUFFER
, kBufferId
);
1543 gl_
->VertexAttribPointer(kAttribIndex2
, kNumComponents2
,
1544 GL_FLOAT
, GL_FALSE
, kStride2
,
1545 reinterpret_cast<const void*>(kOffset2
));
1546 // first get the service side once to see that we make a command
1547 GLint buffer_id
= 0;
1552 GLint normalized
= 1;
1553 float current
[4] = { 0.0f
, };
1555 gl_
->GetVertexAttribiv(
1556 kAttribIndex2
, GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING
, &buffer_id
);
1557 EXPECT_EQ(kBufferId
, static_cast<GLuint
>(buffer_id
));
1558 gl_
->GetVertexAttribiv(
1559 kAttribIndex1
, GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING
, &buffer_id
);
1560 gl_
->GetVertexAttribiv(
1561 kAttribIndex1
, GL_VERTEX_ATTRIB_ARRAY_ENABLED
, &enabled
);
1562 gl_
->GetVertexAttribiv(
1563 kAttribIndex1
, GL_VERTEX_ATTRIB_ARRAY_SIZE
, &size
);
1564 gl_
->GetVertexAttribiv(
1565 kAttribIndex1
, GL_VERTEX_ATTRIB_ARRAY_STRIDE
, &stride
);
1566 gl_
->GetVertexAttribiv(
1567 kAttribIndex1
, GL_VERTEX_ATTRIB_ARRAY_TYPE
, &type
);
1568 gl_
->GetVertexAttribiv(
1569 kAttribIndex1
, GL_VERTEX_ATTRIB_ARRAY_NORMALIZED
, &normalized
);
1570 gl_
->GetVertexAttribfv(
1571 kAttribIndex1
, GL_CURRENT_VERTEX_ATTRIB
, ¤t
[0]);
1573 EXPECT_EQ(0, buffer_id
);
1574 EXPECT_EQ(GL_TRUE
, enabled
);
1575 EXPECT_EQ(kNumComponents1
, size
);
1576 EXPECT_EQ(kStride1
, stride
);
1577 EXPECT_EQ(GL_FLOAT
, type
);
1578 EXPECT_EQ(GL_FALSE
, normalized
);
1579 EXPECT_EQ(0, memcmp(¤t_attrib
, ¤t
, sizeof(current_attrib
)));
1581 EXPECT_EQ(0, memcmp(&expected
, commands_
, sizeof(expected
)));
1584 TEST_F(GLES2ImplementationTest
, ReservedIds
) {
1585 // Only the get error command should be issued.
1591 ExpectedMemoryInfo mem1
= GetExpectedResultMemory(
1592 sizeof(cmds::GetError::Result
));
1594 expected
.get
.Init(mem1
.id
, mem1
.offset
);
1596 // One call to flush to wait for GetError
1597 EXPECT_CALL(*command_buffer(), OnFlush())
1598 .WillOnce(SetMemory(mem1
.ptr
, GLuint(GL_NO_ERROR
)))
1599 .RetiresOnSaturation();
1603 GLES2Implementation::kClientSideArrayId
);
1606 GLES2Implementation::kClientSideElementArrayId
);
1607 GLenum err
= gl_
->GetError();
1608 EXPECT_EQ(static_cast<GLenum
>(GL_INVALID_OPERATION
), err
);
1609 EXPECT_EQ(0, memcmp(&expected
, commands_
, sizeof(expected
)));
1612 #endif // defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS)
1614 TEST_F(GLES2ImplementationTest
, ReadPixels2Reads
) {
1616 cmds::ReadPixels read1
;
1617 cmd::SetToken set_token1
;
1618 cmds::ReadPixels read2
;
1619 cmd::SetToken set_token2
;
1621 const GLint kBytesPerPixel
= 4;
1622 const GLint kWidth
=
1623 (kTransferBufferSize
- GLES2Implementation::kStartingOffset
) /
1625 const GLint kHeight
= 2;
1626 const GLenum kFormat
= GL_RGBA
;
1627 const GLenum kType
= GL_UNSIGNED_BYTE
;
1629 ExpectedMemoryInfo mem1
=
1630 GetExpectedMemory(kWidth
* kHeight
/ 2 * kBytesPerPixel
);
1631 ExpectedMemoryInfo result1
=
1632 GetExpectedResultMemory(sizeof(cmds::ReadPixels::Result
));
1633 ExpectedMemoryInfo mem2
=
1634 GetExpectedMemory(kWidth
* kHeight
/ 2 * kBytesPerPixel
);
1635 ExpectedMemoryInfo result2
=
1636 GetExpectedResultMemory(sizeof(cmds::ReadPixels::Result
));
1639 expected
.read1
.Init(
1640 0, 0, kWidth
, kHeight
/ 2, kFormat
, kType
,
1641 mem1
.id
, mem1
.offset
, result1
.id
, result1
.offset
,
1643 expected
.set_token1
.Init(GetNextToken());
1644 expected
.read2
.Init(
1645 0, kHeight
/ 2, kWidth
, kHeight
/ 2, kFormat
, kType
,
1646 mem2
.id
, mem2
.offset
, result2
.id
, result2
.offset
, false);
1647 expected
.set_token2
.Init(GetNextToken());
1648 scoped_ptr
<int8
[]> buffer(new int8
[kWidth
* kHeight
* kBytesPerPixel
]);
1650 EXPECT_CALL(*command_buffer(), OnFlush())
1651 .WillOnce(SetMemory(result1
.ptr
, static_cast<uint32
>(1)))
1652 .WillOnce(SetMemory(result2
.ptr
, static_cast<uint32
>(1)))
1653 .RetiresOnSaturation();
1655 gl_
->ReadPixels(0, 0, kWidth
, kHeight
, kFormat
, kType
, buffer
.get());
1656 EXPECT_EQ(0, memcmp(&expected
, commands_
, sizeof(expected
)));
1659 TEST_F(GLES2ImplementationTest
, ReadPixelsBadFormatType
) {
1661 cmds::ReadPixels read
;
1662 cmd::SetToken set_token
;
1664 const GLint kBytesPerPixel
= 4;
1665 const GLint kWidth
= 2;
1666 const GLint kHeight
= 2;
1667 const GLenum kFormat
= 0;
1668 const GLenum kType
= 0;
1670 ExpectedMemoryInfo mem1
=
1671 GetExpectedMemory(kWidth
* kHeight
* kBytesPerPixel
);
1672 ExpectedMemoryInfo result1
=
1673 GetExpectedResultMemory(sizeof(cmds::ReadPixels::Result
));
1677 0, 0, kWidth
, kHeight
, kFormat
, kType
,
1678 mem1
.id
, mem1
.offset
, result1
.id
, result1
.offset
, false);
1679 expected
.set_token
.Init(GetNextToken());
1680 scoped_ptr
<int8
[]> buffer(new int8
[kWidth
* kHeight
* kBytesPerPixel
]);
1682 EXPECT_CALL(*command_buffer(), OnFlush())
1684 .RetiresOnSaturation();
1686 gl_
->ReadPixels(0, 0, kWidth
, kHeight
, kFormat
, kType
, buffer
.get());
1689 TEST_F(GLES2ImplementationTest
, FreeUnusedSharedMemory
) {
1691 cmds::BufferSubData buf
;
1692 cmd::SetToken set_token
;
1694 const GLenum kTarget
= GL_ELEMENT_ARRAY_BUFFER
;
1695 const GLintptr kOffset
= 15;
1696 const GLsizeiptr kSize
= 16;
1698 ExpectedMemoryInfo mem1
= GetExpectedMemory(kSize
);
1702 kTarget
, kOffset
, kSize
, mem1
.id
, mem1
.offset
);
1703 expected
.set_token
.Init(GetNextToken());
1705 void* mem
= gl_
->MapBufferSubDataCHROMIUM(
1706 kTarget
, kOffset
, kSize
, GL_WRITE_ONLY
);
1707 ASSERT_TRUE(mem
!= NULL
);
1708 gl_
->UnmapBufferSubDataCHROMIUM(mem
);
1709 EXPECT_CALL(*command_buffer(), DestroyTransferBuffer(_
))
1711 .RetiresOnSaturation();
1712 gl_
->FreeUnusedSharedMemory();
1715 TEST_F(GLES2ImplementationTest
, MapUnmapBufferSubDataCHROMIUM
) {
1717 cmds::BufferSubData buf
;
1718 cmd::SetToken set_token
;
1720 const GLenum kTarget
= GL_ELEMENT_ARRAY_BUFFER
;
1721 const GLintptr kOffset
= 15;
1722 const GLsizeiptr kSize
= 16;
1727 kTarget
, kOffset
, kSize
,
1728 command_buffer()->GetNextFreeTransferBufferId(), offset
);
1729 expected
.set_token
.Init(GetNextToken());
1731 void* mem
= gl_
->MapBufferSubDataCHROMIUM(
1732 kTarget
, kOffset
, kSize
, GL_WRITE_ONLY
);
1733 ASSERT_TRUE(mem
!= NULL
);
1734 gl_
->UnmapBufferSubDataCHROMIUM(mem
);
1735 EXPECT_EQ(0, memcmp(&expected
, commands_
, sizeof(expected
)));
1738 TEST_F(GLES2ImplementationTest
, MapUnmapBufferSubDataCHROMIUMBadArgs
) {
1739 const GLenum kTarget
= GL_ELEMENT_ARRAY_BUFFER
;
1740 const GLintptr kOffset
= 15;
1741 const GLsizeiptr kSize
= 16;
1743 ExpectedMemoryInfo result1
=
1744 GetExpectedResultMemory(sizeof(cmds::GetError::Result
));
1745 ExpectedMemoryInfo result2
=
1746 GetExpectedResultMemory(sizeof(cmds::GetError::Result
));
1747 ExpectedMemoryInfo result3
=
1748 GetExpectedResultMemory(sizeof(cmds::GetError::Result
));
1749 ExpectedMemoryInfo result4
=
1750 GetExpectedResultMemory(sizeof(cmds::GetError::Result
));
1752 // Calls to flush to wait for GetError
1753 EXPECT_CALL(*command_buffer(), OnFlush())
1754 .WillOnce(SetMemory(result1
.ptr
, GLuint(GL_NO_ERROR
)))
1755 .WillOnce(SetMemory(result2
.ptr
, GLuint(GL_NO_ERROR
)))
1756 .WillOnce(SetMemory(result3
.ptr
, GLuint(GL_NO_ERROR
)))
1757 .WillOnce(SetMemory(result4
.ptr
, GLuint(GL_NO_ERROR
)))
1758 .RetiresOnSaturation();
1761 mem
= gl_
->MapBufferSubDataCHROMIUM(kTarget
, -1, kSize
, GL_WRITE_ONLY
);
1762 ASSERT_TRUE(mem
== NULL
);
1763 EXPECT_EQ(static_cast<GLenum
>(GL_INVALID_VALUE
), gl_
->GetError());
1764 mem
= gl_
->MapBufferSubDataCHROMIUM(kTarget
, kOffset
, -1, GL_WRITE_ONLY
);
1765 ASSERT_TRUE(mem
== NULL
);
1766 EXPECT_EQ(static_cast<GLenum
>(GL_INVALID_VALUE
), gl_
->GetError());
1767 mem
= gl_
->MapBufferSubDataCHROMIUM(kTarget
, kOffset
, kSize
, GL_READ_ONLY
);
1768 ASSERT_TRUE(mem
== NULL
);
1769 EXPECT_EQ(static_cast<GLenum
>(GL_INVALID_ENUM
), gl_
->GetError());
1770 const char* kPtr
= "something";
1771 gl_
->UnmapBufferSubDataCHROMIUM(kPtr
);
1772 EXPECT_EQ(static_cast<GLenum
>(GL_INVALID_VALUE
), gl_
->GetError());
1775 TEST_F(GLES2ImplementationTest
, MapUnmapTexSubImage2DCHROMIUM
) {
1777 cmds::TexSubImage2D tex
;
1778 cmd::SetToken set_token
;
1780 const GLint kLevel
= 1;
1781 const GLint kXOffset
= 2;
1782 const GLint kYOffset
= 3;
1783 const GLint kWidth
= 4;
1784 const GLint kHeight
= 5;
1785 const GLenum kFormat
= GL_RGBA
;
1786 const GLenum kType
= GL_UNSIGNED_BYTE
;
1791 GL_TEXTURE_2D
, kLevel
, kXOffset
, kYOffset
, kWidth
, kHeight
, kFormat
,
1793 command_buffer()->GetNextFreeTransferBufferId(), offset
, GL_FALSE
);
1794 expected
.set_token
.Init(GetNextToken());
1796 void* mem
= gl_
->MapTexSubImage2DCHROMIUM(
1806 ASSERT_TRUE(mem
!= NULL
);
1807 gl_
->UnmapTexSubImage2DCHROMIUM(mem
);
1808 EXPECT_EQ(0, memcmp(&expected
, commands_
, sizeof(expected
)));
1811 TEST_F(GLES2ImplementationTest
, MapUnmapTexSubImage2DCHROMIUMBadArgs
) {
1812 const GLint kLevel
= 1;
1813 const GLint kXOffset
= 2;
1814 const GLint kYOffset
= 3;
1815 const GLint kWidth
= 4;
1816 const GLint kHeight
= 5;
1817 const GLenum kFormat
= GL_RGBA
;
1818 const GLenum kType
= GL_UNSIGNED_BYTE
;
1820 ExpectedMemoryInfo result1
=
1821 GetExpectedResultMemory(sizeof(cmds::GetError::Result
));
1822 ExpectedMemoryInfo result2
=
1823 GetExpectedResultMemory(sizeof(cmds::GetError::Result
));
1824 ExpectedMemoryInfo result3
=
1825 GetExpectedResultMemory(sizeof(cmds::GetError::Result
));
1826 ExpectedMemoryInfo result4
=
1827 GetExpectedResultMemory(sizeof(cmds::GetError::Result
));
1828 ExpectedMemoryInfo result5
=
1829 GetExpectedResultMemory(sizeof(cmds::GetError::Result
));
1830 ExpectedMemoryInfo result6
=
1831 GetExpectedResultMemory(sizeof(cmds::GetError::Result
));
1832 ExpectedMemoryInfo result7
=
1833 GetExpectedResultMemory(sizeof(cmds::GetError::Result
));
1835 // Calls to flush to wait for GetError
1836 EXPECT_CALL(*command_buffer(), OnFlush())
1837 .WillOnce(SetMemory(result1
.ptr
, GLuint(GL_NO_ERROR
)))
1838 .WillOnce(SetMemory(result2
.ptr
, GLuint(GL_NO_ERROR
)))
1839 .WillOnce(SetMemory(result3
.ptr
, GLuint(GL_NO_ERROR
)))
1840 .WillOnce(SetMemory(result4
.ptr
, GLuint(GL_NO_ERROR
)))
1841 .WillOnce(SetMemory(result5
.ptr
, GLuint(GL_NO_ERROR
)))
1842 .WillOnce(SetMemory(result6
.ptr
, GLuint(GL_NO_ERROR
)))
1843 .WillOnce(SetMemory(result7
.ptr
, GLuint(GL_NO_ERROR
)))
1844 .RetiresOnSaturation();
1847 mem
= gl_
->MapTexSubImage2DCHROMIUM(
1857 EXPECT_TRUE(mem
== NULL
);
1858 EXPECT_EQ(static_cast<GLenum
>(GL_INVALID_VALUE
), gl_
->GetError());
1859 mem
= gl_
->MapTexSubImage2DCHROMIUM(
1869 EXPECT_TRUE(mem
== NULL
);
1870 EXPECT_EQ(static_cast<GLenum
>(GL_INVALID_VALUE
), gl_
->GetError());
1871 mem
= gl_
->MapTexSubImage2DCHROMIUM(
1881 EXPECT_TRUE(mem
== NULL
);
1882 EXPECT_EQ(static_cast<GLenum
>(GL_INVALID_VALUE
), gl_
->GetError());
1883 mem
= gl_
->MapTexSubImage2DCHROMIUM(
1893 EXPECT_TRUE(mem
== NULL
);
1894 EXPECT_EQ(static_cast<GLenum
>(GL_INVALID_VALUE
), gl_
->GetError());
1895 mem
= gl_
->MapTexSubImage2DCHROMIUM(
1905 EXPECT_TRUE(mem
== NULL
);
1906 EXPECT_EQ(static_cast<GLenum
>(GL_INVALID_VALUE
), gl_
->GetError());
1907 mem
= gl_
->MapTexSubImage2DCHROMIUM(
1917 EXPECT_TRUE(mem
== NULL
);
1918 EXPECT_EQ(static_cast<GLenum
>(GL_INVALID_ENUM
), gl_
->GetError());
1919 const char* kPtr
= "something";
1920 gl_
->UnmapTexSubImage2DCHROMIUM(kPtr
);
1921 EXPECT_EQ(static_cast<GLenum
>(GL_INVALID_VALUE
), gl_
->GetError());
1924 TEST_F(GLES2ImplementationTest
, GetProgramInfoCHROMIUMGoodArgs
) {
1925 const uint32 kBucketId
= GLES2Implementation::kResultBucketId
;
1926 const GLuint kProgramId
= 123;
1927 const char kBad
= 0x12;
1929 const Str7 kString
= {"foobar"};
1932 ExpectedMemoryInfo mem1
=
1933 GetExpectedMemory(MaxTransferBufferSize());
1934 ExpectedMemoryInfo result1
=
1935 GetExpectedResultMemory(sizeof(cmd::GetBucketStart::Result
));
1936 ExpectedMemoryInfo result2
=
1937 GetExpectedResultMemory(sizeof(cmds::GetError::Result
));
1939 memset(buf
, kBad
, sizeof(buf
));
1940 EXPECT_CALL(*command_buffer(), OnFlush())
1941 .WillOnce(DoAll(SetMemory(result1
.ptr
, uint32(sizeof(kString
))),
1942 SetMemory(mem1
.ptr
, kString
)))
1943 .WillOnce(SetMemory(result2
.ptr
, GLuint(GL_NO_ERROR
)))
1944 .RetiresOnSaturation();
1947 cmd::SetBucketSize set_bucket_size1
;
1948 cmds::GetProgramInfoCHROMIUM get_program_info
;
1949 cmd::GetBucketStart get_bucket_start
;
1950 cmd::SetToken set_token1
;
1951 cmd::SetBucketSize set_bucket_size2
;
1954 expected
.set_bucket_size1
.Init(kBucketId
, 0);
1955 expected
.get_program_info
.Init(kProgramId
, kBucketId
);
1956 expected
.get_bucket_start
.Init(
1957 kBucketId
, result1
.id
, result1
.offset
,
1958 MaxTransferBufferSize(), mem1
.id
, mem1
.offset
);
1959 expected
.set_token1
.Init(GetNextToken());
1960 expected
.set_bucket_size2
.Init(kBucketId
, 0);
1961 gl_
->GetProgramInfoCHROMIUM(kProgramId
, sizeof(buf
), &size
, &buf
);
1962 EXPECT_EQ(0, memcmp(&expected
, commands_
, sizeof(expected
)));
1963 EXPECT_EQ(static_cast<GLenum
>(GL_NO_ERROR
), gl_
->GetError());
1964 EXPECT_EQ(sizeof(kString
), static_cast<size_t>(size
));
1965 EXPECT_STREQ(kString
.str
, buf
);
1966 EXPECT_EQ(buf
[sizeof(kString
)], kBad
);
1969 TEST_F(GLES2ImplementationTest
, GetProgramInfoCHROMIUMBadArgs
) {
1970 const uint32 kBucketId
= GLES2Implementation::kResultBucketId
;
1971 const GLuint kProgramId
= 123;
1973 const Str7 kString
= {"foobar"};
1976 ExpectedMemoryInfo mem1
= GetExpectedMemory(MaxTransferBufferSize());
1977 ExpectedMemoryInfo result1
=
1978 GetExpectedResultMemory(sizeof(cmd::GetBucketStart::Result
));
1979 ExpectedMemoryInfo result2
=
1980 GetExpectedResultMemory(sizeof(cmds::GetError::Result
));
1981 ExpectedMemoryInfo result3
=
1982 GetExpectedResultMemory(sizeof(cmds::GetError::Result
));
1983 ExpectedMemoryInfo result4
=
1984 GetExpectedResultMemory(sizeof(cmds::GetError::Result
));
1986 EXPECT_CALL(*command_buffer(), OnFlush())
1987 .WillOnce(DoAll(SetMemory(result1
.ptr
, uint32(sizeof(kString
))),
1988 SetMemory(mem1
.ptr
, kString
)))
1989 .WillOnce(SetMemory(result2
.ptr
, GLuint(GL_NO_ERROR
)))
1990 .WillOnce(SetMemory(result3
.ptr
, GLuint(GL_NO_ERROR
)))
1991 .WillOnce(SetMemory(result4
.ptr
, GLuint(GL_NO_ERROR
)))
1992 .RetiresOnSaturation();
1994 // try bufsize not big enough.
1996 cmd::SetBucketSize set_bucket_size1
;
1997 cmds::GetProgramInfoCHROMIUM get_program_info
;
1998 cmd::GetBucketStart get_bucket_start
;
1999 cmd::SetToken set_token1
;
2000 cmd::SetBucketSize set_bucket_size2
;
2003 expected
.set_bucket_size1
.Init(kBucketId
, 0);
2004 expected
.get_program_info
.Init(kProgramId
, kBucketId
);
2005 expected
.get_bucket_start
.Init(
2006 kBucketId
, result1
.id
, result1
.offset
,
2007 MaxTransferBufferSize(), mem1
.id
, mem1
.offset
);
2008 expected
.set_token1
.Init(GetNextToken());
2009 expected
.set_bucket_size2
.Init(kBucketId
, 0);
2010 gl_
->GetProgramInfoCHROMIUM(kProgramId
, 6, &size
, &buf
);
2011 EXPECT_EQ(0, memcmp(&expected
, commands_
, sizeof(expected
)));
2012 EXPECT_EQ(static_cast<GLenum
>(GL_INVALID_OPERATION
), gl_
->GetError());
2016 gl_
->GetProgramInfoCHROMIUM(kProgramId
, -1, &size
, &buf
);
2017 EXPECT_TRUE(NoCommandsWritten());
2018 EXPECT_EQ(static_cast<GLenum
>(GL_INVALID_VALUE
), gl_
->GetError());
2021 gl_
->GetProgramInfoCHROMIUM(kProgramId
, sizeof(buf
), NULL
, &buf
);
2022 EXPECT_TRUE(NoCommandsWritten());
2023 EXPECT_EQ(static_cast<GLenum
>(GL_INVALID_VALUE
), gl_
->GetError());
2026 TEST_F(GLES2ImplementationTest
, GetUniformBlocksCHROMIUMGoodArgs
) {
2027 const uint32 kBucketId
= GLES2Implementation::kResultBucketId
;
2028 const GLuint kProgramId
= 123;
2029 const char kBad
= 0x12;
2031 const Str7 kString
= {"foobar"};
2034 ExpectedMemoryInfo mem1
=
2035 GetExpectedMemory(MaxTransferBufferSize());
2036 ExpectedMemoryInfo result1
=
2037 GetExpectedResultMemory(sizeof(cmd::GetBucketStart::Result
));
2038 ExpectedMemoryInfo result2
=
2039 GetExpectedResultMemory(sizeof(cmds::GetError::Result
));
2041 memset(buf
, kBad
, sizeof(buf
));
2042 EXPECT_CALL(*command_buffer(), OnFlush())
2043 .WillOnce(DoAll(SetMemory(result1
.ptr
, uint32(sizeof(kString
))),
2044 SetMemory(mem1
.ptr
, kString
)))
2045 .WillOnce(SetMemory(result2
.ptr
, GLuint(GL_NO_ERROR
)))
2046 .RetiresOnSaturation();
2049 cmd::SetBucketSize set_bucket_size1
;
2050 cmds::GetUniformBlocksCHROMIUM get_uniform_blocks
;
2051 cmd::GetBucketStart get_bucket_start
;
2052 cmd::SetToken set_token1
;
2053 cmd::SetBucketSize set_bucket_size2
;
2056 expected
.set_bucket_size1
.Init(kBucketId
, 0);
2057 expected
.get_uniform_blocks
.Init(kProgramId
, kBucketId
);
2058 expected
.get_bucket_start
.Init(
2059 kBucketId
, result1
.id
, result1
.offset
,
2060 MaxTransferBufferSize(), mem1
.id
, mem1
.offset
);
2061 expected
.set_token1
.Init(GetNextToken());
2062 expected
.set_bucket_size2
.Init(kBucketId
, 0);
2063 gl_
->GetUniformBlocksCHROMIUM(kProgramId
, sizeof(buf
), &size
, &buf
);
2064 EXPECT_EQ(0, memcmp(&expected
, commands_
, sizeof(expected
)));
2065 EXPECT_EQ(static_cast<GLenum
>(GL_NO_ERROR
), gl_
->GetError());
2066 EXPECT_EQ(sizeof(kString
), static_cast<size_t>(size
));
2067 EXPECT_STREQ(kString
.str
, buf
);
2068 EXPECT_EQ(buf
[sizeof(kString
)], kBad
);
2071 TEST_F(GLES2ImplementationTest
, GetUniformBlocksCHROMIUMBadArgs
) {
2072 const uint32 kBucketId
= GLES2Implementation::kResultBucketId
;
2073 const GLuint kProgramId
= 123;
2075 const Str7 kString
= {"foobar"};
2078 ExpectedMemoryInfo mem1
= GetExpectedMemory(MaxTransferBufferSize());
2079 ExpectedMemoryInfo result1
=
2080 GetExpectedResultMemory(sizeof(cmd::GetBucketStart::Result
));
2081 ExpectedMemoryInfo result2
=
2082 GetExpectedResultMemory(sizeof(cmds::GetError::Result
));
2083 ExpectedMemoryInfo result3
=
2084 GetExpectedResultMemory(sizeof(cmds::GetError::Result
));
2085 ExpectedMemoryInfo result4
=
2086 GetExpectedResultMemory(sizeof(cmds::GetError::Result
));
2088 EXPECT_CALL(*command_buffer(), OnFlush())
2089 .WillOnce(DoAll(SetMemory(result1
.ptr
, uint32(sizeof(kString
))),
2090 SetMemory(mem1
.ptr
, kString
)))
2091 .WillOnce(SetMemory(result2
.ptr
, GLuint(GL_NO_ERROR
)))
2092 .WillOnce(SetMemory(result3
.ptr
, GLuint(GL_NO_ERROR
)))
2093 .WillOnce(SetMemory(result4
.ptr
, GLuint(GL_NO_ERROR
)))
2094 .RetiresOnSaturation();
2096 // try bufsize not big enough.
2098 cmd::SetBucketSize set_bucket_size1
;
2099 cmds::GetUniformBlocksCHROMIUM get_uniform_blocks
;
2100 cmd::GetBucketStart get_bucket_start
;
2101 cmd::SetToken set_token1
;
2102 cmd::SetBucketSize set_bucket_size2
;
2105 expected
.set_bucket_size1
.Init(kBucketId
, 0);
2106 expected
.get_uniform_blocks
.Init(kProgramId
, kBucketId
);
2107 expected
.get_bucket_start
.Init(
2108 kBucketId
, result1
.id
, result1
.offset
,
2109 MaxTransferBufferSize(), mem1
.id
, mem1
.offset
);
2110 expected
.set_token1
.Init(GetNextToken());
2111 expected
.set_bucket_size2
.Init(kBucketId
, 0);
2112 gl_
->GetUniformBlocksCHROMIUM(kProgramId
, 6, &size
, &buf
);
2113 EXPECT_EQ(0, memcmp(&expected
, commands_
, sizeof(expected
)));
2114 EXPECT_EQ(static_cast<GLenum
>(GL_INVALID_OPERATION
), gl_
->GetError());
2118 gl_
->GetUniformBlocksCHROMIUM(kProgramId
, -1, &size
, &buf
);
2119 EXPECT_TRUE(NoCommandsWritten());
2120 EXPECT_EQ(static_cast<GLenum
>(GL_INVALID_VALUE
), gl_
->GetError());
2123 gl_
->GetUniformBlocksCHROMIUM(kProgramId
, sizeof(buf
), NULL
, &buf
);
2124 EXPECT_TRUE(NoCommandsWritten());
2125 EXPECT_EQ(static_cast<GLenum
>(GL_INVALID_VALUE
), gl_
->GetError());
2128 // Test that things are cached
2129 TEST_F(GLES2ImplementationTest
, GetIntegerCacheRead
) {
2134 const PNameValue pairs
[] = {
2135 {GL_ACTIVE_TEXTURE
, GL_TEXTURE0
, },
2136 {GL_TEXTURE_BINDING_2D
, 0, },
2137 {GL_TEXTURE_BINDING_CUBE_MAP
, 0, },
2138 {GL_TEXTURE_BINDING_EXTERNAL_OES
, 0, },
2139 {GL_FRAMEBUFFER_BINDING
, 0, },
2140 {GL_RENDERBUFFER_BINDING
, 0, },
2141 {GL_ARRAY_BUFFER_BINDING
, 0, },
2142 {GL_ELEMENT_ARRAY_BUFFER_BINDING
, 0, },
2143 {GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS
, kMaxCombinedTextureImageUnits
, },
2144 {GL_MAX_CUBE_MAP_TEXTURE_SIZE
, kMaxCubeMapTextureSize
, },
2145 {GL_MAX_FRAGMENT_UNIFORM_VECTORS
, kMaxFragmentUniformVectors
, },
2146 {GL_MAX_RENDERBUFFER_SIZE
, kMaxRenderbufferSize
, },
2147 {GL_MAX_TEXTURE_IMAGE_UNITS
, kMaxTextureImageUnits
, },
2148 {GL_MAX_TEXTURE_SIZE
, kMaxTextureSize
, },
2149 {GL_MAX_VARYING_VECTORS
, kMaxVaryingVectors
, },
2150 {GL_MAX_VERTEX_ATTRIBS
, kMaxVertexAttribs
, },
2151 {GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS
, kMaxVertexTextureImageUnits
, },
2152 {GL_MAX_VERTEX_UNIFORM_VECTORS
, kMaxVertexUniformVectors
, },
2153 {GL_NUM_COMPRESSED_TEXTURE_FORMATS
, kNumCompressedTextureFormats
, },
2154 {GL_NUM_SHADER_BINARY_FORMATS
, kNumShaderBinaryFormats
, }, };
2155 size_t num_pairs
= sizeof(pairs
) / sizeof(pairs
[0]);
2156 for (size_t ii
= 0; ii
< num_pairs
; ++ii
) {
2157 const PNameValue
& pv
= pairs
[ii
];
2159 gl_
->GetIntegerv(pv
.pname
, &v
);
2160 EXPECT_TRUE(NoCommandsWritten());
2161 EXPECT_EQ(pv
.expected
, v
);
2164 ExpectedMemoryInfo result1
=
2165 GetExpectedResultMemory(sizeof(cmds::GetError::Result
));
2167 EXPECT_CALL(*command_buffer(), OnFlush())
2168 .WillOnce(SetMemory(result1
.ptr
, GLuint(GL_NO_ERROR
)))
2169 .RetiresOnSaturation();
2170 EXPECT_EQ(static_cast<GLenum
>(GL_NO_ERROR
), gl_
->GetError());
2173 TEST_F(GLES2ImplementationTest
, GetIntegerCacheWrite
) {
2178 gl_
->ActiveTexture(GL_TEXTURE4
);
2179 gl_
->BindBuffer(GL_ARRAY_BUFFER
, 2);
2180 gl_
->BindBuffer(GL_ELEMENT_ARRAY_BUFFER
, 3);
2181 gl_
->BindFramebuffer(GL_FRAMEBUFFER
, 4);
2182 gl_
->BindRenderbuffer(GL_RENDERBUFFER
, 5);
2183 gl_
->BindTexture(GL_TEXTURE_2D
, 6);
2184 gl_
->BindTexture(GL_TEXTURE_CUBE_MAP
, 7);
2185 gl_
->BindTexture(GL_TEXTURE_EXTERNAL_OES
, 8);
2187 const PNameValue pairs
[] = {{GL_ACTIVE_TEXTURE
, GL_TEXTURE4
, },
2188 {GL_ARRAY_BUFFER_BINDING
, 2, },
2189 {GL_ELEMENT_ARRAY_BUFFER_BINDING
, 3, },
2190 {GL_FRAMEBUFFER_BINDING
, 4, },
2191 {GL_RENDERBUFFER_BINDING
, 5, },
2192 {GL_TEXTURE_BINDING_2D
, 6, },
2193 {GL_TEXTURE_BINDING_CUBE_MAP
, 7, },
2194 {GL_TEXTURE_BINDING_EXTERNAL_OES
, 8, }, };
2195 size_t num_pairs
= sizeof(pairs
) / sizeof(pairs
[0]);
2196 for (size_t ii
= 0; ii
< num_pairs
; ++ii
) {
2197 const PNameValue
& pv
= pairs
[ii
];
2199 gl_
->GetIntegerv(pv
.pname
, &v
);
2200 EXPECT_EQ(pv
.expected
, v
);
2203 ExpectedMemoryInfo result1
=
2204 GetExpectedResultMemory(sizeof(cmds::GetError::Result
));
2206 EXPECT_CALL(*command_buffer(), OnFlush())
2207 .WillOnce(SetMemory(result1
.ptr
, GLuint(GL_NO_ERROR
)))
2208 .RetiresOnSaturation();
2209 EXPECT_EQ(static_cast<GLenum
>(GL_NO_ERROR
), gl_
->GetError());
2212 static bool CheckRect(
2213 int width
, int height
, GLenum format
, GLenum type
, int alignment
,
2214 bool flip_y
, const uint8
* r1
, const uint8
* r2
) {
2216 uint32 unpadded_row_size
= 0;
2217 uint32 padded_row_size
= 0;
2218 if (!GLES2Util::ComputeImageDataSizes(
2219 width
, height
, 1, format
, type
, alignment
, &size
, &unpadded_row_size
,
2220 &padded_row_size
)) {
2224 int r2_stride
= flip_y
?
2225 -static_cast<int>(padded_row_size
) :
2226 static_cast<int>(padded_row_size
);
2227 r2
= flip_y
? (r2
+ (height
- 1) * padded_row_size
) : r2
;
2229 for (int y
= 0; y
< height
; ++y
) {
2230 if (memcmp(r1
, r2
, unpadded_row_size
) != 0) {
2233 r1
+= padded_row_size
;
2239 ACTION_P8(CheckRectAction
, width
, height
, format
, type
, alignment
, flip_y
,
2241 EXPECT_TRUE(CheckRect(
2242 width
, height
, format
, type
, alignment
, flip_y
, r1
, r2
));
2245 // Test TexImage2D with and without flip_y
2246 TEST_F(GLES2ImplementationTest
, TexImage2D
) {
2248 cmds::TexImage2D tex_image_2d
;
2249 cmd::SetToken set_token
;
2252 cmds::TexImage2D tex_image_2d
;
2253 cmd::SetToken set_token
;
2255 const GLenum kTarget
= GL_TEXTURE_2D
;
2256 const GLint kLevel
= 0;
2257 const GLenum kFormat
= GL_RGB
;
2258 const GLsizei kWidth
= 3;
2259 const GLsizei kHeight
= 4;
2260 const GLint kBorder
= 0;
2261 const GLenum kType
= GL_UNSIGNED_BYTE
;
2262 const GLint kPixelStoreUnpackAlignment
= 4;
2263 static uint8 pixels
[] = {
2264 11, 12, 13, 13, 14, 15, 15, 16, 17, 101, 102, 103,
2265 21, 22, 23, 23, 24, 25, 25, 26, 27, 201, 202, 203,
2266 31, 32, 33, 33, 34, 35, 35, 36, 37, 123, 124, 125,
2267 41, 42, 43, 43, 44, 45, 45, 46, 47,
2270 ExpectedMemoryInfo mem1
= GetExpectedMemory(sizeof(pixels
));
2273 expected
.tex_image_2d
.Init(
2274 kTarget
, kLevel
, kFormat
, kWidth
, kHeight
, kFormat
, kType
,
2275 mem1
.id
, mem1
.offset
);
2276 expected
.set_token
.Init(GetNextToken());
2278 kTarget
, kLevel
, kFormat
, kWidth
, kHeight
, kBorder
, kFormat
, kType
,
2280 EXPECT_EQ(0, memcmp(&expected
, commands_
, sizeof(expected
)));
2281 EXPECT_TRUE(CheckRect(
2282 kWidth
, kHeight
, kFormat
, kType
, kPixelStoreUnpackAlignment
, false,
2286 gl_
->PixelStorei(GL_UNPACK_FLIP_Y_CHROMIUM
, GL_TRUE
);
2288 ExpectedMemoryInfo mem2
= GetExpectedMemory(sizeof(pixels
));
2290 expected2
.tex_image_2d
.Init(
2291 kTarget
, kLevel
, kFormat
, kWidth
, kHeight
, kFormat
, kType
,
2292 mem2
.id
, mem2
.offset
);
2293 expected2
.set_token
.Init(GetNextToken());
2294 const void* commands2
= GetPut();
2296 kTarget
, kLevel
, kFormat
, kWidth
, kHeight
, kBorder
, kFormat
, kType
,
2298 EXPECT_EQ(0, memcmp(&expected2
, commands2
, sizeof(expected2
)));
2299 EXPECT_TRUE(CheckRect(
2300 kWidth
, kHeight
, kFormat
, kType
, kPixelStoreUnpackAlignment
, true,
2304 // Test TexImage2D with 2 writes
2305 TEST_F(GLES2ImplementationTest
, TexImage2D2Writes
) {
2307 cmds::TexImage2D tex_image_2d
;
2308 cmds::TexSubImage2D tex_sub_image_2d1
;
2309 cmd::SetToken set_token1
;
2310 cmds::TexSubImage2D tex_sub_image_2d2
;
2311 cmd::SetToken set_token2
;
2313 const GLenum kTarget
= GL_TEXTURE_2D
;
2314 const GLint kLevel
= 0;
2315 const GLenum kFormat
= GL_RGB
;
2316 const GLint kBorder
= 0;
2317 const GLenum kType
= GL_UNSIGNED_BYTE
;
2318 const GLint kPixelStoreUnpackAlignment
= 4;
2319 const GLsizei kWidth
= 3;
2322 uint32 unpadded_row_size
= 0;
2323 uint32 padded_row_size
= 0;
2324 ASSERT_TRUE(GLES2Util::ComputeImageDataSizes(
2325 kWidth
, 2, 1, kFormat
, kType
, kPixelStoreUnpackAlignment
,
2326 &size
, &unpadded_row_size
, &padded_row_size
));
2327 const GLsizei kHeight
= (MaxTransferBufferSize() / padded_row_size
) * 2;
2328 ASSERT_TRUE(GLES2Util::ComputeImageDataSizes(
2329 kWidth
, kHeight
, 1, kFormat
, kType
, kPixelStoreUnpackAlignment
,
2330 &size
, NULL
, NULL
));
2331 uint32 half_size
= 0;
2332 ASSERT_TRUE(GLES2Util::ComputeImageDataSizes(
2333 kWidth
, kHeight
/ 2, 1, kFormat
, kType
, kPixelStoreUnpackAlignment
,
2334 &half_size
, NULL
, NULL
));
2336 scoped_ptr
<uint8
[]> pixels(new uint8
[size
]);
2337 for (uint32 ii
= 0; ii
< size
; ++ii
) {
2338 pixels
[ii
] = static_cast<uint8
>(ii
);
2341 ExpectedMemoryInfo mem1
= GetExpectedMemory(half_size
);
2342 ExpectedMemoryInfo mem2
= GetExpectedMemory(half_size
);
2345 expected
.tex_image_2d
.Init(
2346 kTarget
, kLevel
, kFormat
, kWidth
, kHeight
, kFormat
, kType
,
2348 expected
.tex_sub_image_2d1
.Init(
2349 kTarget
, kLevel
, 0, 0, kWidth
, kHeight
/ 2, kFormat
, kType
,
2350 mem1
.id
, mem1
.offset
, true);
2351 expected
.set_token1
.Init(GetNextToken());
2352 expected
.tex_sub_image_2d2
.Init(
2353 kTarget
, kLevel
, 0, kHeight
/ 2, kWidth
, kHeight
/ 2, kFormat
, kType
,
2354 mem2
.id
, mem2
.offset
, true);
2355 expected
.set_token2
.Init(GetNextToken());
2357 // TODO(gman): Make it possible to run this test
2358 // EXPECT_CALL(*command_buffer(), OnFlush())
2359 // .WillOnce(CheckRectAction(
2360 // kWidth, kHeight / 2, kFormat, kType, kPixelStoreUnpackAlignment,
2361 // false, pixels.get(),
2362 // GetExpectedTransferAddressFromOffsetAs<uint8>(offset1, half_size)))
2363 // .RetiresOnSaturation();
2366 kTarget
, kLevel
, kFormat
, kWidth
, kHeight
, kBorder
, kFormat
, kType
,
2368 EXPECT_EQ(0, memcmp(&expected
, commands_
, sizeof(expected
)));
2369 EXPECT_TRUE(CheckRect(
2370 kWidth
, kHeight
/ 2, kFormat
, kType
, kPixelStoreUnpackAlignment
, false,
2371 pixels
.get() + kHeight
/ 2 * padded_row_size
, mem2
.ptr
));
2374 gl_
->PixelStorei(GL_UNPACK_FLIP_Y_CHROMIUM
, GL_TRUE
);
2375 const void* commands2
= GetPut();
2376 ExpectedMemoryInfo mem3
= GetExpectedMemory(half_size
);
2377 ExpectedMemoryInfo mem4
= GetExpectedMemory(half_size
);
2378 expected
.tex_image_2d
.Init(
2379 kTarget
, kLevel
, kFormat
, kWidth
, kHeight
, kFormat
, kType
,
2381 expected
.tex_sub_image_2d1
.Init(
2382 kTarget
, kLevel
, 0, kHeight
/ 2, kWidth
, kHeight
/ 2, kFormat
, kType
,
2383 mem3
.id
, mem3
.offset
, true);
2384 expected
.set_token1
.Init(GetNextToken());
2385 expected
.tex_sub_image_2d2
.Init(
2386 kTarget
, kLevel
, 0, 0, kWidth
, kHeight
/ 2, kFormat
, kType
,
2387 mem4
.id
, mem4
.offset
, true);
2388 expected
.set_token2
.Init(GetNextToken());
2390 // TODO(gman): Make it possible to run this test
2391 // EXPECT_CALL(*command_buffer(), OnFlush())
2392 // .WillOnce(CheckRectAction(
2393 // kWidth, kHeight / 2, kFormat, kType, kPixelStoreUnpackAlignment,
2394 // true, pixels.get(),
2395 // GetExpectedTransferAddressFromOffsetAs<uint8>(offset3, half_size)))
2396 // .RetiresOnSaturation();
2399 kTarget
, kLevel
, kFormat
, kWidth
, kHeight
, kBorder
, kFormat
, kType
,
2401 EXPECT_EQ(0, memcmp(&expected
, commands2
, sizeof(expected
)));
2402 EXPECT_TRUE(CheckRect(
2403 kWidth
, kHeight
/ 2, kFormat
, kType
, kPixelStoreUnpackAlignment
, true,
2404 pixels
.get() + kHeight
/ 2 * padded_row_size
, mem4
.ptr
));
2407 // Test TexSubImage2D with GL_PACK_FLIP_Y set and partial multirow transfers
2408 TEST_F(GLES2ImplementationTest
, TexSubImage2DFlipY
) {
2409 const GLsizei kTextureWidth
= MaxTransferBufferSize() / 4;
2410 const GLsizei kTextureHeight
= 7;
2411 const GLsizei kSubImageWidth
= MaxTransferBufferSize() / 8;
2412 const GLsizei kSubImageHeight
= 4;
2413 const GLint kSubImageXOffset
= 1;
2414 const GLint kSubImageYOffset
= 2;
2415 const GLenum kFormat
= GL_RGBA
;
2416 const GLenum kType
= GL_UNSIGNED_BYTE
;
2417 const GLenum kTarget
= GL_TEXTURE_2D
;
2418 const GLint kLevel
= 0;
2419 const GLint kBorder
= 0;
2420 const GLint kPixelStoreUnpackAlignment
= 4;
2423 cmds::PixelStorei pixel_store_i1
;
2424 cmds::TexImage2D tex_image_2d
;
2425 cmds::PixelStorei pixel_store_i2
;
2426 cmds::TexSubImage2D tex_sub_image_2d1
;
2427 cmd::SetToken set_token1
;
2428 cmds::TexSubImage2D tex_sub_image_2d2
;
2429 cmd::SetToken set_token2
;
2432 uint32 sub_2_high_size
= 0;
2433 ASSERT_TRUE(GLES2Util::ComputeImageDataSizes(
2434 kSubImageWidth
, 2, 1, kFormat
, kType
, kPixelStoreUnpackAlignment
,
2435 &sub_2_high_size
, NULL
, NULL
));
2437 ExpectedMemoryInfo mem1
= GetExpectedMemory(sub_2_high_size
);
2438 ExpectedMemoryInfo mem2
= GetExpectedMemory(sub_2_high_size
);
2441 expected
.pixel_store_i1
.Init(GL_UNPACK_ALIGNMENT
, kPixelStoreUnpackAlignment
);
2442 expected
.tex_image_2d
.Init(
2443 kTarget
, kLevel
, kFormat
, kTextureWidth
, kTextureHeight
, kFormat
,
2445 expected
.pixel_store_i2
.Init(GL_UNPACK_FLIP_Y_CHROMIUM
, GL_TRUE
);
2446 expected
.tex_sub_image_2d1
.Init(kTarget
, kLevel
, kSubImageXOffset
,
2447 kSubImageYOffset
+ 2, kSubImageWidth
, 2, kFormat
, kType
,
2448 mem1
.id
, mem1
.offset
, false);
2449 expected
.set_token1
.Init(GetNextToken());
2450 expected
.tex_sub_image_2d2
.Init(kTarget
, kLevel
, kSubImageXOffset
,
2451 kSubImageYOffset
, kSubImageWidth
, 2, kFormat
, kType
,
2452 mem2
.id
, mem2
.offset
, false);
2453 expected
.set_token2
.Init(GetNextToken());
2455 gl_
->PixelStorei(GL_UNPACK_ALIGNMENT
, kPixelStoreUnpackAlignment
);
2457 kTarget
, kLevel
, kFormat
, kTextureWidth
, kTextureHeight
, kBorder
, kFormat
,
2459 gl_
->PixelStorei(GL_UNPACK_FLIP_Y_CHROMIUM
, GL_TRUE
);
2460 scoped_ptr
<uint32
[]> pixels(new uint32
[kSubImageWidth
* kSubImageHeight
]);
2461 for (int y
= 0; y
< kSubImageHeight
; ++y
) {
2462 for (int x
= 0; x
< kSubImageWidth
; ++x
) {
2463 pixels
.get()[kSubImageWidth
* y
+ x
] = x
| (y
<< 16);
2467 GL_TEXTURE_2D
, 0, kSubImageXOffset
, kSubImageYOffset
, kSubImageWidth
,
2468 kSubImageHeight
, GL_RGBA
, GL_UNSIGNED_BYTE
, pixels
.get());
2470 EXPECT_EQ(0, memcmp(&expected
, commands_
, sizeof(expected
)));
2471 EXPECT_TRUE(CheckRect(
2472 kSubImageWidth
, 2, kFormat
, kType
, kPixelStoreUnpackAlignment
, true,
2473 reinterpret_cast<uint8
*>(pixels
.get() + 2 * kSubImageWidth
),
2477 TEST_F(GLES2ImplementationTest
, SubImageUnpack
) {
2478 static const GLint unpack_alignments
[] = { 1, 2, 4, 8 };
2480 static const GLenum kFormat
= GL_RGB
;
2481 static const GLenum kType
= GL_UNSIGNED_BYTE
;
2482 static const GLint kLevel
= 0;
2483 static const GLint kBorder
= 0;
2484 // We're testing using the unpack params to pull a subimage out of a larger
2485 // source of pixels. Here we specify the subimage by its border rows /
2487 static const GLint kSrcWidth
= 33;
2488 static const GLint kSrcSubImageX0
= 11;
2489 static const GLint kSrcSubImageX1
= 20;
2490 static const GLint kSrcSubImageY0
= 18;
2491 static const GLint kSrcSubImageY1
= 23;
2492 static const GLint kSrcSubImageWidth
= kSrcSubImageX1
- kSrcSubImageX0
;
2493 static const GLint kSrcSubImageHeight
= kSrcSubImageY1
- kSrcSubImageY0
;
2495 // these are only used in the texsubimage tests
2496 static const GLint kTexWidth
= 1023;
2497 static const GLint kTexHeight
= 511;
2498 static const GLint kTexSubXOffset
= 419;
2499 static const GLint kTexSubYOffset
= 103;
2502 cmds::PixelStorei pixel_store_i
;
2503 cmds::PixelStorei pixel_store_i2
;
2504 cmds::TexImage2D tex_image_2d
;
2508 cmds::PixelStorei pixel_store_i
;
2509 cmds::PixelStorei pixel_store_i2
;
2510 cmds::TexImage2D tex_image_2d
;
2511 cmds::TexSubImage2D tex_sub_image_2d
;
2512 } texSubImageExpected
;
2515 ASSERT_TRUE(GLES2Util::ComputeImageDataSizes(
2516 kSrcWidth
, kSrcSubImageY1
, 1, kFormat
, kType
, 8, &src_size
, NULL
, NULL
));
2517 scoped_ptr
<uint8
[]> src_pixels
;
2518 src_pixels
.reset(new uint8
[src_size
]);
2519 for (size_t i
= 0; i
< src_size
; ++i
) {
2520 src_pixels
[i
] = static_cast<int8
>(i
);
2523 for (int sub
= 0; sub
< 2; ++sub
) {
2524 for (int flip_y
= 0; flip_y
< 2; ++flip_y
) {
2525 for (size_t a
= 0; a
< arraysize(unpack_alignments
); ++a
) {
2526 GLint alignment
= unpack_alignments
[a
];
2528 uint32 unpadded_row_size
;
2529 uint32 padded_row_size
;
2530 ASSERT_TRUE(GLES2Util::ComputeImageDataSizes(
2531 kSrcSubImageWidth
, kSrcSubImageHeight
, 1, kFormat
, kType
, alignment
,
2532 &size
, &unpadded_row_size
, &padded_row_size
));
2533 ASSERT_TRUE(size
<= MaxTransferBufferSize());
2534 ExpectedMemoryInfo mem
= GetExpectedMemory(size
);
2536 const void* commands
= GetPut();
2537 gl_
->PixelStorei(GL_UNPACK_ALIGNMENT
, alignment
);
2538 gl_
->PixelStorei(GL_UNPACK_ROW_LENGTH_EXT
, kSrcWidth
);
2539 gl_
->PixelStorei(GL_UNPACK_SKIP_PIXELS_EXT
, kSrcSubImageX0
);
2540 gl_
->PixelStorei(GL_UNPACK_SKIP_ROWS_EXT
, kSrcSubImageY0
);
2541 gl_
->PixelStorei(GL_UNPACK_FLIP_Y_CHROMIUM
, flip_y
);
2544 GL_TEXTURE_2D
, kLevel
, kFormat
, kTexWidth
, kTexHeight
, kBorder
,
2545 kFormat
, kType
, NULL
);
2547 GL_TEXTURE_2D
, kLevel
, kTexSubXOffset
, kTexSubYOffset
,
2548 kSrcSubImageWidth
, kSrcSubImageHeight
, kFormat
, kType
,
2550 texSubImageExpected
.pixel_store_i
.Init(
2551 GL_UNPACK_ALIGNMENT
, alignment
);
2552 texSubImageExpected
.pixel_store_i2
.Init(
2553 GL_UNPACK_FLIP_Y_CHROMIUM
, flip_y
);
2554 texSubImageExpected
.tex_image_2d
.Init(
2555 GL_TEXTURE_2D
, kLevel
, kFormat
, kTexWidth
, kTexHeight
,
2556 kFormat
, kType
, 0, 0);
2557 texSubImageExpected
.tex_sub_image_2d
.Init(
2558 GL_TEXTURE_2D
, kLevel
, kTexSubXOffset
, kTexSubYOffset
,
2559 kSrcSubImageWidth
, kSrcSubImageHeight
, kFormat
, kType
, mem
.id
,
2560 mem
.offset
, GL_FALSE
);
2561 EXPECT_EQ(0, memcmp(
2562 &texSubImageExpected
, commands
, sizeof(texSubImageExpected
)));
2565 GL_TEXTURE_2D
, kLevel
, kFormat
,
2566 kSrcSubImageWidth
, kSrcSubImageHeight
, kBorder
, kFormat
, kType
,
2568 texImageExpected
.pixel_store_i
.Init(GL_UNPACK_ALIGNMENT
, alignment
);
2569 texImageExpected
.pixel_store_i2
.Init(
2570 GL_UNPACK_FLIP_Y_CHROMIUM
, flip_y
);
2571 texImageExpected
.tex_image_2d
.Init(
2572 GL_TEXTURE_2D
, kLevel
, kFormat
, kSrcSubImageWidth
,
2573 kSrcSubImageHeight
, kFormat
, kType
, mem
.id
, mem
.offset
);
2574 EXPECT_EQ(0, memcmp(
2575 &texImageExpected
, commands
, sizeof(texImageExpected
)));
2577 uint32 src_padded_row_size
;
2578 ASSERT_TRUE(GLES2Util::ComputeImagePaddedRowSize(
2579 kSrcWidth
, kFormat
, kType
, alignment
, &src_padded_row_size
));
2580 uint32 bytes_per_group
= GLES2Util::ComputeImageGroupSize(
2582 for (int y
= 0; y
< kSrcSubImageHeight
; ++y
) {
2583 GLint src_sub_y
= flip_y
? kSrcSubImageHeight
- y
- 1 : y
;
2584 const uint8
* src_row
= src_pixels
.get() +
2585 (kSrcSubImageY0
+ src_sub_y
) * src_padded_row_size
+
2586 bytes_per_group
* kSrcSubImageX0
;
2587 const uint8
* dst_row
= mem
.ptr
+ y
* padded_row_size
;
2588 EXPECT_EQ(0, memcmp(src_row
, dst_row
, unpadded_row_size
));
2596 // Test texture related calls with invalid arguments.
2597 TEST_F(GLES2ImplementationTest
, TextureInvalidArguments
) {
2599 cmds::TexImage2D tex_image_2d
;
2600 cmd::SetToken set_token
;
2602 const GLenum kTarget
= GL_TEXTURE_2D
;
2603 const GLint kLevel
= 0;
2604 const GLenum kFormat
= GL_RGB
;
2605 const GLsizei kWidth
= 3;
2606 const GLsizei kHeight
= 4;
2607 const GLint kBorder
= 0;
2608 const GLint kInvalidBorder
= 1;
2609 const GLenum kType
= GL_UNSIGNED_BYTE
;
2610 const GLint kPixelStoreUnpackAlignment
= 4;
2611 static uint8 pixels
[] = {
2612 11, 12, 13, 13, 14, 15, 15, 16, 17, 101, 102, 103,
2613 21, 22, 23, 23, 24, 25, 25, 26, 27, 201, 202, 203,
2614 31, 32, 33, 33, 34, 35, 35, 36, 37, 123, 124, 125,
2615 41, 42, 43, 43, 44, 45, 45, 46, 47,
2618 // Verify that something works.
2620 ExpectedMemoryInfo mem1
= GetExpectedMemory(sizeof(pixels
));
2623 expected
.tex_image_2d
.Init(
2624 kTarget
, kLevel
, kFormat
, kWidth
, kHeight
, kFormat
, kType
,
2625 mem1
.id
, mem1
.offset
);
2626 expected
.set_token
.Init(GetNextToken());
2628 kTarget
, kLevel
, kFormat
, kWidth
, kHeight
, kBorder
, kFormat
, kType
,
2630 EXPECT_EQ(0, memcmp(&expected
, commands_
, sizeof(expected
)));
2631 EXPECT_TRUE(CheckRect(
2632 kWidth
, kHeight
, kFormat
, kType
, kPixelStoreUnpackAlignment
, false,
2637 // Use invalid border.
2639 kTarget
, kLevel
, kFormat
, kWidth
, kHeight
, kInvalidBorder
, kFormat
, kType
,
2642 EXPECT_TRUE(NoCommandsWritten());
2643 EXPECT_EQ(GL_INVALID_VALUE
, CheckError());
2647 gl_
->AsyncTexImage2DCHROMIUM(
2648 kTarget
, kLevel
, kFormat
, kWidth
, kHeight
, kInvalidBorder
, kFormat
, kType
,
2651 EXPECT_TRUE(NoCommandsWritten());
2652 EXPECT_EQ(GL_INVALID_VALUE
, CheckError());
2656 // Checking for CompressedTexImage2D argument validation is a bit tricky due
2657 // to (runtime-detected) compression formats. Try to infer the error with an
2659 const GLenum kCompressedFormat
= GL_ETC1_RGB8_OES
;
2660 gl_
->CompressedTexImage2D(
2661 kTarget
, kLevel
, kCompressedFormat
, kWidth
, kHeight
, kBorder
,
2662 arraysize(pixels
), pixels
);
2664 // In the above, kCompressedFormat and arraysize(pixels) are possibly wrong
2665 // values. First ensure that these do not cause failures at the client. If
2666 // this check ever fails, it probably means that client checks more than at
2667 // the time of writing of this test. In this case, more code needs to be
2668 // written for this test.
2669 EXPECT_FALSE(NoCommandsWritten());
2673 // Changing border to invalid border should make the call fail at the client
2675 gl_
->CompressedTexImage2D(
2676 kTarget
, kLevel
, kCompressedFormat
, kWidth
, kHeight
, kInvalidBorder
,
2677 arraysize(pixels
), pixels
);
2678 EXPECT_TRUE(NoCommandsWritten());
2679 EXPECT_EQ(GL_INVALID_VALUE
, CheckError());
2682 TEST_F(GLES2ImplementationTest
, TexImage3DSingleCommand
) {
2684 cmds::TexImage3D tex_image_3d
;
2686 const GLenum kTarget
= GL_TEXTURE_3D
;
2687 const GLint kLevel
= 0;
2688 const GLint kBorder
= 0;
2689 const GLenum kFormat
= GL_RGB
;
2690 const GLenum kType
= GL_UNSIGNED_BYTE
;
2691 const GLint kPixelStoreUnpackAlignment
= 4;
2692 const GLsizei kWidth
= 3;
2693 const GLsizei kDepth
= 2;
2696 uint32 unpadded_row_size
= 0;
2697 uint32 padded_row_size
= 0;
2698 ASSERT_TRUE(GLES2Util::ComputeImageDataSizes(
2699 kWidth
, 2, kDepth
, kFormat
, kType
, kPixelStoreUnpackAlignment
,
2700 &size
, &unpadded_row_size
, &padded_row_size
));
2701 // Makes sure we can just send over the data in one command.
2702 const GLsizei kHeight
= MaxTransferBufferSize() / padded_row_size
/ kDepth
;
2703 ASSERT_TRUE(GLES2Util::ComputeImageDataSizes(
2704 kWidth
, kHeight
, kDepth
, kFormat
, kType
, kPixelStoreUnpackAlignment
,
2705 &size
, NULL
, NULL
));
2707 scoped_ptr
<uint8
[]> pixels(new uint8
[size
]);
2708 for (uint32 ii
= 0; ii
< size
; ++ii
) {
2709 pixels
[ii
] = static_cast<uint8
>(ii
);
2712 ExpectedMemoryInfo mem
= GetExpectedMemory(size
);
2715 expected
.tex_image_3d
.Init(
2716 kTarget
, kLevel
, kFormat
, kWidth
, kHeight
, kDepth
,
2717 kFormat
, kType
, mem
.id
, mem
.offset
);
2720 kTarget
, kLevel
, kFormat
, kWidth
, kHeight
, kDepth
, kBorder
,
2721 kFormat
, kType
, pixels
.get());
2723 EXPECT_EQ(0, memcmp(&expected
, commands_
, sizeof(expected
)));
2724 EXPECT_TRUE(CheckRect(
2725 kWidth
, kHeight
* kDepth
, kFormat
, kType
, kPixelStoreUnpackAlignment
,
2726 false, reinterpret_cast<uint8
*>(pixels
.get()), mem
.ptr
));
2729 TEST_F(GLES2ImplementationTest
, TexImage3DViaTexSubImage3D
) {
2731 cmds::TexImage3D tex_image_3d
;
2732 cmds::TexSubImage3D tex_sub_image_3d1
;
2733 cmd::SetToken set_token
;
2734 cmds::TexSubImage3D tex_sub_image_3d2
;
2736 const GLenum kTarget
= GL_TEXTURE_3D
;
2737 const GLint kLevel
= 0;
2738 const GLint kBorder
= 0;
2739 const GLenum kFormat
= GL_RGB
;
2740 const GLenum kType
= GL_UNSIGNED_BYTE
;
2741 const GLint kPixelStoreUnpackAlignment
= 4;
2742 const GLsizei kWidth
= 3;
2745 uint32 unpadded_row_size
= 0;
2746 uint32 padded_row_size
= 0;
2747 ASSERT_TRUE(GLES2Util::ComputeImageDataSizes(
2748 kWidth
, 2, 1, kFormat
, kType
, kPixelStoreUnpackAlignment
,
2749 &size
, &unpadded_row_size
, &padded_row_size
));
2750 // Makes sure the data is more than one command can hold.
2751 const GLsizei kHeight
= MaxTransferBufferSize() / padded_row_size
+ 3;
2752 ASSERT_TRUE(GLES2Util::ComputeImageDataSizes(
2753 kWidth
, kHeight
, 1, kFormat
, kType
, kPixelStoreUnpackAlignment
,
2754 &size
, NULL
, NULL
));
2755 uint32 first_size
= padded_row_size
* (kHeight
- 3);
2756 uint32 second_size
=
2757 padded_row_size
* 3 - (padded_row_size
- unpadded_row_size
);
2758 EXPECT_EQ(size
, first_size
+ second_size
);
2759 ExpectedMemoryInfo mem1
= GetExpectedMemory(first_size
);
2760 ExpectedMemoryInfo mem2
= GetExpectedMemory(second_size
);
2761 scoped_ptr
<uint8
[]> pixels(new uint8
[size
]);
2762 for (uint32 ii
= 0; ii
< size
; ++ii
) {
2763 pixels
[ii
] = static_cast<uint8
>(ii
);
2767 expected
.tex_image_3d
.Init(
2768 kTarget
, kLevel
, kFormat
, kWidth
, kHeight
, 1, kFormat
, kType
, 0, 0);
2769 expected
.tex_sub_image_3d1
.Init(
2770 kTarget
, kLevel
, 0, 0, 0, kWidth
, kHeight
- 3, 1, kFormat
, kType
,
2771 mem1
.id
, mem1
.offset
, GL_TRUE
);
2772 expected
.tex_sub_image_3d2
.Init(
2773 kTarget
, kLevel
, 0, kHeight
- 3, 0, kWidth
, 3, 1, kFormat
, kType
,
2774 mem2
.id
, mem2
.offset
, GL_TRUE
);
2775 expected
.set_token
.Init(GetNextToken());
2778 kTarget
, kLevel
, kFormat
, kWidth
, kHeight
, 1, kBorder
,
2779 kFormat
, kType
, pixels
.get());
2780 EXPECT_EQ(0, memcmp(&expected
, commands_
, sizeof(expected
)));
2783 // Test TexSubImage3D with 4 writes
2784 TEST_F(GLES2ImplementationTest
, TexSubImage3D4Writes
) {
2786 cmds::TexSubImage3D tex_sub_image_3d1_1
;
2787 cmd::SetToken set_token1
;
2788 cmds::TexSubImage3D tex_sub_image_3d1_2
;
2789 cmd::SetToken set_token2
;
2790 cmds::TexSubImage3D tex_sub_image_3d2_1
;
2791 cmd::SetToken set_token3
;
2792 cmds::TexSubImage3D tex_sub_image_3d2_2
;
2794 const GLenum kTarget
= GL_TEXTURE_3D
;
2795 const GLint kLevel
= 0;
2796 const GLint kXOffset
= 0;
2797 const GLint kYOffset
= 0;
2798 const GLint kZOffset
= 0;
2799 const GLenum kFormat
= GL_RGB
;
2800 const GLenum kType
= GL_UNSIGNED_BYTE
;
2801 const GLint kPixelStoreUnpackAlignment
= 4;
2802 const GLsizei kWidth
= 3;
2803 const GLsizei kDepth
= 2;
2806 uint32 unpadded_row_size
= 0;
2807 uint32 padded_row_size
= 0;
2808 ASSERT_TRUE(GLES2Util::ComputeImageDataSizes(
2809 kWidth
, 2, 1, kFormat
, kType
, kPixelStoreUnpackAlignment
,
2810 &size
, &unpadded_row_size
, &padded_row_size
));
2811 const GLsizei kHeight
= MaxTransferBufferSize() / padded_row_size
+ 2;
2812 ASSERT_TRUE(GLES2Util::ComputeImageDataSizes(
2813 kWidth
, kHeight
, kDepth
, kFormat
, kType
, kPixelStoreUnpackAlignment
,
2814 &size
, NULL
, NULL
));
2815 uint32 first_size
= (kHeight
- 2) * padded_row_size
;
2816 uint32 second_size
= 2 * padded_row_size
;
2817 uint32 third_size
= first_size
;
2818 uint32 fourth_size
= second_size
- (padded_row_size
- unpadded_row_size
);
2819 EXPECT_EQ(size
, first_size
+ second_size
+ third_size
+ fourth_size
);
2821 scoped_ptr
<uint8
[]> pixels(new uint8
[size
]);
2822 for (uint32 ii
= 0; ii
< size
; ++ii
) {
2823 pixels
[ii
] = static_cast<uint8
>(ii
);
2826 ExpectedMemoryInfo mem1_1
= GetExpectedMemory(first_size
);
2827 ExpectedMemoryInfo mem1_2
= GetExpectedMemory(second_size
);
2828 ExpectedMemoryInfo mem2_1
= GetExpectedMemory(third_size
);
2829 ExpectedMemoryInfo mem2_2
= GetExpectedMemory(fourth_size
);
2832 expected
.tex_sub_image_3d1_1
.Init(
2833 kTarget
, kLevel
, kXOffset
, kYOffset
, kZOffset
,
2834 kWidth
, kHeight
- 2, 1, kFormat
, kType
,
2835 mem1_1
.id
, mem1_1
.offset
, GL_FALSE
);
2836 expected
.tex_sub_image_3d1_2
.Init(
2837 kTarget
, kLevel
, kXOffset
, kYOffset
+ kHeight
- 2, kZOffset
,
2838 kWidth
, 2, 1, kFormat
, kType
, mem1_2
.id
, mem1_2
.offset
, GL_FALSE
);
2839 expected
.tex_sub_image_3d2_1
.Init(
2840 kTarget
, kLevel
, kXOffset
, kYOffset
, kZOffset
+ 1,
2841 kWidth
, kHeight
- 2, 1, kFormat
, kType
,
2842 mem2_1
.id
, mem2_1
.offset
, GL_FALSE
);
2843 expected
.tex_sub_image_3d2_2
.Init(
2844 kTarget
, kLevel
, kXOffset
, kYOffset
+ kHeight
- 2, kZOffset
+ 1,
2845 kWidth
, 2, 1, kFormat
, kType
, mem2_2
.id
, mem2_2
.offset
, GL_FALSE
);
2846 expected
.set_token1
.Init(GetNextToken());
2847 expected
.set_token2
.Init(GetNextToken());
2848 expected
.set_token3
.Init(GetNextToken());
2851 kTarget
, kLevel
, kXOffset
, kYOffset
, kZOffset
, kWidth
, kHeight
, kDepth
,
2852 kFormat
, kType
, pixels
.get());
2854 EXPECT_EQ(0, memcmp(&expected
, commands_
, sizeof(expected
)));
2855 uint32 offset_to_last
= first_size
+ second_size
+ third_size
;
2856 EXPECT_TRUE(CheckRect(
2857 kWidth
, 2, kFormat
, kType
, kPixelStoreUnpackAlignment
, false,
2858 reinterpret_cast<uint8
*>(pixels
.get()) + offset_to_last
, mem2_2
.ptr
));
2861 // Binds can not be cached with bind_generates_resource = false because
2862 // our id might not be valid. More specifically if you bind on contextA then
2863 // delete on contextB the resource is still bound on contextA but GetInterger
2864 // won't return an id.
2865 TEST_F(GLES2ImplementationStrictSharedTest
, BindsNotCached
) {
2870 const PNameValue pairs
[] = {{GL_TEXTURE_BINDING_2D
, 1, },
2871 {GL_TEXTURE_BINDING_CUBE_MAP
, 2, },
2872 {GL_TEXTURE_BINDING_EXTERNAL_OES
, 3, },
2873 {GL_FRAMEBUFFER_BINDING
, 4, },
2874 {GL_RENDERBUFFER_BINDING
, 5, },
2875 {GL_ARRAY_BUFFER_BINDING
, 6, },
2876 {GL_ELEMENT_ARRAY_BUFFER_BINDING
, 7, }, };
2877 size_t num_pairs
= sizeof(pairs
) / sizeof(pairs
[0]);
2878 for (size_t ii
= 0; ii
< num_pairs
; ++ii
) {
2879 const PNameValue
& pv
= pairs
[ii
];
2881 ExpectedMemoryInfo result1
=
2882 GetExpectedResultMemory(sizeof(cmds::GetIntegerv::Result
));
2883 EXPECT_CALL(*command_buffer(), OnFlush())
2884 .WillOnce(SetMemory(result1
.ptr
,
2885 SizedResultHelper
<GLuint
>(pv
.expected
)))
2886 .RetiresOnSaturation();
2887 gl_
->GetIntegerv(pv
.pname
, &v
);
2888 EXPECT_EQ(pv
.expected
, v
);
2892 // glGen* Ids must not be reused until glDelete* commands have been
2893 // flushed by glFlush.
2894 TEST_F(GLES2ImplementationStrictSharedTest
, FlushGenerationTestBuffers
) {
2895 FlushGenerationTest
<GenBuffersAPI
>();
2897 TEST_F(GLES2ImplementationStrictSharedTest
, FlushGenerationTestFramebuffers
) {
2898 FlushGenerationTest
<GenFramebuffersAPI
>();
2900 TEST_F(GLES2ImplementationStrictSharedTest
, FlushGenerationTestRenderbuffers
) {
2901 FlushGenerationTest
<GenRenderbuffersAPI
>();
2903 TEST_F(GLES2ImplementationStrictSharedTest
, FlushGenerationTestTextures
) {
2904 FlushGenerationTest
<GenTexturesAPI
>();
2907 // glGen* Ids must not be reused cross-context until glDelete* commands are
2908 // flushed by glFlush, and the Ids are lazily freed after.
2909 TEST_F(GLES2ImplementationStrictSharedTest
, CrossContextGenerationTestBuffers
) {
2910 CrossContextGenerationTest
<GenBuffersAPI
>();
2912 TEST_F(GLES2ImplementationStrictSharedTest
,
2913 CrossContextGenerationTestFramebuffers
) {
2914 CrossContextGenerationTest
<GenFramebuffersAPI
>();
2916 TEST_F(GLES2ImplementationStrictSharedTest
,
2917 CrossContextGenerationTestRenderbuffers
) {
2918 CrossContextGenerationTest
<GenRenderbuffersAPI
>();
2920 TEST_F(GLES2ImplementationStrictSharedTest
,
2921 CrossContextGenerationTestTextures
) {
2922 CrossContextGenerationTest
<GenTexturesAPI
>();
2925 // Test Delete which causes auto flush. Tests a regression case that occurred
2927 TEST_F(GLES2ImplementationStrictSharedTest
,
2928 CrossContextGenerationAutoFlushTestBuffers
) {
2929 CrossContextGenerationAutoFlushTest
<GenBuffersAPI
>();
2931 TEST_F(GLES2ImplementationStrictSharedTest
,
2932 CrossContextGenerationAutoFlushTestFramebuffers
) {
2933 CrossContextGenerationAutoFlushTest
<GenFramebuffersAPI
>();
2935 TEST_F(GLES2ImplementationStrictSharedTest
,
2936 CrossContextGenerationAutoFlushTestRenderbuffers
) {
2937 CrossContextGenerationAutoFlushTest
<GenRenderbuffersAPI
>();
2939 TEST_F(GLES2ImplementationStrictSharedTest
,
2940 CrossContextGenerationAutoFlushTestTextures
) {
2941 CrossContextGenerationAutoFlushTest
<GenTexturesAPI
>();
2944 TEST_F(GLES2ImplementationTest
, GetString
) {
2945 const uint32 kBucketId
= GLES2Implementation::kResultBucketId
;
2946 const Str7 kString
= {"foobar"};
2947 // GL_CHROMIUM_map_sub GL_CHROMIUM_flipy are hard coded into
2948 // GLES2Implementation.
2949 const char* expected_str
=
2951 "GL_CHROMIUM_flipy "
2952 "GL_EXT_unpack_subimage "
2953 "GL_CHROMIUM_map_sub";
2954 const char kBad
= 0x12;
2956 cmd::SetBucketSize set_bucket_size1
;
2957 cmds::GetString get_string
;
2958 cmd::GetBucketStart get_bucket_start
;
2959 cmd::SetToken set_token1
;
2960 cmd::SetBucketSize set_bucket_size2
;
2962 ExpectedMemoryInfo mem1
= GetExpectedMemory(MaxTransferBufferSize());
2963 ExpectedMemoryInfo result1
=
2964 GetExpectedResultMemory(sizeof(cmd::GetBucketStart::Result
));
2966 expected
.set_bucket_size1
.Init(kBucketId
, 0);
2967 expected
.get_string
.Init(GL_EXTENSIONS
, kBucketId
);
2968 expected
.get_bucket_start
.Init(
2969 kBucketId
, result1
.id
, result1
.offset
,
2970 MaxTransferBufferSize(), mem1
.id
, mem1
.offset
);
2971 expected
.set_token1
.Init(GetNextToken());
2972 expected
.set_bucket_size2
.Init(kBucketId
, 0);
2973 char buf
[sizeof(kString
) + 1];
2974 memset(buf
, kBad
, sizeof(buf
));
2976 EXPECT_CALL(*command_buffer(), OnFlush())
2977 .WillOnce(DoAll(SetMemory(result1
.ptr
, uint32(sizeof(kString
))),
2978 SetMemory(mem1
.ptr
, kString
)))
2979 .RetiresOnSaturation();
2981 const GLubyte
* result
= gl_
->GetString(GL_EXTENSIONS
);
2982 EXPECT_EQ(0, memcmp(&expected
, commands_
, sizeof(expected
)));
2983 EXPECT_STREQ(expected_str
, reinterpret_cast<const char*>(result
));
2986 TEST_F(GLES2ImplementationTest
, PixelStoreiGLPackReverseRowOrderANGLE
) {
2987 const uint32 kBucketId
= GLES2Implementation::kResultBucketId
;
2988 const Str7 kString
= {"foobar"};
2990 cmd::SetBucketSize set_bucket_size1
;
2991 cmds::GetString get_string
;
2992 cmd::GetBucketStart get_bucket_start
;
2993 cmd::SetToken set_token1
;
2994 cmd::SetBucketSize set_bucket_size2
;
2995 cmds::PixelStorei pixel_store
;
2998 ExpectedMemoryInfo mem1
= GetExpectedMemory(MaxTransferBufferSize());
2999 ExpectedMemoryInfo result1
=
3000 GetExpectedResultMemory(sizeof(cmd::GetBucketStart::Result
));
3003 expected
.set_bucket_size1
.Init(kBucketId
, 0);
3004 expected
.get_string
.Init(GL_EXTENSIONS
, kBucketId
);
3005 expected
.get_bucket_start
.Init(
3006 kBucketId
, result1
.id
, result1
.offset
,
3007 MaxTransferBufferSize(), mem1
.id
, mem1
.offset
);
3008 expected
.set_token1
.Init(GetNextToken());
3009 expected
.set_bucket_size2
.Init(kBucketId
, 0);
3010 expected
.pixel_store
.Init(GL_PACK_REVERSE_ROW_ORDER_ANGLE
, 1);
3012 EXPECT_CALL(*command_buffer(), OnFlush())
3013 .WillOnce(DoAll(SetMemory(result1
.ptr
, uint32(sizeof(kString
))),
3014 SetMemory(mem1
.ptr
, kString
)))
3015 .RetiresOnSaturation();
3017 gl_
->PixelStorei(GL_PACK_REVERSE_ROW_ORDER_ANGLE
, 1);
3018 EXPECT_EQ(0, memcmp(&expected
, commands_
, sizeof(expected
)));
3021 TEST_F(GLES2ImplementationTest
, CreateProgram
) {
3023 cmds::CreateProgram cmd
;
3027 expected
.cmd
.Init(kProgramsAndShadersStartId
);
3028 GLuint id
= gl_
->CreateProgram();
3029 EXPECT_EQ(0, memcmp(&expected
, commands_
, sizeof(expected
)));
3030 EXPECT_EQ(kProgramsAndShadersStartId
, id
);
3033 TEST_F(GLES2ImplementationTest
, BufferDataLargerThanTransferBuffer
) {
3035 cmds::BufferData set_size
;
3036 cmds::BufferSubData copy_data1
;
3037 cmd::SetToken set_token1
;
3038 cmds::BufferSubData copy_data2
;
3039 cmd::SetToken set_token2
;
3041 const unsigned kUsableSize
=
3042 kTransferBufferSize
- GLES2Implementation::kStartingOffset
;
3043 uint8 buf
[kUsableSize
* 2] = { 0, };
3045 ExpectedMemoryInfo mem1
= GetExpectedMemory(kUsableSize
);
3046 ExpectedMemoryInfo mem2
= GetExpectedMemory(kUsableSize
);
3049 expected
.set_size
.Init(
3050 GL_ARRAY_BUFFER
, arraysize(buf
), 0, 0, GL_DYNAMIC_DRAW
);
3051 expected
.copy_data1
.Init(
3052 GL_ARRAY_BUFFER
, 0, kUsableSize
, mem1
.id
, mem1
.offset
);
3053 expected
.set_token1
.Init(GetNextToken());
3054 expected
.copy_data2
.Init(
3055 GL_ARRAY_BUFFER
, kUsableSize
, kUsableSize
, mem2
.id
, mem2
.offset
);
3056 expected
.set_token2
.Init(GetNextToken());
3057 gl_
->BufferData(GL_ARRAY_BUFFER
, arraysize(buf
), buf
, GL_DYNAMIC_DRAW
);
3058 EXPECT_EQ(0, memcmp(&expected
, commands_
, sizeof(expected
)));
3061 TEST_F(GLES2ImplementationTest
, CapabilitiesAreCached
) {
3062 static const GLenum kStates
[] = {
3067 GL_POLYGON_OFFSET_FILL
,
3068 GL_SAMPLE_ALPHA_TO_COVERAGE
,
3074 cmds::Enable enable_cmd
;
3078 for (size_t ii
= 0; ii
< arraysize(kStates
); ++ii
) {
3079 GLenum state
= kStates
[ii
];
3080 expected
.enable_cmd
.Init(state
);
3081 GLboolean result
= gl_
->IsEnabled(state
);
3082 EXPECT_EQ(static_cast<GLboolean
>(ii
== 0), result
);
3083 EXPECT_TRUE(NoCommandsWritten());
3084 const void* commands
= GetPut();
3087 EXPECT_EQ(0, memcmp(&expected
, commands
, sizeof(expected
)));
3090 result
= gl_
->IsEnabled(state
);
3091 EXPECT_TRUE(result
);
3092 EXPECT_TRUE(NoCommandsWritten());
3096 TEST_F(GLES2ImplementationTest
, BindVertexArrayOES
) {
3098 gl_
->GenVertexArraysOES(1, &id
);
3102 cmds::BindVertexArrayOES cmd
;
3105 expected
.cmd
.Init(id
);
3107 const void* commands
= GetPut();
3108 gl_
->BindVertexArrayOES(id
);
3109 EXPECT_EQ(0, memcmp(&expected
, commands
, sizeof(expected
)));
3111 gl_
->BindVertexArrayOES(id
);
3112 EXPECT_TRUE(NoCommandsWritten());
3115 TEST_F(GLES2ImplementationTest
, BeginEndQueryEXT
) {
3116 // Test GetQueryivEXT returns 0 if no current query.
3118 gl_
->GetQueryivEXT(GL_ANY_SAMPLES_PASSED_EXT
, GL_CURRENT_QUERY_EXT
, ¶m
);
3119 EXPECT_EQ(0, param
);
3121 GLuint expected_ids
[2] = { 1, 2 }; // These must match what's actually genned.
3123 cmds::GenQueriesEXTImmediate gen
;
3126 GenCmds expected_gen_cmds
;
3127 expected_gen_cmds
.gen
.Init(arraysize(expected_ids
), &expected_ids
[0]);
3128 GLuint ids
[arraysize(expected_ids
)] = { 0, };
3129 gl_
->GenQueriesEXT(arraysize(expected_ids
), &ids
[0]);
3130 EXPECT_EQ(0, memcmp(
3131 &expected_gen_cmds
, commands_
, sizeof(expected_gen_cmds
)));
3132 GLuint id1
= ids
[0];
3133 GLuint id2
= ids
[1];
3136 // Test BeginQueryEXT fails if id = 0.
3137 gl_
->BeginQueryEXT(GL_ANY_SAMPLES_PASSED_EXT
, 0);
3138 EXPECT_TRUE(NoCommandsWritten());
3139 EXPECT_EQ(GL_INVALID_OPERATION
, CheckError());
3141 // Test BeginQueryEXT inserts command.
3143 cmds::BeginQueryEXT begin_query
;
3145 BeginCmds expected_begin_cmds
;
3146 const void* commands
= GetPut();
3147 gl_
->BeginQueryEXT(GL_ANY_SAMPLES_PASSED_EXT
, id1
);
3148 QueryTracker::Query
* query
= GetQuery(id1
);
3149 ASSERT_TRUE(query
!= NULL
);
3150 expected_begin_cmds
.begin_query
.Init(
3151 GL_ANY_SAMPLES_PASSED_EXT
, id1
, query
->shm_id(), query
->shm_offset());
3152 EXPECT_EQ(0, memcmp(
3153 &expected_begin_cmds
, commands
, sizeof(expected_begin_cmds
)));
3156 // Test GetQueryivEXT returns id.
3158 gl_
->GetQueryivEXT(GL_ANY_SAMPLES_PASSED_EXT
, GL_CURRENT_QUERY_EXT
, ¶m
);
3159 EXPECT_EQ(id1
, static_cast<GLuint
>(param
));
3161 GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT
, GL_CURRENT_QUERY_EXT
, ¶m
);
3162 EXPECT_EQ(0, param
);
3164 // Test BeginQueryEXT fails if between Begin/End.
3165 gl_
->BeginQueryEXT(GL_ANY_SAMPLES_PASSED_EXT
, id2
);
3166 EXPECT_TRUE(NoCommandsWritten());
3167 EXPECT_EQ(GL_INVALID_OPERATION
, CheckError());
3169 // Test EndQueryEXT fails if target not same as current query.
3171 gl_
->EndQueryEXT(GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT
);
3172 EXPECT_TRUE(NoCommandsWritten());
3173 EXPECT_EQ(GL_INVALID_OPERATION
, CheckError());
3175 // Test EndQueryEXT sends command
3177 cmds::EndQueryEXT end_query
;
3179 EndCmds expected_end_cmds
;
3180 expected_end_cmds
.end_query
.Init(
3181 GL_ANY_SAMPLES_PASSED_EXT
, query
->submit_count());
3182 commands
= GetPut();
3183 gl_
->EndQueryEXT(GL_ANY_SAMPLES_PASSED_EXT
);
3184 EXPECT_EQ(0, memcmp(
3185 &expected_end_cmds
, commands
, sizeof(expected_end_cmds
)));
3187 // Test EndQueryEXT fails if no current query.
3189 gl_
->EndQueryEXT(GL_ANY_SAMPLES_PASSED_EXT
);
3190 EXPECT_TRUE(NoCommandsWritten());
3191 EXPECT_EQ(GL_INVALID_OPERATION
, CheckError());
3193 // Test 2nd Begin/End increments count.
3194 base::subtle::Atomic32 old_submit_count
= query
->submit_count();
3195 gl_
->BeginQueryEXT(GL_ANY_SAMPLES_PASSED_EXT
, id1
);
3196 EXPECT_NE(old_submit_count
, query
->submit_count());
3197 expected_end_cmds
.end_query
.Init(
3198 GL_ANY_SAMPLES_PASSED_EXT
, query
->submit_count());
3199 commands
= GetPut();
3200 gl_
->EndQueryEXT(GL_ANY_SAMPLES_PASSED_EXT
);
3201 EXPECT_EQ(0, memcmp(
3202 &expected_end_cmds
, commands
, sizeof(expected_end_cmds
)));
3204 // Test BeginQueryEXT fails if target changed.
3206 gl_
->BeginQueryEXT(GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT
, id1
);
3207 EXPECT_TRUE(NoCommandsWritten());
3208 EXPECT_EQ(GL_INVALID_OPERATION
, CheckError());
3210 // Test GetQueryObjectuivEXT fails if unused id
3211 GLuint available
= 0xBDu
;
3213 gl_
->GetQueryObjectuivEXT(id2
, GL_QUERY_RESULT_AVAILABLE_EXT
, &available
);
3214 EXPECT_TRUE(NoCommandsWritten());
3215 EXPECT_EQ(0xBDu
, available
);
3216 EXPECT_EQ(GL_INVALID_OPERATION
, CheckError());
3218 // Test GetQueryObjectuivEXT fails if bad id
3220 gl_
->GetQueryObjectuivEXT(4567, GL_QUERY_RESULT_AVAILABLE_EXT
, &available
);
3221 EXPECT_TRUE(NoCommandsWritten());
3222 EXPECT_EQ(0xBDu
, available
);
3223 EXPECT_EQ(GL_INVALID_OPERATION
, CheckError());
3225 // Test GetQueryObjectuivEXT CheckResultsAvailable
3227 gl_
->GetQueryObjectuivEXT(id1
, GL_QUERY_RESULT_AVAILABLE_EXT
, &available
);
3228 EXPECT_EQ(0u, available
);
3231 TEST_F(GLES2ImplementationTest
, ErrorQuery
) {
3233 gl_
->GenQueriesEXT(1, &id
);
3236 // Test BeginQueryEXT does NOT insert commands.
3237 gl_
->BeginQueryEXT(GL_GET_ERROR_QUERY_CHROMIUM
, id
);
3238 EXPECT_TRUE(NoCommandsWritten());
3239 QueryTracker::Query
* query
= GetQuery(id
);
3240 ASSERT_TRUE(query
!= NULL
);
3242 // Test EndQueryEXT sends both begin and end command
3244 cmds::BeginQueryEXT begin_query
;
3245 cmds::EndQueryEXT end_query
;
3247 EndCmds expected_end_cmds
;
3248 expected_end_cmds
.begin_query
.Init(
3249 GL_GET_ERROR_QUERY_CHROMIUM
, id
, query
->shm_id(), query
->shm_offset());
3250 expected_end_cmds
.end_query
.Init(
3251 GL_GET_ERROR_QUERY_CHROMIUM
, query
->submit_count());
3252 const void* commands
= GetPut();
3253 gl_
->EndQueryEXT(GL_GET_ERROR_QUERY_CHROMIUM
);
3254 EXPECT_EQ(0, memcmp(
3255 &expected_end_cmds
, commands
, sizeof(expected_end_cmds
)));
3258 // Check result is not yet available.
3259 GLuint available
= 0xBDu
;
3260 gl_
->GetQueryObjectuivEXT(id
, GL_QUERY_RESULT_AVAILABLE_EXT
, &available
);
3261 EXPECT_TRUE(NoCommandsWritten());
3262 EXPECT_EQ(0u, available
);
3264 // Test no commands are sent if there is a client side error.
3266 // Generate a client side error
3267 gl_
->ActiveTexture(GL_TEXTURE0
- 1);
3269 gl_
->BeginQueryEXT(GL_GET_ERROR_QUERY_CHROMIUM
, id
);
3270 gl_
->EndQueryEXT(GL_GET_ERROR_QUERY_CHROMIUM
);
3271 EXPECT_TRUE(NoCommandsWritten());
3273 // Check result is available.
3274 gl_
->GetQueryObjectuivEXT(id
, GL_QUERY_RESULT_AVAILABLE_EXT
, &available
);
3275 EXPECT_TRUE(NoCommandsWritten());
3276 EXPECT_NE(0u, available
);
3279 GLuint result
= 0xBDu
;
3280 gl_
->GetQueryObjectuivEXT(id
, GL_QUERY_RESULT_EXT
, &result
);
3281 EXPECT_TRUE(NoCommandsWritten());
3282 EXPECT_EQ(static_cast<GLuint
>(GL_INVALID_ENUM
), result
);
3285 #if !defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS)
3286 TEST_F(GLES2ImplementationTest
, VertexArrays
) {
3287 const GLuint kAttribIndex1
= 1;
3288 const GLint kNumComponents1
= 3;
3289 const GLsizei kClientStride
= 12;
3292 gl_
->GenVertexArraysOES(1, &id
);
3295 gl_
->BindVertexArrayOES(id
);
3297 // Test that VertexAttribPointer cannot be called with a bound buffer of 0
3298 // unless the offset is NULL
3299 gl_
->BindBuffer(GL_ARRAY_BUFFER
, 0);
3301 gl_
->VertexAttribPointer(
3302 kAttribIndex1
, kNumComponents1
, GL_FLOAT
, GL_FALSE
, kClientStride
,
3303 reinterpret_cast<const void*>(4));
3304 EXPECT_EQ(GL_INVALID_OPERATION
, CheckError());
3306 gl_
->VertexAttribPointer(
3307 kAttribIndex1
, kNumComponents1
, GL_FLOAT
, GL_FALSE
, kClientStride
, NULL
);
3308 EXPECT_EQ(GL_NO_ERROR
, CheckError());
3312 TEST_F(GLES2ImplementationTest
, Disable
) {
3317 expected
.cmd
.Init(GL_DITHER
); // Note: DITHER defaults to enabled.
3319 gl_
->Disable(GL_DITHER
);
3320 EXPECT_EQ(0, memcmp(&expected
, commands_
, sizeof(expected
)));
3321 // Check it's cached and not called again.
3323 gl_
->Disable(GL_DITHER
);
3324 EXPECT_TRUE(NoCommandsWritten());
3327 TEST_F(GLES2ImplementationTest
, Enable
) {
3332 expected
.cmd
.Init(GL_BLEND
); // Note: BLEND defaults to disabled.
3334 gl_
->Enable(GL_BLEND
);
3335 EXPECT_EQ(0, memcmp(&expected
, commands_
, sizeof(expected
)));
3336 // Check it's cached and not called again.
3338 gl_
->Enable(GL_BLEND
);
3339 EXPECT_TRUE(NoCommandsWritten());
3342 TEST_F(GLES2ImplementationTest
, ConsumeTextureCHROMIUM
) {
3344 cmds::ConsumeTextureCHROMIUMImmediate cmd
;
3348 Mailbox mailbox
= Mailbox::Generate();
3350 expected
.cmd
.Init(GL_TEXTURE_2D
, mailbox
.name
);
3351 gl_
->ConsumeTextureCHROMIUM(GL_TEXTURE_2D
, mailbox
.name
);
3352 EXPECT_EQ(0, memcmp(&expected
, commands_
, sizeof(expected
)));
3355 TEST_F(GLES2ImplementationTest
, CreateAndConsumeTextureCHROMIUM
) {
3357 cmds::CreateAndConsumeTextureCHROMIUMImmediate cmd
;
3361 Mailbox mailbox
= Mailbox::Generate();
3363 expected
.cmd
.Init(GL_TEXTURE_2D
, kTexturesStartId
, mailbox
.name
);
3364 GLuint id
= gl_
->CreateAndConsumeTextureCHROMIUM(GL_TEXTURE_2D
, mailbox
.name
);
3365 EXPECT_EQ(0, memcmp(&expected
, commands_
, sizeof(expected
)));
3366 EXPECT_EQ(kTexturesStartId
, id
);
3369 TEST_F(GLES2ImplementationTest
, ProduceTextureCHROMIUM
) {
3371 cmds::ProduceTextureCHROMIUMImmediate cmd
;
3375 Mailbox mailbox
= Mailbox::Generate();
3377 expected
.cmd
.Init(GL_TEXTURE_2D
, mailbox
.name
);
3378 gl_
->ProduceTextureCHROMIUM(GL_TEXTURE_2D
, mailbox
.name
);
3379 EXPECT_EQ(0, memcmp(&expected
, commands_
, sizeof(expected
)));
3382 TEST_F(GLES2ImplementationTest
, ProduceTextureDirectCHROMIUM
) {
3384 cmds::ProduceTextureDirectCHROMIUMImmediate cmd
;
3388 Mailbox mailbox
= Mailbox::Generate();
3390 expected
.cmd
.Init(kTexturesStartId
, GL_TEXTURE_2D
, mailbox
.name
);
3391 gl_
->ProduceTextureDirectCHROMIUM(
3392 kTexturesStartId
, GL_TEXTURE_2D
, mailbox
.name
);
3393 EXPECT_EQ(0, memcmp(&expected
, commands_
, sizeof(expected
)));
3396 TEST_F(GLES2ImplementationTest
, LimitSizeAndOffsetTo32Bit
) {
3399 if (sizeof(size
) <= 4 || sizeof(offset
) <= 4)
3401 // The below two casts should be no-op, as we return early if
3402 // it's 32-bit system.
3403 int64 value64
= 0x100000000;
3404 size
= static_cast<GLsizeiptr
>(value64
);
3405 offset
= static_cast<GLintptr
>(value64
);
3407 const char kSizeOverflowMessage
[] = "size more than 32-bit";
3408 const char kOffsetOverflowMessage
[] = "offset more than 32-bit";
3410 const GLfloat buf
[] = { 1.0, 1.0, 1.0, 1.0 };
3411 const GLubyte indices
[] = { 0 };
3413 const GLuint kClientArrayBufferId
= 0x789;
3414 const GLuint kClientElementArrayBufferId
= 0x790;
3415 gl_
->BindBuffer(GL_ARRAY_BUFFER
, kClientArrayBufferId
);
3416 gl_
->BindBuffer(GL_ELEMENT_ARRAY_BUFFER
, kClientElementArrayBufferId
);
3417 EXPECT_EQ(GL_NO_ERROR
, CheckError());
3419 // Call BufferData() should succeed with legal paramaters.
3420 gl_
->BufferData(GL_ARRAY_BUFFER
, sizeof(buf
), buf
, GL_DYNAMIC_DRAW
);
3422 GL_ELEMENT_ARRAY_BUFFER
, sizeof(indices
), indices
, GL_DYNAMIC_DRAW
);
3423 EXPECT_EQ(GL_NO_ERROR
, CheckError());
3426 gl_
->BufferData(GL_ARRAY_BUFFER
, size
, buf
, GL_DYNAMIC_DRAW
);
3427 EXPECT_EQ(GL_INVALID_OPERATION
, CheckError());
3428 EXPECT_STREQ(kSizeOverflowMessage
, GetLastError().c_str());
3430 // Call BufferSubData() should succeed with legal paramaters.
3431 gl_
->BufferSubData(GL_ARRAY_BUFFER
, 0, sizeof(buf
[0]), buf
);
3432 EXPECT_EQ(GL_NO_ERROR
, CheckError());
3434 // BufferSubData: offset
3435 gl_
->BufferSubData(GL_ARRAY_BUFFER
, offset
, 1, buf
);
3436 EXPECT_EQ(GL_INVALID_OPERATION
, CheckError());
3437 EXPECT_STREQ(kOffsetOverflowMessage
, GetLastError().c_str());
3439 // BufferSubData: size
3440 EXPECT_EQ(GL_NO_ERROR
, CheckError());
3441 gl_
->BufferSubData(GL_ARRAY_BUFFER
, 0, size
, buf
);
3442 EXPECT_EQ(GL_INVALID_OPERATION
, CheckError());
3443 EXPECT_STREQ(kSizeOverflowMessage
, GetLastError().c_str());
3445 // Call MapBufferSubDataCHROMIUM() should succeed with legal paramaters.
3447 gl_
->MapBufferSubDataCHROMIUM(GL_ARRAY_BUFFER
, 0, 1, GL_WRITE_ONLY
);
3448 EXPECT_TRUE(NULL
!= mem
);
3449 EXPECT_EQ(GL_NO_ERROR
, CheckError());
3450 gl_
->UnmapBufferSubDataCHROMIUM(mem
);
3452 // MapBufferSubDataCHROMIUM: offset
3453 EXPECT_TRUE(NULL
== gl_
->MapBufferSubDataCHROMIUM(
3454 GL_ARRAY_BUFFER
, offset
, 1, GL_WRITE_ONLY
));
3455 EXPECT_EQ(GL_INVALID_OPERATION
, CheckError());
3456 EXPECT_STREQ(kOffsetOverflowMessage
, GetLastError().c_str());
3458 // MapBufferSubDataCHROMIUM: size
3459 EXPECT_EQ(GL_NO_ERROR
, CheckError());
3460 EXPECT_TRUE(NULL
== gl_
->MapBufferSubDataCHROMIUM(
3461 GL_ARRAY_BUFFER
, 0, size
, GL_WRITE_ONLY
));
3462 EXPECT_EQ(GL_INVALID_OPERATION
, CheckError());
3463 EXPECT_STREQ(kSizeOverflowMessage
, GetLastError().c_str());
3465 // Call DrawElements() should succeed with legal paramaters.
3466 gl_
->DrawElements(GL_POINTS
, 1, GL_UNSIGNED_BYTE
, NULL
);
3467 EXPECT_EQ(GL_NO_ERROR
, CheckError());
3469 // DrawElements: offset
3471 GL_POINTS
, 1, GL_UNSIGNED_BYTE
, reinterpret_cast<void*>(offset
));
3472 EXPECT_EQ(GL_INVALID_OPERATION
, CheckError());
3473 EXPECT_STREQ(kOffsetOverflowMessage
, GetLastError().c_str());
3475 // Call DrawElementsInstancedANGLE() should succeed with legal paramaters.
3476 gl_
->DrawElementsInstancedANGLE(GL_POINTS
, 1, GL_UNSIGNED_BYTE
, NULL
, 1);
3477 EXPECT_EQ(GL_NO_ERROR
, CheckError());
3479 // DrawElementsInstancedANGLE: offset
3480 gl_
->DrawElementsInstancedANGLE(
3481 GL_POINTS
, 1, GL_UNSIGNED_BYTE
, reinterpret_cast<void*>(offset
), 1);
3482 EXPECT_EQ(GL_INVALID_OPERATION
, CheckError());
3483 EXPECT_STREQ(kOffsetOverflowMessage
, GetLastError().c_str());
3485 // Call VertexAttribPointer() should succeed with legal paramaters.
3486 const GLuint kAttribIndex
= 1;
3487 const GLsizei kStride
= 4;
3488 gl_
->VertexAttribPointer(
3489 kAttribIndex
, 1, GL_FLOAT
, GL_FALSE
, kStride
, NULL
);
3490 EXPECT_EQ(GL_NO_ERROR
, CheckError());
3492 // VertexAttribPointer: offset
3493 gl_
->VertexAttribPointer(
3494 kAttribIndex
, 1, GL_FLOAT
, GL_FALSE
, kStride
,
3495 reinterpret_cast<void*>(offset
));
3496 EXPECT_EQ(GL_INVALID_OPERATION
, CheckError());
3497 EXPECT_STREQ(kOffsetOverflowMessage
, GetLastError().c_str());
3500 TEST_F(GLES2ImplementationTest
, TraceBeginCHROMIUM
) {
3501 const uint32 kCategoryBucketId
= GLES2Implementation::kResultBucketId
;
3502 const uint32 kNameBucketId
= GLES2Implementation::kResultBucketId
+ 1;
3503 const std::string category_name
= "test category";
3504 const std::string trace_name
= "test trace";
3505 const size_t kPaddedString1Size
=
3506 transfer_buffer_
->RoundToAlignment(category_name
.size() + 1);
3507 const size_t kPaddedString2Size
=
3508 transfer_buffer_
->RoundToAlignment(trace_name
.size() + 1);
3510 gl_
->TraceBeginCHROMIUM(category_name
.c_str(), trace_name
.c_str());
3511 EXPECT_EQ(GL_NO_ERROR
, CheckError());
3514 cmd::SetBucketSize category_size1
;
3515 cmd::SetBucketData category_data
;
3516 cmd::SetToken set_token1
;
3517 cmd::SetBucketSize name_size1
;
3518 cmd::SetBucketData name_data
;
3519 cmd::SetToken set_token2
;
3520 cmds::TraceBeginCHROMIUM trace_call_begin
;
3521 cmd::SetBucketSize category_size2
;
3522 cmd::SetBucketSize name_size2
;
3525 ExpectedMemoryInfo mem1
= GetExpectedMemory(kPaddedString1Size
);
3526 ExpectedMemoryInfo mem2
= GetExpectedMemory(kPaddedString2Size
);
3528 ASSERT_STREQ(category_name
.c_str(), reinterpret_cast<char*>(mem1
.ptr
));
3529 ASSERT_STREQ(trace_name
.c_str(), reinterpret_cast<char*>(mem2
.ptr
));
3532 expected
.category_size1
.Init(kCategoryBucketId
, category_name
.size() + 1);
3533 expected
.category_data
.Init(
3534 kCategoryBucketId
, 0, category_name
.size() + 1, mem1
.id
, mem1
.offset
);
3535 expected
.set_token1
.Init(GetNextToken());
3536 expected
.name_size1
.Init(kNameBucketId
, trace_name
.size() + 1);
3537 expected
.name_data
.Init(
3538 kNameBucketId
, 0, trace_name
.size() + 1, mem2
.id
, mem2
.offset
);
3539 expected
.set_token2
.Init(GetNextToken());
3540 expected
.trace_call_begin
.Init(kCategoryBucketId
, kNameBucketId
);
3541 expected
.category_size2
.Init(kCategoryBucketId
, 0);
3542 expected
.name_size2
.Init(kNameBucketId
, 0);
3544 EXPECT_EQ(0, memcmp(&expected
, commands_
, sizeof(expected
)));
3547 TEST_F(GLES2ImplementationTest
, AllowNestedTracesCHROMIUM
) {
3548 const std::string category1_name
= "test category 1";
3549 const std::string trace1_name
= "test trace 1";
3550 const std::string category2_name
= "test category 2";
3551 const std::string trace2_name
= "test trace 2";
3553 gl_
->TraceBeginCHROMIUM(category1_name
.c_str(), trace1_name
.c_str());
3554 EXPECT_EQ(GL_NO_ERROR
, CheckError());
3556 gl_
->TraceBeginCHROMIUM(category2_name
.c_str(), trace2_name
.c_str());
3557 EXPECT_EQ(GL_NO_ERROR
, CheckError());
3559 gl_
->TraceEndCHROMIUM();
3560 EXPECT_EQ(GL_NO_ERROR
, CheckError());
3562 gl_
->TraceEndCHROMIUM();
3563 EXPECT_EQ(GL_NO_ERROR
, CheckError());
3565 // No more corresponding begin tracer marker should error.
3566 gl_
->TraceEndCHROMIUM();
3567 EXPECT_EQ(GL_INVALID_OPERATION
, CheckError());
3570 TEST_F(GLES2ImplementationTest
, IsEnabled
) {
3571 // If we use a valid enum, its state is cached on client side, so no command
3572 // is actually generated, and this test will fail.
3573 // TODO(zmo): it seems we never need the command. Maybe remove it.
3576 cmds::IsEnabled cmd
;
3580 ExpectedMemoryInfo result1
=
3581 GetExpectedResultMemory(sizeof(cmds::IsEnabled::Result
));
3582 expected
.cmd
.Init(kCap
, result1
.id
, result1
.offset
);
3584 EXPECT_CALL(*command_buffer(), OnFlush())
3585 .WillOnce(SetMemory(result1
.ptr
, uint32_t(GL_TRUE
)))
3586 .RetiresOnSaturation();
3588 GLboolean result
= gl_
->IsEnabled(kCap
);
3589 EXPECT_EQ(0, memcmp(&expected
, commands_
, sizeof(expected
)));
3590 EXPECT_TRUE(result
);
3593 TEST_F(GLES2ImplementationTest
, ClientWaitSync
) {
3594 const GLuint client_sync_id
= 36;
3596 cmds::ClientWaitSync cmd
;
3600 ExpectedMemoryInfo result1
=
3601 GetExpectedResultMemory(sizeof(cmds::ClientWaitSync::Result
));
3602 const GLuint64 kTimeout
= 0xABCDEF0123456789;
3603 uint32_t v32_0
= 0, v32_1
= 0;
3604 GLES2Util::MapUint64ToTwoUint32(kTimeout
, &v32_0
, &v32_1
);
3605 expected
.cmd
.Init(client_sync_id
, GL_SYNC_FLUSH_COMMANDS_BIT
,
3606 v32_0
, v32_1
, result1
.id
, result1
.offset
);
3608 EXPECT_CALL(*command_buffer(), OnFlush())
3609 .WillOnce(SetMemory(result1
.ptr
, uint32_t(GL_CONDITION_SATISFIED
)))
3610 .RetiresOnSaturation();
3612 GLenum result
= gl_
->ClientWaitSync(
3613 reinterpret_cast<GLsync
>(client_sync_id
), GL_SYNC_FLUSH_COMMANDS_BIT
,
3615 EXPECT_EQ(0, memcmp(&expected
, commands_
, sizeof(expected
)));
3616 EXPECT_EQ(static_cast<GLenum
>(GL_CONDITION_SATISFIED
), result
);
3619 TEST_F(GLES2ImplementationTest
, WaitSync
) {
3620 const GLuint kClientSyncId
= 36;
3625 const GLuint64 kTimeout
= GL_TIMEOUT_IGNORED
;
3626 uint32_t v32_0
= 0, v32_1
= 0;
3627 GLES2Util::MapUint64ToTwoUint32(kTimeout
, &v32_0
, &v32_1
);
3628 expected
.cmd
.Init(kClientSyncId
, 0, v32_0
, v32_1
);
3630 gl_
->WaitSync(reinterpret_cast<GLsync
>(kClientSyncId
), 0, kTimeout
);
3631 EXPECT_EQ(0, memcmp(&expected
, commands_
, sizeof(expected
)));
3634 TEST_F(GLES2ImplementationManualInitTest
, LoseContextOnOOM
) {
3635 ContextInitOptions init_options
;
3636 init_options
.lose_context_when_out_of_memory
= true;
3637 ASSERT_TRUE(Initialize(init_options
));
3640 cmds::LoseContextCHROMIUM cmd
;
3643 GLsizei max
= std::numeric_limits
<GLsizei
>::max();
3644 EXPECT_CALL(*gpu_control_
, CreateGpuMemoryBufferImage(max
, max
, _
, _
))
3645 .WillOnce(Return(-1));
3646 gl_
->CreateGpuMemoryBufferImageCHROMIUM(max
, max
, GL_RGBA
, GL_MAP_CHROMIUM
);
3647 // The context should be lost.
3649 expected
.cmd
.Init(GL_GUILTY_CONTEXT_RESET_ARB
, GL_UNKNOWN_CONTEXT_RESET_ARB
);
3650 EXPECT_EQ(0, memcmp(&expected
, commands_
, sizeof(expected
)));
3653 TEST_F(GLES2ImplementationManualInitTest
, NoLoseContextOnOOM
) {
3654 ContextInitOptions init_options
;
3655 ASSERT_TRUE(Initialize(init_options
));
3658 cmds::LoseContextCHROMIUM cmd
;
3661 GLsizei max
= std::numeric_limits
<GLsizei
>::max();
3662 EXPECT_CALL(*gpu_control_
, CreateGpuMemoryBufferImage(max
, max
, _
, _
))
3663 .WillOnce(Return(-1));
3664 gl_
->CreateGpuMemoryBufferImageCHROMIUM(max
, max
, GL_RGBA
, GL_MAP_CHROMIUM
);
3665 // The context should not be lost.
3666 EXPECT_TRUE(NoCommandsWritten());
3669 TEST_F(GLES2ImplementationManualInitTest
, FailInitOnBGRMismatch1
) {
3670 ContextInitOptions init_options
;
3671 init_options
.bind_generates_resource_client
= false;
3672 init_options
.bind_generates_resource_service
= true;
3673 EXPECT_FALSE(Initialize(init_options
));
3676 TEST_F(GLES2ImplementationManualInitTest
, FailInitOnBGRMismatch2
) {
3677 ContextInitOptions init_options
;
3678 init_options
.bind_generates_resource_client
= true;
3679 init_options
.bind_generates_resource_service
= false;
3680 EXPECT_FALSE(Initialize(init_options
));
3683 TEST_F(GLES2ImplementationManualInitTest
, FailInitOnTransferBufferFail
) {
3684 ContextInitOptions init_options
;
3685 init_options
.transfer_buffer_initialize_fail
= true;
3686 EXPECT_FALSE(Initialize(init_options
));
3689 #include "gpu/command_buffer/client/gles2_implementation_unittest_autogen.h"
3691 } // namespace gles2