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
)) {
55 memcpy(result_
, &result
, sizeof(T
));
60 char result_
[sizeof(T
)];
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 DiscardBlock(void* p
) override
;
137 void FreePendingToken(void* p
, unsigned int /* token */) override
;
139 size_t MaxTransferBufferSize() {
140 return size_
- result_size_
;
143 unsigned int RoundToAlignment(unsigned int size
) {
144 return (size
+ alignment_
- 1) & ~(alignment_
- 1);
148 return expected_buffer_index_
== actual_buffer_index_
&&
149 expected_offset_
== actual_offset_
;
152 ExpectedMemoryInfo
GetExpectedMemory(size_t size
) {
153 ExpectedMemoryInfo mem
;
154 mem
.offset
= AllocateExpectedTransferBuffer(size
);
155 mem
.id
= GetExpectedTransferBufferId();
156 mem
.ptr
= static_cast<uint8
*>(
157 GetExpectedTransferAddressFromOffset(mem
.offset
, size
));
161 ExpectedMemoryInfo
GetExpectedResultMemory(size_t size
) {
162 ExpectedMemoryInfo mem
;
163 mem
.offset
= GetExpectedResultBufferOffset();
164 mem
.id
= GetExpectedResultBufferId();
165 mem
.ptr
= static_cast<uint8
*>(
166 GetExpectedTransferAddressFromOffset(mem
.offset
, size
));
171 static const int kNumBuffers
= 2;
173 uint8
* actual_buffer() const {
174 return static_cast<uint8
*>(buffers_
[actual_buffer_index_
]->memory());
177 uint8
* expected_buffer() const {
178 return static_cast<uint8
*>(buffers_
[expected_buffer_index_
]->memory());
181 uint32
AllocateExpectedTransferBuffer(size_t size
) {
182 EXPECT_LE(size
, MaxTransferBufferSize());
184 // Toggle which buffer we get each time to simulate the buffer being
186 expected_buffer_index_
= (expected_buffer_index_
+ 1) % kNumBuffers
;
188 if (expected_offset_
+ size
> size_
) {
189 expected_offset_
= result_size_
;
191 uint32 offset
= expected_offset_
;
192 expected_offset_
+= RoundToAlignment(size
);
194 // Make sure each buffer has a different offset.
195 return offset
+ expected_buffer_index_
* alignment_
;
198 void* GetExpectedTransferAddressFromOffset(uint32 offset
, size_t size
) {
199 EXPECT_GE(offset
, expected_buffer_index_
* alignment_
);
200 EXPECT_LE(offset
+ size
, size_
+ expected_buffer_index_
* alignment_
);
201 return expected_buffer() + offset
;
204 int GetExpectedResultBufferId() {
205 return buffer_ids_
[expected_buffer_index_
];
208 uint32
GetExpectedResultBufferOffset() {
209 return expected_buffer_index_
* alignment_
;
212 int GetExpectedTransferBufferId() {
213 return buffer_ids_
[expected_buffer_index_
];
216 CommandBuffer
* command_buffer_
;
220 int buffer_ids_
[kNumBuffers
];
221 scoped_refptr
<Buffer
> buffers_
[kNumBuffers
];
222 int actual_buffer_index_
;
223 int expected_buffer_index_
;
225 uint32 expected_offset_
;
226 uint32 actual_offset_
;
227 bool initialize_fail_
;
229 DISALLOW_COPY_AND_ASSIGN(MockTransferBuffer
);
232 bool MockTransferBuffer::Initialize(
233 unsigned int starting_buffer_size
,
234 unsigned int result_size
,
235 unsigned int /* min_buffer_size */,
236 unsigned int /* max_buffer_size */,
237 unsigned int alignment
,
238 unsigned int /* size_to_flush */) {
239 // Just check they match.
240 return size_
== starting_buffer_size
&&
241 result_size_
== result_size
&&
242 alignment_
== alignment
&& !initialize_fail_
;
245 int MockTransferBuffer::GetShmId() {
246 return buffer_ids_
[actual_buffer_index_
];
249 void* MockTransferBuffer::GetResultBuffer() {
250 return actual_buffer() + actual_buffer_index_
* alignment_
;
253 int MockTransferBuffer::GetResultOffset() {
254 return actual_buffer_index_
* alignment_
;
257 void MockTransferBuffer::Free() {
261 bool MockTransferBuffer::HaveBuffer() const {
265 void* MockTransferBuffer::AllocUpTo(
266 unsigned int size
, unsigned int* size_allocated
) {
267 EXPECT_TRUE(size_allocated
!= NULL
);
268 EXPECT_TRUE(last_alloc_
== NULL
);
270 // Toggle which buffer we get each time to simulate the buffer being
272 actual_buffer_index_
= (actual_buffer_index_
+ 1) % kNumBuffers
;
274 size
= std::min(static_cast<size_t>(size
), MaxTransferBufferSize());
275 if (actual_offset_
+ size
> size_
) {
276 actual_offset_
= result_size_
;
278 uint32 offset
= actual_offset_
;
279 actual_offset_
+= RoundToAlignment(size
);
280 *size_allocated
= size
;
282 // Make sure each buffer has a different offset.
283 last_alloc_
= actual_buffer() + offset
+ actual_buffer_index_
* alignment_
;
287 void* MockTransferBuffer::Alloc(unsigned int size
) {
288 EXPECT_LE(size
, MaxTransferBufferSize());
289 unsigned int temp
= 0;
290 void* p
= AllocUpTo(size
, &temp
);
291 EXPECT_EQ(temp
, size
);
295 RingBuffer::Offset
MockTransferBuffer::GetOffset(void* pointer
) const {
296 // Make sure each buffer has a different offset.
297 return static_cast<uint8
*>(pointer
) - actual_buffer();
300 void MockTransferBuffer::DiscardBlock(void* p
) {
301 EXPECT_EQ(last_alloc_
, p
);
305 void MockTransferBuffer::FreePendingToken(void* p
, unsigned int /* token */) {
306 EXPECT_EQ(last_alloc_
, p
);
310 // API wrapper for Buffers.
311 class GenBuffersAPI
{
313 static void Gen(GLES2Implementation
* gl_impl
, GLsizei n
, GLuint
* ids
) {
314 gl_impl
->GenBuffers(n
, ids
);
317 static void Delete(GLES2Implementation
* gl_impl
,
320 gl_impl
->DeleteBuffers(n
, ids
);
324 // API wrapper for Framebuffers.
325 class GenFramebuffersAPI
{
327 static void Gen(GLES2Implementation
* gl_impl
, GLsizei n
, GLuint
* ids
) {
328 gl_impl
->GenFramebuffers(n
, ids
);
331 static void Delete(GLES2Implementation
* gl_impl
,
334 gl_impl
->DeleteFramebuffers(n
, ids
);
338 // API wrapper for Renderbuffers.
339 class GenRenderbuffersAPI
{
341 static void Gen(GLES2Implementation
* gl_impl
, GLsizei n
, GLuint
* ids
) {
342 gl_impl
->GenRenderbuffers(n
, ids
);
345 static void Delete(GLES2Implementation
* gl_impl
,
348 gl_impl
->DeleteRenderbuffers(n
, ids
);
352 // API wrapper for Textures.
353 class GenTexturesAPI
{
355 static void Gen(GLES2Implementation
* gl_impl
, GLsizei n
, GLuint
* ids
) {
356 gl_impl
->GenTextures(n
, ids
);
359 static void Delete(GLES2Implementation
* gl_impl
,
362 gl_impl
->DeleteTextures(n
, ids
);
366 class GLES2ImplementationTest
: public testing::Test
{
368 static const int kNumTestContexts
= 2;
369 static const uint8 kInitialValue
= 0xBD;
370 static const int32 kNumCommandEntries
= 500;
371 static const int32 kCommandBufferSizeBytes
=
372 kNumCommandEntries
* sizeof(CommandBufferEntry
);
373 static const size_t kTransferBufferSize
= 512;
375 static const GLint kMaxCombinedTextureImageUnits
= 8;
376 static const GLint kMaxCubeMapTextureSize
= 64;
377 static const GLint kMaxFragmentUniformVectors
= 16;
378 static const GLint kMaxRenderbufferSize
= 64;
379 static const GLint kMaxTextureImageUnits
= 8;
380 static const GLint kMaxTextureSize
= 128;
381 static const GLint kMaxVaryingVectors
= 8;
382 static const GLint kMaxVertexAttribs
= 8;
383 static const GLint kMaxVertexTextureImageUnits
= 0;
384 static const GLint kMaxVertexUniformVectors
= 128;
385 static const GLint kNumCompressedTextureFormats
= 0;
386 static const GLint kNumShaderBinaryFormats
= 0;
387 static const GLuint kMaxTransformFeedbackSeparateAttribs
= 4;
388 static const GLuint kMaxUniformBufferBindings
= 36;
389 static const GLuint kStartId
= 1024;
390 static const GLuint kBuffersStartId
= 1;
391 static const GLuint kFramebuffersStartId
= 1;
392 static const GLuint kProgramsAndShadersStartId
= 1;
393 static const GLuint kRenderbuffersStartId
= 1;
394 static const GLuint kSamplersStartId
= 1;
395 static const GLuint kTexturesStartId
= 1;
396 static const GLuint kTransformFeedbacksStartId
= 1;
397 static const GLuint kQueriesStartId
= 1;
398 static const GLuint kVertexArraysStartId
= 1;
399 static const GLuint kValuebuffersStartId
= 1;
401 typedef MockTransferBuffer::ExpectedMemoryInfo ExpectedMemoryInfo
;
405 TestContext() : commands_(NULL
), token_(0) {}
407 bool Initialize(ShareGroup
* share_group
,
408 bool bind_generates_resource_client
,
409 bool bind_generates_resource_service
,
410 bool lose_context_when_out_of_memory
,
411 bool transfer_buffer_initialize_fail
) {
412 command_buffer_
.reset(new StrictMock
<MockClientCommandBuffer
>());
413 if (!command_buffer_
->Initialize())
416 transfer_buffer_
.reset(
417 new MockTransferBuffer(command_buffer_
.get(),
419 GLES2Implementation::kStartingOffset
,
420 GLES2Implementation::kAlignment
,
421 transfer_buffer_initialize_fail
));
423 helper_
.reset(new GLES2CmdHelper(command_buffer()));
424 helper_
->Initialize(kCommandBufferSizeBytes
);
426 gpu_control_
.reset(new StrictMock
<MockClientGpuControl
>());
427 Capabilities capabilities
;
428 capabilities
.VisitPrecisions(
429 [](GLenum shader
, GLenum type
,
430 Capabilities::ShaderPrecision
* precision
) {
431 precision
->min_range
= 3;
432 precision
->max_range
= 5;
433 precision
->precision
= 7;
435 capabilities
.max_combined_texture_image_units
=
436 kMaxCombinedTextureImageUnits
;
437 capabilities
.max_cube_map_texture_size
= kMaxCubeMapTextureSize
;
438 capabilities
.max_fragment_uniform_vectors
= kMaxFragmentUniformVectors
;
439 capabilities
.max_renderbuffer_size
= kMaxRenderbufferSize
;
440 capabilities
.max_texture_image_units
= kMaxTextureImageUnits
;
441 capabilities
.max_texture_size
= kMaxTextureSize
;
442 capabilities
.max_varying_vectors
= kMaxVaryingVectors
;
443 capabilities
.max_vertex_attribs
= kMaxVertexAttribs
;
444 capabilities
.max_vertex_texture_image_units
= kMaxVertexTextureImageUnits
;
445 capabilities
.max_vertex_uniform_vectors
= kMaxVertexUniformVectors
;
446 capabilities
.num_compressed_texture_formats
=
447 kNumCompressedTextureFormats
;
448 capabilities
.num_shader_binary_formats
= kNumShaderBinaryFormats
;
449 capabilities
.max_transform_feedback_separate_attribs
=
450 kMaxTransformFeedbackSeparateAttribs
;
451 capabilities
.max_uniform_buffer_bindings
= kMaxUniformBufferBindings
;
452 capabilities
.bind_generates_resource_chromium
=
453 bind_generates_resource_service
? 1 : 0;
454 EXPECT_CALL(*gpu_control_
, GetCapabilities())
455 .WillOnce(testing::Return(capabilities
));
460 const bool support_client_side_arrays
= true;
461 gl_
.reset(new GLES2Implementation(helper_
.get(),
463 transfer_buffer_
.get(),
464 bind_generates_resource_client
,
465 lose_context_when_out_of_memory
,
466 support_client_side_arrays
,
467 gpu_control_
.get()));
469 if (!gl_
->Initialize(kTransferBufferSize
,
472 GLES2Implementation::kNoLimit
))
476 helper_
->CommandBufferHelper::Finish();
477 ::testing::Mock::VerifyAndClearExpectations(gl_
.get());
479 scoped_refptr
<Buffer
> ring_buffer
= helper_
->get_ring_buffer();
480 commands_
= static_cast<CommandBufferEntry
*>(ring_buffer
->memory()) +
481 command_buffer()->GetPutOffset();
483 EXPECT_TRUE(transfer_buffer_
->InSync());
485 ::testing::Mock::VerifyAndClearExpectations(command_buffer());
490 Mock::VerifyAndClear(gl_
.get());
491 EXPECT_CALL(*command_buffer(), OnFlush()).Times(AnyNumber());
492 // For command buffer.
493 EXPECT_CALL(*command_buffer(), DestroyTransferBuffer(_
))
498 MockClientCommandBuffer
* command_buffer() const {
499 return command_buffer_
.get();
502 int GetNextToken() { return ++token_
; }
504 void ClearCommands() {
505 scoped_refptr
<Buffer
> ring_buffer
= helper_
->get_ring_buffer();
506 memset(ring_buffer
->memory(), kInitialValue
, ring_buffer
->size());
509 scoped_ptr
<MockClientCommandBuffer
> command_buffer_
;
510 scoped_ptr
<MockClientGpuControl
> gpu_control_
;
511 scoped_ptr
<GLES2CmdHelper
> helper_
;
512 scoped_ptr
<MockTransferBuffer
> transfer_buffer_
;
513 scoped_ptr
<GLES2Implementation
> gl_
;
514 CommandBufferEntry
* commands_
;
518 GLES2ImplementationTest() : commands_(NULL
) {}
520 void SetUp() override
;
521 void TearDown() override
;
523 bool NoCommandsWritten() {
524 scoped_refptr
<Buffer
> ring_buffer
= helper_
->get_ring_buffer();
525 const uint8
* cmds
= reinterpret_cast<const uint8
*>(ring_buffer
->memory());
526 const uint8
* end
= cmds
+ ring_buffer
->size();
527 for (; cmds
< end
; ++cmds
) {
528 if (*cmds
!= kInitialValue
) {
535 QueryTracker::Query
* GetQuery(GLuint id
) {
536 return gl_
->query_tracker_
->GetQuery(id
);
539 struct ContextInitOptions
{
541 : bind_generates_resource_client(true),
542 bind_generates_resource_service(true),
543 lose_context_when_out_of_memory(false),
544 transfer_buffer_initialize_fail(false) {}
546 bool bind_generates_resource_client
;
547 bool bind_generates_resource_service
;
548 bool lose_context_when_out_of_memory
;
549 bool transfer_buffer_initialize_fail
;
552 bool Initialize(const ContextInitOptions
& init_options
) {
554 share_group_
= new ShareGroup(init_options
.bind_generates_resource_client
);
556 for (int i
= 0; i
< kNumTestContexts
; i
++) {
557 if (!test_contexts_
[i
].Initialize(
559 init_options
.bind_generates_resource_client
,
560 init_options
.bind_generates_resource_service
,
561 init_options
.lose_context_when_out_of_memory
,
562 init_options
.transfer_buffer_initialize_fail
))
566 // Default to test context 0.
567 gpu_control_
= test_contexts_
[0].gpu_control_
.get();
568 helper_
= test_contexts_
[0].helper_
.get();
569 transfer_buffer_
= test_contexts_
[0].transfer_buffer_
.get();
570 gl_
= test_contexts_
[0].gl_
.get();
571 commands_
= test_contexts_
[0].commands_
;
575 MockClientCommandBuffer
* command_buffer() const {
576 return test_contexts_
[0].command_buffer_
.get();
579 int GetNextToken() { return test_contexts_
[0].GetNextToken(); }
581 const void* GetPut() {
582 return helper_
->GetSpace(0);
585 void ClearCommands() {
586 scoped_refptr
<Buffer
> ring_buffer
= helper_
->get_ring_buffer();
587 memset(ring_buffer
->memory(), kInitialValue
, ring_buffer
->size());
590 size_t MaxTransferBufferSize() {
591 return transfer_buffer_
->MaxTransferBufferSize();
594 void SetMappedMemoryLimit(size_t limit
) {
595 gl_
->mapped_memory_
->set_max_allocated_bytes(limit
);
598 ExpectedMemoryInfo
GetExpectedMemory(size_t size
) {
599 return transfer_buffer_
->GetExpectedMemory(size
);
602 ExpectedMemoryInfo
GetExpectedResultMemory(size_t size
) {
603 return transfer_buffer_
->GetExpectedResultMemory(size
);
606 ExpectedMemoryInfo
GetExpectedMappedMemory(size_t size
) {
607 ExpectedMemoryInfo mem
;
609 // Temporarily allocate memory and expect that memory block to be reused.
610 mem
.ptr
= static_cast<uint8
*>(gl_
->mapped_memory_
->Alloc(size
,
613 gl_
->mapped_memory_
->Free(mem
.ptr
);
618 // Sets the ProgramInfoManager. The manager will be owned
619 // by the ShareGroup.
620 void SetProgramInfoManager(ProgramInfoManager
* manager
) {
621 gl_
->share_group()->set_program_info_manager(manager
);
625 ExpectedMemoryInfo result
=
626 GetExpectedResultMemory(sizeof(cmds::GetError::Result
));
627 EXPECT_CALL(*command_buffer(), OnFlush())
628 .WillOnce(SetMemory(result
.ptr
, GLuint(GL_NO_ERROR
)))
629 .RetiresOnSaturation();
630 return gl_
->GetError();
633 const std::string
& GetLastError() {
634 return gl_
->GetLastError();
637 bool GetBucketContents(uint32 bucket_id
, std::vector
<int8
>* data
) {
638 return gl_
->GetBucketContents(bucket_id
, data
);
641 TestContext test_contexts_
[kNumTestContexts
];
643 scoped_refptr
<ShareGroup
> share_group_
;
644 MockClientGpuControl
* gpu_control_
;
645 GLES2CmdHelper
* helper_
;
646 MockTransferBuffer
* transfer_buffer_
;
647 GLES2Implementation
* gl_
;
648 CommandBufferEntry
* commands_
;
651 void GLES2ImplementationTest::SetUp() {
652 ContextInitOptions init_options
;
653 ASSERT_TRUE(Initialize(init_options
));
656 void GLES2ImplementationTest::TearDown() {
657 for (int i
= 0; i
< kNumTestContexts
; i
++)
658 test_contexts_
[i
].TearDown();
661 class GLES2ImplementationManualInitTest
: public GLES2ImplementationTest
{
663 void SetUp() override
{}
666 class GLES2ImplementationStrictSharedTest
: public GLES2ImplementationTest
{
668 void SetUp() override
;
670 template <class ResApi
>
671 void FlushGenerationTest() {
672 GLuint id1
, id2
, id3
;
674 // Generate valid id.
675 ResApi::Gen(gl_
, 1, &id1
);
678 // Delete id1 and generate id2. id1 should not be reused.
679 ResApi::Delete(gl_
, 1, &id1
);
680 ResApi::Gen(gl_
, 1, &id2
);
684 // Expect id1 reuse after Flush.
686 ResApi::Gen(gl_
, 1, &id3
);
690 // Ids should not be reused unless the |Deleting| context does a Flush()
691 // AND triggers a lazy release after that.
692 template <class ResApi
>
693 void CrossContextGenerationTest() {
694 GLES2Implementation
* gl1
= test_contexts_
[0].gl_
.get();
695 GLES2Implementation
* gl2
= test_contexts_
[1].gl_
.get();
696 GLuint id1
, id2
, id3
;
698 // Delete, no flush on context 1. No reuse.
699 ResApi::Gen(gl1
, 1, &id1
);
700 ResApi::Delete(gl1
, 1, &id1
);
701 ResApi::Gen(gl1
, 1, &id2
);
704 // Flush context 2. Still no reuse.
706 ResApi::Gen(gl2
, 1, &id3
);
710 // Flush on context 1, but no lazy release. Still no reuse.
712 ResApi::Gen(gl2
, 1, &id3
);
715 // Lazy release triggered by another Delete. Should reuse id1.
716 ResApi::Delete(gl1
, 1, &id2
);
717 ResApi::Gen(gl2
, 1, &id3
);
721 // Same as CrossContextGenerationTest(), but triggers an Auto Flush on
722 // the Delete(). Tests an edge case regression.
723 template <class ResApi
>
724 void CrossContextGenerationAutoFlushTest() {
725 GLES2Implementation
* gl1
= test_contexts_
[0].gl_
.get();
726 GLES2Implementation
* gl2
= test_contexts_
[1].gl_
.get();
727 GLuint id1
, id2
, id3
;
729 // Delete, no flush on context 1. No reuse.
730 // By half filling the buffer, an internal flush is forced on the Delete().
731 ResApi::Gen(gl1
, 1, &id1
);
732 gl1
->helper()->Noop(kNumCommandEntries
/ 2);
733 ResApi::Delete(gl1
, 1, &id1
);
734 ResApi::Gen(gl1
, 1, &id2
);
737 // Flush context 2. Still no reuse.
739 ResApi::Gen(gl2
, 1, &id3
);
743 // Flush on context 1, but no lazy release. Still no reuse.
745 ResApi::Gen(gl2
, 1, &id3
);
748 // Lazy release triggered by another Delete. Should reuse id1.
749 ResApi::Delete(gl1
, 1, &id2
);
750 ResApi::Gen(gl2
, 1, &id3
);
755 void GLES2ImplementationStrictSharedTest::SetUp() {
756 ContextInitOptions init_options
;
757 init_options
.bind_generates_resource_client
= false;
758 init_options
.bind_generates_resource_service
= false;
759 ASSERT_TRUE(Initialize(init_options
));
762 // GCC requires these declarations, but MSVC requires they not be present
764 const uint8
GLES2ImplementationTest::kInitialValue
;
765 const int32
GLES2ImplementationTest::kNumCommandEntries
;
766 const int32
GLES2ImplementationTest::kCommandBufferSizeBytes
;
767 const size_t GLES2ImplementationTest::kTransferBufferSize
;
768 const GLint
GLES2ImplementationTest::kMaxCombinedTextureImageUnits
;
769 const GLint
GLES2ImplementationTest::kMaxCubeMapTextureSize
;
770 const GLint
GLES2ImplementationTest::kMaxFragmentUniformVectors
;
771 const GLint
GLES2ImplementationTest::kMaxRenderbufferSize
;
772 const GLint
GLES2ImplementationTest::kMaxTextureImageUnits
;
773 const GLint
GLES2ImplementationTest::kMaxTextureSize
;
774 const GLint
GLES2ImplementationTest::kMaxVaryingVectors
;
775 const GLint
GLES2ImplementationTest::kMaxVertexAttribs
;
776 const GLint
GLES2ImplementationTest::kMaxVertexTextureImageUnits
;
777 const GLint
GLES2ImplementationTest::kMaxVertexUniformVectors
;
778 const GLint
GLES2ImplementationTest::kNumCompressedTextureFormats
;
779 const GLint
GLES2ImplementationTest::kNumShaderBinaryFormats
;
780 const GLuint
GLES2ImplementationTest::kStartId
;
781 const GLuint
GLES2ImplementationTest::kBuffersStartId
;
782 const GLuint
GLES2ImplementationTest::kFramebuffersStartId
;
783 const GLuint
GLES2ImplementationTest::kProgramsAndShadersStartId
;
784 const GLuint
GLES2ImplementationTest::kRenderbuffersStartId
;
785 const GLuint
GLES2ImplementationTest::kSamplersStartId
;
786 const GLuint
GLES2ImplementationTest::kTexturesStartId
;
787 const GLuint
GLES2ImplementationTest::kTransformFeedbacksStartId
;
788 const GLuint
GLES2ImplementationTest::kQueriesStartId
;
789 const GLuint
GLES2ImplementationTest::kVertexArraysStartId
;
790 const GLuint
GLES2ImplementationTest::kValuebuffersStartId
;
793 TEST_F(GLES2ImplementationTest
, Basic
) {
794 EXPECT_TRUE(gl_
->share_group() != NULL
);
797 TEST_F(GLES2ImplementationTest
, GetBucketContents
) {
798 const uint32 kBucketId
= GLES2Implementation::kResultBucketId
;
799 const uint32 kTestSize
= MaxTransferBufferSize() + 32;
801 scoped_ptr
<uint8
[]> buf(new uint8
[kTestSize
]);
802 uint8
* expected_data
= buf
.get();
803 for (uint32 ii
= 0; ii
< kTestSize
; ++ii
) {
804 expected_data
[ii
] = ii
* 3;
808 cmd::GetBucketStart get_bucket_start
;
809 cmd::SetToken set_token1
;
810 cmd::GetBucketData get_bucket_data
;
811 cmd::SetToken set_token2
;
812 cmd::SetBucketSize set_bucket_size2
;
815 ExpectedMemoryInfo mem1
= GetExpectedMemory(MaxTransferBufferSize());
816 ExpectedMemoryInfo result1
= GetExpectedResultMemory(sizeof(uint32
));
817 ExpectedMemoryInfo mem2
= GetExpectedMemory(
818 kTestSize
- MaxTransferBufferSize());
821 expected
.get_bucket_start
.Init(
822 kBucketId
, result1
.id
, result1
.offset
,
823 MaxTransferBufferSize(), mem1
.id
, mem1
.offset
);
824 expected
.set_token1
.Init(GetNextToken());
825 expected
.get_bucket_data
.Init(
826 kBucketId
, MaxTransferBufferSize(),
827 kTestSize
- MaxTransferBufferSize(), mem2
.id
, mem2
.offset
);
828 expected
.set_bucket_size2
.Init(kBucketId
, 0);
829 expected
.set_token2
.Init(GetNextToken());
831 EXPECT_CALL(*command_buffer(), OnFlush())
833 SetMemory(result1
.ptr
, kTestSize
),
835 mem1
.ptr
, expected_data
, MaxTransferBufferSize())))
836 .WillOnce(SetMemoryFromArray(
837 mem2
.ptr
, expected_data
+ MaxTransferBufferSize(),
838 kTestSize
- MaxTransferBufferSize()))
839 .RetiresOnSaturation();
841 std::vector
<int8
> data
;
842 GetBucketContents(kBucketId
, &data
);
843 EXPECT_EQ(0, memcmp(&expected
, commands_
, sizeof(expected
)));
844 ASSERT_EQ(kTestSize
, data
.size());
845 EXPECT_EQ(0, memcmp(expected_data
, &data
[0], data
.size()));
848 TEST_F(GLES2ImplementationTest
, GetShaderPrecisionFormat
) {
850 cmds::GetShaderPrecisionFormat cmd
;
852 typedef cmds::GetShaderPrecisionFormat::Result Result
;
853 const unsigned kDummyType1
= 3;
854 const unsigned kDummyType2
= 4;
856 // The first call for dummy type 1 should trigger a command buffer request.
857 GLint range1
[2] = {0, 0};
858 GLint precision1
= 0;
860 ExpectedMemoryInfo client_result1
= GetExpectedResultMemory(4);
861 expected1
.cmd
.Init(GL_FRAGMENT_SHADER
, kDummyType1
, client_result1
.id
,
862 client_result1
.offset
);
863 Result server_result1
= {true, 14, 14, 10};
864 EXPECT_CALL(*command_buffer(), OnFlush())
865 .WillOnce(SetMemory(client_result1
.ptr
, server_result1
))
866 .RetiresOnSaturation();
867 gl_
->GetShaderPrecisionFormat(GL_FRAGMENT_SHADER
, kDummyType1
, range1
,
869 const void* commands2
= GetPut();
870 EXPECT_NE(commands_
, commands2
);
871 EXPECT_EQ(0, memcmp(&expected1
, commands_
, sizeof(expected1
)));
872 EXPECT_EQ(range1
[0], 14);
873 EXPECT_EQ(range1
[1], 14);
874 EXPECT_EQ(precision1
, 10);
876 // The second call for dummy type 1 should use the cached value and avoid
877 // triggering a command buffer request, so we do not expect a call to
878 // OnFlush() here. We do expect the results to be correct though.
879 GLint range2
[2] = {0, 0};
880 GLint precision2
= 0;
881 gl_
->GetShaderPrecisionFormat(GL_FRAGMENT_SHADER
, kDummyType1
, range2
,
883 const void* commands3
= GetPut();
884 EXPECT_EQ(commands2
, commands3
);
885 EXPECT_EQ(range2
[0], 14);
886 EXPECT_EQ(range2
[1], 14);
887 EXPECT_EQ(precision2
, 10);
889 // If we then make a request for dummy type 2, we should get another command
890 // buffer request since it hasn't been cached yet.
891 GLint range3
[2] = {0, 0};
892 GLint precision3
= 0;
894 ExpectedMemoryInfo result3
= GetExpectedResultMemory(4);
895 expected3
.cmd
.Init(GL_FRAGMENT_SHADER
, kDummyType2
, result3
.id
,
897 Result result3_source
= {true, 62, 62, 16};
898 EXPECT_CALL(*command_buffer(), OnFlush())
899 .WillOnce(SetMemory(result3
.ptr
, result3_source
))
900 .RetiresOnSaturation();
901 gl_
->GetShaderPrecisionFormat(GL_FRAGMENT_SHADER
, kDummyType2
, range3
,
903 const void* commands4
= GetPut();
904 EXPECT_NE(commands3
, commands4
);
905 EXPECT_EQ(0, memcmp(&expected3
, commands3
, sizeof(expected3
)));
906 EXPECT_EQ(range3
[0], 62);
907 EXPECT_EQ(range3
[1], 62);
908 EXPECT_EQ(precision3
, 16);
910 // Any call for predefined types should use the cached value from the
911 // Capabilities and avoid triggering a command buffer request, so we do not
912 // expect a call to OnFlush() here. We do expect the results to be correct
914 GLint range4
[2] = {0, 0};
915 GLint precision4
= 0;
916 gl_
->GetShaderPrecisionFormat(GL_FRAGMENT_SHADER
, GL_MEDIUM_FLOAT
, range4
,
918 const void* commands5
= GetPut();
919 EXPECT_EQ(commands4
, commands5
);
920 EXPECT_EQ(range4
[0], 3);
921 EXPECT_EQ(range4
[1], 5);
922 EXPECT_EQ(precision4
, 7);
925 TEST_F(GLES2ImplementationTest
, GetShaderSource
) {
926 const uint32 kBucketId
= GLES2Implementation::kResultBucketId
;
927 const GLuint kShaderId
= 456;
928 const Str7 kString
= {"foobar"};
929 const char kBad
= 0x12;
931 cmd::SetBucketSize set_bucket_size1
;
932 cmds::GetShaderSource get_shader_source
;
933 cmd::GetBucketStart get_bucket_start
;
934 cmd::SetToken set_token1
;
935 cmd::SetBucketSize set_bucket_size2
;
938 ExpectedMemoryInfo mem1
= GetExpectedMemory(MaxTransferBufferSize());
939 ExpectedMemoryInfo result1
= GetExpectedResultMemory(sizeof(uint32
));
942 expected
.set_bucket_size1
.Init(kBucketId
, 0);
943 expected
.get_shader_source
.Init(kShaderId
, kBucketId
);
944 expected
.get_bucket_start
.Init(
945 kBucketId
, result1
.id
, result1
.offset
,
946 MaxTransferBufferSize(), mem1
.id
, mem1
.offset
);
947 expected
.set_token1
.Init(GetNextToken());
948 expected
.set_bucket_size2
.Init(kBucketId
, 0);
949 char buf
[sizeof(kString
) + 1];
950 memset(buf
, kBad
, sizeof(buf
));
952 EXPECT_CALL(*command_buffer(), OnFlush())
953 .WillOnce(DoAll(SetMemory(result1
.ptr
, uint32(sizeof(kString
))),
954 SetMemory(mem1
.ptr
, kString
)))
955 .RetiresOnSaturation();
958 gl_
->GetShaderSource(kShaderId
, sizeof(buf
), &length
, buf
);
959 EXPECT_EQ(0, memcmp(&expected
, commands_
, sizeof(expected
)));
960 EXPECT_EQ(sizeof(kString
) - 1, static_cast<size_t>(length
));
961 EXPECT_STREQ(kString
.str
, buf
);
962 EXPECT_EQ(buf
[sizeof(kString
)], kBad
);
965 #if defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS)
967 TEST_F(GLES2ImplementationTest
, DrawArraysClientSideBuffers
) {
968 static const float verts
[][4] = {
969 { 12.0f
, 23.0f
, 34.0f
, 45.0f
, },
970 { 56.0f
, 67.0f
, 78.0f
, 89.0f
, },
971 { 13.0f
, 24.0f
, 35.0f
, 46.0f
, },
974 cmds::EnableVertexAttribArray enable1
;
975 cmds::EnableVertexAttribArray enable2
;
976 cmds::BindBuffer bind_to_emu
;
977 cmds::BufferData set_size
;
978 cmds::BufferSubData copy_data1
;
979 cmd::SetToken set_token1
;
980 cmds::VertexAttribPointer set_pointer1
;
981 cmds::BufferSubData copy_data2
;
982 cmd::SetToken set_token2
;
983 cmds::VertexAttribPointer set_pointer2
;
984 cmds::DrawArrays draw
;
985 cmds::BindBuffer restore
;
987 const GLuint kEmuBufferId
= GLES2Implementation::kClientSideArrayId
;
988 const GLuint kAttribIndex1
= 1;
989 const GLuint kAttribIndex2
= 3;
990 const GLint kNumComponents1
= 3;
991 const GLint kNumComponents2
= 2;
992 const GLsizei kClientStride
= sizeof(verts
[0]);
993 const GLint kFirst
= 1;
994 const GLsizei kCount
= 2;
995 const GLsizei kSize1
=
996 arraysize(verts
) * kNumComponents1
* sizeof(verts
[0][0]);
997 const GLsizei kSize2
=
998 arraysize(verts
) * kNumComponents2
* sizeof(verts
[0][0]);
999 const GLsizei kEmuOffset1
= 0;
1000 const GLsizei kEmuOffset2
= kSize1
;
1001 const GLsizei kTotalSize
= kSize1
+ kSize2
;
1003 ExpectedMemoryInfo mem1
= GetExpectedMemory(kSize1
);
1004 ExpectedMemoryInfo mem2
= GetExpectedMemory(kSize2
);
1007 expected
.enable1
.Init(kAttribIndex1
);
1008 expected
.enable2
.Init(kAttribIndex2
);
1009 expected
.bind_to_emu
.Init(GL_ARRAY_BUFFER
, kEmuBufferId
);
1010 expected
.set_size
.Init(GL_ARRAY_BUFFER
, kTotalSize
, 0, 0, GL_DYNAMIC_DRAW
);
1011 expected
.copy_data1
.Init(
1012 GL_ARRAY_BUFFER
, kEmuOffset1
, kSize1
, mem1
.id
, mem1
.offset
);
1013 expected
.set_token1
.Init(GetNextToken());
1014 expected
.set_pointer1
.Init(
1015 kAttribIndex1
, kNumComponents1
, GL_FLOAT
, GL_FALSE
, 0, kEmuOffset1
);
1016 expected
.copy_data2
.Init(
1017 GL_ARRAY_BUFFER
, kEmuOffset2
, kSize2
, mem2
.id
, mem2
.offset
);
1018 expected
.set_token2
.Init(GetNextToken());
1019 expected
.set_pointer2
.Init(
1020 kAttribIndex2
, kNumComponents2
, GL_FLOAT
, GL_FALSE
, 0, kEmuOffset2
);
1021 expected
.draw
.Init(GL_POINTS
, kFirst
, kCount
);
1022 expected
.restore
.Init(GL_ARRAY_BUFFER
, 0);
1023 gl_
->EnableVertexAttribArray(kAttribIndex1
);
1024 gl_
->EnableVertexAttribArray(kAttribIndex2
);
1025 gl_
->VertexAttribPointer(
1026 kAttribIndex1
, kNumComponents1
, GL_FLOAT
, GL_FALSE
, kClientStride
, verts
);
1027 gl_
->VertexAttribPointer(
1028 kAttribIndex2
, kNumComponents2
, GL_FLOAT
, GL_FALSE
, kClientStride
, verts
);
1029 gl_
->DrawArrays(GL_POINTS
, kFirst
, kCount
);
1030 EXPECT_EQ(0, memcmp(&expected
, commands_
, sizeof(expected
)));
1033 TEST_F(GLES2ImplementationTest
, DrawArraysInstancedANGLEClientSideBuffers
) {
1034 static const float verts
[][4] = {
1035 { 12.0f
, 23.0f
, 34.0f
, 45.0f
, },
1036 { 56.0f
, 67.0f
, 78.0f
, 89.0f
, },
1037 { 13.0f
, 24.0f
, 35.0f
, 46.0f
, },
1040 cmds::EnableVertexAttribArray enable1
;
1041 cmds::EnableVertexAttribArray enable2
;
1042 cmds::VertexAttribDivisorANGLE divisor
;
1043 cmds::BindBuffer bind_to_emu
;
1044 cmds::BufferData set_size
;
1045 cmds::BufferSubData copy_data1
;
1046 cmd::SetToken set_token1
;
1047 cmds::VertexAttribPointer set_pointer1
;
1048 cmds::BufferSubData copy_data2
;
1049 cmd::SetToken set_token2
;
1050 cmds::VertexAttribPointer set_pointer2
;
1051 cmds::DrawArraysInstancedANGLE draw
;
1052 cmds::BindBuffer restore
;
1054 const GLuint kEmuBufferId
= GLES2Implementation::kClientSideArrayId
;
1055 const GLuint kAttribIndex1
= 1;
1056 const GLuint kAttribIndex2
= 3;
1057 const GLint kNumComponents1
= 3;
1058 const GLint kNumComponents2
= 2;
1059 const GLsizei kClientStride
= sizeof(verts
[0]);
1060 const GLint kFirst
= 1;
1061 const GLsizei kCount
= 2;
1062 const GLuint kDivisor
= 1;
1063 const GLsizei kSize1
=
1064 arraysize(verts
) * kNumComponents1
* sizeof(verts
[0][0]);
1065 const GLsizei kSize2
=
1066 1 * kNumComponents2
* sizeof(verts
[0][0]);
1067 const GLsizei kEmuOffset1
= 0;
1068 const GLsizei kEmuOffset2
= kSize1
;
1069 const GLsizei kTotalSize
= kSize1
+ kSize2
;
1071 ExpectedMemoryInfo mem1
= GetExpectedMemory(kSize1
);
1072 ExpectedMemoryInfo mem2
= GetExpectedMemory(kSize2
);
1075 expected
.enable1
.Init(kAttribIndex1
);
1076 expected
.enable2
.Init(kAttribIndex2
);
1077 expected
.divisor
.Init(kAttribIndex2
, kDivisor
);
1078 expected
.bind_to_emu
.Init(GL_ARRAY_BUFFER
, kEmuBufferId
);
1079 expected
.set_size
.Init(GL_ARRAY_BUFFER
, kTotalSize
, 0, 0, GL_DYNAMIC_DRAW
);
1080 expected
.copy_data1
.Init(
1081 GL_ARRAY_BUFFER
, kEmuOffset1
, kSize1
, mem1
.id
, mem1
.offset
);
1082 expected
.set_token1
.Init(GetNextToken());
1083 expected
.set_pointer1
.Init(
1084 kAttribIndex1
, kNumComponents1
, GL_FLOAT
, GL_FALSE
, 0, kEmuOffset1
);
1085 expected
.copy_data2
.Init(
1086 GL_ARRAY_BUFFER
, kEmuOffset2
, kSize2
, mem2
.id
, mem2
.offset
);
1087 expected
.set_token2
.Init(GetNextToken());
1088 expected
.set_pointer2
.Init(
1089 kAttribIndex2
, kNumComponents2
, GL_FLOAT
, GL_FALSE
, 0, kEmuOffset2
);
1090 expected
.draw
.Init(GL_POINTS
, kFirst
, kCount
, 1);
1091 expected
.restore
.Init(GL_ARRAY_BUFFER
, 0);
1092 gl_
->EnableVertexAttribArray(kAttribIndex1
);
1093 gl_
->EnableVertexAttribArray(kAttribIndex2
);
1094 gl_
->VertexAttribPointer(
1095 kAttribIndex1
, kNumComponents1
, GL_FLOAT
, GL_FALSE
, kClientStride
, verts
);
1096 gl_
->VertexAttribPointer(
1097 kAttribIndex2
, kNumComponents2
, GL_FLOAT
, GL_FALSE
, kClientStride
, verts
);
1098 gl_
->VertexAttribDivisorANGLE(kAttribIndex2
, kDivisor
);
1099 gl_
->DrawArraysInstancedANGLE(GL_POINTS
, kFirst
, kCount
, 1);
1100 EXPECT_EQ(0, memcmp(&expected
, commands_
, sizeof(expected
)));
1103 TEST_F(GLES2ImplementationTest
, DrawElementsClientSideBuffers
) {
1104 static const float verts
[][4] = {
1105 { 12.0f
, 23.0f
, 34.0f
, 45.0f
, },
1106 { 56.0f
, 67.0f
, 78.0f
, 89.0f
, },
1107 { 13.0f
, 24.0f
, 35.0f
, 46.0f
, },
1109 static const uint16 indices
[] = {
1113 cmds::EnableVertexAttribArray enable1
;
1114 cmds::EnableVertexAttribArray enable2
;
1115 cmds::BindBuffer bind_to_index_emu
;
1116 cmds::BufferData set_index_size
;
1117 cmds::BufferSubData copy_data0
;
1118 cmd::SetToken set_token0
;
1119 cmds::BindBuffer bind_to_emu
;
1120 cmds::BufferData set_size
;
1121 cmds::BufferSubData copy_data1
;
1122 cmd::SetToken set_token1
;
1123 cmds::VertexAttribPointer set_pointer1
;
1124 cmds::BufferSubData copy_data2
;
1125 cmd::SetToken set_token2
;
1126 cmds::VertexAttribPointer set_pointer2
;
1127 cmds::DrawElements draw
;
1128 cmds::BindBuffer restore
;
1129 cmds::BindBuffer restore_element
;
1131 const GLsizei kIndexSize
= sizeof(indices
);
1132 const GLuint kEmuBufferId
= GLES2Implementation::kClientSideArrayId
;
1133 const GLuint kEmuIndexBufferId
=
1134 GLES2Implementation::kClientSideElementArrayId
;
1135 const GLuint kAttribIndex1
= 1;
1136 const GLuint kAttribIndex2
= 3;
1137 const GLint kNumComponents1
= 3;
1138 const GLint kNumComponents2
= 2;
1139 const GLsizei kClientStride
= sizeof(verts
[0]);
1140 const GLsizei kCount
= 2;
1141 const GLsizei kSize1
=
1142 arraysize(verts
) * kNumComponents1
* sizeof(verts
[0][0]);
1143 const GLsizei kSize2
=
1144 arraysize(verts
) * kNumComponents2
* sizeof(verts
[0][0]);
1145 const GLsizei kEmuOffset1
= 0;
1146 const GLsizei kEmuOffset2
= kSize1
;
1147 const GLsizei kTotalSize
= kSize1
+ kSize2
;
1149 ExpectedMemoryInfo mem1
= GetExpectedMemory(kIndexSize
);
1150 ExpectedMemoryInfo mem2
= GetExpectedMemory(kSize1
);
1151 ExpectedMemoryInfo mem3
= GetExpectedMemory(kSize2
);
1154 expected
.enable1
.Init(kAttribIndex1
);
1155 expected
.enable2
.Init(kAttribIndex2
);
1156 expected
.bind_to_index_emu
.Init(GL_ELEMENT_ARRAY_BUFFER
, kEmuIndexBufferId
);
1157 expected
.set_index_size
.Init(
1158 GL_ELEMENT_ARRAY_BUFFER
, kIndexSize
, 0, 0, GL_DYNAMIC_DRAW
);
1159 expected
.copy_data0
.Init(
1160 GL_ELEMENT_ARRAY_BUFFER
, 0, kIndexSize
, mem1
.id
, mem1
.offset
);
1161 expected
.set_token0
.Init(GetNextToken());
1162 expected
.bind_to_emu
.Init(GL_ARRAY_BUFFER
, kEmuBufferId
);
1163 expected
.set_size
.Init(GL_ARRAY_BUFFER
, kTotalSize
, 0, 0, GL_DYNAMIC_DRAW
);
1164 expected
.copy_data1
.Init(
1165 GL_ARRAY_BUFFER
, kEmuOffset1
, kSize1
, mem2
.id
, mem2
.offset
);
1166 expected
.set_token1
.Init(GetNextToken());
1167 expected
.set_pointer1
.Init(
1168 kAttribIndex1
, kNumComponents1
, GL_FLOAT
, GL_FALSE
, 0, kEmuOffset1
);
1169 expected
.copy_data2
.Init(
1170 GL_ARRAY_BUFFER
, kEmuOffset2
, kSize2
, mem3
.id
, mem3
.offset
);
1171 expected
.set_token2
.Init(GetNextToken());
1172 expected
.set_pointer2
.Init(kAttribIndex2
, kNumComponents2
,
1173 GL_FLOAT
, GL_FALSE
, 0, kEmuOffset2
);
1174 expected
.draw
.Init(GL_POINTS
, kCount
, GL_UNSIGNED_SHORT
, 0);
1175 expected
.restore
.Init(GL_ARRAY_BUFFER
, 0);
1176 expected
.restore_element
.Init(GL_ELEMENT_ARRAY_BUFFER
, 0);
1177 gl_
->EnableVertexAttribArray(kAttribIndex1
);
1178 gl_
->EnableVertexAttribArray(kAttribIndex2
);
1179 gl_
->VertexAttribPointer(kAttribIndex1
, kNumComponents1
,
1180 GL_FLOAT
, GL_FALSE
, kClientStride
, verts
);
1181 gl_
->VertexAttribPointer(kAttribIndex2
, kNumComponents2
,
1182 GL_FLOAT
, GL_FALSE
, kClientStride
, verts
);
1183 gl_
->DrawElements(GL_POINTS
, kCount
, GL_UNSIGNED_SHORT
, indices
);
1184 EXPECT_EQ(0, memcmp(&expected
, commands_
, sizeof(expected
)));
1187 TEST_F(GLES2ImplementationTest
, DrawElementsClientSideBuffersIndexUint
) {
1188 static const float verts
[][4] = {
1189 { 12.0f
, 23.0f
, 34.0f
, 45.0f
, },
1190 { 56.0f
, 67.0f
, 78.0f
, 89.0f
, },
1191 { 13.0f
, 24.0f
, 35.0f
, 46.0f
, },
1193 static const uint32 indices
[] = {
1197 cmds::EnableVertexAttribArray enable1
;
1198 cmds::EnableVertexAttribArray enable2
;
1199 cmds::BindBuffer bind_to_index_emu
;
1200 cmds::BufferData set_index_size
;
1201 cmds::BufferSubData copy_data0
;
1202 cmd::SetToken set_token0
;
1203 cmds::BindBuffer bind_to_emu
;
1204 cmds::BufferData set_size
;
1205 cmds::BufferSubData copy_data1
;
1206 cmd::SetToken set_token1
;
1207 cmds::VertexAttribPointer set_pointer1
;
1208 cmds::BufferSubData copy_data2
;
1209 cmd::SetToken set_token2
;
1210 cmds::VertexAttribPointer set_pointer2
;
1211 cmds::DrawElements draw
;
1212 cmds::BindBuffer restore
;
1213 cmds::BindBuffer restore_element
;
1215 const GLsizei kIndexSize
= sizeof(indices
);
1216 const GLuint kEmuBufferId
= GLES2Implementation::kClientSideArrayId
;
1217 const GLuint kEmuIndexBufferId
=
1218 GLES2Implementation::kClientSideElementArrayId
;
1219 const GLuint kAttribIndex1
= 1;
1220 const GLuint kAttribIndex2
= 3;
1221 const GLint kNumComponents1
= 3;
1222 const GLint kNumComponents2
= 2;
1223 const GLsizei kClientStride
= sizeof(verts
[0]);
1224 const GLsizei kCount
= 2;
1225 const GLsizei kSize1
=
1226 arraysize(verts
) * kNumComponents1
* sizeof(verts
[0][0]);
1227 const GLsizei kSize2
=
1228 arraysize(verts
) * kNumComponents2
* sizeof(verts
[0][0]);
1229 const GLsizei kEmuOffset1
= 0;
1230 const GLsizei kEmuOffset2
= kSize1
;
1231 const GLsizei kTotalSize
= kSize1
+ kSize2
;
1233 ExpectedMemoryInfo mem1
= GetExpectedMemory(kIndexSize
);
1234 ExpectedMemoryInfo mem2
= GetExpectedMemory(kSize1
);
1235 ExpectedMemoryInfo mem3
= GetExpectedMemory(kSize2
);
1238 expected
.enable1
.Init(kAttribIndex1
);
1239 expected
.enable2
.Init(kAttribIndex2
);
1240 expected
.bind_to_index_emu
.Init(GL_ELEMENT_ARRAY_BUFFER
, kEmuIndexBufferId
);
1241 expected
.set_index_size
.Init(
1242 GL_ELEMENT_ARRAY_BUFFER
, kIndexSize
, 0, 0, GL_DYNAMIC_DRAW
);
1243 expected
.copy_data0
.Init(
1244 GL_ELEMENT_ARRAY_BUFFER
, 0, kIndexSize
, mem1
.id
, mem1
.offset
);
1245 expected
.set_token0
.Init(GetNextToken());
1246 expected
.bind_to_emu
.Init(GL_ARRAY_BUFFER
, kEmuBufferId
);
1247 expected
.set_size
.Init(GL_ARRAY_BUFFER
, kTotalSize
, 0, 0, GL_DYNAMIC_DRAW
);
1248 expected
.copy_data1
.Init(
1249 GL_ARRAY_BUFFER
, kEmuOffset1
, kSize1
, mem2
.id
, mem2
.offset
);
1250 expected
.set_token1
.Init(GetNextToken());
1251 expected
.set_pointer1
.Init(
1252 kAttribIndex1
, kNumComponents1
, GL_FLOAT
, GL_FALSE
, 0, kEmuOffset1
);
1253 expected
.copy_data2
.Init(
1254 GL_ARRAY_BUFFER
, kEmuOffset2
, kSize2
, mem3
.id
, mem3
.offset
);
1255 expected
.set_token2
.Init(GetNextToken());
1256 expected
.set_pointer2
.Init(kAttribIndex2
, kNumComponents2
,
1257 GL_FLOAT
, GL_FALSE
, 0, kEmuOffset2
);
1258 expected
.draw
.Init(GL_POINTS
, kCount
, GL_UNSIGNED_INT
, 0);
1259 expected
.restore
.Init(GL_ARRAY_BUFFER
, 0);
1260 expected
.restore_element
.Init(GL_ELEMENT_ARRAY_BUFFER
, 0);
1261 gl_
->EnableVertexAttribArray(kAttribIndex1
);
1262 gl_
->EnableVertexAttribArray(kAttribIndex2
);
1263 gl_
->VertexAttribPointer(kAttribIndex1
, kNumComponents1
,
1264 GL_FLOAT
, GL_FALSE
, kClientStride
, verts
);
1265 gl_
->VertexAttribPointer(kAttribIndex2
, kNumComponents2
,
1266 GL_FLOAT
, GL_FALSE
, kClientStride
, verts
);
1267 gl_
->DrawElements(GL_POINTS
, kCount
, GL_UNSIGNED_INT
, indices
);
1268 EXPECT_EQ(0, memcmp(&expected
, commands_
, sizeof(expected
)));
1271 TEST_F(GLES2ImplementationTest
, DrawElementsClientSideBuffersInvalidIndexUint
) {
1272 static const float verts
[][4] = {
1273 { 12.0f
, 23.0f
, 34.0f
, 45.0f
, },
1274 { 56.0f
, 67.0f
, 78.0f
, 89.0f
, },
1275 { 13.0f
, 24.0f
, 35.0f
, 46.0f
, },
1277 static const uint32 indices
[] = {
1281 const GLuint kAttribIndex1
= 1;
1282 const GLuint kAttribIndex2
= 3;
1283 const GLint kNumComponents1
= 3;
1284 const GLint kNumComponents2
= 2;
1285 const GLsizei kClientStride
= sizeof(verts
[0]);
1286 const GLsizei kCount
= 2;
1288 EXPECT_CALL(*command_buffer(), OnFlush())
1290 .RetiresOnSaturation();
1292 gl_
->EnableVertexAttribArray(kAttribIndex1
);
1293 gl_
->EnableVertexAttribArray(kAttribIndex2
);
1294 gl_
->VertexAttribPointer(kAttribIndex1
, kNumComponents1
,
1295 GL_FLOAT
, GL_FALSE
, kClientStride
, verts
);
1296 gl_
->VertexAttribPointer(kAttribIndex2
, kNumComponents2
,
1297 GL_FLOAT
, GL_FALSE
, kClientStride
, verts
);
1298 gl_
->DrawElements(GL_POINTS
, kCount
, GL_UNSIGNED_INT
, indices
);
1300 EXPECT_EQ(static_cast<GLenum
>(GL_INVALID_OPERATION
), gl_
->GetError());
1303 TEST_F(GLES2ImplementationTest
,
1304 DrawElementsClientSideBuffersServiceSideIndices
) {
1305 static const float verts
[][4] = {
1306 { 12.0f
, 23.0f
, 34.0f
, 45.0f
, },
1307 { 56.0f
, 67.0f
, 78.0f
, 89.0f
, },
1308 { 13.0f
, 24.0f
, 35.0f
, 46.0f
, },
1311 cmds::EnableVertexAttribArray enable1
;
1312 cmds::EnableVertexAttribArray enable2
;
1313 cmds::BindBuffer bind_to_index
;
1314 cmds::GetMaxValueInBufferCHROMIUM get_max
;
1315 cmds::BindBuffer bind_to_emu
;
1316 cmds::BufferData set_size
;
1317 cmds::BufferSubData copy_data1
;
1318 cmd::SetToken set_token1
;
1319 cmds::VertexAttribPointer set_pointer1
;
1320 cmds::BufferSubData copy_data2
;
1321 cmd::SetToken set_token2
;
1322 cmds::VertexAttribPointer set_pointer2
;
1323 cmds::DrawElements draw
;
1324 cmds::BindBuffer restore
;
1326 const GLuint kEmuBufferId
= GLES2Implementation::kClientSideArrayId
;
1327 const GLuint kClientIndexBufferId
= 0x789;
1328 const GLuint kIndexOffset
= 0x40;
1329 const GLuint kMaxIndex
= 2;
1330 const GLuint kAttribIndex1
= 1;
1331 const GLuint kAttribIndex2
= 3;
1332 const GLint kNumComponents1
= 3;
1333 const GLint kNumComponents2
= 2;
1334 const GLsizei kClientStride
= sizeof(verts
[0]);
1335 const GLsizei kCount
= 2;
1336 const GLsizei kSize1
=
1337 arraysize(verts
) * kNumComponents1
* sizeof(verts
[0][0]);
1338 const GLsizei kSize2
=
1339 arraysize(verts
) * kNumComponents2
* sizeof(verts
[0][0]);
1340 const GLsizei kEmuOffset1
= 0;
1341 const GLsizei kEmuOffset2
= kSize1
;
1342 const GLsizei kTotalSize
= kSize1
+ kSize2
;
1344 ExpectedMemoryInfo mem1
= GetExpectedResultMemory(sizeof(uint32
));
1345 ExpectedMemoryInfo mem2
= GetExpectedMemory(kSize1
);
1346 ExpectedMemoryInfo mem3
= GetExpectedMemory(kSize2
);
1350 expected
.enable1
.Init(kAttribIndex1
);
1351 expected
.enable2
.Init(kAttribIndex2
);
1352 expected
.bind_to_index
.Init(GL_ELEMENT_ARRAY_BUFFER
, kClientIndexBufferId
);
1353 expected
.get_max
.Init(kClientIndexBufferId
, kCount
, GL_UNSIGNED_SHORT
,
1354 kIndexOffset
, mem1
.id
, mem1
.offset
);
1355 expected
.bind_to_emu
.Init(GL_ARRAY_BUFFER
, kEmuBufferId
);
1356 expected
.set_size
.Init(GL_ARRAY_BUFFER
, kTotalSize
, 0, 0, GL_DYNAMIC_DRAW
);
1357 expected
.copy_data1
.Init(
1358 GL_ARRAY_BUFFER
, kEmuOffset1
, kSize1
, mem2
.id
, mem2
.offset
);
1359 expected
.set_token1
.Init(GetNextToken());
1360 expected
.set_pointer1
.Init(kAttribIndex1
, kNumComponents1
,
1361 GL_FLOAT
, GL_FALSE
, 0, kEmuOffset1
);
1362 expected
.copy_data2
.Init(
1363 GL_ARRAY_BUFFER
, kEmuOffset2
, kSize2
, mem3
.id
, mem3
.offset
);
1364 expected
.set_token2
.Init(GetNextToken());
1365 expected
.set_pointer2
.Init(kAttribIndex2
, kNumComponents2
,
1366 GL_FLOAT
, GL_FALSE
, 0, kEmuOffset2
);
1367 expected
.draw
.Init(GL_POINTS
, kCount
, GL_UNSIGNED_SHORT
, kIndexOffset
);
1368 expected
.restore
.Init(GL_ARRAY_BUFFER
, 0);
1370 EXPECT_CALL(*command_buffer(), OnFlush())
1371 .WillOnce(SetMemory(mem1
.ptr
,kMaxIndex
))
1372 .RetiresOnSaturation();
1374 gl_
->EnableVertexAttribArray(kAttribIndex1
);
1375 gl_
->EnableVertexAttribArray(kAttribIndex2
);
1376 gl_
->BindBuffer(GL_ELEMENT_ARRAY_BUFFER
, kClientIndexBufferId
);
1377 gl_
->VertexAttribPointer(kAttribIndex1
, kNumComponents1
,
1378 GL_FLOAT
, GL_FALSE
, kClientStride
, verts
);
1379 gl_
->VertexAttribPointer(kAttribIndex2
, kNumComponents2
,
1380 GL_FLOAT
, GL_FALSE
, kClientStride
, verts
);
1381 gl_
->DrawElements(GL_POINTS
, kCount
, GL_UNSIGNED_SHORT
,
1382 reinterpret_cast<const void*>(kIndexOffset
));
1383 EXPECT_EQ(0, memcmp(&expected
, commands_
, sizeof(expected
)));
1386 TEST_F(GLES2ImplementationTest
, DrawElementsInstancedANGLEClientSideBuffers
) {
1387 static const float verts
[][4] = {
1388 { 12.0f
, 23.0f
, 34.0f
, 45.0f
, },
1389 { 56.0f
, 67.0f
, 78.0f
, 89.0f
, },
1390 { 13.0f
, 24.0f
, 35.0f
, 46.0f
, },
1392 static const uint16 indices
[] = {
1396 cmds::EnableVertexAttribArray enable1
;
1397 cmds::EnableVertexAttribArray enable2
;
1398 cmds::VertexAttribDivisorANGLE divisor
;
1399 cmds::BindBuffer bind_to_index_emu
;
1400 cmds::BufferData set_index_size
;
1401 cmds::BufferSubData copy_data0
;
1402 cmd::SetToken set_token0
;
1403 cmds::BindBuffer bind_to_emu
;
1404 cmds::BufferData set_size
;
1405 cmds::BufferSubData copy_data1
;
1406 cmd::SetToken set_token1
;
1407 cmds::VertexAttribPointer set_pointer1
;
1408 cmds::BufferSubData copy_data2
;
1409 cmd::SetToken set_token2
;
1410 cmds::VertexAttribPointer set_pointer2
;
1411 cmds::DrawElementsInstancedANGLE draw
;
1412 cmds::BindBuffer restore
;
1413 cmds::BindBuffer restore_element
;
1415 const GLsizei kIndexSize
= sizeof(indices
);
1416 const GLuint kEmuBufferId
= GLES2Implementation::kClientSideArrayId
;
1417 const GLuint kEmuIndexBufferId
=
1418 GLES2Implementation::kClientSideElementArrayId
;
1419 const GLuint kAttribIndex1
= 1;
1420 const GLuint kAttribIndex2
= 3;
1421 const GLint kNumComponents1
= 3;
1422 const GLint kNumComponents2
= 2;
1423 const GLsizei kClientStride
= sizeof(verts
[0]);
1424 const GLsizei kCount
= 2;
1425 const GLsizei kSize1
=
1426 arraysize(verts
) * kNumComponents1
* sizeof(verts
[0][0]);
1427 const GLsizei kSize2
=
1428 1 * kNumComponents2
* sizeof(verts
[0][0]);
1429 const GLuint kDivisor
= 1;
1430 const GLsizei kEmuOffset1
= 0;
1431 const GLsizei kEmuOffset2
= kSize1
;
1432 const GLsizei kTotalSize
= kSize1
+ kSize2
;
1434 ExpectedMemoryInfo mem1
= GetExpectedMemory(kIndexSize
);
1435 ExpectedMemoryInfo mem2
= GetExpectedMemory(kSize1
);
1436 ExpectedMemoryInfo mem3
= GetExpectedMemory(kSize2
);
1439 expected
.enable1
.Init(kAttribIndex1
);
1440 expected
.enable2
.Init(kAttribIndex2
);
1441 expected
.divisor
.Init(kAttribIndex2
, kDivisor
);
1442 expected
.bind_to_index_emu
.Init(GL_ELEMENT_ARRAY_BUFFER
, kEmuIndexBufferId
);
1443 expected
.set_index_size
.Init(
1444 GL_ELEMENT_ARRAY_BUFFER
, kIndexSize
, 0, 0, GL_DYNAMIC_DRAW
);
1445 expected
.copy_data0
.Init(
1446 GL_ELEMENT_ARRAY_BUFFER
, 0, kIndexSize
, mem1
.id
, mem1
.offset
);
1447 expected
.set_token0
.Init(GetNextToken());
1448 expected
.bind_to_emu
.Init(GL_ARRAY_BUFFER
, kEmuBufferId
);
1449 expected
.set_size
.Init(GL_ARRAY_BUFFER
, kTotalSize
, 0, 0, GL_DYNAMIC_DRAW
);
1450 expected
.copy_data1
.Init(
1451 GL_ARRAY_BUFFER
, kEmuOffset1
, kSize1
, mem2
.id
, mem2
.offset
);
1452 expected
.set_token1
.Init(GetNextToken());
1453 expected
.set_pointer1
.Init(
1454 kAttribIndex1
, kNumComponents1
, GL_FLOAT
, GL_FALSE
, 0, kEmuOffset1
);
1455 expected
.copy_data2
.Init(
1456 GL_ARRAY_BUFFER
, kEmuOffset2
, kSize2
, mem3
.id
, mem3
.offset
);
1457 expected
.set_token2
.Init(GetNextToken());
1458 expected
.set_pointer2
.Init(kAttribIndex2
, kNumComponents2
,
1459 GL_FLOAT
, GL_FALSE
, 0, kEmuOffset2
);
1460 expected
.draw
.Init(GL_POINTS
, kCount
, GL_UNSIGNED_SHORT
, 0, 1);
1461 expected
.restore
.Init(GL_ARRAY_BUFFER
, 0);
1462 expected
.restore_element
.Init(GL_ELEMENT_ARRAY_BUFFER
, 0);
1463 gl_
->EnableVertexAttribArray(kAttribIndex1
);
1464 gl_
->EnableVertexAttribArray(kAttribIndex2
);
1465 gl_
->VertexAttribPointer(kAttribIndex1
, kNumComponents1
,
1466 GL_FLOAT
, GL_FALSE
, kClientStride
, verts
);
1467 gl_
->VertexAttribPointer(kAttribIndex2
, kNumComponents2
,
1468 GL_FLOAT
, GL_FALSE
, kClientStride
, verts
);
1469 gl_
->VertexAttribDivisorANGLE(kAttribIndex2
, kDivisor
);
1470 gl_
->DrawElementsInstancedANGLE(
1471 GL_POINTS
, kCount
, GL_UNSIGNED_SHORT
, indices
, 1);
1472 EXPECT_EQ(0, memcmp(&expected
, commands_
, sizeof(expected
)));
1475 TEST_F(GLES2ImplementationTest
, GetVertexBufferPointerv
) {
1476 static const float verts
[1] = { 0.0f
, };
1477 const GLuint kAttribIndex1
= 1;
1478 const GLuint kAttribIndex2
= 3;
1479 const GLint kNumComponents1
= 3;
1480 const GLint kNumComponents2
= 2;
1481 const GLsizei kStride1
= 12;
1482 const GLsizei kStride2
= 0;
1483 const GLuint kBufferId
= 0x123;
1484 const GLint kOffset2
= 0x456;
1486 // It's all cached on the client side so no get commands are issued.
1488 cmds::BindBuffer bind
;
1489 cmds::VertexAttribPointer set_pointer
;
1493 expected
.bind
.Init(GL_ARRAY_BUFFER
, kBufferId
);
1494 expected
.set_pointer
.Init(kAttribIndex2
, kNumComponents2
, GL_FLOAT
, GL_FALSE
,
1495 kStride2
, kOffset2
);
1497 // Set one client side buffer.
1498 gl_
->VertexAttribPointer(kAttribIndex1
, kNumComponents1
,
1499 GL_FLOAT
, GL_FALSE
, kStride1
, verts
);
1501 gl_
->BindBuffer(GL_ARRAY_BUFFER
, kBufferId
);
1502 gl_
->VertexAttribPointer(kAttribIndex2
, kNumComponents2
,
1503 GL_FLOAT
, GL_FALSE
, kStride2
,
1504 reinterpret_cast<const void*>(kOffset2
));
1505 // now get them both.
1509 gl_
->GetVertexAttribPointerv(
1510 kAttribIndex1
, GL_VERTEX_ATTRIB_ARRAY_POINTER
, &ptr1
);
1511 gl_
->GetVertexAttribPointerv(
1512 kAttribIndex2
, GL_VERTEX_ATTRIB_ARRAY_POINTER
, &ptr2
);
1514 EXPECT_EQ(0, memcmp(&expected
, commands_
, sizeof(expected
)));
1515 EXPECT_TRUE(static_cast<const void*>(&verts
) == ptr1
);
1516 EXPECT_TRUE(ptr2
== reinterpret_cast<void*>(kOffset2
));
1519 TEST_F(GLES2ImplementationTest
, GetVertexAttrib
) {
1520 static const float verts
[1] = { 0.0f
, };
1521 const GLuint kAttribIndex1
= 1;
1522 const GLuint kAttribIndex2
= 3;
1523 const GLint kNumComponents1
= 3;
1524 const GLint kNumComponents2
= 2;
1525 const GLsizei kStride1
= 12;
1526 const GLsizei kStride2
= 0;
1527 const GLuint kBufferId
= 0x123;
1528 const GLint kOffset2
= 0x456;
1530 // Only one set and one get because the client side buffer's info is stored
1531 // on the client side.
1533 cmds::EnableVertexAttribArray enable
;
1534 cmds::BindBuffer bind
;
1535 cmds::VertexAttribPointer set_pointer
;
1536 cmds::GetVertexAttribfv get2
; // for getting the value from attrib1
1539 ExpectedMemoryInfo mem2
= GetExpectedResultMemory(16);
1542 expected
.enable
.Init(kAttribIndex1
);
1543 expected
.bind
.Init(GL_ARRAY_BUFFER
, kBufferId
);
1544 expected
.set_pointer
.Init(kAttribIndex2
, kNumComponents2
, GL_FLOAT
, GL_FALSE
,
1545 kStride2
, kOffset2
);
1546 expected
.get2
.Init(kAttribIndex1
,
1547 GL_CURRENT_VERTEX_ATTRIB
,
1548 mem2
.id
, mem2
.offset
);
1550 FourFloats
current_attrib(1.2f
, 3.4f
, 5.6f
, 7.8f
);
1552 // One call to flush to wait for last call to GetVertexAttribiv
1553 // as others are all cached.
1554 EXPECT_CALL(*command_buffer(), OnFlush())
1555 .WillOnce(SetMemory(
1556 mem2
.ptr
, SizedResultHelper
<FourFloats
>(current_attrib
)))
1557 .RetiresOnSaturation();
1559 gl_
->EnableVertexAttribArray(kAttribIndex1
);
1560 // Set one client side buffer.
1561 gl_
->VertexAttribPointer(kAttribIndex1
, kNumComponents1
,
1562 GL_FLOAT
, GL_FALSE
, kStride1
, verts
);
1564 gl_
->BindBuffer(GL_ARRAY_BUFFER
, kBufferId
);
1565 gl_
->VertexAttribPointer(kAttribIndex2
, kNumComponents2
,
1566 GL_FLOAT
, GL_FALSE
, kStride2
,
1567 reinterpret_cast<const void*>(kOffset2
));
1568 // first get the service side once to see that we make a command
1569 GLint buffer_id
= 0;
1574 GLint normalized
= 1;
1575 float current
[4] = { 0.0f
, };
1577 gl_
->GetVertexAttribiv(
1578 kAttribIndex2
, GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING
, &buffer_id
);
1579 EXPECT_EQ(kBufferId
, static_cast<GLuint
>(buffer_id
));
1580 gl_
->GetVertexAttribiv(
1581 kAttribIndex1
, GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING
, &buffer_id
);
1582 gl_
->GetVertexAttribiv(
1583 kAttribIndex1
, GL_VERTEX_ATTRIB_ARRAY_ENABLED
, &enabled
);
1584 gl_
->GetVertexAttribiv(
1585 kAttribIndex1
, GL_VERTEX_ATTRIB_ARRAY_SIZE
, &size
);
1586 gl_
->GetVertexAttribiv(
1587 kAttribIndex1
, GL_VERTEX_ATTRIB_ARRAY_STRIDE
, &stride
);
1588 gl_
->GetVertexAttribiv(
1589 kAttribIndex1
, GL_VERTEX_ATTRIB_ARRAY_TYPE
, &type
);
1590 gl_
->GetVertexAttribiv(
1591 kAttribIndex1
, GL_VERTEX_ATTRIB_ARRAY_NORMALIZED
, &normalized
);
1592 gl_
->GetVertexAttribfv(
1593 kAttribIndex1
, GL_CURRENT_VERTEX_ATTRIB
, ¤t
[0]);
1595 EXPECT_EQ(0, buffer_id
);
1596 EXPECT_EQ(GL_TRUE
, enabled
);
1597 EXPECT_EQ(kNumComponents1
, size
);
1598 EXPECT_EQ(kStride1
, stride
);
1599 EXPECT_EQ(GL_FLOAT
, type
);
1600 EXPECT_EQ(GL_FALSE
, normalized
);
1601 EXPECT_EQ(0, memcmp(¤t_attrib
, ¤t
, sizeof(current_attrib
)));
1603 EXPECT_EQ(0, memcmp(&expected
, commands_
, sizeof(expected
)));
1606 TEST_F(GLES2ImplementationTest
, ReservedIds
) {
1607 // Only the get error command should be issued.
1613 ExpectedMemoryInfo mem1
= GetExpectedResultMemory(
1614 sizeof(cmds::GetError::Result
));
1616 expected
.get
.Init(mem1
.id
, mem1
.offset
);
1618 // One call to flush to wait for GetError
1619 EXPECT_CALL(*command_buffer(), OnFlush())
1620 .WillOnce(SetMemory(mem1
.ptr
, GLuint(GL_NO_ERROR
)))
1621 .RetiresOnSaturation();
1625 GLES2Implementation::kClientSideArrayId
);
1628 GLES2Implementation::kClientSideElementArrayId
);
1629 GLenum err
= gl_
->GetError();
1630 EXPECT_EQ(static_cast<GLenum
>(GL_INVALID_OPERATION
), err
);
1631 EXPECT_EQ(0, memcmp(&expected
, commands_
, sizeof(expected
)));
1634 #endif // defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS)
1636 TEST_F(GLES2ImplementationTest
, ReadPixels2Reads
) {
1638 cmds::ReadPixels read1
;
1639 cmd::SetToken set_token1
;
1640 cmds::ReadPixels read2
;
1641 cmd::SetToken set_token2
;
1643 const GLint kBytesPerPixel
= 4;
1644 const GLint kWidth
=
1645 (kTransferBufferSize
- GLES2Implementation::kStartingOffset
) /
1647 const GLint kHeight
= 2;
1648 const GLenum kFormat
= GL_RGBA
;
1649 const GLenum kType
= GL_UNSIGNED_BYTE
;
1651 ExpectedMemoryInfo mem1
=
1652 GetExpectedMemory(kWidth
* kHeight
/ 2 * kBytesPerPixel
);
1653 ExpectedMemoryInfo result1
=
1654 GetExpectedResultMemory(sizeof(cmds::ReadPixels::Result
));
1655 ExpectedMemoryInfo mem2
=
1656 GetExpectedMemory(kWidth
* kHeight
/ 2 * kBytesPerPixel
);
1657 ExpectedMemoryInfo result2
=
1658 GetExpectedResultMemory(sizeof(cmds::ReadPixels::Result
));
1661 expected
.read1
.Init(
1662 0, 0, kWidth
, kHeight
/ 2, kFormat
, kType
,
1663 mem1
.id
, mem1
.offset
, result1
.id
, result1
.offset
,
1665 expected
.set_token1
.Init(GetNextToken());
1666 expected
.read2
.Init(
1667 0, kHeight
/ 2, kWidth
, kHeight
/ 2, kFormat
, kType
,
1668 mem2
.id
, mem2
.offset
, result2
.id
, result2
.offset
, false);
1669 expected
.set_token2
.Init(GetNextToken());
1670 scoped_ptr
<int8
[]> buffer(new int8
[kWidth
* kHeight
* kBytesPerPixel
]);
1672 EXPECT_CALL(*command_buffer(), OnFlush())
1673 .WillOnce(SetMemory(result1
.ptr
, static_cast<uint32
>(1)))
1674 .WillOnce(SetMemory(result2
.ptr
, static_cast<uint32
>(1)))
1675 .RetiresOnSaturation();
1677 gl_
->ReadPixels(0, 0, kWidth
, kHeight
, kFormat
, kType
, buffer
.get());
1678 EXPECT_EQ(0, memcmp(&expected
, commands_
, sizeof(expected
)));
1681 TEST_F(GLES2ImplementationTest
, ReadPixelsBadFormatType
) {
1683 cmds::ReadPixels read
;
1684 cmd::SetToken set_token
;
1686 const GLint kBytesPerPixel
= 4;
1687 const GLint kWidth
= 2;
1688 const GLint kHeight
= 2;
1689 const GLenum kFormat
= 0;
1690 const GLenum kType
= 0;
1692 ExpectedMemoryInfo mem1
=
1693 GetExpectedMemory(kWidth
* kHeight
* kBytesPerPixel
);
1694 ExpectedMemoryInfo result1
=
1695 GetExpectedResultMemory(sizeof(cmds::ReadPixels::Result
));
1699 0, 0, kWidth
, kHeight
, kFormat
, kType
,
1700 mem1
.id
, mem1
.offset
, result1
.id
, result1
.offset
, false);
1701 expected
.set_token
.Init(GetNextToken());
1702 scoped_ptr
<int8
[]> buffer(new int8
[kWidth
* kHeight
* kBytesPerPixel
]);
1704 EXPECT_CALL(*command_buffer(), OnFlush())
1706 .RetiresOnSaturation();
1708 gl_
->ReadPixels(0, 0, kWidth
, kHeight
, kFormat
, kType
, buffer
.get());
1711 TEST_F(GLES2ImplementationTest
, FreeUnusedSharedMemory
) {
1713 cmds::BufferSubData buf
;
1714 cmd::SetToken set_token
;
1716 const GLenum kTarget
= GL_ELEMENT_ARRAY_BUFFER
;
1717 const GLintptr kOffset
= 15;
1718 const GLsizeiptr kSize
= 16;
1720 ExpectedMemoryInfo mem1
= GetExpectedMemory(kSize
);
1724 kTarget
, kOffset
, kSize
, mem1
.id
, mem1
.offset
);
1725 expected
.set_token
.Init(GetNextToken());
1727 void* mem
= gl_
->MapBufferSubDataCHROMIUM(
1728 kTarget
, kOffset
, kSize
, GL_WRITE_ONLY
);
1729 ASSERT_TRUE(mem
!= NULL
);
1730 gl_
->UnmapBufferSubDataCHROMIUM(mem
);
1731 EXPECT_CALL(*command_buffer(), DestroyTransferBuffer(_
))
1733 .RetiresOnSaturation();
1734 gl_
->FreeUnusedSharedMemory();
1737 TEST_F(GLES2ImplementationTest
, MapUnmapBufferSubDataCHROMIUM
) {
1739 cmds::BufferSubData buf
;
1740 cmd::SetToken set_token
;
1742 const GLenum kTarget
= GL_ELEMENT_ARRAY_BUFFER
;
1743 const GLintptr kOffset
= 15;
1744 const GLsizeiptr kSize
= 16;
1749 kTarget
, kOffset
, kSize
,
1750 command_buffer()->GetNextFreeTransferBufferId(), offset
);
1751 expected
.set_token
.Init(GetNextToken());
1753 void* mem
= gl_
->MapBufferSubDataCHROMIUM(
1754 kTarget
, kOffset
, kSize
, GL_WRITE_ONLY
);
1755 ASSERT_TRUE(mem
!= NULL
);
1756 gl_
->UnmapBufferSubDataCHROMIUM(mem
);
1757 EXPECT_EQ(0, memcmp(&expected
, commands_
, sizeof(expected
)));
1760 TEST_F(GLES2ImplementationTest
, MapUnmapBufferSubDataCHROMIUMBadArgs
) {
1761 const GLenum kTarget
= GL_ELEMENT_ARRAY_BUFFER
;
1762 const GLintptr kOffset
= 15;
1763 const GLsizeiptr kSize
= 16;
1765 ExpectedMemoryInfo result1
=
1766 GetExpectedResultMemory(sizeof(cmds::GetError::Result
));
1767 ExpectedMemoryInfo result2
=
1768 GetExpectedResultMemory(sizeof(cmds::GetError::Result
));
1769 ExpectedMemoryInfo result3
=
1770 GetExpectedResultMemory(sizeof(cmds::GetError::Result
));
1771 ExpectedMemoryInfo result4
=
1772 GetExpectedResultMemory(sizeof(cmds::GetError::Result
));
1774 // Calls to flush to wait for GetError
1775 EXPECT_CALL(*command_buffer(), OnFlush())
1776 .WillOnce(SetMemory(result1
.ptr
, GLuint(GL_NO_ERROR
)))
1777 .WillOnce(SetMemory(result2
.ptr
, GLuint(GL_NO_ERROR
)))
1778 .WillOnce(SetMemory(result3
.ptr
, GLuint(GL_NO_ERROR
)))
1779 .WillOnce(SetMemory(result4
.ptr
, GLuint(GL_NO_ERROR
)))
1780 .RetiresOnSaturation();
1783 mem
= gl_
->MapBufferSubDataCHROMIUM(kTarget
, -1, kSize
, GL_WRITE_ONLY
);
1784 ASSERT_TRUE(mem
== NULL
);
1785 EXPECT_EQ(static_cast<GLenum
>(GL_INVALID_VALUE
), gl_
->GetError());
1786 mem
= gl_
->MapBufferSubDataCHROMIUM(kTarget
, kOffset
, -1, GL_WRITE_ONLY
);
1787 ASSERT_TRUE(mem
== NULL
);
1788 EXPECT_EQ(static_cast<GLenum
>(GL_INVALID_VALUE
), gl_
->GetError());
1789 mem
= gl_
->MapBufferSubDataCHROMIUM(kTarget
, kOffset
, kSize
, GL_READ_ONLY
);
1790 ASSERT_TRUE(mem
== NULL
);
1791 EXPECT_EQ(static_cast<GLenum
>(GL_INVALID_ENUM
), gl_
->GetError());
1792 const char* kPtr
= "something";
1793 gl_
->UnmapBufferSubDataCHROMIUM(kPtr
);
1794 EXPECT_EQ(static_cast<GLenum
>(GL_INVALID_VALUE
), gl_
->GetError());
1797 TEST_F(GLES2ImplementationTest
, MapUnmapTexSubImage2DCHROMIUM
) {
1799 cmds::TexSubImage2D tex
;
1800 cmd::SetToken set_token
;
1802 const GLint kLevel
= 1;
1803 const GLint kXOffset
= 2;
1804 const GLint kYOffset
= 3;
1805 const GLint kWidth
= 4;
1806 const GLint kHeight
= 5;
1807 const GLenum kFormat
= GL_RGBA
;
1808 const GLenum kType
= GL_UNSIGNED_BYTE
;
1813 GL_TEXTURE_2D
, kLevel
, kXOffset
, kYOffset
, kWidth
, kHeight
, kFormat
,
1815 command_buffer()->GetNextFreeTransferBufferId(), offset
, GL_FALSE
);
1816 expected
.set_token
.Init(GetNextToken());
1818 void* mem
= gl_
->MapTexSubImage2DCHROMIUM(
1828 ASSERT_TRUE(mem
!= NULL
);
1829 gl_
->UnmapTexSubImage2DCHROMIUM(mem
);
1830 EXPECT_EQ(0, memcmp(&expected
, commands_
, sizeof(expected
)));
1833 TEST_F(GLES2ImplementationTest
, MapUnmapTexSubImage2DCHROMIUMBadArgs
) {
1834 const GLint kLevel
= 1;
1835 const GLint kXOffset
= 2;
1836 const GLint kYOffset
= 3;
1837 const GLint kWidth
= 4;
1838 const GLint kHeight
= 5;
1839 const GLenum kFormat
= GL_RGBA
;
1840 const GLenum kType
= GL_UNSIGNED_BYTE
;
1842 ExpectedMemoryInfo result1
=
1843 GetExpectedResultMemory(sizeof(cmds::GetError::Result
));
1844 ExpectedMemoryInfo result2
=
1845 GetExpectedResultMemory(sizeof(cmds::GetError::Result
));
1846 ExpectedMemoryInfo result3
=
1847 GetExpectedResultMemory(sizeof(cmds::GetError::Result
));
1848 ExpectedMemoryInfo result4
=
1849 GetExpectedResultMemory(sizeof(cmds::GetError::Result
));
1850 ExpectedMemoryInfo result5
=
1851 GetExpectedResultMemory(sizeof(cmds::GetError::Result
));
1852 ExpectedMemoryInfo result6
=
1853 GetExpectedResultMemory(sizeof(cmds::GetError::Result
));
1854 ExpectedMemoryInfo result7
=
1855 GetExpectedResultMemory(sizeof(cmds::GetError::Result
));
1857 // Calls to flush to wait for GetError
1858 EXPECT_CALL(*command_buffer(), OnFlush())
1859 .WillOnce(SetMemory(result1
.ptr
, GLuint(GL_NO_ERROR
)))
1860 .WillOnce(SetMemory(result2
.ptr
, GLuint(GL_NO_ERROR
)))
1861 .WillOnce(SetMemory(result3
.ptr
, GLuint(GL_NO_ERROR
)))
1862 .WillOnce(SetMemory(result4
.ptr
, GLuint(GL_NO_ERROR
)))
1863 .WillOnce(SetMemory(result5
.ptr
, GLuint(GL_NO_ERROR
)))
1864 .WillOnce(SetMemory(result6
.ptr
, GLuint(GL_NO_ERROR
)))
1865 .WillOnce(SetMemory(result7
.ptr
, GLuint(GL_NO_ERROR
)))
1866 .RetiresOnSaturation();
1869 mem
= gl_
->MapTexSubImage2DCHROMIUM(
1879 EXPECT_TRUE(mem
== NULL
);
1880 EXPECT_EQ(static_cast<GLenum
>(GL_INVALID_VALUE
), gl_
->GetError());
1881 mem
= gl_
->MapTexSubImage2DCHROMIUM(
1891 EXPECT_TRUE(mem
== NULL
);
1892 EXPECT_EQ(static_cast<GLenum
>(GL_INVALID_VALUE
), gl_
->GetError());
1893 mem
= gl_
->MapTexSubImage2DCHROMIUM(
1903 EXPECT_TRUE(mem
== NULL
);
1904 EXPECT_EQ(static_cast<GLenum
>(GL_INVALID_VALUE
), gl_
->GetError());
1905 mem
= gl_
->MapTexSubImage2DCHROMIUM(
1915 EXPECT_TRUE(mem
== NULL
);
1916 EXPECT_EQ(static_cast<GLenum
>(GL_INVALID_VALUE
), gl_
->GetError());
1917 mem
= gl_
->MapTexSubImage2DCHROMIUM(
1927 EXPECT_TRUE(mem
== NULL
);
1928 EXPECT_EQ(static_cast<GLenum
>(GL_INVALID_VALUE
), gl_
->GetError());
1929 mem
= gl_
->MapTexSubImage2DCHROMIUM(
1939 EXPECT_TRUE(mem
== NULL
);
1940 EXPECT_EQ(static_cast<GLenum
>(GL_INVALID_ENUM
), gl_
->GetError());
1941 const char* kPtr
= "something";
1942 gl_
->UnmapTexSubImage2DCHROMIUM(kPtr
);
1943 EXPECT_EQ(static_cast<GLenum
>(GL_INVALID_VALUE
), gl_
->GetError());
1946 TEST_F(GLES2ImplementationTest
, GetProgramInfoCHROMIUMGoodArgs
) {
1947 const uint32 kBucketId
= GLES2Implementation::kResultBucketId
;
1948 const GLuint kProgramId
= 123;
1949 const char kBad
= 0x12;
1951 const Str7 kString
= {"foobar"};
1954 ExpectedMemoryInfo mem1
=
1955 GetExpectedMemory(MaxTransferBufferSize());
1956 ExpectedMemoryInfo result1
=
1957 GetExpectedResultMemory(sizeof(cmd::GetBucketStart::Result
));
1958 ExpectedMemoryInfo result2
=
1959 GetExpectedResultMemory(sizeof(cmds::GetError::Result
));
1961 memset(buf
, kBad
, sizeof(buf
));
1962 EXPECT_CALL(*command_buffer(), OnFlush())
1963 .WillOnce(DoAll(SetMemory(result1
.ptr
, uint32(sizeof(kString
))),
1964 SetMemory(mem1
.ptr
, kString
)))
1965 .WillOnce(SetMemory(result2
.ptr
, GLuint(GL_NO_ERROR
)))
1966 .RetiresOnSaturation();
1969 cmd::SetBucketSize set_bucket_size1
;
1970 cmds::GetProgramInfoCHROMIUM get_program_info
;
1971 cmd::GetBucketStart get_bucket_start
;
1972 cmd::SetToken set_token1
;
1973 cmd::SetBucketSize set_bucket_size2
;
1976 expected
.set_bucket_size1
.Init(kBucketId
, 0);
1977 expected
.get_program_info
.Init(kProgramId
, kBucketId
);
1978 expected
.get_bucket_start
.Init(
1979 kBucketId
, result1
.id
, result1
.offset
,
1980 MaxTransferBufferSize(), mem1
.id
, mem1
.offset
);
1981 expected
.set_token1
.Init(GetNextToken());
1982 expected
.set_bucket_size2
.Init(kBucketId
, 0);
1983 gl_
->GetProgramInfoCHROMIUM(kProgramId
, sizeof(buf
), &size
, &buf
);
1984 EXPECT_EQ(0, memcmp(&expected
, commands_
, sizeof(expected
)));
1985 EXPECT_EQ(static_cast<GLenum
>(GL_NO_ERROR
), gl_
->GetError());
1986 EXPECT_EQ(sizeof(kString
), static_cast<size_t>(size
));
1987 EXPECT_STREQ(kString
.str
, buf
);
1988 EXPECT_EQ(buf
[sizeof(kString
)], kBad
);
1991 TEST_F(GLES2ImplementationTest
, GetProgramInfoCHROMIUMBadArgs
) {
1992 const uint32 kBucketId
= GLES2Implementation::kResultBucketId
;
1993 const GLuint kProgramId
= 123;
1995 const Str7 kString
= {"foobar"};
1998 ExpectedMemoryInfo mem1
= GetExpectedMemory(MaxTransferBufferSize());
1999 ExpectedMemoryInfo result1
=
2000 GetExpectedResultMemory(sizeof(cmd::GetBucketStart::Result
));
2001 ExpectedMemoryInfo result2
=
2002 GetExpectedResultMemory(sizeof(cmds::GetError::Result
));
2003 ExpectedMemoryInfo result3
=
2004 GetExpectedResultMemory(sizeof(cmds::GetError::Result
));
2005 ExpectedMemoryInfo result4
=
2006 GetExpectedResultMemory(sizeof(cmds::GetError::Result
));
2008 EXPECT_CALL(*command_buffer(), OnFlush())
2009 .WillOnce(DoAll(SetMemory(result1
.ptr
, uint32(sizeof(kString
))),
2010 SetMemory(mem1
.ptr
, kString
)))
2011 .WillOnce(SetMemory(result2
.ptr
, GLuint(GL_NO_ERROR
)))
2012 .WillOnce(SetMemory(result3
.ptr
, GLuint(GL_NO_ERROR
)))
2013 .WillOnce(SetMemory(result4
.ptr
, GLuint(GL_NO_ERROR
)))
2014 .RetiresOnSaturation();
2016 // try bufsize not big enough.
2018 cmd::SetBucketSize set_bucket_size1
;
2019 cmds::GetProgramInfoCHROMIUM get_program_info
;
2020 cmd::GetBucketStart get_bucket_start
;
2021 cmd::SetToken set_token1
;
2022 cmd::SetBucketSize set_bucket_size2
;
2025 expected
.set_bucket_size1
.Init(kBucketId
, 0);
2026 expected
.get_program_info
.Init(kProgramId
, kBucketId
);
2027 expected
.get_bucket_start
.Init(
2028 kBucketId
, result1
.id
, result1
.offset
,
2029 MaxTransferBufferSize(), mem1
.id
, mem1
.offset
);
2030 expected
.set_token1
.Init(GetNextToken());
2031 expected
.set_bucket_size2
.Init(kBucketId
, 0);
2032 gl_
->GetProgramInfoCHROMIUM(kProgramId
, 6, &size
, &buf
);
2033 EXPECT_EQ(0, memcmp(&expected
, commands_
, sizeof(expected
)));
2034 EXPECT_EQ(static_cast<GLenum
>(GL_INVALID_OPERATION
), gl_
->GetError());
2038 gl_
->GetProgramInfoCHROMIUM(kProgramId
, -1, &size
, &buf
);
2039 EXPECT_TRUE(NoCommandsWritten());
2040 EXPECT_EQ(static_cast<GLenum
>(GL_INVALID_VALUE
), gl_
->GetError());
2043 gl_
->GetProgramInfoCHROMIUM(kProgramId
, sizeof(buf
), NULL
, &buf
);
2044 EXPECT_TRUE(NoCommandsWritten());
2045 EXPECT_EQ(static_cast<GLenum
>(GL_INVALID_VALUE
), gl_
->GetError());
2048 TEST_F(GLES2ImplementationTest
, GetUniformBlocksCHROMIUMGoodArgs
) {
2049 const uint32 kBucketId
= GLES2Implementation::kResultBucketId
;
2050 const GLuint kProgramId
= 123;
2051 const char kBad
= 0x12;
2053 const Str7 kString
= {"foobar"};
2056 ExpectedMemoryInfo mem1
=
2057 GetExpectedMemory(MaxTransferBufferSize());
2058 ExpectedMemoryInfo result1
=
2059 GetExpectedResultMemory(sizeof(cmd::GetBucketStart::Result
));
2060 ExpectedMemoryInfo result2
=
2061 GetExpectedResultMemory(sizeof(cmds::GetError::Result
));
2063 memset(buf
, kBad
, sizeof(buf
));
2064 EXPECT_CALL(*command_buffer(), OnFlush())
2065 .WillOnce(DoAll(SetMemory(result1
.ptr
, uint32(sizeof(kString
))),
2066 SetMemory(mem1
.ptr
, kString
)))
2067 .WillOnce(SetMemory(result2
.ptr
, GLuint(GL_NO_ERROR
)))
2068 .RetiresOnSaturation();
2071 cmd::SetBucketSize set_bucket_size1
;
2072 cmds::GetUniformBlocksCHROMIUM get_uniform_blocks
;
2073 cmd::GetBucketStart get_bucket_start
;
2074 cmd::SetToken set_token1
;
2075 cmd::SetBucketSize set_bucket_size2
;
2078 expected
.set_bucket_size1
.Init(kBucketId
, 0);
2079 expected
.get_uniform_blocks
.Init(kProgramId
, kBucketId
);
2080 expected
.get_bucket_start
.Init(
2081 kBucketId
, result1
.id
, result1
.offset
,
2082 MaxTransferBufferSize(), mem1
.id
, mem1
.offset
);
2083 expected
.set_token1
.Init(GetNextToken());
2084 expected
.set_bucket_size2
.Init(kBucketId
, 0);
2085 gl_
->GetUniformBlocksCHROMIUM(kProgramId
, sizeof(buf
), &size
, &buf
);
2086 EXPECT_EQ(0, memcmp(&expected
, commands_
, sizeof(expected
)));
2087 EXPECT_EQ(static_cast<GLenum
>(GL_NO_ERROR
), gl_
->GetError());
2088 EXPECT_EQ(sizeof(kString
), static_cast<size_t>(size
));
2089 EXPECT_STREQ(kString
.str
, buf
);
2090 EXPECT_EQ(buf
[sizeof(kString
)], kBad
);
2093 TEST_F(GLES2ImplementationTest
, GetUniformBlocksCHROMIUMBadArgs
) {
2094 const uint32 kBucketId
= GLES2Implementation::kResultBucketId
;
2095 const GLuint kProgramId
= 123;
2097 const Str7 kString
= {"foobar"};
2100 ExpectedMemoryInfo mem1
= GetExpectedMemory(MaxTransferBufferSize());
2101 ExpectedMemoryInfo result1
=
2102 GetExpectedResultMemory(sizeof(cmd::GetBucketStart::Result
));
2103 ExpectedMemoryInfo result2
=
2104 GetExpectedResultMemory(sizeof(cmds::GetError::Result
));
2105 ExpectedMemoryInfo result3
=
2106 GetExpectedResultMemory(sizeof(cmds::GetError::Result
));
2107 ExpectedMemoryInfo result4
=
2108 GetExpectedResultMemory(sizeof(cmds::GetError::Result
));
2110 EXPECT_CALL(*command_buffer(), OnFlush())
2111 .WillOnce(DoAll(SetMemory(result1
.ptr
, uint32(sizeof(kString
))),
2112 SetMemory(mem1
.ptr
, kString
)))
2113 .WillOnce(SetMemory(result2
.ptr
, GLuint(GL_NO_ERROR
)))
2114 .WillOnce(SetMemory(result3
.ptr
, GLuint(GL_NO_ERROR
)))
2115 .WillOnce(SetMemory(result4
.ptr
, GLuint(GL_NO_ERROR
)))
2116 .RetiresOnSaturation();
2118 // try bufsize not big enough.
2120 cmd::SetBucketSize set_bucket_size1
;
2121 cmds::GetUniformBlocksCHROMIUM get_uniform_blocks
;
2122 cmd::GetBucketStart get_bucket_start
;
2123 cmd::SetToken set_token1
;
2124 cmd::SetBucketSize set_bucket_size2
;
2127 expected
.set_bucket_size1
.Init(kBucketId
, 0);
2128 expected
.get_uniform_blocks
.Init(kProgramId
, kBucketId
);
2129 expected
.get_bucket_start
.Init(
2130 kBucketId
, result1
.id
, result1
.offset
,
2131 MaxTransferBufferSize(), mem1
.id
, mem1
.offset
);
2132 expected
.set_token1
.Init(GetNextToken());
2133 expected
.set_bucket_size2
.Init(kBucketId
, 0);
2134 gl_
->GetUniformBlocksCHROMIUM(kProgramId
, 6, &size
, &buf
);
2135 EXPECT_EQ(0, memcmp(&expected
, commands_
, sizeof(expected
)));
2136 EXPECT_EQ(static_cast<GLenum
>(GL_INVALID_OPERATION
), gl_
->GetError());
2140 gl_
->GetUniformBlocksCHROMIUM(kProgramId
, -1, &size
, &buf
);
2141 EXPECT_TRUE(NoCommandsWritten());
2142 EXPECT_EQ(static_cast<GLenum
>(GL_INVALID_VALUE
), gl_
->GetError());
2145 gl_
->GetUniformBlocksCHROMIUM(kProgramId
, sizeof(buf
), NULL
, &buf
);
2146 EXPECT_TRUE(NoCommandsWritten());
2147 EXPECT_EQ(static_cast<GLenum
>(GL_INVALID_VALUE
), gl_
->GetError());
2150 // Test that things are cached
2151 TEST_F(GLES2ImplementationTest
, GetIntegerCacheRead
) {
2156 const PNameValue pairs
[] = {
2157 {GL_ACTIVE_TEXTURE
, GL_TEXTURE0
, },
2158 {GL_TEXTURE_BINDING_2D
, 0, },
2159 {GL_TEXTURE_BINDING_CUBE_MAP
, 0, },
2160 {GL_TEXTURE_BINDING_EXTERNAL_OES
, 0, },
2161 {GL_FRAMEBUFFER_BINDING
, 0, },
2162 {GL_RENDERBUFFER_BINDING
, 0, },
2163 {GL_ARRAY_BUFFER_BINDING
, 0, },
2164 {GL_ELEMENT_ARRAY_BUFFER_BINDING
, 0, },
2165 {GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS
, kMaxCombinedTextureImageUnits
, },
2166 {GL_MAX_CUBE_MAP_TEXTURE_SIZE
, kMaxCubeMapTextureSize
, },
2167 {GL_MAX_FRAGMENT_UNIFORM_VECTORS
, kMaxFragmentUniformVectors
, },
2168 {GL_MAX_RENDERBUFFER_SIZE
, kMaxRenderbufferSize
, },
2169 {GL_MAX_TEXTURE_IMAGE_UNITS
, kMaxTextureImageUnits
, },
2170 {GL_MAX_TEXTURE_SIZE
, kMaxTextureSize
, },
2171 {GL_MAX_VARYING_VECTORS
, kMaxVaryingVectors
, },
2172 {GL_MAX_VERTEX_ATTRIBS
, kMaxVertexAttribs
, },
2173 {GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS
, kMaxVertexTextureImageUnits
, },
2174 {GL_MAX_VERTEX_UNIFORM_VECTORS
, kMaxVertexUniformVectors
, },
2175 {GL_NUM_COMPRESSED_TEXTURE_FORMATS
, kNumCompressedTextureFormats
, },
2176 {GL_NUM_SHADER_BINARY_FORMATS
, kNumShaderBinaryFormats
, }, };
2177 size_t num_pairs
= sizeof(pairs
) / sizeof(pairs
[0]);
2178 for (size_t ii
= 0; ii
< num_pairs
; ++ii
) {
2179 const PNameValue
& pv
= pairs
[ii
];
2181 gl_
->GetIntegerv(pv
.pname
, &v
);
2182 EXPECT_TRUE(NoCommandsWritten());
2183 EXPECT_EQ(pv
.expected
, v
);
2186 ExpectedMemoryInfo result1
=
2187 GetExpectedResultMemory(sizeof(cmds::GetError::Result
));
2189 EXPECT_CALL(*command_buffer(), OnFlush())
2190 .WillOnce(SetMemory(result1
.ptr
, GLuint(GL_NO_ERROR
)))
2191 .RetiresOnSaturation();
2192 EXPECT_EQ(static_cast<GLenum
>(GL_NO_ERROR
), gl_
->GetError());
2195 TEST_F(GLES2ImplementationTest
, GetIntegerCacheWrite
) {
2200 gl_
->ActiveTexture(GL_TEXTURE4
);
2201 gl_
->BindBuffer(GL_ARRAY_BUFFER
, 2);
2202 gl_
->BindBuffer(GL_ELEMENT_ARRAY_BUFFER
, 3);
2203 gl_
->BindFramebuffer(GL_FRAMEBUFFER
, 4);
2204 gl_
->BindRenderbuffer(GL_RENDERBUFFER
, 5);
2205 gl_
->BindTexture(GL_TEXTURE_2D
, 6);
2206 gl_
->BindTexture(GL_TEXTURE_CUBE_MAP
, 7);
2207 gl_
->BindTexture(GL_TEXTURE_EXTERNAL_OES
, 8);
2209 const PNameValue pairs
[] = {{GL_ACTIVE_TEXTURE
, GL_TEXTURE4
, },
2210 {GL_ARRAY_BUFFER_BINDING
, 2, },
2211 {GL_ELEMENT_ARRAY_BUFFER_BINDING
, 3, },
2212 {GL_FRAMEBUFFER_BINDING
, 4, },
2213 {GL_RENDERBUFFER_BINDING
, 5, },
2214 {GL_TEXTURE_BINDING_2D
, 6, },
2215 {GL_TEXTURE_BINDING_CUBE_MAP
, 7, },
2216 {GL_TEXTURE_BINDING_EXTERNAL_OES
, 8, }, };
2217 size_t num_pairs
= sizeof(pairs
) / sizeof(pairs
[0]);
2218 for (size_t ii
= 0; ii
< num_pairs
; ++ii
) {
2219 const PNameValue
& pv
= pairs
[ii
];
2221 gl_
->GetIntegerv(pv
.pname
, &v
);
2222 EXPECT_EQ(pv
.expected
, v
);
2225 ExpectedMemoryInfo result1
=
2226 GetExpectedResultMemory(sizeof(cmds::GetError::Result
));
2228 EXPECT_CALL(*command_buffer(), OnFlush())
2229 .WillOnce(SetMemory(result1
.ptr
, GLuint(GL_NO_ERROR
)))
2230 .RetiresOnSaturation();
2231 EXPECT_EQ(static_cast<GLenum
>(GL_NO_ERROR
), gl_
->GetError());
2234 static bool CheckRect(
2235 int width
, int height
, GLenum format
, GLenum type
, int alignment
,
2236 bool flip_y
, const uint8
* r1
, const uint8
* r2
) {
2238 uint32 unpadded_row_size
= 0;
2239 uint32 padded_row_size
= 0;
2240 if (!GLES2Util::ComputeImageDataSizes(
2241 width
, height
, 1, format
, type
, alignment
, &size
, &unpadded_row_size
,
2242 &padded_row_size
)) {
2246 int r2_stride
= flip_y
?
2247 -static_cast<int>(padded_row_size
) :
2248 static_cast<int>(padded_row_size
);
2249 r2
= flip_y
? (r2
+ (height
- 1) * padded_row_size
) : r2
;
2251 for (int y
= 0; y
< height
; ++y
) {
2252 if (memcmp(r1
, r2
, unpadded_row_size
) != 0) {
2255 r1
+= padded_row_size
;
2261 ACTION_P8(CheckRectAction
, width
, height
, format
, type
, alignment
, flip_y
,
2263 EXPECT_TRUE(CheckRect(
2264 width
, height
, format
, type
, alignment
, flip_y
, r1
, r2
));
2267 // Test TexImage2D with and without flip_y
2268 TEST_F(GLES2ImplementationTest
, TexImage2D
) {
2270 cmds::TexImage2D tex_image_2d
;
2271 cmd::SetToken set_token
;
2274 cmds::TexImage2D tex_image_2d
;
2275 cmd::SetToken set_token
;
2277 const GLenum kTarget
= GL_TEXTURE_2D
;
2278 const GLint kLevel
= 0;
2279 const GLenum kFormat
= GL_RGB
;
2280 const GLsizei kWidth
= 3;
2281 const GLsizei kHeight
= 4;
2282 const GLint kBorder
= 0;
2283 const GLenum kType
= GL_UNSIGNED_BYTE
;
2284 const GLint kPixelStoreUnpackAlignment
= 4;
2285 static uint8 pixels
[] = {
2286 11, 12, 13, 13, 14, 15, 15, 16, 17, 101, 102, 103,
2287 21, 22, 23, 23, 24, 25, 25, 26, 27, 201, 202, 203,
2288 31, 32, 33, 33, 34, 35, 35, 36, 37, 123, 124, 125,
2289 41, 42, 43, 43, 44, 45, 45, 46, 47,
2292 ExpectedMemoryInfo mem1
= GetExpectedMemory(sizeof(pixels
));
2295 expected
.tex_image_2d
.Init(
2296 kTarget
, kLevel
, kFormat
, kWidth
, kHeight
, kFormat
, kType
,
2297 mem1
.id
, mem1
.offset
);
2298 expected
.set_token
.Init(GetNextToken());
2300 kTarget
, kLevel
, kFormat
, kWidth
, kHeight
, kBorder
, kFormat
, kType
,
2302 EXPECT_EQ(0, memcmp(&expected
, commands_
, sizeof(expected
)));
2303 EXPECT_TRUE(CheckRect(
2304 kWidth
, kHeight
, kFormat
, kType
, kPixelStoreUnpackAlignment
, false,
2308 gl_
->PixelStorei(GL_UNPACK_FLIP_Y_CHROMIUM
, GL_TRUE
);
2310 ExpectedMemoryInfo mem2
= GetExpectedMemory(sizeof(pixels
));
2312 expected2
.tex_image_2d
.Init(
2313 kTarget
, kLevel
, kFormat
, kWidth
, kHeight
, kFormat
, kType
,
2314 mem2
.id
, mem2
.offset
);
2315 expected2
.set_token
.Init(GetNextToken());
2316 const void* commands2
= GetPut();
2318 kTarget
, kLevel
, kFormat
, kWidth
, kHeight
, kBorder
, kFormat
, kType
,
2320 EXPECT_EQ(0, memcmp(&expected2
, commands2
, sizeof(expected2
)));
2321 EXPECT_TRUE(CheckRect(
2322 kWidth
, kHeight
, kFormat
, kType
, kPixelStoreUnpackAlignment
, true,
2326 TEST_F(GLES2ImplementationTest
, TexImage2DViaMappedMem
) {
2328 cmds::TexImage2D tex_image_2d
;
2329 cmd::SetToken set_token
;
2331 const GLenum kTarget
= GL_TEXTURE_2D
;
2332 const GLint kLevel
= 0;
2333 const GLenum kFormat
= GL_RGB
;
2334 const GLsizei kWidth
= 3;
2335 const GLint kBorder
= 0;
2336 const GLenum kType
= GL_UNSIGNED_BYTE
;
2337 const GLint kPixelStoreUnpackAlignment
= 4;
2340 uint32 unpadded_row_size
= 0;
2341 uint32 padded_row_size
= 0;
2342 ASSERT_TRUE(GLES2Util::ComputeImageDataSizes(
2343 kWidth
, 2, 1, kFormat
, kType
, kPixelStoreUnpackAlignment
,
2344 &size
, &unpadded_row_size
, &padded_row_size
));
2345 const GLsizei kMaxHeight
= (MaxTransferBufferSize() / padded_row_size
) * 2;
2346 const GLsizei kHeight
= kMaxHeight
* 2;
2347 ASSERT_TRUE(GLES2Util::ComputeImageDataSizes(
2348 kWidth
, kHeight
, 1, kFormat
, kType
, kPixelStoreUnpackAlignment
,
2349 &size
, &unpadded_row_size
, &padded_row_size
));
2351 scoped_ptr
<uint8
[]> pixels(new uint8
[size
]);
2352 for (uint32 ii
= 0; ii
< size
; ++ii
) {
2353 pixels
[ii
] = static_cast<uint8
>(ii
);
2356 ExpectedMemoryInfo mem1
= GetExpectedMappedMemory(size
);
2359 expected
.tex_image_2d
.Init(
2360 kTarget
, kLevel
, kFormat
, kWidth
, kHeight
, kFormat
, kType
,
2361 mem1
.id
, mem1
.offset
);
2362 expected
.set_token
.Init(GetNextToken());
2364 kTarget
, kLevel
, kFormat
, kWidth
, kHeight
, kBorder
, kFormat
, kType
,
2366 EXPECT_EQ(0, memcmp(&expected
, commands_
, sizeof(expected
)));
2367 EXPECT_TRUE(CheckRect(
2368 kWidth
, kHeight
, kFormat
, kType
, kPixelStoreUnpackAlignment
, false,
2369 pixels
.get(), mem1
.ptr
));
2372 // Test TexImage2D with 2 writes
2373 TEST_F(GLES2ImplementationTest
, TexImage2DViaTexSubImage2D
) {
2374 // Set limit to 1 to effectively disable mapped memory.
2375 SetMappedMemoryLimit(1);
2378 cmds::TexImage2D tex_image_2d
;
2379 cmds::TexSubImage2D tex_sub_image_2d1
;
2380 cmd::SetToken set_token1
;
2381 cmds::TexSubImage2D tex_sub_image_2d2
;
2382 cmd::SetToken set_token2
;
2384 const GLenum kTarget
= GL_TEXTURE_2D
;
2385 const GLint kLevel
= 0;
2386 const GLenum kFormat
= GL_RGB
;
2387 const GLint kBorder
= 0;
2388 const GLenum kType
= GL_UNSIGNED_BYTE
;
2389 const GLint kPixelStoreUnpackAlignment
= 4;
2390 const GLsizei kWidth
= 3;
2393 uint32 unpadded_row_size
= 0;
2394 uint32 padded_row_size
= 0;
2395 ASSERT_TRUE(GLES2Util::ComputeImageDataSizes(
2396 kWidth
, 2, 1, kFormat
, kType
, kPixelStoreUnpackAlignment
,
2397 &size
, &unpadded_row_size
, &padded_row_size
));
2398 const GLsizei kHeight
= (MaxTransferBufferSize() / padded_row_size
) * 2;
2399 ASSERT_TRUE(GLES2Util::ComputeImageDataSizes(
2400 kWidth
, kHeight
, 1, kFormat
, kType
, kPixelStoreUnpackAlignment
,
2401 &size
, NULL
, NULL
));
2402 uint32 half_size
= 0;
2403 ASSERT_TRUE(GLES2Util::ComputeImageDataSizes(
2404 kWidth
, kHeight
/ 2, 1, kFormat
, kType
, kPixelStoreUnpackAlignment
,
2405 &half_size
, NULL
, NULL
));
2407 scoped_ptr
<uint8
[]> pixels(new uint8
[size
]);
2408 for (uint32 ii
= 0; ii
< size
; ++ii
) {
2409 pixels
[ii
] = static_cast<uint8
>(ii
);
2412 ExpectedMemoryInfo mem1
= GetExpectedMemory(half_size
);
2413 ExpectedMemoryInfo mem2
= GetExpectedMemory(half_size
);
2416 expected
.tex_image_2d
.Init(
2417 kTarget
, kLevel
, kFormat
, kWidth
, kHeight
, kFormat
, kType
,
2419 expected
.tex_sub_image_2d1
.Init(
2420 kTarget
, kLevel
, 0, 0, kWidth
, kHeight
/ 2, kFormat
, kType
,
2421 mem1
.id
, mem1
.offset
, true);
2422 expected
.set_token1
.Init(GetNextToken());
2423 expected
.tex_sub_image_2d2
.Init(
2424 kTarget
, kLevel
, 0, kHeight
/ 2, kWidth
, kHeight
/ 2, kFormat
, kType
,
2425 mem2
.id
, mem2
.offset
, true);
2426 expected
.set_token2
.Init(GetNextToken());
2428 // TODO(gman): Make it possible to run this test
2429 // EXPECT_CALL(*command_buffer(), OnFlush())
2430 // .WillOnce(CheckRectAction(
2431 // kWidth, kHeight / 2, kFormat, kType, kPixelStoreUnpackAlignment,
2432 // false, pixels.get(),
2433 // GetExpectedTransferAddressFromOffsetAs<uint8>(offset1, half_size)))
2434 // .RetiresOnSaturation();
2437 kTarget
, kLevel
, kFormat
, kWidth
, kHeight
, kBorder
, kFormat
, kType
,
2439 EXPECT_EQ(0, memcmp(&expected
, commands_
, sizeof(expected
)));
2440 EXPECT_TRUE(CheckRect(
2441 kWidth
, kHeight
/ 2, kFormat
, kType
, kPixelStoreUnpackAlignment
, false,
2442 pixels
.get() + kHeight
/ 2 * padded_row_size
, mem2
.ptr
));
2445 gl_
->PixelStorei(GL_UNPACK_FLIP_Y_CHROMIUM
, GL_TRUE
);
2446 const void* commands2
= GetPut();
2447 ExpectedMemoryInfo mem3
= GetExpectedMemory(half_size
);
2448 ExpectedMemoryInfo mem4
= GetExpectedMemory(half_size
);
2449 expected
.tex_image_2d
.Init(
2450 kTarget
, kLevel
, kFormat
, kWidth
, kHeight
, kFormat
, kType
,
2452 expected
.tex_sub_image_2d1
.Init(
2453 kTarget
, kLevel
, 0, kHeight
/ 2, kWidth
, kHeight
/ 2, kFormat
, kType
,
2454 mem3
.id
, mem3
.offset
, true);
2455 expected
.set_token1
.Init(GetNextToken());
2456 expected
.tex_sub_image_2d2
.Init(
2457 kTarget
, kLevel
, 0, 0, kWidth
, kHeight
/ 2, kFormat
, kType
,
2458 mem4
.id
, mem4
.offset
, true);
2459 expected
.set_token2
.Init(GetNextToken());
2461 // TODO(gman): Make it possible to run this test
2462 // EXPECT_CALL(*command_buffer(), OnFlush())
2463 // .WillOnce(CheckRectAction(
2464 // kWidth, kHeight / 2, kFormat, kType, kPixelStoreUnpackAlignment,
2465 // true, pixels.get(),
2466 // GetExpectedTransferAddressFromOffsetAs<uint8>(offset3, half_size)))
2467 // .RetiresOnSaturation();
2470 kTarget
, kLevel
, kFormat
, kWidth
, kHeight
, kBorder
, kFormat
, kType
,
2472 EXPECT_EQ(0, memcmp(&expected
, commands2
, sizeof(expected
)));
2473 EXPECT_TRUE(CheckRect(
2474 kWidth
, kHeight
/ 2, kFormat
, kType
, kPixelStoreUnpackAlignment
, true,
2475 pixels
.get() + kHeight
/ 2 * padded_row_size
, mem4
.ptr
));
2478 // Test TexSubImage2D with GL_PACK_FLIP_Y set and partial multirow transfers
2479 TEST_F(GLES2ImplementationTest
, TexSubImage2DFlipY
) {
2480 const GLsizei kTextureWidth
= MaxTransferBufferSize() / 4;
2481 const GLsizei kTextureHeight
= 7;
2482 const GLsizei kSubImageWidth
= MaxTransferBufferSize() / 8;
2483 const GLsizei kSubImageHeight
= 4;
2484 const GLint kSubImageXOffset
= 1;
2485 const GLint kSubImageYOffset
= 2;
2486 const GLenum kFormat
= GL_RGBA
;
2487 const GLenum kType
= GL_UNSIGNED_BYTE
;
2488 const GLenum kTarget
= GL_TEXTURE_2D
;
2489 const GLint kLevel
= 0;
2490 const GLint kBorder
= 0;
2491 const GLint kPixelStoreUnpackAlignment
= 4;
2494 cmds::PixelStorei pixel_store_i1
;
2495 cmds::TexImage2D tex_image_2d
;
2496 cmds::PixelStorei pixel_store_i2
;
2497 cmds::TexSubImage2D tex_sub_image_2d1
;
2498 cmd::SetToken set_token1
;
2499 cmds::TexSubImage2D tex_sub_image_2d2
;
2500 cmd::SetToken set_token2
;
2503 uint32 sub_2_high_size
= 0;
2504 ASSERT_TRUE(GLES2Util::ComputeImageDataSizes(
2505 kSubImageWidth
, 2, 1, kFormat
, kType
, kPixelStoreUnpackAlignment
,
2506 &sub_2_high_size
, NULL
, NULL
));
2508 ExpectedMemoryInfo mem1
= GetExpectedMemory(sub_2_high_size
);
2509 ExpectedMemoryInfo mem2
= GetExpectedMemory(sub_2_high_size
);
2512 expected
.pixel_store_i1
.Init(GL_UNPACK_ALIGNMENT
, kPixelStoreUnpackAlignment
);
2513 expected
.tex_image_2d
.Init(
2514 kTarget
, kLevel
, kFormat
, kTextureWidth
, kTextureHeight
, kFormat
,
2516 expected
.pixel_store_i2
.Init(GL_UNPACK_FLIP_Y_CHROMIUM
, GL_TRUE
);
2517 expected
.tex_sub_image_2d1
.Init(kTarget
, kLevel
, kSubImageXOffset
,
2518 kSubImageYOffset
+ 2, kSubImageWidth
, 2, kFormat
, kType
,
2519 mem1
.id
, mem1
.offset
, false);
2520 expected
.set_token1
.Init(GetNextToken());
2521 expected
.tex_sub_image_2d2
.Init(kTarget
, kLevel
, kSubImageXOffset
,
2522 kSubImageYOffset
, kSubImageWidth
, 2, kFormat
, kType
,
2523 mem2
.id
, mem2
.offset
, false);
2524 expected
.set_token2
.Init(GetNextToken());
2526 gl_
->PixelStorei(GL_UNPACK_ALIGNMENT
, kPixelStoreUnpackAlignment
);
2528 kTarget
, kLevel
, kFormat
, kTextureWidth
, kTextureHeight
, kBorder
, kFormat
,
2530 gl_
->PixelStorei(GL_UNPACK_FLIP_Y_CHROMIUM
, GL_TRUE
);
2531 scoped_ptr
<uint32
[]> pixels(new uint32
[kSubImageWidth
* kSubImageHeight
]);
2532 for (int y
= 0; y
< kSubImageHeight
; ++y
) {
2533 for (int x
= 0; x
< kSubImageWidth
; ++x
) {
2534 pixels
.get()[kSubImageWidth
* y
+ x
] = x
| (y
<< 16);
2538 GL_TEXTURE_2D
, 0, kSubImageXOffset
, kSubImageYOffset
, kSubImageWidth
,
2539 kSubImageHeight
, GL_RGBA
, GL_UNSIGNED_BYTE
, pixels
.get());
2541 EXPECT_EQ(0, memcmp(&expected
, commands_
, sizeof(expected
)));
2542 EXPECT_TRUE(CheckRect(
2543 kSubImageWidth
, 2, kFormat
, kType
, kPixelStoreUnpackAlignment
, true,
2544 reinterpret_cast<uint8
*>(pixels
.get() + 2 * kSubImageWidth
),
2548 TEST_F(GLES2ImplementationTest
, SubImageUnpack
) {
2549 static const GLint unpack_alignments
[] = { 1, 2, 4, 8 };
2551 static const GLenum kFormat
= GL_RGB
;
2552 static const GLenum kType
= GL_UNSIGNED_BYTE
;
2553 static const GLint kLevel
= 0;
2554 static const GLint kBorder
= 0;
2555 // We're testing using the unpack params to pull a subimage out of a larger
2556 // source of pixels. Here we specify the subimage by its border rows /
2558 static const GLint kSrcWidth
= 33;
2559 static const GLint kSrcSubImageX0
= 11;
2560 static const GLint kSrcSubImageX1
= 20;
2561 static const GLint kSrcSubImageY0
= 18;
2562 static const GLint kSrcSubImageY1
= 23;
2563 static const GLint kSrcSubImageWidth
= kSrcSubImageX1
- kSrcSubImageX0
;
2564 static const GLint kSrcSubImageHeight
= kSrcSubImageY1
- kSrcSubImageY0
;
2566 // these are only used in the texsubimage tests
2567 static const GLint kTexWidth
= 1023;
2568 static const GLint kTexHeight
= 511;
2569 static const GLint kTexSubXOffset
= 419;
2570 static const GLint kTexSubYOffset
= 103;
2573 cmds::PixelStorei pixel_store_i
;
2574 cmds::PixelStorei pixel_store_i2
;
2575 cmds::TexImage2D tex_image_2d
;
2579 cmds::PixelStorei pixel_store_i
;
2580 cmds::PixelStorei pixel_store_i2
;
2581 cmds::TexImage2D tex_image_2d
;
2582 cmds::TexSubImage2D tex_sub_image_2d
;
2583 } texSubImageExpected
;
2586 ASSERT_TRUE(GLES2Util::ComputeImageDataSizes(
2587 kSrcWidth
, kSrcSubImageY1
, 1, kFormat
, kType
, 8, &src_size
, NULL
, NULL
));
2588 scoped_ptr
<uint8
[]> src_pixels
;
2589 src_pixels
.reset(new uint8
[src_size
]);
2590 for (size_t i
= 0; i
< src_size
; ++i
) {
2591 src_pixels
[i
] = static_cast<int8
>(i
);
2594 for (int sub
= 0; sub
< 2; ++sub
) {
2595 for (int flip_y
= 0; flip_y
< 2; ++flip_y
) {
2596 for (size_t a
= 0; a
< arraysize(unpack_alignments
); ++a
) {
2597 GLint alignment
= unpack_alignments
[a
];
2599 uint32 unpadded_row_size
;
2600 uint32 padded_row_size
;
2601 ASSERT_TRUE(GLES2Util::ComputeImageDataSizes(
2602 kSrcSubImageWidth
, kSrcSubImageHeight
, 1, kFormat
, kType
, alignment
,
2603 &size
, &unpadded_row_size
, &padded_row_size
));
2604 ASSERT_TRUE(size
<= MaxTransferBufferSize());
2605 ExpectedMemoryInfo mem
= GetExpectedMemory(size
);
2607 const void* commands
= GetPut();
2608 gl_
->PixelStorei(GL_UNPACK_ALIGNMENT
, alignment
);
2609 gl_
->PixelStorei(GL_UNPACK_ROW_LENGTH_EXT
, kSrcWidth
);
2610 gl_
->PixelStorei(GL_UNPACK_SKIP_PIXELS_EXT
, kSrcSubImageX0
);
2611 gl_
->PixelStorei(GL_UNPACK_SKIP_ROWS_EXT
, kSrcSubImageY0
);
2612 gl_
->PixelStorei(GL_UNPACK_FLIP_Y_CHROMIUM
, flip_y
);
2615 GL_TEXTURE_2D
, kLevel
, kFormat
, kTexWidth
, kTexHeight
, kBorder
,
2616 kFormat
, kType
, NULL
);
2618 GL_TEXTURE_2D
, kLevel
, kTexSubXOffset
, kTexSubYOffset
,
2619 kSrcSubImageWidth
, kSrcSubImageHeight
, kFormat
, kType
,
2621 texSubImageExpected
.pixel_store_i
.Init(
2622 GL_UNPACK_ALIGNMENT
, alignment
);
2623 texSubImageExpected
.pixel_store_i2
.Init(
2624 GL_UNPACK_FLIP_Y_CHROMIUM
, flip_y
);
2625 texSubImageExpected
.tex_image_2d
.Init(
2626 GL_TEXTURE_2D
, kLevel
, kFormat
, kTexWidth
, kTexHeight
,
2627 kFormat
, kType
, 0, 0);
2628 texSubImageExpected
.tex_sub_image_2d
.Init(
2629 GL_TEXTURE_2D
, kLevel
, kTexSubXOffset
, kTexSubYOffset
,
2630 kSrcSubImageWidth
, kSrcSubImageHeight
, kFormat
, kType
, mem
.id
,
2631 mem
.offset
, GL_FALSE
);
2632 EXPECT_EQ(0, memcmp(
2633 &texSubImageExpected
, commands
, sizeof(texSubImageExpected
)));
2636 GL_TEXTURE_2D
, kLevel
, kFormat
,
2637 kSrcSubImageWidth
, kSrcSubImageHeight
, kBorder
, kFormat
, kType
,
2639 texImageExpected
.pixel_store_i
.Init(GL_UNPACK_ALIGNMENT
, alignment
);
2640 texImageExpected
.pixel_store_i2
.Init(
2641 GL_UNPACK_FLIP_Y_CHROMIUM
, flip_y
);
2642 texImageExpected
.tex_image_2d
.Init(
2643 GL_TEXTURE_2D
, kLevel
, kFormat
, kSrcSubImageWidth
,
2644 kSrcSubImageHeight
, kFormat
, kType
, mem
.id
, mem
.offset
);
2645 EXPECT_EQ(0, memcmp(
2646 &texImageExpected
, commands
, sizeof(texImageExpected
)));
2648 uint32 src_padded_row_size
;
2649 ASSERT_TRUE(GLES2Util::ComputeImagePaddedRowSize(
2650 kSrcWidth
, kFormat
, kType
, alignment
, &src_padded_row_size
));
2651 uint32 bytes_per_group
= GLES2Util::ComputeImageGroupSize(
2653 for (int y
= 0; y
< kSrcSubImageHeight
; ++y
) {
2654 GLint src_sub_y
= flip_y
? kSrcSubImageHeight
- y
- 1 : y
;
2655 const uint8
* src_row
= src_pixels
.get() +
2656 (kSrcSubImageY0
+ src_sub_y
) * src_padded_row_size
+
2657 bytes_per_group
* kSrcSubImageX0
;
2658 const uint8
* dst_row
= mem
.ptr
+ y
* padded_row_size
;
2659 EXPECT_EQ(0, memcmp(src_row
, dst_row
, unpadded_row_size
));
2667 // Test texture related calls with invalid arguments.
2668 TEST_F(GLES2ImplementationTest
, TextureInvalidArguments
) {
2670 cmds::TexImage2D tex_image_2d
;
2671 cmd::SetToken set_token
;
2673 const GLenum kTarget
= GL_TEXTURE_2D
;
2674 const GLint kLevel
= 0;
2675 const GLenum kFormat
= GL_RGB
;
2676 const GLsizei kWidth
= 3;
2677 const GLsizei kHeight
= 4;
2678 const GLint kBorder
= 0;
2679 const GLint kInvalidBorder
= 1;
2680 const GLenum kType
= GL_UNSIGNED_BYTE
;
2681 const GLint kPixelStoreUnpackAlignment
= 4;
2682 static uint8 pixels
[] = {
2683 11, 12, 13, 13, 14, 15, 15, 16, 17, 101, 102, 103,
2684 21, 22, 23, 23, 24, 25, 25, 26, 27, 201, 202, 203,
2685 31, 32, 33, 33, 34, 35, 35, 36, 37, 123, 124, 125,
2686 41, 42, 43, 43, 44, 45, 45, 46, 47,
2689 // Verify that something works.
2691 ExpectedMemoryInfo mem1
= GetExpectedMemory(sizeof(pixels
));
2694 expected
.tex_image_2d
.Init(
2695 kTarget
, kLevel
, kFormat
, kWidth
, kHeight
, kFormat
, kType
,
2696 mem1
.id
, mem1
.offset
);
2697 expected
.set_token
.Init(GetNextToken());
2699 kTarget
, kLevel
, kFormat
, kWidth
, kHeight
, kBorder
, kFormat
, kType
,
2701 EXPECT_EQ(0, memcmp(&expected
, commands_
, sizeof(expected
)));
2702 EXPECT_TRUE(CheckRect(
2703 kWidth
, kHeight
, kFormat
, kType
, kPixelStoreUnpackAlignment
, false,
2708 // Use invalid border.
2710 kTarget
, kLevel
, kFormat
, kWidth
, kHeight
, kInvalidBorder
, kFormat
, kType
,
2713 EXPECT_TRUE(NoCommandsWritten());
2714 EXPECT_EQ(GL_INVALID_VALUE
, CheckError());
2718 gl_
->AsyncTexImage2DCHROMIUM(
2719 kTarget
, kLevel
, kFormat
, kWidth
, kHeight
, kInvalidBorder
, kFormat
, kType
,
2722 EXPECT_TRUE(NoCommandsWritten());
2723 EXPECT_EQ(GL_INVALID_VALUE
, CheckError());
2727 // Checking for CompressedTexImage2D argument validation is a bit tricky due
2728 // to (runtime-detected) compression formats. Try to infer the error with an
2730 const GLenum kCompressedFormat
= GL_ETC1_RGB8_OES
;
2731 gl_
->CompressedTexImage2D(
2732 kTarget
, kLevel
, kCompressedFormat
, kWidth
, kHeight
, kBorder
,
2733 arraysize(pixels
), pixels
);
2735 // In the above, kCompressedFormat and arraysize(pixels) are possibly wrong
2736 // values. First ensure that these do not cause failures at the client. If
2737 // this check ever fails, it probably means that client checks more than at
2738 // the time of writing of this test. In this case, more code needs to be
2739 // written for this test.
2740 EXPECT_FALSE(NoCommandsWritten());
2744 // Changing border to invalid border should make the call fail at the client
2746 gl_
->CompressedTexImage2D(
2747 kTarget
, kLevel
, kCompressedFormat
, kWidth
, kHeight
, kInvalidBorder
,
2748 arraysize(pixels
), pixels
);
2749 EXPECT_TRUE(NoCommandsWritten());
2750 EXPECT_EQ(GL_INVALID_VALUE
, CheckError());
2753 TEST_F(GLES2ImplementationTest
, TexImage3DSingleCommand
) {
2755 cmds::TexImage3D tex_image_3d
;
2757 const GLenum kTarget
= GL_TEXTURE_3D
;
2758 const GLint kLevel
= 0;
2759 const GLint kBorder
= 0;
2760 const GLenum kFormat
= GL_RGB
;
2761 const GLenum kType
= GL_UNSIGNED_BYTE
;
2762 const GLint kPixelStoreUnpackAlignment
= 4;
2763 const GLsizei kWidth
= 3;
2764 const GLsizei kDepth
= 2;
2767 uint32 unpadded_row_size
= 0;
2768 uint32 padded_row_size
= 0;
2769 ASSERT_TRUE(GLES2Util::ComputeImageDataSizes(
2770 kWidth
, 2, kDepth
, kFormat
, kType
, kPixelStoreUnpackAlignment
,
2771 &size
, &unpadded_row_size
, &padded_row_size
));
2772 // Makes sure we can just send over the data in one command.
2773 const GLsizei kHeight
= MaxTransferBufferSize() / padded_row_size
/ kDepth
;
2774 ASSERT_TRUE(GLES2Util::ComputeImageDataSizes(
2775 kWidth
, kHeight
, kDepth
, kFormat
, kType
, kPixelStoreUnpackAlignment
,
2776 &size
, NULL
, NULL
));
2778 scoped_ptr
<uint8
[]> pixels(new uint8
[size
]);
2779 for (uint32 ii
= 0; ii
< size
; ++ii
) {
2780 pixels
[ii
] = static_cast<uint8
>(ii
);
2783 ExpectedMemoryInfo mem
= GetExpectedMemory(size
);
2786 expected
.tex_image_3d
.Init(
2787 kTarget
, kLevel
, kFormat
, kWidth
, kHeight
, kDepth
,
2788 kFormat
, kType
, mem
.id
, mem
.offset
);
2791 kTarget
, kLevel
, kFormat
, kWidth
, kHeight
, kDepth
, kBorder
,
2792 kFormat
, kType
, pixels
.get());
2794 EXPECT_EQ(0, memcmp(&expected
, commands_
, sizeof(expected
)));
2795 EXPECT_TRUE(CheckRect(
2796 kWidth
, kHeight
* kDepth
, kFormat
, kType
, kPixelStoreUnpackAlignment
,
2797 false, reinterpret_cast<uint8
*>(pixels
.get()), mem
.ptr
));
2800 TEST_F(GLES2ImplementationTest
, TexImage3DViaMappedMem
) {
2802 cmds::TexImage3D tex_image_3d
;
2804 const GLenum kTarget
= GL_TEXTURE_3D
;
2805 const GLint kLevel
= 0;
2806 const GLint kBorder
= 0;
2807 const GLenum kFormat
= GL_RGB
;
2808 const GLenum kType
= GL_UNSIGNED_BYTE
;
2809 const GLint kPixelStoreUnpackAlignment
= 4;
2810 const GLsizei kWidth
= 3;
2811 const GLsizei kDepth
= 2;
2814 uint32 unpadded_row_size
= 0;
2815 uint32 padded_row_size
= 0;
2816 ASSERT_TRUE(GLES2Util::ComputeImageDataSizes(
2817 kWidth
, 2, kDepth
, kFormat
, kType
, kPixelStoreUnpackAlignment
,
2818 &size
, &unpadded_row_size
, &padded_row_size
));
2819 // Makes sure we can just send over the data in one command.
2820 const GLsizei kMaxHeight
= MaxTransferBufferSize() / padded_row_size
/ kDepth
;
2821 const GLsizei kHeight
= kMaxHeight
* 2;
2822 ASSERT_TRUE(GLES2Util::ComputeImageDataSizes(
2823 kWidth
, kHeight
, kDepth
, kFormat
, kType
, kPixelStoreUnpackAlignment
,
2824 &size
, NULL
, NULL
));
2826 scoped_ptr
<uint8
[]> pixels(new uint8
[size
]);
2827 for (uint32 ii
= 0; ii
< size
; ++ii
) {
2828 pixels
[ii
] = static_cast<uint8
>(ii
);
2831 ExpectedMemoryInfo mem
= GetExpectedMappedMemory(size
);
2834 expected
.tex_image_3d
.Init(
2835 kTarget
, kLevel
, kFormat
, kWidth
, kHeight
, kDepth
,
2836 kFormat
, kType
, mem
.id
, mem
.offset
);
2839 kTarget
, kLevel
, kFormat
, kWidth
, kHeight
, kDepth
, kBorder
,
2840 kFormat
, kType
, pixels
.get());
2842 EXPECT_EQ(0, memcmp(&expected
, commands_
, sizeof(expected
)));
2843 EXPECT_TRUE(CheckRect(
2844 kWidth
, kHeight
* kDepth
, kFormat
, kType
, kPixelStoreUnpackAlignment
,
2845 false, reinterpret_cast<uint8
*>(pixels
.get()), mem
.ptr
));
2848 TEST_F(GLES2ImplementationTest
, TexImage3DViaTexSubImage3D
) {
2849 // Set limit to 1 to effectively disable mapped memory.
2850 SetMappedMemoryLimit(1);
2853 cmds::TexImage3D tex_image_3d
;
2854 cmds::TexSubImage3D tex_sub_image_3d1
;
2855 cmd::SetToken set_token
;
2856 cmds::TexSubImage3D tex_sub_image_3d2
;
2858 const GLenum kTarget
= GL_TEXTURE_3D
;
2859 const GLint kLevel
= 0;
2860 const GLint kBorder
= 0;
2861 const GLenum kFormat
= GL_RGB
;
2862 const GLenum kType
= GL_UNSIGNED_BYTE
;
2863 const GLint kPixelStoreUnpackAlignment
= 4;
2864 const GLsizei kWidth
= 3;
2867 uint32 unpadded_row_size
= 0;
2868 uint32 padded_row_size
= 0;
2869 ASSERT_TRUE(GLES2Util::ComputeImageDataSizes(
2870 kWidth
, 2, 1, kFormat
, kType
, kPixelStoreUnpackAlignment
,
2871 &size
, &unpadded_row_size
, &padded_row_size
));
2872 // Makes sure the data is more than one command can hold.
2873 const GLsizei kHeight
= MaxTransferBufferSize() / padded_row_size
+ 3;
2874 ASSERT_TRUE(GLES2Util::ComputeImageDataSizes(
2875 kWidth
, kHeight
, 1, kFormat
, kType
, kPixelStoreUnpackAlignment
,
2876 &size
, NULL
, NULL
));
2877 uint32 first_size
= padded_row_size
* (kHeight
- 3);
2878 uint32 second_size
=
2879 padded_row_size
* 3 - (padded_row_size
- unpadded_row_size
);
2880 EXPECT_EQ(size
, first_size
+ second_size
);
2881 ExpectedMemoryInfo mem1
= GetExpectedMemory(first_size
);
2882 ExpectedMemoryInfo mem2
= GetExpectedMemory(second_size
);
2883 scoped_ptr
<uint8
[]> pixels(new uint8
[size
]);
2884 for (uint32 ii
= 0; ii
< size
; ++ii
) {
2885 pixels
[ii
] = static_cast<uint8
>(ii
);
2889 expected
.tex_image_3d
.Init(
2890 kTarget
, kLevel
, kFormat
, kWidth
, kHeight
, 1, kFormat
, kType
, 0, 0);
2891 expected
.tex_sub_image_3d1
.Init(
2892 kTarget
, kLevel
, 0, 0, 0, kWidth
, kHeight
- 3, 1, kFormat
, kType
,
2893 mem1
.id
, mem1
.offset
, GL_TRUE
);
2894 expected
.tex_sub_image_3d2
.Init(
2895 kTarget
, kLevel
, 0, kHeight
- 3, 0, kWidth
, 3, 1, kFormat
, kType
,
2896 mem2
.id
, mem2
.offset
, GL_TRUE
);
2897 expected
.set_token
.Init(GetNextToken());
2900 kTarget
, kLevel
, kFormat
, kWidth
, kHeight
, 1, kBorder
,
2901 kFormat
, kType
, pixels
.get());
2902 EXPECT_EQ(0, memcmp(&expected
, commands_
, sizeof(expected
)));
2905 // Test TexSubImage3D with 4 writes
2906 TEST_F(GLES2ImplementationTest
, TexSubImage3D4Writes
) {
2908 cmds::TexSubImage3D tex_sub_image_3d1_1
;
2909 cmd::SetToken set_token1
;
2910 cmds::TexSubImage3D tex_sub_image_3d1_2
;
2911 cmd::SetToken set_token2
;
2912 cmds::TexSubImage3D tex_sub_image_3d2_1
;
2913 cmd::SetToken set_token3
;
2914 cmds::TexSubImage3D tex_sub_image_3d2_2
;
2916 const GLenum kTarget
= GL_TEXTURE_3D
;
2917 const GLint kLevel
= 0;
2918 const GLint kXOffset
= 0;
2919 const GLint kYOffset
= 0;
2920 const GLint kZOffset
= 0;
2921 const GLenum kFormat
= GL_RGB
;
2922 const GLenum kType
= GL_UNSIGNED_BYTE
;
2923 const GLint kPixelStoreUnpackAlignment
= 4;
2924 const GLsizei kWidth
= 3;
2925 const GLsizei kDepth
= 2;
2928 uint32 unpadded_row_size
= 0;
2929 uint32 padded_row_size
= 0;
2930 ASSERT_TRUE(GLES2Util::ComputeImageDataSizes(
2931 kWidth
, 2, 1, kFormat
, kType
, kPixelStoreUnpackAlignment
,
2932 &size
, &unpadded_row_size
, &padded_row_size
));
2933 const GLsizei kHeight
= MaxTransferBufferSize() / padded_row_size
+ 2;
2934 ASSERT_TRUE(GLES2Util::ComputeImageDataSizes(
2935 kWidth
, kHeight
, kDepth
, kFormat
, kType
, kPixelStoreUnpackAlignment
,
2936 &size
, NULL
, NULL
));
2937 uint32 first_size
= (kHeight
- 2) * padded_row_size
;
2938 uint32 second_size
= 2 * padded_row_size
;
2939 uint32 third_size
= first_size
;
2940 uint32 fourth_size
= second_size
- (padded_row_size
- unpadded_row_size
);
2941 EXPECT_EQ(size
, first_size
+ second_size
+ third_size
+ fourth_size
);
2943 scoped_ptr
<uint8
[]> pixels(new uint8
[size
]);
2944 for (uint32 ii
= 0; ii
< size
; ++ii
) {
2945 pixels
[ii
] = static_cast<uint8
>(ii
);
2948 ExpectedMemoryInfo mem1_1
= GetExpectedMemory(first_size
);
2949 ExpectedMemoryInfo mem1_2
= GetExpectedMemory(second_size
);
2950 ExpectedMemoryInfo mem2_1
= GetExpectedMemory(third_size
);
2951 ExpectedMemoryInfo mem2_2
= GetExpectedMemory(fourth_size
);
2954 expected
.tex_sub_image_3d1_1
.Init(
2955 kTarget
, kLevel
, kXOffset
, kYOffset
, kZOffset
,
2956 kWidth
, kHeight
- 2, 1, kFormat
, kType
,
2957 mem1_1
.id
, mem1_1
.offset
, GL_FALSE
);
2958 expected
.tex_sub_image_3d1_2
.Init(
2959 kTarget
, kLevel
, kXOffset
, kYOffset
+ kHeight
- 2, kZOffset
,
2960 kWidth
, 2, 1, kFormat
, kType
, mem1_2
.id
, mem1_2
.offset
, GL_FALSE
);
2961 expected
.tex_sub_image_3d2_1
.Init(
2962 kTarget
, kLevel
, kXOffset
, kYOffset
, kZOffset
+ 1,
2963 kWidth
, kHeight
- 2, 1, kFormat
, kType
,
2964 mem2_1
.id
, mem2_1
.offset
, GL_FALSE
);
2965 expected
.tex_sub_image_3d2_2
.Init(
2966 kTarget
, kLevel
, kXOffset
, kYOffset
+ kHeight
- 2, kZOffset
+ 1,
2967 kWidth
, 2, 1, kFormat
, kType
, mem2_2
.id
, mem2_2
.offset
, GL_FALSE
);
2968 expected
.set_token1
.Init(GetNextToken());
2969 expected
.set_token2
.Init(GetNextToken());
2970 expected
.set_token3
.Init(GetNextToken());
2973 kTarget
, kLevel
, kXOffset
, kYOffset
, kZOffset
, kWidth
, kHeight
, kDepth
,
2974 kFormat
, kType
, pixels
.get());
2976 EXPECT_EQ(0, memcmp(&expected
, commands_
, sizeof(expected
)));
2977 uint32 offset_to_last
= first_size
+ second_size
+ third_size
;
2978 EXPECT_TRUE(CheckRect(
2979 kWidth
, 2, kFormat
, kType
, kPixelStoreUnpackAlignment
, false,
2980 reinterpret_cast<uint8
*>(pixels
.get()) + offset_to_last
, mem2_2
.ptr
));
2983 // glGen* Ids must not be reused until glDelete* commands have been
2984 // flushed by glFlush.
2985 TEST_F(GLES2ImplementationStrictSharedTest
, FlushGenerationTestBuffers
) {
2986 FlushGenerationTest
<GenBuffersAPI
>();
2988 TEST_F(GLES2ImplementationStrictSharedTest
, FlushGenerationTestFramebuffers
) {
2989 FlushGenerationTest
<GenFramebuffersAPI
>();
2991 TEST_F(GLES2ImplementationStrictSharedTest
, FlushGenerationTestRenderbuffers
) {
2992 FlushGenerationTest
<GenRenderbuffersAPI
>();
2994 TEST_F(GLES2ImplementationStrictSharedTest
, FlushGenerationTestTextures
) {
2995 FlushGenerationTest
<GenTexturesAPI
>();
2998 // glGen* Ids must not be reused cross-context until glDelete* commands are
2999 // flushed by glFlush, and the Ids are lazily freed after.
3000 TEST_F(GLES2ImplementationStrictSharedTest
, CrossContextGenerationTestBuffers
) {
3001 CrossContextGenerationTest
<GenBuffersAPI
>();
3003 TEST_F(GLES2ImplementationStrictSharedTest
,
3004 CrossContextGenerationTestFramebuffers
) {
3005 CrossContextGenerationTest
<GenFramebuffersAPI
>();
3007 TEST_F(GLES2ImplementationStrictSharedTest
,
3008 CrossContextGenerationTestRenderbuffers
) {
3009 CrossContextGenerationTest
<GenRenderbuffersAPI
>();
3011 TEST_F(GLES2ImplementationStrictSharedTest
,
3012 CrossContextGenerationTestTextures
) {
3013 CrossContextGenerationTest
<GenTexturesAPI
>();
3016 // Test Delete which causes auto flush. Tests a regression case that occurred
3018 TEST_F(GLES2ImplementationStrictSharedTest
,
3019 CrossContextGenerationAutoFlushTestBuffers
) {
3020 CrossContextGenerationAutoFlushTest
<GenBuffersAPI
>();
3022 TEST_F(GLES2ImplementationStrictSharedTest
,
3023 CrossContextGenerationAutoFlushTestFramebuffers
) {
3024 CrossContextGenerationAutoFlushTest
<GenFramebuffersAPI
>();
3026 TEST_F(GLES2ImplementationStrictSharedTest
,
3027 CrossContextGenerationAutoFlushTestRenderbuffers
) {
3028 CrossContextGenerationAutoFlushTest
<GenRenderbuffersAPI
>();
3030 TEST_F(GLES2ImplementationStrictSharedTest
,
3031 CrossContextGenerationAutoFlushTestTextures
) {
3032 CrossContextGenerationAutoFlushTest
<GenTexturesAPI
>();
3035 TEST_F(GLES2ImplementationTest
, GetString
) {
3036 const uint32 kBucketId
= GLES2Implementation::kResultBucketId
;
3037 const Str7 kString
= {"foobar"};
3038 // GL_CHROMIUM_map_sub GL_CHROMIUM_flipy are hard coded into
3039 // GLES2Implementation.
3040 const char* expected_str
=
3042 "GL_CHROMIUM_flipy "
3043 "GL_EXT_unpack_subimage "
3044 "GL_CHROMIUM_map_sub";
3045 const char kBad
= 0x12;
3047 cmd::SetBucketSize set_bucket_size1
;
3048 cmds::GetString get_string
;
3049 cmd::GetBucketStart get_bucket_start
;
3050 cmd::SetToken set_token1
;
3051 cmd::SetBucketSize set_bucket_size2
;
3053 ExpectedMemoryInfo mem1
= GetExpectedMemory(MaxTransferBufferSize());
3054 ExpectedMemoryInfo result1
=
3055 GetExpectedResultMemory(sizeof(cmd::GetBucketStart::Result
));
3057 expected
.set_bucket_size1
.Init(kBucketId
, 0);
3058 expected
.get_string
.Init(GL_EXTENSIONS
, kBucketId
);
3059 expected
.get_bucket_start
.Init(
3060 kBucketId
, result1
.id
, result1
.offset
,
3061 MaxTransferBufferSize(), mem1
.id
, mem1
.offset
);
3062 expected
.set_token1
.Init(GetNextToken());
3063 expected
.set_bucket_size2
.Init(kBucketId
, 0);
3064 char buf
[sizeof(kString
) + 1];
3065 memset(buf
, kBad
, sizeof(buf
));
3067 EXPECT_CALL(*command_buffer(), OnFlush())
3068 .WillOnce(DoAll(SetMemory(result1
.ptr
, uint32(sizeof(kString
))),
3069 SetMemory(mem1
.ptr
, kString
)))
3070 .RetiresOnSaturation();
3072 const GLubyte
* result
= gl_
->GetString(GL_EXTENSIONS
);
3073 EXPECT_EQ(0, memcmp(&expected
, commands_
, sizeof(expected
)));
3074 EXPECT_STREQ(expected_str
, reinterpret_cast<const char*>(result
));
3077 TEST_F(GLES2ImplementationTest
, PixelStoreiGLPackReverseRowOrderANGLE
) {
3078 const uint32 kBucketId
= GLES2Implementation::kResultBucketId
;
3079 const Str7 kString
= {"foobar"};
3081 cmd::SetBucketSize set_bucket_size1
;
3082 cmds::GetString get_string
;
3083 cmd::GetBucketStart get_bucket_start
;
3084 cmd::SetToken set_token1
;
3085 cmd::SetBucketSize set_bucket_size2
;
3086 cmds::PixelStorei pixel_store
;
3089 ExpectedMemoryInfo mem1
= GetExpectedMemory(MaxTransferBufferSize());
3090 ExpectedMemoryInfo result1
=
3091 GetExpectedResultMemory(sizeof(cmd::GetBucketStart::Result
));
3094 expected
.set_bucket_size1
.Init(kBucketId
, 0);
3095 expected
.get_string
.Init(GL_EXTENSIONS
, kBucketId
);
3096 expected
.get_bucket_start
.Init(
3097 kBucketId
, result1
.id
, result1
.offset
,
3098 MaxTransferBufferSize(), mem1
.id
, mem1
.offset
);
3099 expected
.set_token1
.Init(GetNextToken());
3100 expected
.set_bucket_size2
.Init(kBucketId
, 0);
3101 expected
.pixel_store
.Init(GL_PACK_REVERSE_ROW_ORDER_ANGLE
, 1);
3103 EXPECT_CALL(*command_buffer(), OnFlush())
3104 .WillOnce(DoAll(SetMemory(result1
.ptr
, uint32(sizeof(kString
))),
3105 SetMemory(mem1
.ptr
, kString
)))
3106 .RetiresOnSaturation();
3108 gl_
->PixelStorei(GL_PACK_REVERSE_ROW_ORDER_ANGLE
, 1);
3109 EXPECT_EQ(0, memcmp(&expected
, commands_
, sizeof(expected
)));
3112 TEST_F(GLES2ImplementationTest
, CreateProgram
) {
3114 cmds::CreateProgram cmd
;
3118 expected
.cmd
.Init(kProgramsAndShadersStartId
);
3119 GLuint id
= gl_
->CreateProgram();
3120 EXPECT_EQ(0, memcmp(&expected
, commands_
, sizeof(expected
)));
3121 EXPECT_EQ(kProgramsAndShadersStartId
, id
);
3124 TEST_F(GLES2ImplementationTest
, BufferDataLargerThanTransferBuffer
) {
3126 cmds::BufferData set_size
;
3127 cmds::BufferSubData copy_data1
;
3128 cmd::SetToken set_token1
;
3129 cmds::BufferSubData copy_data2
;
3130 cmd::SetToken set_token2
;
3132 const unsigned kUsableSize
=
3133 kTransferBufferSize
- GLES2Implementation::kStartingOffset
;
3134 uint8 buf
[kUsableSize
* 2] = { 0, };
3136 ExpectedMemoryInfo mem1
= GetExpectedMemory(kUsableSize
);
3137 ExpectedMemoryInfo mem2
= GetExpectedMemory(kUsableSize
);
3140 expected
.set_size
.Init(
3141 GL_ARRAY_BUFFER
, arraysize(buf
), 0, 0, GL_DYNAMIC_DRAW
);
3142 expected
.copy_data1
.Init(
3143 GL_ARRAY_BUFFER
, 0, kUsableSize
, mem1
.id
, mem1
.offset
);
3144 expected
.set_token1
.Init(GetNextToken());
3145 expected
.copy_data2
.Init(
3146 GL_ARRAY_BUFFER
, kUsableSize
, kUsableSize
, mem2
.id
, mem2
.offset
);
3147 expected
.set_token2
.Init(GetNextToken());
3148 gl_
->BufferData(GL_ARRAY_BUFFER
, arraysize(buf
), buf
, GL_DYNAMIC_DRAW
);
3149 EXPECT_EQ(0, memcmp(&expected
, commands_
, sizeof(expected
)));
3152 TEST_F(GLES2ImplementationTest
, CapabilitiesAreCached
) {
3153 static const GLenum kStates
[] = {
3158 GL_POLYGON_OFFSET_FILL
,
3159 GL_SAMPLE_ALPHA_TO_COVERAGE
,
3165 cmds::Enable enable_cmd
;
3169 for (size_t ii
= 0; ii
< arraysize(kStates
); ++ii
) {
3170 GLenum state
= kStates
[ii
];
3171 expected
.enable_cmd
.Init(state
);
3172 GLboolean result
= gl_
->IsEnabled(state
);
3173 EXPECT_EQ(static_cast<GLboolean
>(ii
== 0), result
);
3174 EXPECT_TRUE(NoCommandsWritten());
3175 const void* commands
= GetPut();
3178 EXPECT_EQ(0, memcmp(&expected
, commands
, sizeof(expected
)));
3181 result
= gl_
->IsEnabled(state
);
3182 EXPECT_TRUE(result
);
3183 EXPECT_TRUE(NoCommandsWritten());
3187 TEST_F(GLES2ImplementationTest
, BindVertexArrayOES
) {
3189 gl_
->GenVertexArraysOES(1, &id
);
3193 cmds::BindVertexArrayOES cmd
;
3196 expected
.cmd
.Init(id
);
3198 const void* commands
= GetPut();
3199 gl_
->BindVertexArrayOES(id
);
3200 EXPECT_EQ(0, memcmp(&expected
, commands
, sizeof(expected
)));
3202 gl_
->BindVertexArrayOES(id
);
3203 EXPECT_TRUE(NoCommandsWritten());
3206 TEST_F(GLES2ImplementationTest
, BeginEndQueryEXT
) {
3207 // Test GetQueryivEXT returns 0 if no current query.
3209 gl_
->GetQueryivEXT(GL_ANY_SAMPLES_PASSED_EXT
, GL_CURRENT_QUERY_EXT
, ¶m
);
3210 EXPECT_EQ(0, param
);
3212 GLuint expected_ids
[2] = { 1, 2 }; // These must match what's actually genned.
3214 cmds::GenQueriesEXTImmediate gen
;
3217 GenCmds expected_gen_cmds
;
3218 expected_gen_cmds
.gen
.Init(arraysize(expected_ids
), &expected_ids
[0]);
3219 GLuint ids
[arraysize(expected_ids
)] = { 0, };
3220 gl_
->GenQueriesEXT(arraysize(expected_ids
), &ids
[0]);
3221 EXPECT_EQ(0, memcmp(
3222 &expected_gen_cmds
, commands_
, sizeof(expected_gen_cmds
)));
3223 GLuint id1
= ids
[0];
3224 GLuint id2
= ids
[1];
3227 // Test BeginQueryEXT fails if id = 0.
3228 gl_
->BeginQueryEXT(GL_ANY_SAMPLES_PASSED_EXT
, 0);
3229 EXPECT_TRUE(NoCommandsWritten());
3230 EXPECT_EQ(GL_INVALID_OPERATION
, CheckError());
3232 // Test BeginQueryEXT inserts command.
3234 cmds::BeginQueryEXT begin_query
;
3236 BeginCmds expected_begin_cmds
;
3237 const void* commands
= GetPut();
3238 gl_
->BeginQueryEXT(GL_ANY_SAMPLES_PASSED_EXT
, id1
);
3239 QueryTracker::Query
* query
= GetQuery(id1
);
3240 ASSERT_TRUE(query
!= NULL
);
3241 expected_begin_cmds
.begin_query
.Init(
3242 GL_ANY_SAMPLES_PASSED_EXT
, id1
, query
->shm_id(), query
->shm_offset());
3243 EXPECT_EQ(0, memcmp(
3244 &expected_begin_cmds
, commands
, sizeof(expected_begin_cmds
)));
3247 // Test GetQueryivEXT returns id.
3249 gl_
->GetQueryivEXT(GL_ANY_SAMPLES_PASSED_EXT
, GL_CURRENT_QUERY_EXT
, ¶m
);
3250 EXPECT_EQ(id1
, static_cast<GLuint
>(param
));
3252 GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT
, GL_CURRENT_QUERY_EXT
, ¶m
);
3253 EXPECT_EQ(0, param
);
3255 // Test BeginQueryEXT fails if between Begin/End.
3256 gl_
->BeginQueryEXT(GL_ANY_SAMPLES_PASSED_EXT
, id2
);
3257 EXPECT_TRUE(NoCommandsWritten());
3258 EXPECT_EQ(GL_INVALID_OPERATION
, CheckError());
3260 // Test EndQueryEXT fails if target not same as current query.
3262 gl_
->EndQueryEXT(GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT
);
3263 EXPECT_TRUE(NoCommandsWritten());
3264 EXPECT_EQ(GL_INVALID_OPERATION
, CheckError());
3266 // Test EndQueryEXT sends command
3268 cmds::EndQueryEXT end_query
;
3270 EndCmds expected_end_cmds
;
3271 expected_end_cmds
.end_query
.Init(
3272 GL_ANY_SAMPLES_PASSED_EXT
, query
->submit_count());
3273 commands
= GetPut();
3274 gl_
->EndQueryEXT(GL_ANY_SAMPLES_PASSED_EXT
);
3275 EXPECT_EQ(0, memcmp(
3276 &expected_end_cmds
, commands
, sizeof(expected_end_cmds
)));
3278 // Test EndQueryEXT fails if no current query.
3280 gl_
->EndQueryEXT(GL_ANY_SAMPLES_PASSED_EXT
);
3281 EXPECT_TRUE(NoCommandsWritten());
3282 EXPECT_EQ(GL_INVALID_OPERATION
, CheckError());
3284 // Test 2nd Begin/End increments count.
3285 base::subtle::Atomic32 old_submit_count
= query
->submit_count();
3286 gl_
->BeginQueryEXT(GL_ANY_SAMPLES_PASSED_EXT
, id1
);
3287 EXPECT_NE(old_submit_count
, query
->submit_count());
3288 expected_end_cmds
.end_query
.Init(
3289 GL_ANY_SAMPLES_PASSED_EXT
, query
->submit_count());
3290 commands
= GetPut();
3291 gl_
->EndQueryEXT(GL_ANY_SAMPLES_PASSED_EXT
);
3292 EXPECT_EQ(0, memcmp(
3293 &expected_end_cmds
, commands
, sizeof(expected_end_cmds
)));
3295 // Test BeginQueryEXT fails if target changed.
3297 gl_
->BeginQueryEXT(GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT
, id1
);
3298 EXPECT_TRUE(NoCommandsWritten());
3299 EXPECT_EQ(GL_INVALID_OPERATION
, CheckError());
3301 // Test GetQueryObjectuivEXT fails if unused id
3302 GLuint available
= 0xBDu
;
3304 gl_
->GetQueryObjectuivEXT(id2
, GL_QUERY_RESULT_AVAILABLE_EXT
, &available
);
3305 EXPECT_TRUE(NoCommandsWritten());
3306 EXPECT_EQ(0xBDu
, available
);
3307 EXPECT_EQ(GL_INVALID_OPERATION
, CheckError());
3309 // Test GetQueryObjectuivEXT fails if bad id
3311 gl_
->GetQueryObjectuivEXT(4567, GL_QUERY_RESULT_AVAILABLE_EXT
, &available
);
3312 EXPECT_TRUE(NoCommandsWritten());
3313 EXPECT_EQ(0xBDu
, available
);
3314 EXPECT_EQ(GL_INVALID_OPERATION
, CheckError());
3316 // Test GetQueryObjectuivEXT CheckResultsAvailable
3318 gl_
->GetQueryObjectuivEXT(id1
, GL_QUERY_RESULT_AVAILABLE_EXT
, &available
);
3319 EXPECT_EQ(0u, available
);
3322 TEST_F(GLES2ImplementationTest
, ErrorQuery
) {
3324 gl_
->GenQueriesEXT(1, &id
);
3327 // Test BeginQueryEXT does NOT insert commands.
3328 gl_
->BeginQueryEXT(GL_GET_ERROR_QUERY_CHROMIUM
, id
);
3329 EXPECT_TRUE(NoCommandsWritten());
3330 QueryTracker::Query
* query
= GetQuery(id
);
3331 ASSERT_TRUE(query
!= NULL
);
3333 // Test EndQueryEXT sends both begin and end command
3335 cmds::BeginQueryEXT begin_query
;
3336 cmds::EndQueryEXT end_query
;
3338 EndCmds expected_end_cmds
;
3339 expected_end_cmds
.begin_query
.Init(
3340 GL_GET_ERROR_QUERY_CHROMIUM
, id
, query
->shm_id(), query
->shm_offset());
3341 expected_end_cmds
.end_query
.Init(
3342 GL_GET_ERROR_QUERY_CHROMIUM
, query
->submit_count());
3343 const void* commands
= GetPut();
3344 gl_
->EndQueryEXT(GL_GET_ERROR_QUERY_CHROMIUM
);
3345 EXPECT_EQ(0, memcmp(
3346 &expected_end_cmds
, commands
, sizeof(expected_end_cmds
)));
3349 // Check result is not yet available.
3350 GLuint available
= 0xBDu
;
3351 gl_
->GetQueryObjectuivEXT(id
, GL_QUERY_RESULT_AVAILABLE_EXT
, &available
);
3352 EXPECT_TRUE(NoCommandsWritten());
3353 EXPECT_EQ(0u, available
);
3355 // Test no commands are sent if there is a client side error.
3357 // Generate a client side error
3358 gl_
->ActiveTexture(GL_TEXTURE0
- 1);
3360 gl_
->BeginQueryEXT(GL_GET_ERROR_QUERY_CHROMIUM
, id
);
3361 gl_
->EndQueryEXT(GL_GET_ERROR_QUERY_CHROMIUM
);
3362 EXPECT_TRUE(NoCommandsWritten());
3364 // Check result is available.
3365 gl_
->GetQueryObjectuivEXT(id
, GL_QUERY_RESULT_AVAILABLE_EXT
, &available
);
3366 EXPECT_TRUE(NoCommandsWritten());
3367 EXPECT_NE(0u, available
);
3370 GLuint result
= 0xBDu
;
3371 gl_
->GetQueryObjectuivEXT(id
, GL_QUERY_RESULT_EXT
, &result
);
3372 EXPECT_TRUE(NoCommandsWritten());
3373 EXPECT_EQ(static_cast<GLuint
>(GL_INVALID_ENUM
), result
);
3376 #if !defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS)
3377 TEST_F(GLES2ImplementationTest
, VertexArrays
) {
3378 const GLuint kAttribIndex1
= 1;
3379 const GLint kNumComponents1
= 3;
3380 const GLsizei kClientStride
= 12;
3383 gl_
->GenVertexArraysOES(1, &id
);
3386 gl_
->BindVertexArrayOES(id
);
3388 // Test that VertexAttribPointer cannot be called with a bound buffer of 0
3389 // unless the offset is NULL
3390 gl_
->BindBuffer(GL_ARRAY_BUFFER
, 0);
3392 gl_
->VertexAttribPointer(
3393 kAttribIndex1
, kNumComponents1
, GL_FLOAT
, GL_FALSE
, kClientStride
,
3394 reinterpret_cast<const void*>(4));
3395 EXPECT_EQ(GL_INVALID_OPERATION
, CheckError());
3397 gl_
->VertexAttribPointer(
3398 kAttribIndex1
, kNumComponents1
, GL_FLOAT
, GL_FALSE
, kClientStride
, NULL
);
3399 EXPECT_EQ(GL_NO_ERROR
, CheckError());
3403 TEST_F(GLES2ImplementationTest
, Disable
) {
3408 expected
.cmd
.Init(GL_DITHER
); // Note: DITHER defaults to enabled.
3410 gl_
->Disable(GL_DITHER
);
3411 EXPECT_EQ(0, memcmp(&expected
, commands_
, sizeof(expected
)));
3412 // Check it's cached and not called again.
3414 gl_
->Disable(GL_DITHER
);
3415 EXPECT_TRUE(NoCommandsWritten());
3418 TEST_F(GLES2ImplementationTest
, Enable
) {
3423 expected
.cmd
.Init(GL_BLEND
); // Note: BLEND defaults to disabled.
3425 gl_
->Enable(GL_BLEND
);
3426 EXPECT_EQ(0, memcmp(&expected
, commands_
, sizeof(expected
)));
3427 // Check it's cached and not called again.
3429 gl_
->Enable(GL_BLEND
);
3430 EXPECT_TRUE(NoCommandsWritten());
3433 TEST_F(GLES2ImplementationTest
, ConsumeTextureCHROMIUM
) {
3435 cmds::ConsumeTextureCHROMIUMImmediate cmd
;
3439 Mailbox mailbox
= Mailbox::Generate();
3441 expected
.cmd
.Init(GL_TEXTURE_2D
, mailbox
.name
);
3442 gl_
->ConsumeTextureCHROMIUM(GL_TEXTURE_2D
, mailbox
.name
);
3443 EXPECT_EQ(0, memcmp(&expected
, commands_
, sizeof(expected
)));
3446 TEST_F(GLES2ImplementationTest
, CreateAndConsumeTextureCHROMIUM
) {
3448 cmds::CreateAndConsumeTextureCHROMIUMImmediate cmd
;
3452 Mailbox mailbox
= Mailbox::Generate();
3454 expected
.cmd
.Init(GL_TEXTURE_2D
, kTexturesStartId
, mailbox
.name
);
3455 GLuint id
= gl_
->CreateAndConsumeTextureCHROMIUM(GL_TEXTURE_2D
, mailbox
.name
);
3456 EXPECT_EQ(0, memcmp(&expected
, commands_
, sizeof(expected
)));
3457 EXPECT_EQ(kTexturesStartId
, id
);
3460 TEST_F(GLES2ImplementationTest
, ProduceTextureCHROMIUM
) {
3462 cmds::ProduceTextureCHROMIUMImmediate cmd
;
3466 Mailbox mailbox
= Mailbox::Generate();
3468 expected
.cmd
.Init(GL_TEXTURE_2D
, mailbox
.name
);
3469 gl_
->ProduceTextureCHROMIUM(GL_TEXTURE_2D
, mailbox
.name
);
3470 EXPECT_EQ(0, memcmp(&expected
, commands_
, sizeof(expected
)));
3473 TEST_F(GLES2ImplementationTest
, ProduceTextureDirectCHROMIUM
) {
3475 cmds::ProduceTextureDirectCHROMIUMImmediate cmd
;
3479 Mailbox mailbox
= Mailbox::Generate();
3481 expected
.cmd
.Init(kTexturesStartId
, GL_TEXTURE_2D
, mailbox
.name
);
3482 gl_
->ProduceTextureDirectCHROMIUM(
3483 kTexturesStartId
, GL_TEXTURE_2D
, mailbox
.name
);
3484 EXPECT_EQ(0, memcmp(&expected
, commands_
, sizeof(expected
)));
3487 TEST_F(GLES2ImplementationTest
, LimitSizeAndOffsetTo32Bit
) {
3490 if (sizeof(size
) <= 4 || sizeof(offset
) <= 4)
3492 // The below two casts should be no-op, as we return early if
3493 // it's 32-bit system.
3494 int64 value64
= 0x100000000;
3495 size
= static_cast<GLsizeiptr
>(value64
);
3496 offset
= static_cast<GLintptr
>(value64
);
3498 const char kSizeOverflowMessage
[] = "size more than 32-bit";
3499 const char kOffsetOverflowMessage
[] = "offset more than 32-bit";
3501 const GLfloat buf
[] = { 1.0, 1.0, 1.0, 1.0 };
3502 const GLubyte indices
[] = { 0 };
3504 const GLuint kClientArrayBufferId
= 0x789;
3505 const GLuint kClientElementArrayBufferId
= 0x790;
3506 gl_
->BindBuffer(GL_ARRAY_BUFFER
, kClientArrayBufferId
);
3507 gl_
->BindBuffer(GL_ELEMENT_ARRAY_BUFFER
, kClientElementArrayBufferId
);
3508 EXPECT_EQ(GL_NO_ERROR
, CheckError());
3510 // Call BufferData() should succeed with legal paramaters.
3511 gl_
->BufferData(GL_ARRAY_BUFFER
, sizeof(buf
), buf
, GL_DYNAMIC_DRAW
);
3513 GL_ELEMENT_ARRAY_BUFFER
, sizeof(indices
), indices
, GL_DYNAMIC_DRAW
);
3514 EXPECT_EQ(GL_NO_ERROR
, CheckError());
3517 gl_
->BufferData(GL_ARRAY_BUFFER
, size
, buf
, GL_DYNAMIC_DRAW
);
3518 EXPECT_EQ(GL_INVALID_OPERATION
, CheckError());
3519 EXPECT_STREQ(kSizeOverflowMessage
, GetLastError().c_str());
3521 // Call BufferSubData() should succeed with legal paramaters.
3522 gl_
->BufferSubData(GL_ARRAY_BUFFER
, 0, sizeof(buf
[0]), buf
);
3523 EXPECT_EQ(GL_NO_ERROR
, CheckError());
3525 // BufferSubData: offset
3526 gl_
->BufferSubData(GL_ARRAY_BUFFER
, offset
, 1, buf
);
3527 EXPECT_EQ(GL_INVALID_OPERATION
, CheckError());
3528 EXPECT_STREQ(kOffsetOverflowMessage
, GetLastError().c_str());
3530 // BufferSubData: size
3531 EXPECT_EQ(GL_NO_ERROR
, CheckError());
3532 gl_
->BufferSubData(GL_ARRAY_BUFFER
, 0, size
, buf
);
3533 EXPECT_EQ(GL_INVALID_OPERATION
, CheckError());
3534 EXPECT_STREQ(kSizeOverflowMessage
, GetLastError().c_str());
3536 // Call MapBufferSubDataCHROMIUM() should succeed with legal paramaters.
3538 gl_
->MapBufferSubDataCHROMIUM(GL_ARRAY_BUFFER
, 0, 1, GL_WRITE_ONLY
);
3539 EXPECT_TRUE(NULL
!= mem
);
3540 EXPECT_EQ(GL_NO_ERROR
, CheckError());
3541 gl_
->UnmapBufferSubDataCHROMIUM(mem
);
3543 // MapBufferSubDataCHROMIUM: offset
3544 EXPECT_TRUE(NULL
== gl_
->MapBufferSubDataCHROMIUM(
3545 GL_ARRAY_BUFFER
, offset
, 1, GL_WRITE_ONLY
));
3546 EXPECT_EQ(GL_INVALID_OPERATION
, CheckError());
3547 EXPECT_STREQ(kOffsetOverflowMessage
, GetLastError().c_str());
3549 // MapBufferSubDataCHROMIUM: size
3550 EXPECT_EQ(GL_NO_ERROR
, CheckError());
3551 EXPECT_TRUE(NULL
== gl_
->MapBufferSubDataCHROMIUM(
3552 GL_ARRAY_BUFFER
, 0, size
, GL_WRITE_ONLY
));
3553 EXPECT_EQ(GL_INVALID_OPERATION
, CheckError());
3554 EXPECT_STREQ(kSizeOverflowMessage
, GetLastError().c_str());
3556 // Call DrawElements() should succeed with legal paramaters.
3557 gl_
->DrawElements(GL_POINTS
, 1, GL_UNSIGNED_BYTE
, NULL
);
3558 EXPECT_EQ(GL_NO_ERROR
, CheckError());
3560 // DrawElements: offset
3562 GL_POINTS
, 1, GL_UNSIGNED_BYTE
, reinterpret_cast<void*>(offset
));
3563 EXPECT_EQ(GL_INVALID_OPERATION
, CheckError());
3564 EXPECT_STREQ(kOffsetOverflowMessage
, GetLastError().c_str());
3566 // Call DrawElementsInstancedANGLE() should succeed with legal paramaters.
3567 gl_
->DrawElementsInstancedANGLE(GL_POINTS
, 1, GL_UNSIGNED_BYTE
, NULL
, 1);
3568 EXPECT_EQ(GL_NO_ERROR
, CheckError());
3570 // DrawElementsInstancedANGLE: offset
3571 gl_
->DrawElementsInstancedANGLE(
3572 GL_POINTS
, 1, GL_UNSIGNED_BYTE
, reinterpret_cast<void*>(offset
), 1);
3573 EXPECT_EQ(GL_INVALID_OPERATION
, CheckError());
3574 EXPECT_STREQ(kOffsetOverflowMessage
, GetLastError().c_str());
3576 // Call VertexAttribPointer() should succeed with legal paramaters.
3577 const GLuint kAttribIndex
= 1;
3578 const GLsizei kStride
= 4;
3579 gl_
->VertexAttribPointer(
3580 kAttribIndex
, 1, GL_FLOAT
, GL_FALSE
, kStride
, NULL
);
3581 EXPECT_EQ(GL_NO_ERROR
, CheckError());
3583 // VertexAttribPointer: offset
3584 gl_
->VertexAttribPointer(
3585 kAttribIndex
, 1, GL_FLOAT
, GL_FALSE
, kStride
,
3586 reinterpret_cast<void*>(offset
));
3587 EXPECT_EQ(GL_INVALID_OPERATION
, CheckError());
3588 EXPECT_STREQ(kOffsetOverflowMessage
, GetLastError().c_str());
3591 TEST_F(GLES2ImplementationTest
, TraceBeginCHROMIUM
) {
3592 const uint32 kCategoryBucketId
= GLES2Implementation::kResultBucketId
;
3593 const uint32 kNameBucketId
= GLES2Implementation::kResultBucketId
+ 1;
3594 const std::string category_name
= "test category";
3595 const std::string trace_name
= "test trace";
3596 const size_t kPaddedString1Size
=
3597 transfer_buffer_
->RoundToAlignment(category_name
.size() + 1);
3598 const size_t kPaddedString2Size
=
3599 transfer_buffer_
->RoundToAlignment(trace_name
.size() + 1);
3601 gl_
->TraceBeginCHROMIUM(category_name
.c_str(), trace_name
.c_str());
3602 EXPECT_EQ(GL_NO_ERROR
, CheckError());
3605 cmd::SetBucketSize category_size1
;
3606 cmd::SetBucketData category_data
;
3607 cmd::SetToken set_token1
;
3608 cmd::SetBucketSize name_size1
;
3609 cmd::SetBucketData name_data
;
3610 cmd::SetToken set_token2
;
3611 cmds::TraceBeginCHROMIUM trace_call_begin
;
3612 cmd::SetBucketSize category_size2
;
3613 cmd::SetBucketSize name_size2
;
3616 ExpectedMemoryInfo mem1
= GetExpectedMemory(kPaddedString1Size
);
3617 ExpectedMemoryInfo mem2
= GetExpectedMemory(kPaddedString2Size
);
3619 ASSERT_STREQ(category_name
.c_str(), reinterpret_cast<char*>(mem1
.ptr
));
3620 ASSERT_STREQ(trace_name
.c_str(), reinterpret_cast<char*>(mem2
.ptr
));
3623 expected
.category_size1
.Init(kCategoryBucketId
, category_name
.size() + 1);
3624 expected
.category_data
.Init(
3625 kCategoryBucketId
, 0, category_name
.size() + 1, mem1
.id
, mem1
.offset
);
3626 expected
.set_token1
.Init(GetNextToken());
3627 expected
.name_size1
.Init(kNameBucketId
, trace_name
.size() + 1);
3628 expected
.name_data
.Init(
3629 kNameBucketId
, 0, trace_name
.size() + 1, mem2
.id
, mem2
.offset
);
3630 expected
.set_token2
.Init(GetNextToken());
3631 expected
.trace_call_begin
.Init(kCategoryBucketId
, kNameBucketId
);
3632 expected
.category_size2
.Init(kCategoryBucketId
, 0);
3633 expected
.name_size2
.Init(kNameBucketId
, 0);
3635 EXPECT_EQ(0, memcmp(&expected
, commands_
, sizeof(expected
)));
3638 TEST_F(GLES2ImplementationTest
, AllowNestedTracesCHROMIUM
) {
3639 const std::string category1_name
= "test category 1";
3640 const std::string trace1_name
= "test trace 1";
3641 const std::string category2_name
= "test category 2";
3642 const std::string trace2_name
= "test trace 2";
3644 gl_
->TraceBeginCHROMIUM(category1_name
.c_str(), trace1_name
.c_str());
3645 EXPECT_EQ(GL_NO_ERROR
, CheckError());
3647 gl_
->TraceBeginCHROMIUM(category2_name
.c_str(), trace2_name
.c_str());
3648 EXPECT_EQ(GL_NO_ERROR
, CheckError());
3650 gl_
->TraceEndCHROMIUM();
3651 EXPECT_EQ(GL_NO_ERROR
, CheckError());
3653 gl_
->TraceEndCHROMIUM();
3654 EXPECT_EQ(GL_NO_ERROR
, CheckError());
3656 // No more corresponding begin tracer marker should error.
3657 gl_
->TraceEndCHROMIUM();
3658 EXPECT_EQ(GL_INVALID_OPERATION
, CheckError());
3661 TEST_F(GLES2ImplementationTest
, IsEnabled
) {
3662 // If we use a valid enum, its state is cached on client side, so no command
3663 // is actually generated, and this test will fail.
3664 // TODO(zmo): it seems we never need the command. Maybe remove it.
3667 cmds::IsEnabled cmd
;
3671 ExpectedMemoryInfo result1
=
3672 GetExpectedResultMemory(sizeof(cmds::IsEnabled::Result
));
3673 expected
.cmd
.Init(kCap
, result1
.id
, result1
.offset
);
3675 EXPECT_CALL(*command_buffer(), OnFlush())
3676 .WillOnce(SetMemory(result1
.ptr
, uint32_t(GL_TRUE
)))
3677 .RetiresOnSaturation();
3679 GLboolean result
= gl_
->IsEnabled(kCap
);
3680 EXPECT_EQ(0, memcmp(&expected
, commands_
, sizeof(expected
)));
3681 EXPECT_TRUE(result
);
3684 TEST_F(GLES2ImplementationTest
, ClientWaitSync
) {
3685 const GLuint client_sync_id
= 36;
3687 cmds::ClientWaitSync cmd
;
3691 ExpectedMemoryInfo result1
=
3692 GetExpectedResultMemory(sizeof(cmds::ClientWaitSync::Result
));
3693 const GLuint64 kTimeout
= 0xABCDEF0123456789;
3694 uint32_t v32_0
= 0, v32_1
= 0;
3695 GLES2Util::MapUint64ToTwoUint32(kTimeout
, &v32_0
, &v32_1
);
3696 expected
.cmd
.Init(client_sync_id
, GL_SYNC_FLUSH_COMMANDS_BIT
,
3697 v32_0
, v32_1
, result1
.id
, result1
.offset
);
3699 EXPECT_CALL(*command_buffer(), OnFlush())
3700 .WillOnce(SetMemory(result1
.ptr
, uint32_t(GL_CONDITION_SATISFIED
)))
3701 .RetiresOnSaturation();
3703 GLenum result
= gl_
->ClientWaitSync(
3704 reinterpret_cast<GLsync
>(client_sync_id
), GL_SYNC_FLUSH_COMMANDS_BIT
,
3706 EXPECT_EQ(0, memcmp(&expected
, commands_
, sizeof(expected
)));
3707 EXPECT_EQ(static_cast<GLenum
>(GL_CONDITION_SATISFIED
), result
);
3710 TEST_F(GLES2ImplementationTest
, WaitSync
) {
3711 const GLuint kClientSyncId
= 36;
3716 const GLuint64 kTimeout
= GL_TIMEOUT_IGNORED
;
3717 uint32_t v32_0
= 0, v32_1
= 0;
3718 GLES2Util::MapUint64ToTwoUint32(kTimeout
, &v32_0
, &v32_1
);
3719 expected
.cmd
.Init(kClientSyncId
, 0, v32_0
, v32_1
);
3721 gl_
->WaitSync(reinterpret_cast<GLsync
>(kClientSyncId
), 0, kTimeout
);
3722 EXPECT_EQ(0, memcmp(&expected
, commands_
, sizeof(expected
)));
3725 TEST_F(GLES2ImplementationTest
, MapBufferRangeUnmapBufferWrite
) {
3726 ExpectedMemoryInfo result
=
3727 GetExpectedResultMemory(sizeof(cmds::MapBufferRange::Result
));
3729 EXPECT_CALL(*command_buffer(), OnFlush())
3730 .WillOnce(SetMemory(result
.ptr
, uint32_t(1)))
3731 .RetiresOnSaturation();
3733 const GLuint kBufferId
= 123;
3734 gl_
->BindBuffer(GL_ARRAY_BUFFER
, kBufferId
);
3736 void* mem
= gl_
->MapBufferRange(GL_ARRAY_BUFFER
, 10, 64, GL_MAP_WRITE_BIT
);
3737 EXPECT_TRUE(mem
!= nullptr);
3739 EXPECT_TRUE(gl_
->UnmapBuffer(GL_ARRAY_BUFFER
));
3742 TEST_F(GLES2ImplementationTest
, MapBufferRangeWriteWithInvalidateBit
) {
3743 ExpectedMemoryInfo result
=
3744 GetExpectedResultMemory(sizeof(cmds::MapBufferRange::Result
));
3746 EXPECT_CALL(*command_buffer(), OnFlush())
3747 .WillOnce(SetMemory(result
.ptr
, uint32_t(1)))
3748 .RetiresOnSaturation();
3750 const GLuint kBufferId
= 123;
3751 gl_
->BindBuffer(GL_ARRAY_BUFFER
, kBufferId
);
3753 GLsizeiptr kSize
= 64;
3754 void* mem
= gl_
->MapBufferRange(
3755 GL_ARRAY_BUFFER
, 10, kSize
,
3756 GL_MAP_WRITE_BIT
| GL_MAP_INVALIDATE_RANGE_BIT
);
3757 EXPECT_TRUE(mem
!= nullptr);
3758 std::vector
<int8_t> zero(kSize
);
3759 memset(&zero
[0], 0, kSize
);
3760 EXPECT_EQ(0, memcmp(mem
, &zero
[0], kSize
));
3763 TEST_F(GLES2ImplementationTest
, MapBufferRangeWriteWithGLError
) {
3764 ExpectedMemoryInfo result
=
3765 GetExpectedResultMemory(sizeof(cmds::MapBufferRange::Result
));
3767 // Return a result of 0 to indicate an GL error.
3768 EXPECT_CALL(*command_buffer(), OnFlush())
3769 .WillOnce(SetMemory(result
.ptr
, uint32_t(0)))
3770 .RetiresOnSaturation();
3772 const GLuint kBufferId
= 123;
3773 gl_
->BindBuffer(GL_ARRAY_BUFFER
, kBufferId
);
3775 void* mem
= gl_
->MapBufferRange(GL_ARRAY_BUFFER
, 10, 64, GL_MAP_WRITE_BIT
);
3776 EXPECT_TRUE(mem
== nullptr);
3779 TEST_F(GLES2ImplementationTest
, MapBufferRangeUnmapBufferRead
) {
3780 ExpectedMemoryInfo result
=
3781 GetExpectedResultMemory(sizeof(cmds::MapBufferRange::Result
));
3783 EXPECT_CALL(*command_buffer(), OnFlush())
3784 .WillOnce(SetMemory(result
.ptr
, uint32_t(1)))
3785 .RetiresOnSaturation();
3787 const GLuint kBufferId
= 123;
3788 gl_
->BindBuffer(GL_ARRAY_BUFFER
, kBufferId
);
3790 void* mem
= gl_
->MapBufferRange(GL_ARRAY_BUFFER
, 10, 64, GL_MAP_READ_BIT
);
3791 EXPECT_TRUE(mem
!= nullptr);
3793 EXPECT_TRUE(gl_
->UnmapBuffer(GL_ARRAY_BUFFER
));
3796 TEST_F(GLES2ImplementationTest
, MapBufferRangeReadWithGLError
) {
3797 ExpectedMemoryInfo result
=
3798 GetExpectedResultMemory(sizeof(cmds::MapBufferRange::Result
));
3800 // Return a result of 0 to indicate an GL error.
3801 EXPECT_CALL(*command_buffer(), OnFlush())
3802 .WillOnce(SetMemory(result
.ptr
, uint32_t(0)))
3803 .RetiresOnSaturation();
3805 const GLuint kBufferId
= 123;
3806 gl_
->BindBuffer(GL_ARRAY_BUFFER
, kBufferId
);
3808 void* mem
= gl_
->MapBufferRange(GL_ARRAY_BUFFER
, 10, 64, GL_MAP_READ_BIT
);
3809 EXPECT_TRUE(mem
== nullptr);
3812 TEST_F(GLES2ImplementationTest
, UnmapBufferFails
) {
3814 EXPECT_FALSE(gl_
->UnmapBuffer(GL_ARRAY_BUFFER
));
3815 EXPECT_EQ(GL_INVALID_OPERATION
, CheckError());
3817 const GLuint kBufferId
= 123;
3818 gl_
->BindBuffer(GL_ARRAY_BUFFER
, kBufferId
);
3820 // Buffer is unmapped.
3821 EXPECT_FALSE(gl_
->UnmapBuffer(GL_ARRAY_BUFFER
));
3822 EXPECT_EQ(GL_INVALID_OPERATION
, CheckError());
3825 TEST_F(GLES2ImplementationTest
, BufferDataUnmapsDataStore
) {
3826 ExpectedMemoryInfo result
=
3827 GetExpectedResultMemory(sizeof(cmds::MapBufferRange::Result
));
3829 EXPECT_CALL(*command_buffer(), OnFlush())
3830 .WillOnce(SetMemory(result
.ptr
, uint32_t(1)))
3831 .RetiresOnSaturation();
3833 const GLuint kBufferId
= 123;
3834 gl_
->BindBuffer(GL_ARRAY_BUFFER
, kBufferId
);
3836 void* mem
= gl_
->MapBufferRange(GL_ARRAY_BUFFER
, 10, 64, GL_MAP_WRITE_BIT
);
3837 EXPECT_TRUE(mem
!= nullptr);
3839 std::vector
<uint8_t> data(16);
3840 // BufferData unmaps the data store.
3841 gl_
->BufferData(GL_ARRAY_BUFFER
, 16, &data
[0], GL_STREAM_DRAW
);
3843 EXPECT_FALSE(gl_
->UnmapBuffer(GL_ARRAY_BUFFER
));
3844 EXPECT_EQ(GL_INVALID_OPERATION
, CheckError());
3847 TEST_F(GLES2ImplementationTest
, DeleteBuffersUnmapsDataStore
) {
3848 ExpectedMemoryInfo result
=
3849 GetExpectedResultMemory(sizeof(cmds::MapBufferRange::Result
));
3851 EXPECT_CALL(*command_buffer(), OnFlush())
3852 .WillOnce(SetMemory(result
.ptr
, uint32_t(1)))
3853 .RetiresOnSaturation();
3855 const GLuint kBufferId
= 123;
3856 gl_
->BindBuffer(GL_ARRAY_BUFFER
, kBufferId
);
3858 void* mem
= gl_
->MapBufferRange(GL_ARRAY_BUFFER
, 10, 64, GL_MAP_WRITE_BIT
);
3859 EXPECT_TRUE(mem
!= nullptr);
3861 std::vector
<uint8_t> data(16);
3862 // DeleteBuffers unmaps the data store.
3863 gl_
->DeleteBuffers(1, &kBufferId
);
3865 EXPECT_FALSE(gl_
->UnmapBuffer(GL_ARRAY_BUFFER
));
3866 EXPECT_EQ(GL_INVALID_OPERATION
, CheckError());
3869 TEST_F(GLES2ImplementationTest
, GetInternalformativ
) {
3870 const GLint kNumSampleCounts
= 8;
3872 cmds::GetInternalformativ cmd
;
3874 typedef cmds::GetInternalformativ::Result::Type ResultType
;
3875 ResultType result
= 0;
3877 ExpectedMemoryInfo result1
=
3878 GetExpectedResultMemory(sizeof(uint32_t) + sizeof(ResultType
));
3879 expected
.cmd
.Init(123, GL_RGBA8
, GL_NUM_SAMPLE_COUNTS
,
3880 result1
.id
, result1
.offset
);
3881 EXPECT_CALL(*command_buffer(), OnFlush())
3882 .WillOnce(SetMemory(result1
.ptr
,
3883 SizedResultHelper
<ResultType
>(kNumSampleCounts
)))
3884 .RetiresOnSaturation();
3885 gl_
->GetInternalformativ(123, GL_RGBA8
, GL_NUM_SAMPLE_COUNTS
, 1, &result
);
3886 EXPECT_EQ(0, memcmp(&expected
, commands_
, sizeof(expected
)));
3887 EXPECT_EQ(static_cast<ResultType
>(kNumSampleCounts
), result
);
3890 TEST_F(GLES2ImplementationManualInitTest
, LoseContextOnOOM
) {
3891 ContextInitOptions init_options
;
3892 init_options
.lose_context_when_out_of_memory
= true;
3893 ASSERT_TRUE(Initialize(init_options
));
3896 cmds::LoseContextCHROMIUM cmd
;
3899 GLsizei max
= std::numeric_limits
<GLsizei
>::max();
3900 EXPECT_CALL(*gpu_control_
, CreateGpuMemoryBufferImage(max
, max
, _
, _
))
3901 .WillOnce(Return(-1));
3902 gl_
->CreateGpuMemoryBufferImageCHROMIUM(max
, max
, GL_RGBA
, GL_MAP_CHROMIUM
);
3903 // The context should be lost.
3905 expected
.cmd
.Init(GL_GUILTY_CONTEXT_RESET_ARB
, GL_UNKNOWN_CONTEXT_RESET_ARB
);
3906 EXPECT_EQ(0, memcmp(&expected
, commands_
, sizeof(expected
)));
3909 TEST_F(GLES2ImplementationManualInitTest
, NoLoseContextOnOOM
) {
3910 ContextInitOptions init_options
;
3911 ASSERT_TRUE(Initialize(init_options
));
3914 cmds::LoseContextCHROMIUM cmd
;
3917 GLsizei max
= std::numeric_limits
<GLsizei
>::max();
3918 EXPECT_CALL(*gpu_control_
, CreateGpuMemoryBufferImage(max
, max
, _
, _
))
3919 .WillOnce(Return(-1));
3920 gl_
->CreateGpuMemoryBufferImageCHROMIUM(max
, max
, GL_RGBA
, GL_MAP_CHROMIUM
);
3921 // The context should not be lost.
3922 EXPECT_TRUE(NoCommandsWritten());
3925 TEST_F(GLES2ImplementationManualInitTest
, FailInitOnBGRMismatch1
) {
3926 ContextInitOptions init_options
;
3927 init_options
.bind_generates_resource_client
= false;
3928 init_options
.bind_generates_resource_service
= true;
3929 EXPECT_FALSE(Initialize(init_options
));
3932 TEST_F(GLES2ImplementationManualInitTest
, FailInitOnBGRMismatch2
) {
3933 ContextInitOptions init_options
;
3934 init_options
.bind_generates_resource_client
= true;
3935 init_options
.bind_generates_resource_service
= false;
3936 EXPECT_FALSE(Initialize(init_options
));
3939 TEST_F(GLES2ImplementationManualInitTest
, FailInitOnTransferBufferFail
) {
3940 ContextInitOptions init_options
;
3941 init_options
.transfer_buffer_initialize_fail
= true;
3942 EXPECT_FALSE(Initialize(init_options
));
3945 #include "gpu/command_buffer/client/gles2_implementation_unittest_autogen.h"
3947 } // namespace gles2