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 // Test codepath with workaround clear_alpha_in_readpixels because
95 // ReadPixelsEmulator emulates the incorrect driver behavior.
96 base::CommandLine
command_line(0, NULL
);
97 command_line
.AppendSwitch(switches::kEnableUnsafeES3APIs
);
99 init
.gl_version
= "4.4";
100 init
.bind_generates_resource
= true;
101 InitDecoderWithCommandLine(init
, &command_line
);
105 TEST_P(GLES2DecoderTest
, GetIntegervCached
) {
112 GL_MAX_TEXTURE_SIZE
, TestHelper::kMaxTextureSize
,
115 GL_MAX_CUBE_MAP_TEXTURE_SIZE
, TestHelper::kMaxCubeMapTextureSize
,
118 GL_MAX_RENDERBUFFER_SIZE
, TestHelper::kMaxRenderbufferSize
,
121 typedef GetIntegerv::Result Result
;
122 for (size_t ii
= 0; ii
< sizeof(tests
) / sizeof(tests
[0]); ++ii
) {
123 const TestInfo
& test
= tests
[ii
];
124 Result
* result
= static_cast<Result
*>(shared_memory_address_
);
125 EXPECT_CALL(*gl_
, GetError())
126 .WillOnce(Return(GL_NO_ERROR
))
127 .WillOnce(Return(GL_NO_ERROR
))
128 .RetiresOnSaturation();
129 EXPECT_CALL(*gl_
, GetIntegerv(test
.pname
, _
)).Times(0);
132 cmd2
.Init(test
.pname
, shared_memory_id_
, shared_memory_offset_
);
133 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd2
));
134 EXPECT_EQ(decoder_
->GetGLES2Util()->GLGetNumValuesReturned(test
.pname
),
135 result
->GetNumResults());
136 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
137 EXPECT_EQ(test
.expected
, result
->GetData()[0]);
141 TEST_P(GLES2DecoderWithShaderTest
, GetMaxValueInBufferCHROMIUM
) {
143 GetMaxValueInBufferCHROMIUM::Result
* result
=
144 static_cast<GetMaxValueInBufferCHROMIUM::Result
*>(shared_memory_address_
);
147 GetMaxValueInBufferCHROMIUM cmd
;
148 cmd
.Init(client_element_buffer_id_
,
149 kValidIndexRangeCount
,
151 kValidIndexRangeStart
* 2,
153 kSharedMemoryOffset
);
154 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
155 EXPECT_EQ(7u, *result
);
156 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
157 cmd
.Init(client_element_buffer_id_
,
158 kValidIndexRangeCount
+ 1,
160 kValidIndexRangeStart
* 2,
162 kSharedMemoryOffset
);
163 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
164 EXPECT_EQ(100u, *result
);
165 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
167 cmd
.Init(kInvalidClientId
,
168 kValidIndexRangeCount
,
170 kValidIndexRangeStart
* 2,
172 kSharedMemoryOffset
);
173 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
174 EXPECT_EQ(GL_INVALID_VALUE
, GetGLError());
175 cmd
.Init(client_element_buffer_id_
,
176 kOutOfRangeIndexRangeEnd
,
178 kValidIndexRangeStart
* 2,
180 kSharedMemoryOffset
);
181 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
182 EXPECT_EQ(GL_INVALID_OPERATION
, GetGLError());
183 cmd
.Init(client_element_buffer_id_
,
184 kValidIndexRangeCount
+ 1,
186 kOutOfRangeIndexRangeEnd
* 2,
188 kSharedMemoryOffset
);
189 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
190 EXPECT_EQ(GL_INVALID_OPERATION
, GetGLError());
191 cmd
.Init(client_element_buffer_id_
,
192 kValidIndexRangeCount
+ 1,
194 kValidIndexRangeStart
* 2,
196 kSharedMemoryOffset
);
197 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
198 cmd
.Init(client_buffer_id_
,
199 kValidIndexRangeCount
+ 1,
201 kValidIndexRangeStart
* 2,
203 kSharedMemoryOffset
);
204 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
205 EXPECT_EQ(GL_INVALID_OPERATION
, GetGLError());
206 cmd
.Init(client_element_buffer_id_
,
207 kValidIndexRangeCount
+ 1,
209 kValidIndexRangeStart
* 2,
210 kInvalidSharedMemoryId
,
211 kSharedMemoryOffset
);
212 EXPECT_NE(error::kNoError
, ExecuteCmd(cmd
));
213 cmd
.Init(client_element_buffer_id_
,
214 kValidIndexRangeCount
+ 1,
216 kValidIndexRangeStart
* 2,
218 kInvalidSharedMemoryOffset
);
219 EXPECT_NE(error::kNoError
, ExecuteCmd(cmd
));
222 TEST_P(GLES2DecoderTest
, IsBuffer
) {
223 EXPECT_FALSE(DoIsBuffer(client_buffer_id_
));
224 DoBindBuffer(GL_ARRAY_BUFFER
, client_buffer_id_
, kServiceBufferId
);
225 EXPECT_TRUE(DoIsBuffer(client_buffer_id_
));
226 DoDeleteBuffer(client_buffer_id_
, kServiceBufferId
);
227 EXPECT_FALSE(DoIsBuffer(client_buffer_id_
));
230 TEST_P(GLES2DecoderTest
, IsFramebuffer
) {
231 EXPECT_FALSE(DoIsFramebuffer(client_framebuffer_id_
));
233 GL_FRAMEBUFFER
, client_framebuffer_id_
, kServiceFramebufferId
);
234 EXPECT_TRUE(DoIsFramebuffer(client_framebuffer_id_
));
235 DoDeleteFramebuffer(client_framebuffer_id_
,
236 kServiceFramebufferId
,
243 EXPECT_FALSE(DoIsFramebuffer(client_framebuffer_id_
));
246 TEST_P(GLES2DecoderTest
, IsProgram
) {
247 // IsProgram is true as soon as the program is created.
248 EXPECT_TRUE(DoIsProgram(client_program_id_
));
249 EXPECT_CALL(*gl_
, DeleteProgram(kServiceProgramId
))
251 .RetiresOnSaturation();
252 DoDeleteProgram(client_program_id_
, kServiceProgramId
);
253 EXPECT_FALSE(DoIsProgram(client_program_id_
));
256 TEST_P(GLES2DecoderTest
, IsRenderbuffer
) {
257 EXPECT_FALSE(DoIsRenderbuffer(client_renderbuffer_id_
));
259 GL_RENDERBUFFER
, client_renderbuffer_id_
, kServiceRenderbufferId
);
260 EXPECT_TRUE(DoIsRenderbuffer(client_renderbuffer_id_
));
261 DoDeleteRenderbuffer(client_renderbuffer_id_
, kServiceRenderbufferId
);
262 EXPECT_FALSE(DoIsRenderbuffer(client_renderbuffer_id_
));
265 TEST_P(GLES2DecoderTest
, IsShader
) {
266 // IsShader is true as soon as the program is created.
267 EXPECT_TRUE(DoIsShader(client_shader_id_
));
268 DoDeleteShader(client_shader_id_
, kServiceShaderId
);
269 EXPECT_FALSE(DoIsShader(client_shader_id_
));
272 TEST_P(GLES2DecoderTest
, IsTexture
) {
273 EXPECT_FALSE(DoIsTexture(client_texture_id_
));
274 DoBindTexture(GL_TEXTURE_2D
, client_texture_id_
, kServiceTextureId
);
275 EXPECT_TRUE(DoIsTexture(client_texture_id_
));
276 DoDeleteTexture(client_texture_id_
, kServiceTextureId
);
277 EXPECT_FALSE(DoIsTexture(client_texture_id_
));
280 TEST_P(GLES2DecoderTest
, ClientWaitSyncValid
) {
281 typedef cmds::ClientWaitSync::Result Result
;
282 Result
* result
= static_cast<Result
*>(shared_memory_address_
);
283 cmds::ClientWaitSync cmd
;
284 uint32_t v32_0
= 0, v32_1
= 0;
285 GLES2Util::MapUint64ToTwoUint32(0, &v32_0
, &v32_1
);
286 cmd
.Init(client_sync_id_
, GL_SYNC_FLUSH_COMMANDS_BIT
, v32_0
, v32_1
,
287 shared_memory_id_
, shared_memory_offset_
);
289 ClientWaitSync(reinterpret_cast<GLsync
>(kServiceSyncId
),
290 GL_SYNC_FLUSH_COMMANDS_BIT
, 0))
291 .WillOnce(Return(GL_CONDITION_SATISFIED
))
292 .RetiresOnSaturation();
293 *result
= GL_WAIT_FAILED
;
294 decoder_
->set_unsafe_es3_apis_enabled(true);
295 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
296 EXPECT_EQ(static_cast<GLenum
>(GL_CONDITION_SATISFIED
), *result
);
297 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
298 decoder_
->set_unsafe_es3_apis_enabled(false);
299 EXPECT_EQ(error::kUnknownCommand
, ExecuteCmd(cmd
));
302 TEST_P(GLES2DecoderTest
, ClientWaitSyncNonZeroTimeoutValid
) {
303 typedef cmds::ClientWaitSync::Result Result
;
304 Result
* result
= static_cast<Result
*>(shared_memory_address_
);
305 cmds::ClientWaitSync cmd
;
306 const GLuint64 kTimeout
= 0xABCDEF0123456789;
307 uint32_t v32_0
= 0, v32_1
= 0;
308 GLES2Util::MapUint64ToTwoUint32(kTimeout
, &v32_0
, &v32_1
);
309 cmd
.Init(client_sync_id_
, GL_SYNC_FLUSH_COMMANDS_BIT
, v32_0
, v32_1
,
310 shared_memory_id_
, shared_memory_offset_
);
312 ClientWaitSync(reinterpret_cast<GLsync
>(kServiceSyncId
),
313 GL_SYNC_FLUSH_COMMANDS_BIT
, kTimeout
))
314 .WillOnce(Return(GL_CONDITION_SATISFIED
))
315 .RetiresOnSaturation();
316 *result
= GL_WAIT_FAILED
;
317 decoder_
->set_unsafe_es3_apis_enabled(true);
318 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
319 EXPECT_EQ(static_cast<GLenum
>(GL_CONDITION_SATISFIED
), *result
);
320 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
321 decoder_
->set_unsafe_es3_apis_enabled(false);
322 EXPECT_EQ(error::kUnknownCommand
, ExecuteCmd(cmd
));
325 TEST_P(GLES2DecoderTest
, ClientWaitSyncInvalidSyncFails
) {
326 typedef cmds::ClientWaitSync::Result Result
;
327 Result
* result
= static_cast<Result
*>(shared_memory_address_
);
328 cmds::ClientWaitSync cmd
;
329 uint32_t v32_0
= 0, v32_1
= 0;
330 GLES2Util::MapUint64ToTwoUint32(0, &v32_0
, &v32_1
);
331 decoder_
->set_unsafe_es3_apis_enabled(true);
332 cmd
.Init(kInvalidClientId
, GL_SYNC_FLUSH_COMMANDS_BIT
, v32_0
, v32_1
,
333 shared_memory_id_
, shared_memory_offset_
);
334 *result
= GL_WAIT_FAILED
;
335 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
336 EXPECT_EQ(static_cast<GLenum
>(GL_WAIT_FAILED
), *result
);
337 EXPECT_EQ(GL_INVALID_VALUE
, GetGLError());
340 TEST_P(GLES2DecoderTest
, ClientWaitSyncResultNotInitFails
) {
341 typedef cmds::ClientWaitSync::Result Result
;
342 Result
* result
= static_cast<Result
*>(shared_memory_address_
);
343 cmds::ClientWaitSync cmd
;
344 uint32_t v32_0
= 0, v32_1
= 0;
345 GLES2Util::MapUint64ToTwoUint32(0, &v32_0
, &v32_1
);
346 decoder_
->set_unsafe_es3_apis_enabled(true);
347 cmd
.Init(client_sync_id_
, GL_SYNC_FLUSH_COMMANDS_BIT
, v32_0
, v32_1
,
348 shared_memory_id_
, shared_memory_offset_
);
349 *result
= 1; // Any value other than GL_WAIT_FAILED
350 EXPECT_NE(error::kNoError
, ExecuteCmd(cmd
));
353 TEST_P(GLES2DecoderTest
, ClientWaitSyncBadSharedMemoryFails
) {
354 typedef cmds::ClientWaitSync::Result Result
;
355 Result
* result
= static_cast<Result
*>(shared_memory_address_
);
356 cmds::ClientWaitSync cmd
;
357 uint32_t v32_0
= 0, v32_1
= 0;
358 GLES2Util::MapUint64ToTwoUint32(0, &v32_0
, &v32_1
);
359 decoder_
->set_unsafe_es3_apis_enabled(true);
360 *result
= GL_WAIT_FAILED
;
361 cmd
.Init(client_sync_id_
, GL_SYNC_FLUSH_COMMANDS_BIT
, v32_0
, v32_1
,
362 kInvalidSharedMemoryId
, shared_memory_offset_
);
363 EXPECT_NE(error::kNoError
, ExecuteCmd(cmd
));
365 *result
= GL_WAIT_FAILED
;
366 cmd
.Init(client_sync_id_
, GL_SYNC_FLUSH_COMMANDS_BIT
, v32_0
, v32_1
,
367 shared_memory_id_
, kInvalidSharedMemoryOffset
);
368 EXPECT_NE(error::kNoError
, ExecuteCmd(cmd
));
371 TEST_P(GLES2DecoderTest
, WaitSyncValidArgs
) {
372 const GLuint64 kTimeout
= GL_TIMEOUT_IGNORED
;
373 EXPECT_CALL(*gl_
, WaitSync(reinterpret_cast<GLsync
>(kServiceSyncId
),
376 .RetiresOnSaturation();
378 uint32_t v32_0
= 0, v32_1
= 0;
379 GLES2Util::MapUint64ToTwoUint32(kTimeout
, &v32_0
, &v32_1
);
381 cmd
.Init(client_sync_id_
, 0, v32_0
, v32_1
);
382 decoder_
->set_unsafe_es3_apis_enabled(true);
383 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
384 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
385 decoder_
->set_unsafe_es3_apis_enabled(false);
386 EXPECT_EQ(error::kUnknownCommand
, ExecuteCmd(cmd
));
389 TEST_P(GLES2DecoderManualInitTest
, BindGeneratesResourceFalse
) {
394 cmd1
.Init(GL_TEXTURE_2D
, kInvalidClientId
);
395 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd1
));
396 EXPECT_EQ(GL_INVALID_OPERATION
, GetGLError());
399 cmd2
.Init(GL_ARRAY_BUFFER
, kInvalidClientId
);
400 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd2
));
401 EXPECT_EQ(GL_INVALID_OPERATION
, GetGLError());
403 BindFramebuffer cmd3
;
404 cmd3
.Init(GL_FRAMEBUFFER
, kInvalidClientId
);
405 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd3
));
406 EXPECT_EQ(GL_INVALID_OPERATION
, GetGLError());
408 BindRenderbuffer cmd4
;
409 cmd4
.Init(GL_RENDERBUFFER
, kInvalidClientId
);
410 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd4
));
411 EXPECT_EQ(GL_INVALID_OPERATION
, GetGLError());
414 TEST_P(GLES2DecoderTest
, EnableFeatureCHROMIUMBadBucket
) {
415 const uint32 kBadBucketId
= 123;
416 EnableFeatureCHROMIUM cmd
;
417 cmd
.Init(kBadBucketId
, shared_memory_id_
, shared_memory_offset_
);
418 EXPECT_NE(error::kNoError
, ExecuteCmd(cmd
));
421 TEST_P(GLES2DecoderTest
, RequestExtensionCHROMIUMBadBucket
) {
422 const uint32 kBadBucketId
= 123;
423 RequestExtensionCHROMIUM cmd
;
424 cmd
.Init(kBadBucketId
);
425 EXPECT_NE(error::kNoError
, ExecuteCmd(cmd
));
428 TEST_P(GLES2DecoderTest
, BeginQueryEXTDisabled
) {
429 // Test something fails if off.
432 TEST_P(GLES2DecoderManualInitTest
, BeginEndQueryEXT
) {
434 init
.extensions
= "GL_EXT_occlusion_query_boolean";
435 init
.gl_version
= "opengl es 2.0";
436 init
.has_alpha
= true;
437 init
.request_alpha
= true;
438 init
.bind_generates_resource
= true;
441 // Test end fails if no begin.
443 end_cmd
.Init(GL_ANY_SAMPLES_PASSED_EXT
, 1);
444 EXPECT_EQ(error::kNoError
, ExecuteCmd(end_cmd
));
445 EXPECT_EQ(GL_INVALID_OPERATION
, GetGLError());
447 BeginQueryEXT begin_cmd
;
449 // Test id = 0 fails.
451 GL_ANY_SAMPLES_PASSED_EXT
, 0, kSharedMemoryId
, kSharedMemoryOffset
);
452 EXPECT_EQ(error::kNoError
, ExecuteCmd(begin_cmd
));
453 EXPECT_EQ(GL_INVALID_OPERATION
, GetGLError());
455 GenHelper
<GenQueriesEXTImmediate
>(kNewClientId
);
457 // Test valid parameters work.
458 EXPECT_CALL(*gl_
, GenQueries(1, _
))
459 .WillOnce(SetArgumentPointee
<1>(kNewServiceId
))
460 .RetiresOnSaturation();
461 EXPECT_CALL(*gl_
, BeginQuery(GL_ANY_SAMPLES_PASSED_EXT
, kNewServiceId
))
463 .RetiresOnSaturation();
465 // Query object should not be created untill BeginQueriesEXT.
466 QueryManager
* query_manager
= decoder_
->GetQueryManager();
467 ASSERT_TRUE(query_manager
!= NULL
);
468 QueryManager::Query
* query
= query_manager
->GetQuery(kNewClientId
);
469 EXPECT_TRUE(query
== NULL
);
471 // BeginQueryEXT should fail if id is not generated from GenQueriesEXT.
472 begin_cmd
.Init(GL_ANY_SAMPLES_PASSED_EXT
,
475 kSharedMemoryOffset
);
476 EXPECT_EQ(error::kNoError
, ExecuteCmd(begin_cmd
));
477 EXPECT_EQ(GL_INVALID_OPERATION
, GetGLError());
479 begin_cmd
.Init(GL_ANY_SAMPLES_PASSED_EXT
,
482 kSharedMemoryOffset
);
483 EXPECT_EQ(error::kNoError
, ExecuteCmd(begin_cmd
));
484 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
486 // After BeginQueriesEXT id name should have query object associated with it.
487 query
= query_manager
->GetQuery(kNewClientId
);
488 ASSERT_TRUE(query
!= NULL
);
489 EXPECT_FALSE(query
->pending());
491 // Test trying begin again fails
492 EXPECT_EQ(error::kNoError
, ExecuteCmd(begin_cmd
));
493 EXPECT_EQ(GL_INVALID_OPERATION
, GetGLError());
495 // Test end fails with different target
496 end_cmd
.Init(GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT
, 1);
497 EXPECT_EQ(error::kNoError
, ExecuteCmd(end_cmd
));
498 EXPECT_EQ(GL_INVALID_OPERATION
, GetGLError());
501 EXPECT_CALL(*gl_
, EndQuery(GL_ANY_SAMPLES_PASSED_EXT
))
503 .RetiresOnSaturation();
504 end_cmd
.Init(GL_ANY_SAMPLES_PASSED_EXT
, 1);
505 EXPECT_EQ(error::kNoError
, ExecuteCmd(end_cmd
));
506 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
507 EXPECT_TRUE(query
->pending());
509 EXPECT_CALL(*gl_
, DeleteQueries(1, _
)).Times(1).RetiresOnSaturation();
517 const QueryType kQueryTypes
[] = {
518 {GL_COMMANDS_ISSUED_CHROMIUM
, false},
519 {GL_LATENCY_QUERY_CHROMIUM
, false},
520 {GL_ASYNC_PIXEL_UNPACK_COMPLETED_CHROMIUM
, false},
521 {GL_ASYNC_PIXEL_PACK_COMPLETED_CHROMIUM
, false},
522 {GL_GET_ERROR_QUERY_CHROMIUM
, false},
523 {GL_COMMANDS_COMPLETED_CHROMIUM
, false},
524 {GL_ANY_SAMPLES_PASSED_EXT
, true},
527 static void CheckBeginEndQueryBadMemoryFails(GLES2DecoderTestBase
* test
,
530 const QueryType
& query_type
,
533 // We need to reset the decoder on each iteration, because we lose the
534 // context every time.
535 GLES2DecoderTestBase::InitState init
;
536 init
.extensions
= "GL_EXT_occlusion_query_boolean GL_ARB_sync";
537 init
.gl_version
= "opengl es 2.0";
538 init
.has_alpha
= true;
539 init
.request_alpha
= true;
540 init
.bind_generates_resource
= true;
541 test
->InitDecoder(init
);
542 ::testing::StrictMock
< ::gfx::MockGLInterface
>* gl
= test
->GetGLMock();
544 BeginQueryEXT begin_cmd
;
546 test
->GenHelper
<GenQueriesEXTImmediate
>(client_id
);
548 if (query_type
.is_gl
) {
549 EXPECT_CALL(*gl
, GenQueries(1, _
))
550 .WillOnce(SetArgumentPointee
<1>(service_id
))
551 .RetiresOnSaturation();
552 EXPECT_CALL(*gl
, BeginQuery(query_type
.type
, service_id
))
554 .RetiresOnSaturation();
557 // Test bad shared memory fails
558 begin_cmd
.Init(query_type
.type
, client_id
, shm_id
, shm_offset
);
559 error::Error error1
= test
->ExecuteCmd(begin_cmd
);
561 if (query_type
.is_gl
) {
562 EXPECT_CALL(*gl
, EndQuery(query_type
.type
))
564 .RetiresOnSaturation();
566 if (query_type
.type
== GL_GET_ERROR_QUERY_CHROMIUM
) {
567 EXPECT_CALL(*gl
, GetError())
568 .WillOnce(Return(GL_NO_ERROR
))
569 .RetiresOnSaturation();
571 GLsync kGlSync
= reinterpret_cast<GLsync
>(0xdeadbeef);
572 if (query_type
.type
== GL_COMMANDS_COMPLETED_CHROMIUM
) {
573 EXPECT_CALL(*gl
, Flush()).RetiresOnSaturation();
574 EXPECT_CALL(*gl
, FenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE
, 0))
575 .WillOnce(Return(kGlSync
))
576 .RetiresOnSaturation();
578 EXPECT_CALL(*gl
, IsSync(kGlSync
))
579 .WillOnce(Return(GL_TRUE
))
580 .RetiresOnSaturation();
585 end_cmd
.Init(query_type
.type
, 1);
586 error::Error error2
= test
->ExecuteCmd(end_cmd
);
588 if (query_type
.is_gl
) {
590 *gl
, GetQueryObjectuiv(service_id
, GL_QUERY_RESULT_AVAILABLE_EXT
, _
))
591 .WillOnce(SetArgumentPointee
<2>(1))
592 .RetiresOnSaturation();
593 EXPECT_CALL(*gl
, GetQueryObjectuiv(service_id
, GL_QUERY_RESULT_EXT
, _
))
594 .WillOnce(SetArgumentPointee
<2>(1))
595 .RetiresOnSaturation();
597 if (query_type
.type
== GL_COMMANDS_COMPLETED_CHROMIUM
) {
599 EXPECT_CALL(*gl
, IsSync(kGlSync
))
600 .WillOnce(Return(GL_TRUE
))
601 .RetiresOnSaturation();
603 EXPECT_CALL(*gl
, ClientWaitSync(kGlSync
, _
, _
))
604 .WillOnce(Return(GL_ALREADY_SIGNALED
))
605 .RetiresOnSaturation();
608 QueryManager
* query_manager
= test
->GetDecoder()->GetQueryManager();
609 ASSERT_TRUE(query_manager
!= NULL
);
610 bool process_success
= query_manager
->ProcessPendingQueries(false);
612 EXPECT_TRUE(error1
!= error::kNoError
|| error2
!= error::kNoError
||
615 if (query_type
.is_gl
) {
616 EXPECT_CALL(*gl
, DeleteQueries(1, _
)).Times(1).RetiresOnSaturation();
618 if (query_type
.type
== GL_COMMANDS_COMPLETED_CHROMIUM
) {
620 EXPECT_CALL(*gl
, IsSync(kGlSync
))
621 .WillOnce(Return(GL_TRUE
))
622 .RetiresOnSaturation();
624 EXPECT_CALL(*gl
, DeleteSync(kGlSync
)).Times(1).RetiresOnSaturation();
626 test
->ResetDecoder();
629 TEST_P(GLES2DecoderManualInitTest
, BeginEndQueryEXTBadMemoryIdFails
) {
630 for (size_t i
= 0; i
< arraysize(kQueryTypes
); ++i
) {
631 CheckBeginEndQueryBadMemoryFails(this,
635 kInvalidSharedMemoryId
,
636 kSharedMemoryOffset
);
640 TEST_P(GLES2DecoderManualInitTest
, BeginEndQueryEXTBadMemoryOffsetFails
) {
641 for (size_t i
= 0; i
< arraysize(kQueryTypes
); ++i
) {
643 CheckBeginEndQueryBadMemoryFails(this,
648 kInvalidSharedMemoryOffset
);
650 CheckBeginEndQueryBadMemoryFails(this,
659 TEST_P(GLES2DecoderTest
, BeginEndQueryEXTCommandsIssuedCHROMIUM
) {
660 BeginQueryEXT begin_cmd
;
662 GenHelper
<GenQueriesEXTImmediate
>(kNewClientId
);
664 // Test valid parameters work.
665 begin_cmd
.Init(GL_COMMANDS_ISSUED_CHROMIUM
,
668 kSharedMemoryOffset
);
669 EXPECT_EQ(error::kNoError
, ExecuteCmd(begin_cmd
));
670 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
672 QueryManager
* query_manager
= decoder_
->GetQueryManager();
673 ASSERT_TRUE(query_manager
!= NULL
);
674 QueryManager::Query
* query
= query_manager
->GetQuery(kNewClientId
);
675 ASSERT_TRUE(query
!= NULL
);
676 EXPECT_FALSE(query
->pending());
680 end_cmd
.Init(GL_COMMANDS_ISSUED_CHROMIUM
, 1);
681 EXPECT_EQ(error::kNoError
, ExecuteCmd(end_cmd
));
682 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
683 EXPECT_FALSE(query
->pending());
686 TEST_P(GLES2DecoderTest
, BeginEndQueryEXTGetErrorQueryCHROMIUM
) {
687 BeginQueryEXT begin_cmd
;
689 GenHelper
<GenQueriesEXTImmediate
>(kNewClientId
);
691 // Test valid parameters work.
692 begin_cmd
.Init(GL_GET_ERROR_QUERY_CHROMIUM
,
695 kSharedMemoryOffset
);
696 EXPECT_EQ(error::kNoError
, ExecuteCmd(begin_cmd
));
697 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
699 QueryManager
* query_manager
= decoder_
->GetQueryManager();
700 ASSERT_TRUE(query_manager
!= NULL
);
701 QueryManager::Query
* query
= query_manager
->GetQuery(kNewClientId
);
702 ASSERT_TRUE(query
!= NULL
);
703 EXPECT_FALSE(query
->pending());
706 QuerySync
* sync
= static_cast<QuerySync
*>(shared_memory_address_
);
708 EXPECT_CALL(*gl_
, GetError())
709 .WillOnce(Return(GL_INVALID_VALUE
))
710 .RetiresOnSaturation();
713 end_cmd
.Init(GL_GET_ERROR_QUERY_CHROMIUM
, 1);
714 EXPECT_EQ(error::kNoError
, ExecuteCmd(end_cmd
));
715 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
716 EXPECT_FALSE(query
->pending());
717 EXPECT_EQ(static_cast<GLenum
>(GL_INVALID_VALUE
),
718 static_cast<GLenum
>(sync
->result
));
721 TEST_P(GLES2DecoderManualInitTest
, BeginEndQueryEXTCommandsCompletedCHROMIUM
) {
723 init
.extensions
= "GL_EXT_occlusion_query_boolean GL_ARB_sync";
724 init
.gl_version
= "opengl es 2.0";
725 init
.has_alpha
= true;
726 init
.request_alpha
= true;
727 init
.bind_generates_resource
= true;
730 GenHelper
<GenQueriesEXTImmediate
>(kNewClientId
);
732 BeginQueryEXT begin_cmd
;
733 begin_cmd
.Init(GL_COMMANDS_COMPLETED_CHROMIUM
,
736 kSharedMemoryOffset
);
737 EXPECT_EQ(error::kNoError
, ExecuteCmd(begin_cmd
));
738 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
740 QueryManager
* query_manager
= decoder_
->GetQueryManager();
741 ASSERT_TRUE(query_manager
!= NULL
);
742 QueryManager::Query
* query
= query_manager
->GetQuery(kNewClientId
);
743 ASSERT_TRUE(query
!= NULL
);
744 EXPECT_FALSE(query
->pending());
746 GLsync kGlSync
= reinterpret_cast<GLsync
>(0xdeadbeef);
747 EXPECT_CALL(*gl_
, Flush()).RetiresOnSaturation();
748 EXPECT_CALL(*gl_
, FenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE
, 0))
749 .WillOnce(Return(kGlSync
))
750 .RetiresOnSaturation();
752 EXPECT_CALL(*gl_
, IsSync(kGlSync
))
753 .WillOnce(Return(GL_TRUE
))
754 .RetiresOnSaturation();
758 end_cmd
.Init(GL_COMMANDS_COMPLETED_CHROMIUM
, 1);
759 EXPECT_EQ(error::kNoError
, ExecuteCmd(end_cmd
));
760 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
761 EXPECT_TRUE(query
->pending());
764 EXPECT_CALL(*gl_
, IsSync(kGlSync
))
765 .WillOnce(Return(GL_TRUE
))
766 .RetiresOnSaturation();
768 EXPECT_CALL(*gl_
, ClientWaitSync(kGlSync
, _
, _
))
769 .WillOnce(Return(GL_TIMEOUT_EXPIRED
))
770 .RetiresOnSaturation();
771 bool process_success
= query_manager
->ProcessPendingQueries(false);
773 EXPECT_TRUE(process_success
);
774 EXPECT_TRUE(query
->pending());
777 EXPECT_CALL(*gl_
, IsSync(kGlSync
))
778 .WillOnce(Return(GL_TRUE
))
779 .RetiresOnSaturation();
781 EXPECT_CALL(*gl_
, ClientWaitSync(kGlSync
, _
, _
))
782 .WillOnce(Return(GL_ALREADY_SIGNALED
))
783 .RetiresOnSaturation();
784 process_success
= query_manager
->ProcessPendingQueries(false);
786 EXPECT_TRUE(process_success
);
787 EXPECT_FALSE(query
->pending());
790 EXPECT_CALL(*gl_
, IsSync(kGlSync
))
791 .WillOnce(Return(GL_TRUE
))
792 .RetiresOnSaturation();
794 EXPECT_CALL(*gl_
, DeleteSync(kGlSync
)).Times(1).RetiresOnSaturation();
798 TEST_P(GLES2DecoderTest
, IsEnabledReturnsCachedValue
) {
799 // NOTE: There are no expectations because no GL functions should be
800 // called for DEPTH_TEST or STENCIL_TEST
801 static const GLenum kStates
[] = {
802 GL_DEPTH_TEST
, GL_STENCIL_TEST
,
804 for (size_t ii
= 0; ii
< arraysize(kStates
); ++ii
) {
806 GLenum state
= kStates
[ii
];
807 enable_cmd
.Init(state
);
808 EXPECT_EQ(error::kNoError
, ExecuteCmd(enable_cmd
));
809 IsEnabled::Result
* result
=
810 static_cast<IsEnabled::Result
*>(shared_memory_address_
);
811 IsEnabled is_enabled_cmd
;
812 is_enabled_cmd
.Init(state
, shared_memory_id_
, shared_memory_offset_
);
813 EXPECT_EQ(error::kNoError
, ExecuteCmd(is_enabled_cmd
));
814 EXPECT_NE(0u, *result
);
816 disable_cmd
.Init(state
);
817 EXPECT_EQ(error::kNoError
, ExecuteCmd(disable_cmd
));
818 EXPECT_EQ(error::kNoError
, ExecuteCmd(is_enabled_cmd
));
819 EXPECT_EQ(0u, *result
);
823 TEST_P(GLES2DecoderManualInitTest
, GpuMemoryManagerCHROMIUM
) {
825 init
.extensions
= "GL_ARB_texture_rectangle";
826 init
.bind_generates_resource
= true;
829 Texture
* texture
= GetTexture(client_texture_id_
)->texture();
830 EXPECT_TRUE(texture
!= NULL
);
831 EXPECT_TRUE(texture
->pool() == GL_TEXTURE_POOL_UNMANAGED_CHROMIUM
);
833 DoBindTexture(GL_TEXTURE_2D
, client_texture_id_
, kServiceTextureId
);
836 cmd
.Init(GL_TEXTURE_2D
,
837 GL_TEXTURE_POOL_CHROMIUM
,
838 GL_TEXTURE_POOL_UNMANAGED_CHROMIUM
);
839 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
840 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
842 cmd
.Init(GL_TEXTURE_2D
,
843 GL_TEXTURE_POOL_CHROMIUM
,
844 GL_TEXTURE_POOL_MANAGED_CHROMIUM
);
845 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
846 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
848 EXPECT_TRUE(texture
->pool() == GL_TEXTURE_POOL_MANAGED_CHROMIUM
);
850 cmd
.Init(GL_TEXTURE_2D
, GL_TEXTURE_POOL_CHROMIUM
, GL_NONE
);
851 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
852 EXPECT_EQ(GL_INVALID_ENUM
, GetGLError());
857 class SizeOnlyMemoryTracker
: public MemoryTracker
{
859 SizeOnlyMemoryTracker() {
860 // These are the default textures. 1 for TEXTURE_2D and 6 faces for
862 const size_t kInitialUnmanagedPoolSize
= 7 * 4;
863 const size_t kInitialManagedPoolSize
= 0;
864 pool_infos_
[MemoryTracker::kUnmanaged
].initial_size
=
865 kInitialUnmanagedPoolSize
;
866 pool_infos_
[MemoryTracker::kManaged
].initial_size
= kInitialManagedPoolSize
;
869 // Ensure a certain amount of GPU memory is free. Returns true on success.
870 MOCK_METHOD1(EnsureGPUMemoryAvailable
, bool(size_t size_needed
));
872 virtual void TrackMemoryAllocatedChange(size_t old_size
,
875 PoolInfo
& info
= pool_infos_
[pool
];
876 info
.size
+= new_size
- old_size
;
879 size_t GetPoolSize(Pool pool
) {
880 const PoolInfo
& info
= pool_infos_
[pool
];
881 return info
.size
- info
.initial_size
;
885 virtual ~SizeOnlyMemoryTracker() {}
887 PoolInfo() : initial_size(0), size(0) {}
891 std::map
<Pool
, PoolInfo
> pool_infos_
;
894 } // anonymous namespace.
896 TEST_P(GLES2DecoderManualInitTest
, MemoryTrackerInitialSize
) {
897 scoped_refptr
<SizeOnlyMemoryTracker
> memory_tracker
=
898 new SizeOnlyMemoryTracker();
899 set_memory_tracker(memory_tracker
.get());
901 init
.bind_generates_resource
= true;
903 // Expect that initial size - size is 0.
904 EXPECT_EQ(0u, memory_tracker
->GetPoolSize(MemoryTracker::kUnmanaged
));
905 EXPECT_EQ(0u, memory_tracker
->GetPoolSize(MemoryTracker::kManaged
));
908 TEST_P(GLES2DecoderManualInitTest
, MemoryTrackerTexImage2D
) {
909 scoped_refptr
<SizeOnlyMemoryTracker
> memory_tracker
=
910 new SizeOnlyMemoryTracker();
911 set_memory_tracker(memory_tracker
.get());
913 init
.bind_generates_resource
= true;
915 DoBindTexture(GL_TEXTURE_2D
, client_texture_id_
, kServiceTextureId
);
916 EXPECT_CALL(*memory_tracker
.get(), EnsureGPUMemoryAvailable(128))
917 .WillOnce(Return(true))
918 .RetiresOnSaturation();
919 DoTexImage2D(GL_TEXTURE_2D
,
928 kSharedMemoryOffset
);
929 EXPECT_EQ(128u, memory_tracker
->GetPoolSize(MemoryTracker::kUnmanaged
));
930 EXPECT_CALL(*memory_tracker
.get(), EnsureGPUMemoryAvailable(64))
931 .WillOnce(Return(true))
932 .RetiresOnSaturation();
933 DoTexImage2D(GL_TEXTURE_2D
,
942 kSharedMemoryOffset
);
943 EXPECT_EQ(64u, memory_tracker
->GetPoolSize(MemoryTracker::kUnmanaged
));
944 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
945 // Check we get out of memory and no call to glTexImage2D if Ensure fails.
946 EXPECT_CALL(*memory_tracker
.get(), EnsureGPUMemoryAvailable(64))
947 .WillOnce(Return(false))
948 .RetiresOnSaturation();
950 cmd
.Init(GL_TEXTURE_2D
,
958 kSharedMemoryOffset
);
959 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
960 EXPECT_EQ(GL_OUT_OF_MEMORY
, GetGLError());
961 EXPECT_EQ(64u, memory_tracker
->GetPoolSize(MemoryTracker::kUnmanaged
));
964 TEST_P(GLES2DecoderManualInitTest
, MemoryTrackerTexStorage2DEXT
) {
965 scoped_refptr
<SizeOnlyMemoryTracker
> memory_tracker
=
966 new SizeOnlyMemoryTracker();
967 set_memory_tracker(memory_tracker
.get());
969 init
.bind_generates_resource
= true;
971 DoBindTexture(GL_TEXTURE_2D
, client_texture_id_
, kServiceTextureId
);
972 // Check we get out of memory and no call to glTexStorage2DEXT
974 EXPECT_CALL(*memory_tracker
.get(), EnsureGPUMemoryAvailable(128))
975 .WillOnce(Return(false))
976 .RetiresOnSaturation();
978 cmd
.Init(GL_TEXTURE_2D
, 1, GL_RGBA8
, 8, 4);
979 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
980 EXPECT_EQ(0u, memory_tracker
->GetPoolSize(MemoryTracker::kUnmanaged
));
981 EXPECT_EQ(GL_OUT_OF_MEMORY
, GetGLError());
984 TEST_P(GLES2DecoderManualInitTest
, MemoryTrackerCopyTexImage2D
) {
985 GLenum target
= GL_TEXTURE_2D
;
987 GLenum internal_format
= GL_RGBA
;
991 scoped_refptr
<SizeOnlyMemoryTracker
> memory_tracker
=
992 new SizeOnlyMemoryTracker();
993 set_memory_tracker(memory_tracker
.get());
995 init
.has_alpha
= true;
996 init
.request_alpha
= true;
997 init
.bind_generates_resource
= true;
999 DoBindTexture(GL_TEXTURE_2D
, client_texture_id_
, kServiceTextureId
);
1000 EXPECT_CALL(*memory_tracker
.get(), EnsureGPUMemoryAvailable(128))
1001 .WillOnce(Return(true))
1002 .RetiresOnSaturation();
1003 EXPECT_CALL(*gl_
, GetError())
1004 .WillOnce(Return(GL_NO_ERROR
))
1005 .WillOnce(Return(GL_NO_ERROR
))
1006 .RetiresOnSaturation();
1009 target
, level
, internal_format
, 0, 0, width
, height
, border
))
1011 .RetiresOnSaturation();
1013 cmd
.Init(target
, level
, internal_format
, 0, 0, width
, height
);
1014 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
1015 EXPECT_EQ(128u, memory_tracker
->GetPoolSize(MemoryTracker::kUnmanaged
));
1016 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
1017 // Check we get out of memory and no call to glCopyTexImage2D if Ensure fails.
1018 EXPECT_CALL(*memory_tracker
.get(), EnsureGPUMemoryAvailable(128))
1019 .WillOnce(Return(false))
1020 .RetiresOnSaturation();
1021 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
1022 EXPECT_EQ(GL_OUT_OF_MEMORY
, GetGLError());
1023 EXPECT_EQ(128u, memory_tracker
->GetPoolSize(MemoryTracker::kUnmanaged
));
1026 TEST_P(GLES2DecoderManualInitTest
, MemoryTrackerRenderbufferStorage
) {
1027 scoped_refptr
<SizeOnlyMemoryTracker
> memory_tracker
=
1028 new SizeOnlyMemoryTracker();
1029 set_memory_tracker(memory_tracker
.get());
1031 init
.bind_generates_resource
= true;
1034 GL_RENDERBUFFER
, client_renderbuffer_id_
, kServiceRenderbufferId
);
1035 EnsureRenderbufferBound(false);
1036 EXPECT_CALL(*gl_
, GetError())
1037 .WillOnce(Return(GL_NO_ERROR
))
1038 .WillOnce(Return(GL_NO_ERROR
))
1039 .RetiresOnSaturation();
1040 EXPECT_CALL(*memory_tracker
.get(), EnsureGPUMemoryAvailable(128))
1041 .WillOnce(Return(true))
1042 .RetiresOnSaturation();
1043 EXPECT_CALL(*gl_
, RenderbufferStorageEXT(GL_RENDERBUFFER
, GL_RGBA
, 8, 4))
1045 .RetiresOnSaturation();
1046 RenderbufferStorage cmd
;
1047 cmd
.Init(GL_RENDERBUFFER
, GL_RGBA4
, 8, 4);
1048 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
1049 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
1050 EXPECT_EQ(128u, memory_tracker
->GetPoolSize(MemoryTracker::kUnmanaged
));
1051 // Check we get out of memory and no call to glRenderbufferStorage if Ensure
1053 EXPECT_CALL(*memory_tracker
.get(), EnsureGPUMemoryAvailable(128))
1054 .WillOnce(Return(false))
1055 .RetiresOnSaturation();
1056 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
1057 EXPECT_EQ(GL_OUT_OF_MEMORY
, GetGLError());
1058 EXPECT_EQ(128u, memory_tracker
->GetPoolSize(MemoryTracker::kUnmanaged
));
1061 TEST_P(GLES2DecoderManualInitTest
, MemoryTrackerBufferData
) {
1062 scoped_refptr
<SizeOnlyMemoryTracker
> memory_tracker
=
1063 new SizeOnlyMemoryTracker();
1064 set_memory_tracker(memory_tracker
.get());
1066 init
.bind_generates_resource
= true;
1068 DoBindBuffer(GL_ARRAY_BUFFER
, client_buffer_id_
, kServiceBufferId
);
1069 EXPECT_CALL(*gl_
, GetError())
1070 .WillOnce(Return(GL_NO_ERROR
))
1071 .WillOnce(Return(GL_NO_ERROR
))
1072 .RetiresOnSaturation();
1073 EXPECT_CALL(*memory_tracker
.get(), EnsureGPUMemoryAvailable(128))
1074 .WillOnce(Return(true))
1075 .RetiresOnSaturation();
1076 EXPECT_CALL(*gl_
, BufferData(GL_ARRAY_BUFFER
, 128, _
, GL_STREAM_DRAW
))
1078 .RetiresOnSaturation();
1080 cmd
.Init(GL_ARRAY_BUFFER
, 128, 0, 0, GL_STREAM_DRAW
);
1081 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
1082 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
1083 EXPECT_EQ(128u, memory_tracker
->GetPoolSize(MemoryTracker::kManaged
));
1084 // Check we get out of memory and no call to glBufferData if Ensure
1086 EXPECT_CALL(*memory_tracker
.get(), EnsureGPUMemoryAvailable(128))
1087 .WillOnce(Return(false))
1088 .RetiresOnSaturation();
1089 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
1090 EXPECT_EQ(GL_OUT_OF_MEMORY
, GetGLError());
1091 EXPECT_EQ(128u, memory_tracker
->GetPoolSize(MemoryTracker::kManaged
));
1094 TEST_P(GLES2DecoderManualInitTest
, ImmutableCopyTexImage2D
) {
1095 const GLenum kTarget
= GL_TEXTURE_2D
;
1096 const GLint kLevel
= 0;
1097 const GLenum kInternalFormat
= GL_RGBA
;
1098 const GLenum kSizedInternalFormat
= GL_RGBA8
;
1099 const GLsizei kWidth
= 4;
1100 const GLsizei kHeight
= 8;
1101 const GLint kBorder
= 0;
1103 init
.extensions
= "GL_EXT_texture_storage";
1104 init
.has_alpha
= true;
1105 init
.request_alpha
= true;
1106 init
.bind_generates_resource
= true;
1108 DoBindTexture(GL_TEXTURE_2D
, client_texture_id_
, kServiceTextureId
);
1110 // CopyTexImage2D will call arbitrary amount of GetErrors.
1111 EXPECT_CALL(*gl_
, GetError())
1116 kTarget
, kLevel
, kInternalFormat
, 0, 0, kWidth
, kHeight
,
1122 kTarget
, kLevel
, kSizedInternalFormat
, kWidth
, kHeight
))
1124 CopyTexImage2D copy_cmd
;
1125 copy_cmd
.Init(kTarget
, kLevel
, kInternalFormat
, 0, 0, kWidth
, kHeight
);
1126 EXPECT_EQ(error::kNoError
, ExecuteCmd(copy_cmd
));
1127 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
1129 TexStorage2DEXT storage_cmd
;
1130 storage_cmd
.Init(kTarget
, kLevel
, kSizedInternalFormat
, kWidth
, kHeight
);
1131 EXPECT_EQ(error::kNoError
, ExecuteCmd(storage_cmd
));
1132 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
1134 // This should not invoke CopyTexImage2D.
1135 copy_cmd
.Init(kTarget
, kLevel
, kInternalFormat
, 0, 0, kWidth
, kHeight
);
1136 EXPECT_EQ(error::kNoError
, ExecuteCmd(copy_cmd
));
1137 EXPECT_EQ(GL_INVALID_OPERATION
, GetGLError());
1140 TEST_P(GLES2DecoderTest
, LoseContextCHROMIUMGuilty
) {
1141 EXPECT_CALL(*mock_decoder_
, MarkContextLost(error::kInnocent
))
1143 cmds::LoseContextCHROMIUM cmd
;
1144 cmd
.Init(GL_GUILTY_CONTEXT_RESET_ARB
, GL_INNOCENT_CONTEXT_RESET_ARB
);
1145 EXPECT_EQ(error::kLostContext
, ExecuteCmd(cmd
));
1146 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
1147 EXPECT_TRUE(decoder_
->WasContextLost());
1148 EXPECT_TRUE(decoder_
->WasContextLostByRobustnessExtension());
1151 TEST_P(GLES2DecoderTest
, LoseContextCHROMIUMUnkown
) {
1152 EXPECT_CALL(*mock_decoder_
, MarkContextLost(error::kUnknown
))
1154 cmds::LoseContextCHROMIUM cmd
;
1155 cmd
.Init(GL_UNKNOWN_CONTEXT_RESET_ARB
, GL_UNKNOWN_CONTEXT_RESET_ARB
);
1156 EXPECT_EQ(error::kLostContext
, ExecuteCmd(cmd
));
1157 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
1158 EXPECT_TRUE(decoder_
->WasContextLost());
1159 EXPECT_TRUE(decoder_
->WasContextLostByRobustnessExtension());
1162 TEST_P(GLES2DecoderTest
, LoseContextCHROMIUMInvalidArgs0_0
) {
1163 EXPECT_CALL(*mock_decoder_
, MarkContextLost(_
))
1165 cmds::LoseContextCHROMIUM cmd
;
1166 cmd
.Init(GL_NONE
, GL_GUILTY_CONTEXT_RESET_ARB
);
1167 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
1168 EXPECT_EQ(GL_INVALID_ENUM
, GetGLError());
1171 TEST_P(GLES2DecoderTest
, LoseContextCHROMIUMInvalidArgs1_0
) {
1172 EXPECT_CALL(*mock_decoder_
, MarkContextLost(_
))
1174 cmds::LoseContextCHROMIUM cmd
;
1175 cmd
.Init(GL_GUILTY_CONTEXT_RESET_ARB
, GL_NONE
);
1176 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
1177 EXPECT_EQ(GL_INVALID_ENUM
, GetGLError());
1180 class GLES2DecoderDoCommandsTest
: public GLES2DecoderTest
{
1182 GLES2DecoderDoCommandsTest() {
1183 for (int i
= 0; i
< 3; i
++) {
1184 cmds_
[i
].Init(GL_BLEND
);
1186 entries_per_cmd_
= ComputeNumEntries(cmds_
[0].ComputeSize());
1189 void SetExpectationsForNCommands(int num_commands
) {
1190 for (int i
= 0; i
< num_commands
; i
++)
1191 SetupExpectationsForEnableDisable(GL_BLEND
, true);
1196 int entries_per_cmd_
;
1199 // Test that processing with 0 entries does nothing.
1200 TEST_P(GLES2DecoderDoCommandsTest
, DoCommandsOneOfZero
) {
1201 int num_processed
= -1;
1202 SetExpectationsForNCommands(0);
1205 decoder_
->DoCommands(1, &cmds_
, entries_per_cmd_
* 0, &num_processed
));
1206 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
1207 EXPECT_EQ(0, num_processed
);
1210 // Test processing at granularity of single commands.
1211 TEST_P(GLES2DecoderDoCommandsTest
, DoCommandsOneOfOne
) {
1212 int num_processed
= -1;
1213 SetExpectationsForNCommands(1);
1216 decoder_
->DoCommands(1, &cmds_
, entries_per_cmd_
* 1, &num_processed
));
1217 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
1218 EXPECT_EQ(entries_per_cmd_
, num_processed
);
1221 // Test processing at granularity of multiple commands.
1222 TEST_P(GLES2DecoderDoCommandsTest
, DoCommandsThreeOfThree
) {
1223 int num_processed
= -1;
1224 SetExpectationsForNCommands(3);
1227 decoder_
->DoCommands(3, &cmds_
, entries_per_cmd_
* 3, &num_processed
));
1228 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
1229 EXPECT_EQ(entries_per_cmd_
* 3, num_processed
);
1232 // Test processing a request smaller than available entries.
1233 TEST_P(GLES2DecoderDoCommandsTest
, DoCommandsTwoOfThree
) {
1234 int num_processed
= -1;
1235 SetExpectationsForNCommands(2);
1238 decoder_
->DoCommands(2, &cmds_
, entries_per_cmd_
* 3, &num_processed
));
1239 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
1240 EXPECT_EQ(entries_per_cmd_
* 2, num_processed
);
1243 // Test that processing stops on a command with size 0.
1244 TEST_P(GLES2DecoderDoCommandsTest
, DoCommandsZeroCmdSize
) {
1245 cmds_
[1].header
.size
= 0;
1246 int num_processed
= -1;
1247 SetExpectationsForNCommands(1);
1249 error::kInvalidSize
,
1250 decoder_
->DoCommands(2, &cmds_
, entries_per_cmd_
* 2, &num_processed
));
1251 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
1252 EXPECT_EQ(entries_per_cmd_
, num_processed
);
1255 // Test that processing stops on a command with size greater than available.
1256 TEST_P(GLES2DecoderDoCommandsTest
, DoCommandsOutOfBounds
) {
1257 int num_processed
= -1;
1258 SetExpectationsForNCommands(1);
1259 EXPECT_EQ(error::kOutOfBounds
,
1260 decoder_
->DoCommands(
1261 2, &cmds_
, entries_per_cmd_
* 2 - 1, &num_processed
));
1262 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
1263 EXPECT_EQ(entries_per_cmd_
, num_processed
);
1266 // Test that commands with bad argument size are skipped without processing.
1267 TEST_P(GLES2DecoderDoCommandsTest
, DoCommandsBadArgSize
) {
1268 cmds_
[1].header
.size
+= 1;
1269 int num_processed
= -1;
1270 SetExpectationsForNCommands(1);
1271 EXPECT_EQ(error::kInvalidArguments
,
1272 decoder_
->DoCommands(
1273 2, &cmds_
, entries_per_cmd_
* 2 + 1, &num_processed
));
1274 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
1275 EXPECT_EQ(entries_per_cmd_
+ cmds_
[1].header
.size
, num_processed
);
1278 INSTANTIATE_TEST_CASE_P(Service
, GLES2DecoderTest
, ::testing::Bool());
1280 INSTANTIATE_TEST_CASE_P(Service
, GLES2DecoderWithShaderTest
, ::testing::Bool());
1282 INSTANTIATE_TEST_CASE_P(Service
, GLES2DecoderManualInitTest
, ::testing::Bool());
1284 INSTANTIATE_TEST_CASE_P(Service
,
1285 GLES2DecoderRGBBackbufferTest
,
1288 INSTANTIATE_TEST_CASE_P(Service
, GLES2DecoderDoCommandsTest
, ::testing::Bool());
1290 } // namespace gles2