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 #include "gpu/command_buffer/service/gles2_cmd_decoder_unittest.h"
7 #include "base/command_line.h"
8 #include "base/strings/string_number_conversions.h"
9 #include "gpu/command_buffer/common/gles2_cmd_format.h"
10 #include "gpu/command_buffer/common/gles2_cmd_utils.h"
11 #include "gpu/command_buffer/service/async_pixel_transfer_delegate_mock.h"
12 #include "gpu/command_buffer/service/async_pixel_transfer_manager.h"
13 #include "gpu/command_buffer/service/async_pixel_transfer_manager_mock.h"
14 #include "gpu/command_buffer/service/cmd_buffer_engine.h"
15 #include "gpu/command_buffer/service/context_group.h"
16 #include "gpu/command_buffer/service/context_state.h"
17 #include "gpu/command_buffer/service/gl_surface_mock.h"
18 #include "gpu/command_buffer/service/gles2_cmd_decoder.h"
19 #include "gpu/command_buffer/service/image_manager.h"
20 #include "gpu/command_buffer/service/mailbox_manager.h"
21 #include "gpu/command_buffer/service/mocks.h"
22 #include "gpu/command_buffer/service/program_manager.h"
23 #include "gpu/command_buffer/service/test_helper.h"
24 #include "gpu/config/gpu_switches.h"
25 #include "testing/gtest/include/gtest/gtest.h"
26 #include "ui/gl/gl_implementation.h"
27 #include "ui/gl/gl_mock.h"
28 #include "ui/gl/gl_surface_stub.h"
31 #if !defined(GL_DEPTH24_STENCIL8)
32 #define GL_DEPTH24_STENCIL8 0x88F0
35 using ::gfx::MockGLInterface
;
37 using ::testing::AtLeast
;
38 using ::testing::DoAll
;
39 using ::testing::InSequence
;
40 using ::testing::Invoke
;
41 using ::testing::MatcherCast
;
42 using ::testing::Mock
;
43 using ::testing::Pointee
;
44 using ::testing::Return
;
45 using ::testing::SaveArg
;
46 using ::testing::SetArrayArgument
;
47 using ::testing::SetArgumentPointee
;
48 using ::testing::SetArgPointee
;
49 using ::testing::StrEq
;
50 using ::testing::StrictMock
;
57 void GLES2DecoderRGBBackbufferTest::SetUp() {
58 // Test codepath with workaround clear_alpha_in_readpixels because
59 // ReadPixelsEmulator emulates the incorrect driver behavior.
60 base::CommandLine
command_line(0, NULL
);
61 command_line
.AppendSwitchASCII(
62 switches::kGpuDriverBugWorkarounds
,
63 base::IntToString(gpu::CLEAR_ALPHA_IN_READPIXELS
));
65 init
.bind_generates_resource
= true;
66 InitDecoderWithCommandLine(init
, &command_line
);
67 SetupDefaultProgram();
70 // Override default setup so nothing gets setup.
71 void GLES2DecoderManualInitTest::SetUp() {
74 void GLES2DecoderManualInitTest::EnableDisableTest(GLenum cap
,
78 SetupExpectationsForEnableDisable(cap
, enable
);
83 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
84 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
88 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
89 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
93 void GLES3DecoderTest::SetUp() {
94 base::CommandLine
command_line(0, NULL
);
95 command_line
.AppendSwitch(switches::kEnableUnsafeES3APIs
);
97 init
.gl_version
= "OpenGL ES 3.0";
98 init
.bind_generates_resource
= true;
99 InitDecoderWithCommandLine(init
, &command_line
);
103 TEST_P(GLES3DecoderTest
, Basic
) {
104 // Make sure the setup is correct for ES3.
105 EXPECT_TRUE(decoder_
->unsafe_es3_apis_enabled());
106 EXPECT_TRUE(feature_info()->validators()->texture_bind_target
.IsValid(
110 TEST_P(GLES2DecoderTest
, GetIntegervCached
) {
117 GL_MAX_TEXTURE_SIZE
, TestHelper::kMaxTextureSize
,
120 GL_MAX_CUBE_MAP_TEXTURE_SIZE
, TestHelper::kMaxCubeMapTextureSize
,
123 GL_MAX_RENDERBUFFER_SIZE
, TestHelper::kMaxRenderbufferSize
,
126 typedef GetIntegerv::Result Result
;
127 for (size_t ii
= 0; ii
< sizeof(tests
) / sizeof(tests
[0]); ++ii
) {
128 const TestInfo
& test
= tests
[ii
];
129 Result
* result
= static_cast<Result
*>(shared_memory_address_
);
130 EXPECT_CALL(*gl_
, GetError())
131 .WillOnce(Return(GL_NO_ERROR
))
132 .WillOnce(Return(GL_NO_ERROR
))
133 .RetiresOnSaturation();
134 EXPECT_CALL(*gl_
, GetIntegerv(test
.pname
, _
)).Times(0);
137 cmd2
.Init(test
.pname
, shared_memory_id_
, shared_memory_offset_
);
138 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd2
));
139 EXPECT_EQ(decoder_
->GetGLES2Util()->GLGetNumValuesReturned(test
.pname
),
140 result
->GetNumResults());
141 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
142 EXPECT_EQ(test
.expected
, result
->GetData()[0]);
146 TEST_P(GLES2DecoderWithShaderTest
, GetMaxValueInBufferCHROMIUM
) {
148 GetMaxValueInBufferCHROMIUM::Result
* result
=
149 static_cast<GetMaxValueInBufferCHROMIUM::Result
*>(shared_memory_address_
);
152 GetMaxValueInBufferCHROMIUM cmd
;
153 cmd
.Init(client_element_buffer_id_
,
154 kValidIndexRangeCount
,
156 kValidIndexRangeStart
* 2,
158 kSharedMemoryOffset
);
159 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
160 EXPECT_EQ(7u, *result
);
161 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
162 cmd
.Init(client_element_buffer_id_
,
163 kValidIndexRangeCount
+ 1,
165 kValidIndexRangeStart
* 2,
167 kSharedMemoryOffset
);
168 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
169 EXPECT_EQ(100u, *result
);
170 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
172 cmd
.Init(kInvalidClientId
,
173 kValidIndexRangeCount
,
175 kValidIndexRangeStart
* 2,
177 kSharedMemoryOffset
);
178 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
179 EXPECT_EQ(GL_INVALID_VALUE
, GetGLError());
180 cmd
.Init(client_element_buffer_id_
,
181 kOutOfRangeIndexRangeEnd
,
183 kValidIndexRangeStart
* 2,
185 kSharedMemoryOffset
);
186 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
187 EXPECT_EQ(GL_INVALID_OPERATION
, GetGLError());
188 cmd
.Init(client_element_buffer_id_
,
189 kValidIndexRangeCount
+ 1,
191 kOutOfRangeIndexRangeEnd
* 2,
193 kSharedMemoryOffset
);
194 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
195 EXPECT_EQ(GL_INVALID_OPERATION
, GetGLError());
196 cmd
.Init(client_element_buffer_id_
,
197 kValidIndexRangeCount
+ 1,
199 kValidIndexRangeStart
* 2,
201 kSharedMemoryOffset
);
202 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
203 cmd
.Init(client_buffer_id_
,
204 kValidIndexRangeCount
+ 1,
206 kValidIndexRangeStart
* 2,
208 kSharedMemoryOffset
);
209 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
210 EXPECT_EQ(GL_INVALID_OPERATION
, GetGLError());
211 cmd
.Init(client_element_buffer_id_
,
212 kValidIndexRangeCount
+ 1,
214 kValidIndexRangeStart
* 2,
215 kInvalidSharedMemoryId
,
216 kSharedMemoryOffset
);
217 EXPECT_NE(error::kNoError
, ExecuteCmd(cmd
));
218 cmd
.Init(client_element_buffer_id_
,
219 kValidIndexRangeCount
+ 1,
221 kValidIndexRangeStart
* 2,
223 kInvalidSharedMemoryOffset
);
224 EXPECT_NE(error::kNoError
, ExecuteCmd(cmd
));
227 TEST_P(GLES2DecoderTest
, IsBuffer
) {
228 EXPECT_FALSE(DoIsBuffer(client_buffer_id_
));
229 DoBindBuffer(GL_ARRAY_BUFFER
, client_buffer_id_
, kServiceBufferId
);
230 EXPECT_TRUE(DoIsBuffer(client_buffer_id_
));
231 DoDeleteBuffer(client_buffer_id_
, kServiceBufferId
);
232 EXPECT_FALSE(DoIsBuffer(client_buffer_id_
));
235 TEST_P(GLES2DecoderTest
, IsFramebuffer
) {
236 EXPECT_FALSE(DoIsFramebuffer(client_framebuffer_id_
));
238 GL_FRAMEBUFFER
, client_framebuffer_id_
, kServiceFramebufferId
);
239 EXPECT_TRUE(DoIsFramebuffer(client_framebuffer_id_
));
240 DoDeleteFramebuffer(client_framebuffer_id_
,
241 kServiceFramebufferId
,
248 EXPECT_FALSE(DoIsFramebuffer(client_framebuffer_id_
));
251 TEST_P(GLES2DecoderTest
, IsProgram
) {
252 // IsProgram is true as soon as the program is created.
253 EXPECT_TRUE(DoIsProgram(client_program_id_
));
254 EXPECT_CALL(*gl_
, DeleteProgram(kServiceProgramId
))
256 .RetiresOnSaturation();
257 DoDeleteProgram(client_program_id_
, kServiceProgramId
);
258 EXPECT_FALSE(DoIsProgram(client_program_id_
));
261 TEST_P(GLES2DecoderTest
, IsRenderbuffer
) {
262 EXPECT_FALSE(DoIsRenderbuffer(client_renderbuffer_id_
));
264 GL_RENDERBUFFER
, client_renderbuffer_id_
, kServiceRenderbufferId
);
265 EXPECT_TRUE(DoIsRenderbuffer(client_renderbuffer_id_
));
266 DoDeleteRenderbuffer(client_renderbuffer_id_
, kServiceRenderbufferId
);
267 EXPECT_FALSE(DoIsRenderbuffer(client_renderbuffer_id_
));
270 TEST_P(GLES2DecoderTest
, IsShader
) {
271 // IsShader is true as soon as the program is created.
272 EXPECT_TRUE(DoIsShader(client_shader_id_
));
273 DoDeleteShader(client_shader_id_
, kServiceShaderId
);
274 EXPECT_FALSE(DoIsShader(client_shader_id_
));
277 TEST_P(GLES2DecoderTest
, IsTexture
) {
278 EXPECT_FALSE(DoIsTexture(client_texture_id_
));
279 DoBindTexture(GL_TEXTURE_2D
, client_texture_id_
, kServiceTextureId
);
280 EXPECT_TRUE(DoIsTexture(client_texture_id_
));
281 DoDeleteTexture(client_texture_id_
, kServiceTextureId
);
282 EXPECT_FALSE(DoIsTexture(client_texture_id_
));
285 TEST_P(GLES2DecoderTest
, ClientWaitSyncValid
) {
286 typedef cmds::ClientWaitSync::Result Result
;
287 Result
* result
= static_cast<Result
*>(shared_memory_address_
);
288 cmds::ClientWaitSync cmd
;
289 uint32_t v32_0
= 0, v32_1
= 0;
290 GLES2Util::MapUint64ToTwoUint32(0, &v32_0
, &v32_1
);
291 cmd
.Init(client_sync_id_
, GL_SYNC_FLUSH_COMMANDS_BIT
, v32_0
, v32_1
,
292 shared_memory_id_
, shared_memory_offset_
);
294 ClientWaitSync(reinterpret_cast<GLsync
>(kServiceSyncId
),
295 GL_SYNC_FLUSH_COMMANDS_BIT
, 0))
296 .WillOnce(Return(GL_CONDITION_SATISFIED
))
297 .RetiresOnSaturation();
298 *result
= GL_WAIT_FAILED
;
299 decoder_
->set_unsafe_es3_apis_enabled(true);
300 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
301 EXPECT_EQ(static_cast<GLenum
>(GL_CONDITION_SATISFIED
), *result
);
302 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
303 decoder_
->set_unsafe_es3_apis_enabled(false);
304 EXPECT_EQ(error::kUnknownCommand
, ExecuteCmd(cmd
));
307 TEST_P(GLES2DecoderTest
, ClientWaitSyncNonZeroTimeoutValid
) {
308 typedef cmds::ClientWaitSync::Result Result
;
309 Result
* result
= static_cast<Result
*>(shared_memory_address_
);
310 cmds::ClientWaitSync cmd
;
311 const GLuint64 kTimeout
= 0xABCDEF0123456789;
312 uint32_t v32_0
= 0, v32_1
= 0;
313 GLES2Util::MapUint64ToTwoUint32(kTimeout
, &v32_0
, &v32_1
);
314 cmd
.Init(client_sync_id_
, GL_SYNC_FLUSH_COMMANDS_BIT
, v32_0
, v32_1
,
315 shared_memory_id_
, shared_memory_offset_
);
317 ClientWaitSync(reinterpret_cast<GLsync
>(kServiceSyncId
),
318 GL_SYNC_FLUSH_COMMANDS_BIT
, kTimeout
))
319 .WillOnce(Return(GL_CONDITION_SATISFIED
))
320 .RetiresOnSaturation();
321 *result
= GL_WAIT_FAILED
;
322 decoder_
->set_unsafe_es3_apis_enabled(true);
323 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
324 EXPECT_EQ(static_cast<GLenum
>(GL_CONDITION_SATISFIED
), *result
);
325 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
326 decoder_
->set_unsafe_es3_apis_enabled(false);
327 EXPECT_EQ(error::kUnknownCommand
, ExecuteCmd(cmd
));
330 TEST_P(GLES2DecoderTest
, ClientWaitSyncInvalidSyncFails
) {
331 typedef cmds::ClientWaitSync::Result Result
;
332 Result
* result
= static_cast<Result
*>(shared_memory_address_
);
333 cmds::ClientWaitSync cmd
;
334 uint32_t v32_0
= 0, v32_1
= 0;
335 GLES2Util::MapUint64ToTwoUint32(0, &v32_0
, &v32_1
);
336 decoder_
->set_unsafe_es3_apis_enabled(true);
337 cmd
.Init(kInvalidClientId
, GL_SYNC_FLUSH_COMMANDS_BIT
, v32_0
, v32_1
,
338 shared_memory_id_
, shared_memory_offset_
);
339 *result
= GL_WAIT_FAILED
;
340 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
341 EXPECT_EQ(static_cast<GLenum
>(GL_WAIT_FAILED
), *result
);
342 EXPECT_EQ(GL_INVALID_VALUE
, GetGLError());
345 TEST_P(GLES2DecoderTest
, ClientWaitSyncResultNotInitFails
) {
346 typedef cmds::ClientWaitSync::Result Result
;
347 Result
* result
= static_cast<Result
*>(shared_memory_address_
);
348 cmds::ClientWaitSync cmd
;
349 uint32_t v32_0
= 0, v32_1
= 0;
350 GLES2Util::MapUint64ToTwoUint32(0, &v32_0
, &v32_1
);
351 decoder_
->set_unsafe_es3_apis_enabled(true);
352 cmd
.Init(client_sync_id_
, GL_SYNC_FLUSH_COMMANDS_BIT
, v32_0
, v32_1
,
353 shared_memory_id_
, shared_memory_offset_
);
354 *result
= 1; // Any value other than GL_WAIT_FAILED
355 EXPECT_NE(error::kNoError
, ExecuteCmd(cmd
));
358 TEST_P(GLES2DecoderTest
, ClientWaitSyncBadSharedMemoryFails
) {
359 typedef cmds::ClientWaitSync::Result Result
;
360 Result
* result
= static_cast<Result
*>(shared_memory_address_
);
361 cmds::ClientWaitSync cmd
;
362 uint32_t v32_0
= 0, v32_1
= 0;
363 GLES2Util::MapUint64ToTwoUint32(0, &v32_0
, &v32_1
);
364 decoder_
->set_unsafe_es3_apis_enabled(true);
365 *result
= GL_WAIT_FAILED
;
366 cmd
.Init(client_sync_id_
, GL_SYNC_FLUSH_COMMANDS_BIT
, v32_0
, v32_1
,
367 kInvalidSharedMemoryId
, shared_memory_offset_
);
368 EXPECT_NE(error::kNoError
, ExecuteCmd(cmd
));
370 *result
= GL_WAIT_FAILED
;
371 cmd
.Init(client_sync_id_
, GL_SYNC_FLUSH_COMMANDS_BIT
, v32_0
, v32_1
,
372 shared_memory_id_
, kInvalidSharedMemoryOffset
);
373 EXPECT_NE(error::kNoError
, ExecuteCmd(cmd
));
376 TEST_P(GLES2DecoderTest
, WaitSyncValidArgs
) {
377 const GLuint64 kTimeout
= GL_TIMEOUT_IGNORED
;
378 EXPECT_CALL(*gl_
, WaitSync(reinterpret_cast<GLsync
>(kServiceSyncId
),
381 .RetiresOnSaturation();
383 uint32_t v32_0
= 0, v32_1
= 0;
384 GLES2Util::MapUint64ToTwoUint32(kTimeout
, &v32_0
, &v32_1
);
386 cmd
.Init(client_sync_id_
, 0, v32_0
, v32_1
);
387 decoder_
->set_unsafe_es3_apis_enabled(true);
388 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
389 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
390 decoder_
->set_unsafe_es3_apis_enabled(false);
391 EXPECT_EQ(error::kUnknownCommand
, ExecuteCmd(cmd
));
394 TEST_P(GLES2DecoderManualInitTest
, BindGeneratesResourceFalse
) {
399 cmd1
.Init(GL_TEXTURE_2D
, kInvalidClientId
);
400 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd1
));
401 EXPECT_EQ(GL_INVALID_OPERATION
, GetGLError());
404 cmd2
.Init(GL_ARRAY_BUFFER
, kInvalidClientId
);
405 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd2
));
406 EXPECT_EQ(GL_INVALID_OPERATION
, GetGLError());
408 BindFramebuffer cmd3
;
409 cmd3
.Init(GL_FRAMEBUFFER
, kInvalidClientId
);
410 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd3
));
411 EXPECT_EQ(GL_INVALID_OPERATION
, GetGLError());
413 BindRenderbuffer cmd4
;
414 cmd4
.Init(GL_RENDERBUFFER
, kInvalidClientId
);
415 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd4
));
416 EXPECT_EQ(GL_INVALID_OPERATION
, GetGLError());
419 TEST_P(GLES2DecoderTest
, EnableFeatureCHROMIUMBadBucket
) {
420 const uint32 kBadBucketId
= 123;
421 EnableFeatureCHROMIUM cmd
;
422 cmd
.Init(kBadBucketId
, shared_memory_id_
, shared_memory_offset_
);
423 EXPECT_NE(error::kNoError
, ExecuteCmd(cmd
));
426 TEST_P(GLES2DecoderTest
, RequestExtensionCHROMIUMBadBucket
) {
427 const uint32 kBadBucketId
= 123;
428 RequestExtensionCHROMIUM cmd
;
429 cmd
.Init(kBadBucketId
);
430 EXPECT_NE(error::kNoError
, ExecuteCmd(cmd
));
433 TEST_P(GLES2DecoderTest
, BeginQueryEXTDisabled
) {
434 // Test something fails if off.
437 TEST_P(GLES2DecoderManualInitTest
, BeginEndQueryEXT
) {
439 init
.extensions
= "GL_EXT_occlusion_query_boolean";
440 init
.gl_version
= "opengl es 2.0";
441 init
.has_alpha
= true;
442 init
.request_alpha
= true;
443 init
.bind_generates_resource
= true;
446 // Test end fails if no begin.
448 end_cmd
.Init(GL_ANY_SAMPLES_PASSED_EXT
, 1);
449 EXPECT_EQ(error::kNoError
, ExecuteCmd(end_cmd
));
450 EXPECT_EQ(GL_INVALID_OPERATION
, GetGLError());
452 BeginQueryEXT begin_cmd
;
454 // Test id = 0 fails.
456 GL_ANY_SAMPLES_PASSED_EXT
, 0, kSharedMemoryId
, kSharedMemoryOffset
);
457 EXPECT_EQ(error::kNoError
, ExecuteCmd(begin_cmd
));
458 EXPECT_EQ(GL_INVALID_OPERATION
, GetGLError());
460 GenHelper
<GenQueriesEXTImmediate
>(kNewClientId
);
462 // Test valid parameters work.
463 EXPECT_CALL(*gl_
, GenQueries(1, _
))
464 .WillOnce(SetArgumentPointee
<1>(kNewServiceId
))
465 .RetiresOnSaturation();
466 EXPECT_CALL(*gl_
, BeginQuery(GL_ANY_SAMPLES_PASSED_EXT
, kNewServiceId
))
468 .RetiresOnSaturation();
470 // Query object should not be created untill BeginQueriesEXT.
471 QueryManager
* query_manager
= decoder_
->GetQueryManager();
472 ASSERT_TRUE(query_manager
!= NULL
);
473 QueryManager::Query
* query
= query_manager
->GetQuery(kNewClientId
);
474 EXPECT_TRUE(query
== NULL
);
476 // BeginQueryEXT should fail if id is not generated from GenQueriesEXT.
477 begin_cmd
.Init(GL_ANY_SAMPLES_PASSED_EXT
,
480 kSharedMemoryOffset
);
481 EXPECT_EQ(error::kNoError
, ExecuteCmd(begin_cmd
));
482 EXPECT_EQ(GL_INVALID_OPERATION
, GetGLError());
484 begin_cmd
.Init(GL_ANY_SAMPLES_PASSED_EXT
,
487 kSharedMemoryOffset
);
488 EXPECT_EQ(error::kNoError
, ExecuteCmd(begin_cmd
));
489 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
491 // After BeginQueriesEXT id name should have query object associated with it.
492 query
= query_manager
->GetQuery(kNewClientId
);
493 ASSERT_TRUE(query
!= NULL
);
494 EXPECT_FALSE(query
->pending());
496 // Test trying begin again fails
497 EXPECT_EQ(error::kNoError
, ExecuteCmd(begin_cmd
));
498 EXPECT_EQ(GL_INVALID_OPERATION
, GetGLError());
500 // Test end fails with different target
501 end_cmd
.Init(GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT
, 1);
502 EXPECT_EQ(error::kNoError
, ExecuteCmd(end_cmd
));
503 EXPECT_EQ(GL_INVALID_OPERATION
, GetGLError());
506 EXPECT_CALL(*gl_
, EndQuery(GL_ANY_SAMPLES_PASSED_EXT
))
508 .RetiresOnSaturation();
509 end_cmd
.Init(GL_ANY_SAMPLES_PASSED_EXT
, 1);
510 EXPECT_EQ(error::kNoError
, ExecuteCmd(end_cmd
));
511 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
512 EXPECT_TRUE(query
->pending());
514 EXPECT_CALL(*gl_
, DeleteQueries(1, _
)).Times(1).RetiresOnSaturation();
522 const QueryType kQueryTypes
[] = {
523 {GL_COMMANDS_ISSUED_CHROMIUM
, false},
524 {GL_LATENCY_QUERY_CHROMIUM
, false},
525 {GL_ASYNC_PIXEL_UNPACK_COMPLETED_CHROMIUM
, false},
526 {GL_ASYNC_PIXEL_PACK_COMPLETED_CHROMIUM
, false},
527 {GL_GET_ERROR_QUERY_CHROMIUM
, false},
528 {GL_COMMANDS_COMPLETED_CHROMIUM
, false},
529 {GL_ANY_SAMPLES_PASSED_EXT
, true},
532 static void CheckBeginEndQueryBadMemoryFails(GLES2DecoderTestBase
* test
,
535 const QueryType
& query_type
,
538 // We need to reset the decoder on each iteration, because we lose the
539 // context every time.
540 GLES2DecoderTestBase::InitState init
;
541 init
.extensions
= "GL_EXT_occlusion_query_boolean GL_ARB_sync";
542 init
.gl_version
= "opengl es 2.0";
543 init
.has_alpha
= true;
544 init
.request_alpha
= true;
545 init
.bind_generates_resource
= true;
546 test
->InitDecoder(init
);
547 ::testing::StrictMock
< ::gfx::MockGLInterface
>* gl
= test
->GetGLMock();
549 BeginQueryEXT begin_cmd
;
551 test
->GenHelper
<GenQueriesEXTImmediate
>(client_id
);
553 if (query_type
.is_gl
) {
554 EXPECT_CALL(*gl
, GenQueries(1, _
))
555 .WillOnce(SetArgumentPointee
<1>(service_id
))
556 .RetiresOnSaturation();
557 EXPECT_CALL(*gl
, BeginQuery(query_type
.type
, service_id
))
559 .RetiresOnSaturation();
562 // Test bad shared memory fails
563 begin_cmd
.Init(query_type
.type
, client_id
, shm_id
, shm_offset
);
564 error::Error error1
= test
->ExecuteCmd(begin_cmd
);
566 if (query_type
.is_gl
) {
567 EXPECT_CALL(*gl
, EndQuery(query_type
.type
))
569 .RetiresOnSaturation();
571 if (query_type
.type
== GL_GET_ERROR_QUERY_CHROMIUM
) {
572 EXPECT_CALL(*gl
, GetError())
573 .WillOnce(Return(GL_NO_ERROR
))
574 .RetiresOnSaturation();
576 GLsync kGlSync
= reinterpret_cast<GLsync
>(0xdeadbeef);
577 if (query_type
.type
== GL_COMMANDS_COMPLETED_CHROMIUM
) {
578 EXPECT_CALL(*gl
, Flush()).RetiresOnSaturation();
579 EXPECT_CALL(*gl
, FenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE
, 0))
580 .WillOnce(Return(kGlSync
))
581 .RetiresOnSaturation();
583 EXPECT_CALL(*gl
, IsSync(kGlSync
))
584 .WillOnce(Return(GL_TRUE
))
585 .RetiresOnSaturation();
590 end_cmd
.Init(query_type
.type
, 1);
591 error::Error error2
= test
->ExecuteCmd(end_cmd
);
593 if (query_type
.is_gl
) {
595 *gl
, GetQueryObjectuiv(service_id
, GL_QUERY_RESULT_AVAILABLE_EXT
, _
))
596 .WillOnce(SetArgumentPointee
<2>(1))
597 .RetiresOnSaturation();
598 EXPECT_CALL(*gl
, GetQueryObjectuiv(service_id
, GL_QUERY_RESULT_EXT
, _
))
599 .WillOnce(SetArgumentPointee
<2>(1))
600 .RetiresOnSaturation();
602 if (query_type
.type
== GL_COMMANDS_COMPLETED_CHROMIUM
) {
604 EXPECT_CALL(*gl
, IsSync(kGlSync
))
605 .WillOnce(Return(GL_TRUE
))
606 .RetiresOnSaturation();
608 EXPECT_CALL(*gl
, ClientWaitSync(kGlSync
, _
, _
))
609 .WillOnce(Return(GL_ALREADY_SIGNALED
))
610 .RetiresOnSaturation();
613 QueryManager
* query_manager
= test
->GetDecoder()->GetQueryManager();
614 ASSERT_TRUE(query_manager
!= NULL
);
615 bool process_success
= query_manager
->ProcessPendingQueries(false);
617 EXPECT_TRUE(error1
!= error::kNoError
|| error2
!= error::kNoError
||
620 if (query_type
.is_gl
) {
621 EXPECT_CALL(*gl
, DeleteQueries(1, _
)).Times(1).RetiresOnSaturation();
623 if (query_type
.type
== GL_COMMANDS_COMPLETED_CHROMIUM
) {
625 EXPECT_CALL(*gl
, IsSync(kGlSync
))
626 .WillOnce(Return(GL_TRUE
))
627 .RetiresOnSaturation();
629 EXPECT_CALL(*gl
, DeleteSync(kGlSync
)).Times(1).RetiresOnSaturation();
631 test
->ResetDecoder();
634 TEST_P(GLES2DecoderManualInitTest
, BeginEndQueryEXTBadMemoryIdFails
) {
635 for (size_t i
= 0; i
< arraysize(kQueryTypes
); ++i
) {
636 CheckBeginEndQueryBadMemoryFails(this,
640 kInvalidSharedMemoryId
,
641 kSharedMemoryOffset
);
645 TEST_P(GLES2DecoderManualInitTest
, BeginEndQueryEXTBadMemoryOffsetFails
) {
646 for (size_t i
= 0; i
< arraysize(kQueryTypes
); ++i
) {
648 CheckBeginEndQueryBadMemoryFails(this,
653 kInvalidSharedMemoryOffset
);
655 CheckBeginEndQueryBadMemoryFails(this,
664 TEST_P(GLES2DecoderTest
, BeginEndQueryEXTCommandsIssuedCHROMIUM
) {
665 BeginQueryEXT begin_cmd
;
667 GenHelper
<GenQueriesEXTImmediate
>(kNewClientId
);
669 // Test valid parameters work.
670 begin_cmd
.Init(GL_COMMANDS_ISSUED_CHROMIUM
,
673 kSharedMemoryOffset
);
674 EXPECT_EQ(error::kNoError
, ExecuteCmd(begin_cmd
));
675 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
677 QueryManager
* query_manager
= decoder_
->GetQueryManager();
678 ASSERT_TRUE(query_manager
!= NULL
);
679 QueryManager::Query
* query
= query_manager
->GetQuery(kNewClientId
);
680 ASSERT_TRUE(query
!= NULL
);
681 EXPECT_FALSE(query
->pending());
685 end_cmd
.Init(GL_COMMANDS_ISSUED_CHROMIUM
, 1);
686 EXPECT_EQ(error::kNoError
, ExecuteCmd(end_cmd
));
687 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
688 EXPECT_FALSE(query
->pending());
691 TEST_P(GLES2DecoderTest
, BeginEndQueryEXTGetErrorQueryCHROMIUM
) {
692 BeginQueryEXT begin_cmd
;
694 GenHelper
<GenQueriesEXTImmediate
>(kNewClientId
);
696 // Test valid parameters work.
697 begin_cmd
.Init(GL_GET_ERROR_QUERY_CHROMIUM
,
700 kSharedMemoryOffset
);
701 EXPECT_EQ(error::kNoError
, ExecuteCmd(begin_cmd
));
702 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
704 QueryManager
* query_manager
= decoder_
->GetQueryManager();
705 ASSERT_TRUE(query_manager
!= NULL
);
706 QueryManager::Query
* query
= query_manager
->GetQuery(kNewClientId
);
707 ASSERT_TRUE(query
!= NULL
);
708 EXPECT_FALSE(query
->pending());
711 QuerySync
* sync
= static_cast<QuerySync
*>(shared_memory_address_
);
713 EXPECT_CALL(*gl_
, GetError())
714 .WillOnce(Return(GL_INVALID_VALUE
))
715 .RetiresOnSaturation();
718 end_cmd
.Init(GL_GET_ERROR_QUERY_CHROMIUM
, 1);
719 EXPECT_EQ(error::kNoError
, ExecuteCmd(end_cmd
));
720 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
721 EXPECT_FALSE(query
->pending());
722 EXPECT_EQ(static_cast<GLenum
>(GL_INVALID_VALUE
),
723 static_cast<GLenum
>(sync
->result
));
726 TEST_P(GLES2DecoderManualInitTest
, BeginEndQueryEXTCommandsCompletedCHROMIUM
) {
728 init
.extensions
= "GL_EXT_occlusion_query_boolean GL_ARB_sync";
729 init
.gl_version
= "opengl es 2.0";
730 init
.has_alpha
= true;
731 init
.request_alpha
= true;
732 init
.bind_generates_resource
= true;
735 GenHelper
<GenQueriesEXTImmediate
>(kNewClientId
);
737 BeginQueryEXT begin_cmd
;
738 begin_cmd
.Init(GL_COMMANDS_COMPLETED_CHROMIUM
,
741 kSharedMemoryOffset
);
742 EXPECT_EQ(error::kNoError
, ExecuteCmd(begin_cmd
));
743 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
745 QueryManager
* query_manager
= decoder_
->GetQueryManager();
746 ASSERT_TRUE(query_manager
!= NULL
);
747 QueryManager::Query
* query
= query_manager
->GetQuery(kNewClientId
);
748 ASSERT_TRUE(query
!= NULL
);
749 EXPECT_FALSE(query
->pending());
751 GLsync kGlSync
= reinterpret_cast<GLsync
>(0xdeadbeef);
752 EXPECT_CALL(*gl_
, Flush()).RetiresOnSaturation();
753 EXPECT_CALL(*gl_
, FenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE
, 0))
754 .WillOnce(Return(kGlSync
))
755 .RetiresOnSaturation();
757 EXPECT_CALL(*gl_
, IsSync(kGlSync
))
758 .WillOnce(Return(GL_TRUE
))
759 .RetiresOnSaturation();
763 end_cmd
.Init(GL_COMMANDS_COMPLETED_CHROMIUM
, 1);
764 EXPECT_EQ(error::kNoError
, ExecuteCmd(end_cmd
));
765 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
766 EXPECT_TRUE(query
->pending());
769 EXPECT_CALL(*gl_
, IsSync(kGlSync
))
770 .WillOnce(Return(GL_TRUE
))
771 .RetiresOnSaturation();
773 EXPECT_CALL(*gl_
, ClientWaitSync(kGlSync
, _
, _
))
774 .WillOnce(Return(GL_TIMEOUT_EXPIRED
))
775 .RetiresOnSaturation();
776 bool process_success
= query_manager
->ProcessPendingQueries(false);
778 EXPECT_TRUE(process_success
);
779 EXPECT_TRUE(query
->pending());
782 EXPECT_CALL(*gl_
, IsSync(kGlSync
))
783 .WillOnce(Return(GL_TRUE
))
784 .RetiresOnSaturation();
786 EXPECT_CALL(*gl_
, ClientWaitSync(kGlSync
, _
, _
))
787 .WillOnce(Return(GL_ALREADY_SIGNALED
))
788 .RetiresOnSaturation();
789 process_success
= query_manager
->ProcessPendingQueries(false);
791 EXPECT_TRUE(process_success
);
792 EXPECT_FALSE(query
->pending());
795 EXPECT_CALL(*gl_
, IsSync(kGlSync
))
796 .WillOnce(Return(GL_TRUE
))
797 .RetiresOnSaturation();
799 EXPECT_CALL(*gl_
, DeleteSync(kGlSync
)).Times(1).RetiresOnSaturation();
803 TEST_P(GLES2DecoderTest
, IsEnabledReturnsCachedValue
) {
804 // NOTE: There are no expectations because no GL functions should be
805 // called for DEPTH_TEST or STENCIL_TEST
806 static const GLenum kStates
[] = {
807 GL_DEPTH_TEST
, GL_STENCIL_TEST
,
809 for (size_t ii
= 0; ii
< arraysize(kStates
); ++ii
) {
811 GLenum state
= kStates
[ii
];
812 enable_cmd
.Init(state
);
813 EXPECT_EQ(error::kNoError
, ExecuteCmd(enable_cmd
));
814 IsEnabled::Result
* result
=
815 static_cast<IsEnabled::Result
*>(shared_memory_address_
);
816 IsEnabled is_enabled_cmd
;
817 is_enabled_cmd
.Init(state
, shared_memory_id_
, shared_memory_offset_
);
818 EXPECT_EQ(error::kNoError
, ExecuteCmd(is_enabled_cmd
));
819 EXPECT_NE(0u, *result
);
821 disable_cmd
.Init(state
);
822 EXPECT_EQ(error::kNoError
, ExecuteCmd(disable_cmd
));
823 EXPECT_EQ(error::kNoError
, ExecuteCmd(is_enabled_cmd
));
824 EXPECT_EQ(0u, *result
);
828 TEST_P(GLES2DecoderManualInitTest
, GpuMemoryManagerCHROMIUM
) {
830 init
.extensions
= "GL_ARB_texture_rectangle";
831 init
.bind_generates_resource
= true;
834 Texture
* texture
= GetTexture(client_texture_id_
)->texture();
835 EXPECT_TRUE(texture
!= NULL
);
836 EXPECT_TRUE(texture
->pool() == GL_TEXTURE_POOL_UNMANAGED_CHROMIUM
);
838 DoBindTexture(GL_TEXTURE_2D
, client_texture_id_
, kServiceTextureId
);
841 cmd
.Init(GL_TEXTURE_2D
,
842 GL_TEXTURE_POOL_CHROMIUM
,
843 GL_TEXTURE_POOL_UNMANAGED_CHROMIUM
);
844 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
845 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
847 cmd
.Init(GL_TEXTURE_2D
,
848 GL_TEXTURE_POOL_CHROMIUM
,
849 GL_TEXTURE_POOL_MANAGED_CHROMIUM
);
850 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
851 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
853 EXPECT_TRUE(texture
->pool() == GL_TEXTURE_POOL_MANAGED_CHROMIUM
);
855 cmd
.Init(GL_TEXTURE_2D
, GL_TEXTURE_POOL_CHROMIUM
, GL_NONE
);
856 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
857 EXPECT_EQ(GL_INVALID_ENUM
, GetGLError());
862 class SizeOnlyMemoryTracker
: public MemoryTracker
{
864 SizeOnlyMemoryTracker() {
865 // These are the default textures. 1 for TEXTURE_2D and 6 faces for
867 const size_t kInitialUnmanagedPoolSize
= 7 * 4;
868 const size_t kInitialManagedPoolSize
= 0;
869 pool_infos_
[MemoryTracker::kUnmanaged
].initial_size
=
870 kInitialUnmanagedPoolSize
;
871 pool_infos_
[MemoryTracker::kManaged
].initial_size
= kInitialManagedPoolSize
;
874 // Ensure a certain amount of GPU memory is free. Returns true on success.
875 MOCK_METHOD1(EnsureGPUMemoryAvailable
, bool(size_t size_needed
));
877 virtual void TrackMemoryAllocatedChange(size_t old_size
,
880 PoolInfo
& info
= pool_infos_
[pool
];
881 info
.size
+= new_size
- old_size
;
884 size_t GetPoolSize(Pool pool
) {
885 const PoolInfo
& info
= pool_infos_
[pool
];
886 return info
.size
- info
.initial_size
;
890 virtual ~SizeOnlyMemoryTracker() {}
892 PoolInfo() : initial_size(0), size(0) {}
896 std::map
<Pool
, PoolInfo
> pool_infos_
;
899 } // anonymous namespace.
901 TEST_P(GLES2DecoderManualInitTest
, MemoryTrackerInitialSize
) {
902 scoped_refptr
<SizeOnlyMemoryTracker
> memory_tracker
=
903 new SizeOnlyMemoryTracker();
904 set_memory_tracker(memory_tracker
.get());
906 init
.bind_generates_resource
= true;
908 // Expect that initial size - size is 0.
909 EXPECT_EQ(0u, memory_tracker
->GetPoolSize(MemoryTracker::kUnmanaged
));
910 EXPECT_EQ(0u, memory_tracker
->GetPoolSize(MemoryTracker::kManaged
));
913 TEST_P(GLES2DecoderManualInitTest
, MemoryTrackerTexImage2D
) {
914 scoped_refptr
<SizeOnlyMemoryTracker
> memory_tracker
=
915 new SizeOnlyMemoryTracker();
916 set_memory_tracker(memory_tracker
.get());
918 init
.bind_generates_resource
= true;
920 DoBindTexture(GL_TEXTURE_2D
, client_texture_id_
, kServiceTextureId
);
921 EXPECT_CALL(*memory_tracker
.get(), EnsureGPUMemoryAvailable(128))
922 .WillOnce(Return(true))
923 .RetiresOnSaturation();
924 DoTexImage2D(GL_TEXTURE_2D
,
933 kSharedMemoryOffset
);
934 EXPECT_EQ(128u, memory_tracker
->GetPoolSize(MemoryTracker::kUnmanaged
));
935 EXPECT_CALL(*memory_tracker
.get(), EnsureGPUMemoryAvailable(64))
936 .WillOnce(Return(true))
937 .RetiresOnSaturation();
938 DoTexImage2D(GL_TEXTURE_2D
,
947 kSharedMemoryOffset
);
948 EXPECT_EQ(64u, memory_tracker
->GetPoolSize(MemoryTracker::kUnmanaged
));
949 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
950 // Check we get out of memory and no call to glTexImage2D if Ensure fails.
951 EXPECT_CALL(*memory_tracker
.get(), EnsureGPUMemoryAvailable(64))
952 .WillOnce(Return(false))
953 .RetiresOnSaturation();
955 cmd
.Init(GL_TEXTURE_2D
,
963 kSharedMemoryOffset
);
964 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
965 EXPECT_EQ(GL_OUT_OF_MEMORY
, GetGLError());
966 EXPECT_EQ(64u, memory_tracker
->GetPoolSize(MemoryTracker::kUnmanaged
));
969 TEST_P(GLES2DecoderManualInitTest
, MemoryTrackerTexStorage2DEXT
) {
970 scoped_refptr
<SizeOnlyMemoryTracker
> memory_tracker
=
971 new SizeOnlyMemoryTracker();
972 set_memory_tracker(memory_tracker
.get());
974 init
.bind_generates_resource
= true;
976 DoBindTexture(GL_TEXTURE_2D
, client_texture_id_
, kServiceTextureId
);
977 // Check we get out of memory and no call to glTexStorage2DEXT
979 EXPECT_CALL(*memory_tracker
.get(), EnsureGPUMemoryAvailable(128))
980 .WillOnce(Return(false))
981 .RetiresOnSaturation();
983 cmd
.Init(GL_TEXTURE_2D
, 1, GL_RGBA8
, 8, 4);
984 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
985 EXPECT_EQ(0u, memory_tracker
->GetPoolSize(MemoryTracker::kUnmanaged
));
986 EXPECT_EQ(GL_OUT_OF_MEMORY
, GetGLError());
989 TEST_P(GLES2DecoderManualInitTest
, MemoryTrackerCopyTexImage2D
) {
990 GLenum target
= GL_TEXTURE_2D
;
992 GLenum internal_format
= GL_RGBA
;
996 scoped_refptr
<SizeOnlyMemoryTracker
> memory_tracker
=
997 new SizeOnlyMemoryTracker();
998 set_memory_tracker(memory_tracker
.get());
1000 init
.has_alpha
= true;
1001 init
.request_alpha
= true;
1002 init
.bind_generates_resource
= true;
1004 DoBindTexture(GL_TEXTURE_2D
, client_texture_id_
, kServiceTextureId
);
1005 EXPECT_CALL(*memory_tracker
.get(), EnsureGPUMemoryAvailable(128))
1006 .WillOnce(Return(true))
1007 .RetiresOnSaturation();
1008 EXPECT_CALL(*gl_
, GetError())
1009 .WillOnce(Return(GL_NO_ERROR
))
1010 .WillOnce(Return(GL_NO_ERROR
))
1011 .RetiresOnSaturation();
1014 target
, level
, internal_format
, 0, 0, width
, height
, border
))
1016 .RetiresOnSaturation();
1018 cmd
.Init(target
, level
, internal_format
, 0, 0, width
, height
);
1019 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
1020 EXPECT_EQ(128u, memory_tracker
->GetPoolSize(MemoryTracker::kUnmanaged
));
1021 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
1022 // Check we get out of memory and no call to glCopyTexImage2D if Ensure fails.
1023 EXPECT_CALL(*memory_tracker
.get(), EnsureGPUMemoryAvailable(128))
1024 .WillOnce(Return(false))
1025 .RetiresOnSaturation();
1026 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
1027 EXPECT_EQ(GL_OUT_OF_MEMORY
, GetGLError());
1028 EXPECT_EQ(128u, memory_tracker
->GetPoolSize(MemoryTracker::kUnmanaged
));
1031 TEST_P(GLES2DecoderManualInitTest
, MemoryTrackerRenderbufferStorage
) {
1032 scoped_refptr
<SizeOnlyMemoryTracker
> memory_tracker
=
1033 new SizeOnlyMemoryTracker();
1034 set_memory_tracker(memory_tracker
.get());
1036 init
.bind_generates_resource
= true;
1039 GL_RENDERBUFFER
, client_renderbuffer_id_
, kServiceRenderbufferId
);
1040 EnsureRenderbufferBound(false);
1041 EXPECT_CALL(*gl_
, GetError())
1042 .WillOnce(Return(GL_NO_ERROR
))
1043 .WillOnce(Return(GL_NO_ERROR
))
1044 .RetiresOnSaturation();
1045 EXPECT_CALL(*memory_tracker
.get(), EnsureGPUMemoryAvailable(128))
1046 .WillOnce(Return(true))
1047 .RetiresOnSaturation();
1048 EXPECT_CALL(*gl_
, RenderbufferStorageEXT(GL_RENDERBUFFER
, GL_RGBA
, 8, 4))
1050 .RetiresOnSaturation();
1051 RenderbufferStorage cmd
;
1052 cmd
.Init(GL_RENDERBUFFER
, GL_RGBA4
, 8, 4);
1053 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
1054 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
1055 EXPECT_EQ(128u, memory_tracker
->GetPoolSize(MemoryTracker::kUnmanaged
));
1056 // Check we get out of memory and no call to glRenderbufferStorage if Ensure
1058 EXPECT_CALL(*memory_tracker
.get(), EnsureGPUMemoryAvailable(128))
1059 .WillOnce(Return(false))
1060 .RetiresOnSaturation();
1061 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
1062 EXPECT_EQ(GL_OUT_OF_MEMORY
, GetGLError());
1063 EXPECT_EQ(128u, memory_tracker
->GetPoolSize(MemoryTracker::kUnmanaged
));
1066 TEST_P(GLES2DecoderManualInitTest
, MemoryTrackerBufferData
) {
1067 scoped_refptr
<SizeOnlyMemoryTracker
> memory_tracker
=
1068 new SizeOnlyMemoryTracker();
1069 set_memory_tracker(memory_tracker
.get());
1071 init
.bind_generates_resource
= true;
1073 DoBindBuffer(GL_ARRAY_BUFFER
, client_buffer_id_
, kServiceBufferId
);
1074 EXPECT_CALL(*gl_
, GetError())
1075 .WillOnce(Return(GL_NO_ERROR
))
1076 .WillOnce(Return(GL_NO_ERROR
))
1077 .RetiresOnSaturation();
1078 EXPECT_CALL(*memory_tracker
.get(), EnsureGPUMemoryAvailable(128))
1079 .WillOnce(Return(true))
1080 .RetiresOnSaturation();
1081 EXPECT_CALL(*gl_
, BufferData(GL_ARRAY_BUFFER
, 128, _
, GL_STREAM_DRAW
))
1083 .RetiresOnSaturation();
1085 cmd
.Init(GL_ARRAY_BUFFER
, 128, 0, 0, GL_STREAM_DRAW
);
1086 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
1087 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
1088 EXPECT_EQ(128u, memory_tracker
->GetPoolSize(MemoryTracker::kManaged
));
1089 // Check we get out of memory and no call to glBufferData if Ensure
1091 EXPECT_CALL(*memory_tracker
.get(), EnsureGPUMemoryAvailable(128))
1092 .WillOnce(Return(false))
1093 .RetiresOnSaturation();
1094 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
1095 EXPECT_EQ(GL_OUT_OF_MEMORY
, GetGLError());
1096 EXPECT_EQ(128u, memory_tracker
->GetPoolSize(MemoryTracker::kManaged
));
1099 TEST_P(GLES2DecoderManualInitTest
, ImmutableCopyTexImage2D
) {
1100 const GLenum kTarget
= GL_TEXTURE_2D
;
1101 const GLint kLevel
= 0;
1102 const GLenum kInternalFormat
= GL_RGBA
;
1103 const GLenum kSizedInternalFormat
= GL_RGBA8
;
1104 const GLsizei kWidth
= 4;
1105 const GLsizei kHeight
= 8;
1106 const GLint kBorder
= 0;
1108 init
.extensions
= "GL_EXT_texture_storage";
1109 init
.has_alpha
= true;
1110 init
.request_alpha
= true;
1111 init
.bind_generates_resource
= true;
1113 DoBindTexture(GL_TEXTURE_2D
, client_texture_id_
, kServiceTextureId
);
1115 // CopyTexImage2D will call arbitrary amount of GetErrors.
1116 EXPECT_CALL(*gl_
, GetError())
1121 kTarget
, kLevel
, kInternalFormat
, 0, 0, kWidth
, kHeight
,
1127 kTarget
, kLevel
, kSizedInternalFormat
, kWidth
, kHeight
))
1129 CopyTexImage2D copy_cmd
;
1130 copy_cmd
.Init(kTarget
, kLevel
, kInternalFormat
, 0, 0, kWidth
, kHeight
);
1131 EXPECT_EQ(error::kNoError
, ExecuteCmd(copy_cmd
));
1132 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
1134 TexStorage2DEXT storage_cmd
;
1135 storage_cmd
.Init(kTarget
, kLevel
, kSizedInternalFormat
, kWidth
, kHeight
);
1136 EXPECT_EQ(error::kNoError
, ExecuteCmd(storage_cmd
));
1137 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
1139 // This should not invoke CopyTexImage2D.
1140 copy_cmd
.Init(kTarget
, kLevel
, kInternalFormat
, 0, 0, kWidth
, kHeight
);
1141 EXPECT_EQ(error::kNoError
, ExecuteCmd(copy_cmd
));
1142 EXPECT_EQ(GL_INVALID_OPERATION
, GetGLError());
1145 TEST_P(GLES2DecoderTest
, LoseContextCHROMIUMGuilty
) {
1146 EXPECT_CALL(*mock_decoder_
, MarkContextLost(error::kInnocent
))
1148 cmds::LoseContextCHROMIUM cmd
;
1149 cmd
.Init(GL_GUILTY_CONTEXT_RESET_ARB
, GL_INNOCENT_CONTEXT_RESET_ARB
);
1150 EXPECT_EQ(error::kLostContext
, ExecuteCmd(cmd
));
1151 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
1152 EXPECT_TRUE(decoder_
->WasContextLost());
1153 EXPECT_TRUE(decoder_
->WasContextLostByRobustnessExtension());
1156 TEST_P(GLES2DecoderTest
, LoseContextCHROMIUMUnkown
) {
1157 EXPECT_CALL(*mock_decoder_
, MarkContextLost(error::kUnknown
))
1159 cmds::LoseContextCHROMIUM cmd
;
1160 cmd
.Init(GL_UNKNOWN_CONTEXT_RESET_ARB
, GL_UNKNOWN_CONTEXT_RESET_ARB
);
1161 EXPECT_EQ(error::kLostContext
, ExecuteCmd(cmd
));
1162 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
1163 EXPECT_TRUE(decoder_
->WasContextLost());
1164 EXPECT_TRUE(decoder_
->WasContextLostByRobustnessExtension());
1167 TEST_P(GLES2DecoderTest
, LoseContextCHROMIUMInvalidArgs0_0
) {
1168 EXPECT_CALL(*mock_decoder_
, MarkContextLost(_
))
1170 cmds::LoseContextCHROMIUM cmd
;
1171 cmd
.Init(GL_NONE
, GL_GUILTY_CONTEXT_RESET_ARB
);
1172 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
1173 EXPECT_EQ(GL_INVALID_ENUM
, GetGLError());
1176 TEST_P(GLES2DecoderTest
, LoseContextCHROMIUMInvalidArgs1_0
) {
1177 EXPECT_CALL(*mock_decoder_
, MarkContextLost(_
))
1179 cmds::LoseContextCHROMIUM cmd
;
1180 cmd
.Init(GL_GUILTY_CONTEXT_RESET_ARB
, GL_NONE
);
1181 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
1182 EXPECT_EQ(GL_INVALID_ENUM
, GetGLError());
1185 class GLES2DecoderDoCommandsTest
: public GLES2DecoderTest
{
1187 GLES2DecoderDoCommandsTest() {
1188 for (int i
= 0; i
< 3; i
++) {
1189 cmds_
[i
].Init(GL_BLEND
);
1191 entries_per_cmd_
= ComputeNumEntries(cmds_
[0].ComputeSize());
1194 void SetExpectationsForNCommands(int num_commands
) {
1195 for (int i
= 0; i
< num_commands
; i
++)
1196 SetupExpectationsForEnableDisable(GL_BLEND
, true);
1201 int entries_per_cmd_
;
1204 // Test that processing with 0 entries does nothing.
1205 TEST_P(GLES2DecoderDoCommandsTest
, DoCommandsOneOfZero
) {
1206 int num_processed
= -1;
1207 SetExpectationsForNCommands(0);
1210 decoder_
->DoCommands(1, &cmds_
, entries_per_cmd_
* 0, &num_processed
));
1211 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
1212 EXPECT_EQ(0, num_processed
);
1215 // Test processing at granularity of single commands.
1216 TEST_P(GLES2DecoderDoCommandsTest
, DoCommandsOneOfOne
) {
1217 int num_processed
= -1;
1218 SetExpectationsForNCommands(1);
1221 decoder_
->DoCommands(1, &cmds_
, entries_per_cmd_
* 1, &num_processed
));
1222 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
1223 EXPECT_EQ(entries_per_cmd_
, num_processed
);
1226 // Test processing at granularity of multiple commands.
1227 TEST_P(GLES2DecoderDoCommandsTest
, DoCommandsThreeOfThree
) {
1228 int num_processed
= -1;
1229 SetExpectationsForNCommands(3);
1232 decoder_
->DoCommands(3, &cmds_
, entries_per_cmd_
* 3, &num_processed
));
1233 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
1234 EXPECT_EQ(entries_per_cmd_
* 3, num_processed
);
1237 // Test processing a request smaller than available entries.
1238 TEST_P(GLES2DecoderDoCommandsTest
, DoCommandsTwoOfThree
) {
1239 int num_processed
= -1;
1240 SetExpectationsForNCommands(2);
1243 decoder_
->DoCommands(2, &cmds_
, entries_per_cmd_
* 3, &num_processed
));
1244 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
1245 EXPECT_EQ(entries_per_cmd_
* 2, num_processed
);
1248 // Test that processing stops on a command with size 0.
1249 TEST_P(GLES2DecoderDoCommandsTest
, DoCommandsZeroCmdSize
) {
1250 cmds_
[1].header
.size
= 0;
1251 int num_processed
= -1;
1252 SetExpectationsForNCommands(1);
1254 error::kInvalidSize
,
1255 decoder_
->DoCommands(2, &cmds_
, entries_per_cmd_
* 2, &num_processed
));
1256 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
1257 EXPECT_EQ(entries_per_cmd_
, num_processed
);
1260 // Test that processing stops on a command with size greater than available.
1261 TEST_P(GLES2DecoderDoCommandsTest
, DoCommandsOutOfBounds
) {
1262 int num_processed
= -1;
1263 SetExpectationsForNCommands(1);
1264 EXPECT_EQ(error::kOutOfBounds
,
1265 decoder_
->DoCommands(
1266 2, &cmds_
, entries_per_cmd_
* 2 - 1, &num_processed
));
1267 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
1268 EXPECT_EQ(entries_per_cmd_
, num_processed
);
1271 // Test that commands with bad argument size are skipped without processing.
1272 TEST_P(GLES2DecoderDoCommandsTest
, DoCommandsBadArgSize
) {
1273 cmds_
[1].header
.size
+= 1;
1274 int num_processed
= -1;
1275 SetExpectationsForNCommands(1);
1276 EXPECT_EQ(error::kInvalidArguments
,
1277 decoder_
->DoCommands(
1278 2, &cmds_
, entries_per_cmd_
* 2 + 1, &num_processed
));
1279 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
1280 EXPECT_EQ(entries_per_cmd_
+ cmds_
[1].header
.size
, num_processed
);
1283 INSTANTIATE_TEST_CASE_P(Service
, GLES2DecoderTest
, ::testing::Bool());
1285 INSTANTIATE_TEST_CASE_P(Service
, GLES2DecoderWithShaderTest
, ::testing::Bool());
1287 INSTANTIATE_TEST_CASE_P(Service
, GLES2DecoderManualInitTest
, ::testing::Bool());
1289 INSTANTIATE_TEST_CASE_P(Service
,
1290 GLES2DecoderRGBBackbufferTest
,
1293 INSTANTIATE_TEST_CASE_P(Service
, GLES2DecoderDoCommandsTest
, ::testing::Bool());
1295 INSTANTIATE_TEST_CASE_P(Service
, GLES3DecoderTest
, ::testing::Bool());
1297 } // namespace gles2