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/gpu_switches.h"
20 #include "gpu/command_buffer/service/image_manager.h"
21 #include "gpu/command_buffer/service/mailbox_manager.h"
22 #include "gpu/command_buffer/service/mocks.h"
23 #include "gpu/command_buffer/service/program_manager.h"
24 #include "gpu/command_buffer/service/test_helper.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 TEST_P(GLES2DecoderTest
, GetIntegervCached
) {
100 GL_MAX_TEXTURE_SIZE
, TestHelper::kMaxTextureSize
,
103 GL_MAX_CUBE_MAP_TEXTURE_SIZE
, TestHelper::kMaxCubeMapTextureSize
,
106 GL_MAX_RENDERBUFFER_SIZE
, TestHelper::kMaxRenderbufferSize
,
109 typedef GetIntegerv::Result Result
;
110 for (size_t ii
= 0; ii
< sizeof(tests
) / sizeof(tests
[0]); ++ii
) {
111 const TestInfo
& test
= tests
[ii
];
112 Result
* result
= static_cast<Result
*>(shared_memory_address_
);
113 EXPECT_CALL(*gl_
, GetError())
114 .WillOnce(Return(GL_NO_ERROR
))
115 .WillOnce(Return(GL_NO_ERROR
))
116 .RetiresOnSaturation();
117 EXPECT_CALL(*gl_
, GetIntegerv(test
.pname
, _
)).Times(0);
120 cmd2
.Init(test
.pname
, shared_memory_id_
, shared_memory_offset_
);
121 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd2
));
122 EXPECT_EQ(decoder_
->GetGLES2Util()->GLGetNumValuesReturned(test
.pname
),
123 result
->GetNumResults());
124 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
125 EXPECT_EQ(test
.expected
, result
->GetData()[0]);
129 TEST_P(GLES2DecoderWithShaderTest
, GetMaxValueInBufferCHROMIUM
) {
131 GetMaxValueInBufferCHROMIUM::Result
* result
=
132 static_cast<GetMaxValueInBufferCHROMIUM::Result
*>(shared_memory_address_
);
135 GetMaxValueInBufferCHROMIUM cmd
;
136 cmd
.Init(client_element_buffer_id_
,
137 kValidIndexRangeCount
,
139 kValidIndexRangeStart
* 2,
141 kSharedMemoryOffset
);
142 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
143 EXPECT_EQ(7u, *result
);
144 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
145 cmd
.Init(client_element_buffer_id_
,
146 kValidIndexRangeCount
+ 1,
148 kValidIndexRangeStart
* 2,
150 kSharedMemoryOffset
);
151 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
152 EXPECT_EQ(100u, *result
);
153 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
155 cmd
.Init(kInvalidClientId
,
156 kValidIndexRangeCount
,
158 kValidIndexRangeStart
* 2,
160 kSharedMemoryOffset
);
161 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
162 EXPECT_EQ(GL_INVALID_VALUE
, GetGLError());
163 cmd
.Init(client_element_buffer_id_
,
164 kOutOfRangeIndexRangeEnd
,
166 kValidIndexRangeStart
* 2,
168 kSharedMemoryOffset
);
169 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
170 EXPECT_EQ(GL_INVALID_OPERATION
, GetGLError());
171 cmd
.Init(client_element_buffer_id_
,
172 kValidIndexRangeCount
+ 1,
174 kOutOfRangeIndexRangeEnd
* 2,
176 kSharedMemoryOffset
);
177 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
178 EXPECT_EQ(GL_INVALID_OPERATION
, GetGLError());
179 cmd
.Init(client_element_buffer_id_
,
180 kValidIndexRangeCount
+ 1,
182 kValidIndexRangeStart
* 2,
184 kSharedMemoryOffset
);
185 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
186 cmd
.Init(client_buffer_id_
,
187 kValidIndexRangeCount
+ 1,
189 kValidIndexRangeStart
* 2,
191 kSharedMemoryOffset
);
192 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
193 EXPECT_EQ(GL_INVALID_OPERATION
, GetGLError());
194 cmd
.Init(client_element_buffer_id_
,
195 kValidIndexRangeCount
+ 1,
197 kValidIndexRangeStart
* 2,
198 kInvalidSharedMemoryId
,
199 kSharedMemoryOffset
);
200 EXPECT_NE(error::kNoError
, ExecuteCmd(cmd
));
201 cmd
.Init(client_element_buffer_id_
,
202 kValidIndexRangeCount
+ 1,
204 kValidIndexRangeStart
* 2,
206 kInvalidSharedMemoryOffset
);
207 EXPECT_NE(error::kNoError
, ExecuteCmd(cmd
));
210 TEST_P(GLES2DecoderTest
, IsBuffer
) {
211 EXPECT_FALSE(DoIsBuffer(client_buffer_id_
));
212 DoBindBuffer(GL_ARRAY_BUFFER
, client_buffer_id_
, kServiceBufferId
);
213 EXPECT_TRUE(DoIsBuffer(client_buffer_id_
));
214 DoDeleteBuffer(client_buffer_id_
, kServiceBufferId
);
215 EXPECT_FALSE(DoIsBuffer(client_buffer_id_
));
218 TEST_P(GLES2DecoderTest
, IsFramebuffer
) {
219 EXPECT_FALSE(DoIsFramebuffer(client_framebuffer_id_
));
221 GL_FRAMEBUFFER
, client_framebuffer_id_
, kServiceFramebufferId
);
222 EXPECT_TRUE(DoIsFramebuffer(client_framebuffer_id_
));
223 DoDeleteFramebuffer(client_framebuffer_id_
,
224 kServiceFramebufferId
,
231 EXPECT_FALSE(DoIsFramebuffer(client_framebuffer_id_
));
234 TEST_P(GLES2DecoderTest
, IsProgram
) {
235 // IsProgram is true as soon as the program is created.
236 EXPECT_TRUE(DoIsProgram(client_program_id_
));
237 EXPECT_CALL(*gl_
, DeleteProgram(kServiceProgramId
))
239 .RetiresOnSaturation();
240 DoDeleteProgram(client_program_id_
, kServiceProgramId
);
241 EXPECT_FALSE(DoIsProgram(client_program_id_
));
244 TEST_P(GLES2DecoderTest
, IsRenderbuffer
) {
245 EXPECT_FALSE(DoIsRenderbuffer(client_renderbuffer_id_
));
247 GL_RENDERBUFFER
, client_renderbuffer_id_
, kServiceRenderbufferId
);
248 EXPECT_TRUE(DoIsRenderbuffer(client_renderbuffer_id_
));
249 DoDeleteRenderbuffer(client_renderbuffer_id_
, kServiceRenderbufferId
);
250 EXPECT_FALSE(DoIsRenderbuffer(client_renderbuffer_id_
));
253 TEST_P(GLES2DecoderTest
, IsShader
) {
254 // IsShader is true as soon as the program is created.
255 EXPECT_TRUE(DoIsShader(client_shader_id_
));
256 DoDeleteShader(client_shader_id_
, kServiceShaderId
);
257 EXPECT_FALSE(DoIsShader(client_shader_id_
));
260 TEST_P(GLES2DecoderTest
, IsTexture
) {
261 EXPECT_FALSE(DoIsTexture(client_texture_id_
));
262 DoBindTexture(GL_TEXTURE_2D
, client_texture_id_
, kServiceTextureId
);
263 EXPECT_TRUE(DoIsTexture(client_texture_id_
));
264 DoDeleteTexture(client_texture_id_
, kServiceTextureId
);
265 EXPECT_FALSE(DoIsTexture(client_texture_id_
));
268 TEST_P(GLES2DecoderTest
, ClientWaitSyncValid
) {
269 typedef cmds::ClientWaitSync::Result Result
;
270 Result
* result
= static_cast<Result
*>(shared_memory_address_
);
271 cmds::ClientWaitSync cmd
;
272 uint32_t v32_0
= 0, v32_1
= 0;
273 GLES2Util::MapUint64ToTwoUint32(0, &v32_0
, &v32_1
);
274 cmd
.Init(client_sync_id_
, GL_SYNC_FLUSH_COMMANDS_BIT
, v32_0
, v32_1
,
275 shared_memory_id_
, shared_memory_offset_
);
277 ClientWaitSync(reinterpret_cast<GLsync
>(kServiceSyncId
),
278 GL_SYNC_FLUSH_COMMANDS_BIT
, 0))
279 .WillOnce(Return(GL_CONDITION_SATISFIED
))
280 .RetiresOnSaturation();
281 *result
= GL_WAIT_FAILED
;
282 decoder_
->set_unsafe_es3_apis_enabled(true);
283 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
284 EXPECT_EQ(static_cast<GLenum
>(GL_CONDITION_SATISFIED
), *result
);
285 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
286 decoder_
->set_unsafe_es3_apis_enabled(false);
287 EXPECT_EQ(error::kUnknownCommand
, ExecuteCmd(cmd
));
290 TEST_P(GLES2DecoderTest
, ClientWaitSyncNonZeroTimeoutValid
) {
291 typedef cmds::ClientWaitSync::Result Result
;
292 Result
* result
= static_cast<Result
*>(shared_memory_address_
);
293 cmds::ClientWaitSync cmd
;
294 const GLuint64 kTimeout
= 0xABCDEF0123456789;
295 uint32_t v32_0
= 0, v32_1
= 0;
296 GLES2Util::MapUint64ToTwoUint32(kTimeout
, &v32_0
, &v32_1
);
297 cmd
.Init(client_sync_id_
, GL_SYNC_FLUSH_COMMANDS_BIT
, v32_0
, v32_1
,
298 shared_memory_id_
, shared_memory_offset_
);
300 ClientWaitSync(reinterpret_cast<GLsync
>(kServiceSyncId
),
301 GL_SYNC_FLUSH_COMMANDS_BIT
, kTimeout
))
302 .WillOnce(Return(GL_CONDITION_SATISFIED
))
303 .RetiresOnSaturation();
304 *result
= GL_WAIT_FAILED
;
305 decoder_
->set_unsafe_es3_apis_enabled(true);
306 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
307 EXPECT_EQ(static_cast<GLenum
>(GL_CONDITION_SATISFIED
), *result
);
308 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
309 decoder_
->set_unsafe_es3_apis_enabled(false);
310 EXPECT_EQ(error::kUnknownCommand
, ExecuteCmd(cmd
));
313 TEST_P(GLES2DecoderTest
, ClientWaitSyncInvalidSyncFails
) {
314 typedef cmds::ClientWaitSync::Result Result
;
315 Result
* result
= static_cast<Result
*>(shared_memory_address_
);
316 cmds::ClientWaitSync cmd
;
317 uint32_t v32_0
= 0, v32_1
= 0;
318 GLES2Util::MapUint64ToTwoUint32(0, &v32_0
, &v32_1
);
319 decoder_
->set_unsafe_es3_apis_enabled(true);
320 cmd
.Init(kInvalidClientId
, GL_SYNC_FLUSH_COMMANDS_BIT
, v32_0
, v32_1
,
321 shared_memory_id_
, shared_memory_offset_
);
322 *result
= GL_WAIT_FAILED
;
323 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
324 EXPECT_EQ(static_cast<GLenum
>(GL_WAIT_FAILED
), *result
);
325 EXPECT_EQ(GL_INVALID_VALUE
, GetGLError());
328 TEST_P(GLES2DecoderTest
, ClientWaitSyncResultNotInitFails
) {
329 typedef cmds::ClientWaitSync::Result Result
;
330 Result
* result
= static_cast<Result
*>(shared_memory_address_
);
331 cmds::ClientWaitSync cmd
;
332 uint32_t v32_0
= 0, v32_1
= 0;
333 GLES2Util::MapUint64ToTwoUint32(0, &v32_0
, &v32_1
);
334 decoder_
->set_unsafe_es3_apis_enabled(true);
335 cmd
.Init(client_sync_id_
, GL_SYNC_FLUSH_COMMANDS_BIT
, v32_0
, v32_1
,
336 shared_memory_id_
, shared_memory_offset_
);
337 *result
= 1; // Any value other than GL_WAIT_FAILED
338 EXPECT_NE(error::kNoError
, ExecuteCmd(cmd
));
341 TEST_P(GLES2DecoderTest
, ClientWaitSyncBadSharedMemoryFails
) {
342 typedef cmds::ClientWaitSync::Result Result
;
343 Result
* result
= static_cast<Result
*>(shared_memory_address_
);
344 cmds::ClientWaitSync cmd
;
345 uint32_t v32_0
= 0, v32_1
= 0;
346 GLES2Util::MapUint64ToTwoUint32(0, &v32_0
, &v32_1
);
347 decoder_
->set_unsafe_es3_apis_enabled(true);
348 *result
= GL_WAIT_FAILED
;
349 cmd
.Init(client_sync_id_
, GL_SYNC_FLUSH_COMMANDS_BIT
, v32_0
, v32_1
,
350 kInvalidSharedMemoryId
, shared_memory_offset_
);
351 EXPECT_NE(error::kNoError
, ExecuteCmd(cmd
));
353 *result
= GL_WAIT_FAILED
;
354 cmd
.Init(client_sync_id_
, GL_SYNC_FLUSH_COMMANDS_BIT
, v32_0
, v32_1
,
355 shared_memory_id_
, kInvalidSharedMemoryOffset
);
356 EXPECT_NE(error::kNoError
, ExecuteCmd(cmd
));
359 TEST_P(GLES2DecoderTest
, WaitSyncValidArgs
) {
360 const GLuint64 kTimeout
= GL_TIMEOUT_IGNORED
;
361 EXPECT_CALL(*gl_
, WaitSync(reinterpret_cast<GLsync
>(kServiceSyncId
),
364 .RetiresOnSaturation();
366 uint32_t v32_0
= 0, v32_1
= 0;
367 GLES2Util::MapUint64ToTwoUint32(kTimeout
, &v32_0
, &v32_1
);
369 cmd
.Init(client_sync_id_
, 0, v32_0
, v32_1
);
370 decoder_
->set_unsafe_es3_apis_enabled(true);
371 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
372 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
373 decoder_
->set_unsafe_es3_apis_enabled(false);
374 EXPECT_EQ(error::kUnknownCommand
, ExecuteCmd(cmd
));
377 TEST_P(GLES2DecoderManualInitTest
, BindGeneratesResourceFalse
) {
382 cmd1
.Init(GL_TEXTURE_2D
, kInvalidClientId
);
383 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd1
));
384 EXPECT_EQ(GL_INVALID_OPERATION
, GetGLError());
387 cmd2
.Init(GL_ARRAY_BUFFER
, kInvalidClientId
);
388 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd2
));
389 EXPECT_EQ(GL_INVALID_OPERATION
, GetGLError());
391 BindFramebuffer cmd3
;
392 cmd3
.Init(GL_FRAMEBUFFER
, kInvalidClientId
);
393 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd3
));
394 EXPECT_EQ(GL_INVALID_OPERATION
, GetGLError());
396 BindRenderbuffer cmd4
;
397 cmd4
.Init(GL_RENDERBUFFER
, kInvalidClientId
);
398 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd4
));
399 EXPECT_EQ(GL_INVALID_OPERATION
, GetGLError());
402 TEST_P(GLES2DecoderTest
, EnableFeatureCHROMIUMBadBucket
) {
403 const uint32 kBadBucketId
= 123;
404 EnableFeatureCHROMIUM cmd
;
405 cmd
.Init(kBadBucketId
, shared_memory_id_
, shared_memory_offset_
);
406 EXPECT_NE(error::kNoError
, ExecuteCmd(cmd
));
409 TEST_P(GLES2DecoderTest
, RequestExtensionCHROMIUMBadBucket
) {
410 const uint32 kBadBucketId
= 123;
411 RequestExtensionCHROMIUM cmd
;
412 cmd
.Init(kBadBucketId
);
413 EXPECT_NE(error::kNoError
, ExecuteCmd(cmd
));
416 TEST_P(GLES2DecoderTest
, BeginQueryEXTDisabled
) {
417 // Test something fails if off.
420 TEST_P(GLES2DecoderManualInitTest
, BeginEndQueryEXT
) {
422 init
.extensions
= "GL_EXT_occlusion_query_boolean";
423 init
.gl_version
= "opengl es 2.0";
424 init
.has_alpha
= true;
425 init
.request_alpha
= true;
426 init
.bind_generates_resource
= true;
429 // Test end fails if no begin.
431 end_cmd
.Init(GL_ANY_SAMPLES_PASSED_EXT
, 1);
432 EXPECT_EQ(error::kNoError
, ExecuteCmd(end_cmd
));
433 EXPECT_EQ(GL_INVALID_OPERATION
, GetGLError());
435 BeginQueryEXT begin_cmd
;
437 // Test id = 0 fails.
439 GL_ANY_SAMPLES_PASSED_EXT
, 0, kSharedMemoryId
, kSharedMemoryOffset
);
440 EXPECT_EQ(error::kNoError
, ExecuteCmd(begin_cmd
));
441 EXPECT_EQ(GL_INVALID_OPERATION
, GetGLError());
443 GenHelper
<GenQueriesEXTImmediate
>(kNewClientId
);
445 // Test valid parameters work.
446 EXPECT_CALL(*gl_
, GenQueries(1, _
))
447 .WillOnce(SetArgumentPointee
<1>(kNewServiceId
))
448 .RetiresOnSaturation();
449 EXPECT_CALL(*gl_
, BeginQuery(GL_ANY_SAMPLES_PASSED_EXT
, kNewServiceId
))
451 .RetiresOnSaturation();
453 // Query object should not be created untill BeginQueriesEXT.
454 QueryManager
* query_manager
= decoder_
->GetQueryManager();
455 ASSERT_TRUE(query_manager
!= NULL
);
456 QueryManager::Query
* query
= query_manager
->GetQuery(kNewClientId
);
457 EXPECT_TRUE(query
== NULL
);
459 // BeginQueryEXT should fail if id is not generated from GenQueriesEXT.
460 begin_cmd
.Init(GL_ANY_SAMPLES_PASSED_EXT
,
463 kSharedMemoryOffset
);
464 EXPECT_EQ(error::kNoError
, ExecuteCmd(begin_cmd
));
465 EXPECT_EQ(GL_INVALID_OPERATION
, GetGLError());
467 begin_cmd
.Init(GL_ANY_SAMPLES_PASSED_EXT
,
470 kSharedMemoryOffset
);
471 EXPECT_EQ(error::kNoError
, ExecuteCmd(begin_cmd
));
472 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
474 // After BeginQueriesEXT id name should have query object associated with it.
475 query
= query_manager
->GetQuery(kNewClientId
);
476 ASSERT_TRUE(query
!= NULL
);
477 EXPECT_FALSE(query
->pending());
479 // Test trying begin again fails
480 EXPECT_EQ(error::kNoError
, ExecuteCmd(begin_cmd
));
481 EXPECT_EQ(GL_INVALID_OPERATION
, GetGLError());
483 // Test end fails with different target
484 end_cmd
.Init(GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT
, 1);
485 EXPECT_EQ(error::kNoError
, ExecuteCmd(end_cmd
));
486 EXPECT_EQ(GL_INVALID_OPERATION
, GetGLError());
489 EXPECT_CALL(*gl_
, EndQuery(GL_ANY_SAMPLES_PASSED_EXT
))
491 .RetiresOnSaturation();
492 end_cmd
.Init(GL_ANY_SAMPLES_PASSED_EXT
, 1);
493 EXPECT_EQ(error::kNoError
, ExecuteCmd(end_cmd
));
494 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
495 EXPECT_TRUE(query
->pending());
497 EXPECT_CALL(*gl_
, DeleteQueries(1, _
)).Times(1).RetiresOnSaturation();
505 const QueryType kQueryTypes
[] = {
506 {GL_COMMANDS_ISSUED_CHROMIUM
, false},
507 {GL_LATENCY_QUERY_CHROMIUM
, false},
508 {GL_ASYNC_PIXEL_UNPACK_COMPLETED_CHROMIUM
, false},
509 {GL_ASYNC_PIXEL_PACK_COMPLETED_CHROMIUM
, false},
510 {GL_GET_ERROR_QUERY_CHROMIUM
, false},
511 {GL_COMMANDS_COMPLETED_CHROMIUM
, false},
512 {GL_ANY_SAMPLES_PASSED_EXT
, true},
515 static void CheckBeginEndQueryBadMemoryFails(GLES2DecoderTestBase
* test
,
518 const QueryType
& query_type
,
521 // We need to reset the decoder on each iteration, because we lose the
522 // context every time.
523 GLES2DecoderTestBase::InitState init
;
524 init
.extensions
= "GL_EXT_occlusion_query_boolean GL_ARB_sync";
525 init
.gl_version
= "opengl es 2.0";
526 init
.has_alpha
= true;
527 init
.request_alpha
= true;
528 init
.bind_generates_resource
= true;
529 test
->InitDecoder(init
);
530 ::testing::StrictMock
< ::gfx::MockGLInterface
>* gl
= test
->GetGLMock();
532 BeginQueryEXT begin_cmd
;
534 test
->GenHelper
<GenQueriesEXTImmediate
>(client_id
);
536 if (query_type
.is_gl
) {
537 EXPECT_CALL(*gl
, GenQueries(1, _
))
538 .WillOnce(SetArgumentPointee
<1>(service_id
))
539 .RetiresOnSaturation();
540 EXPECT_CALL(*gl
, BeginQuery(query_type
.type
, service_id
))
542 .RetiresOnSaturation();
545 // Test bad shared memory fails
546 begin_cmd
.Init(query_type
.type
, client_id
, shm_id
, shm_offset
);
547 error::Error error1
= test
->ExecuteCmd(begin_cmd
);
549 if (query_type
.is_gl
) {
550 EXPECT_CALL(*gl
, EndQuery(query_type
.type
))
552 .RetiresOnSaturation();
554 if (query_type
.type
== GL_GET_ERROR_QUERY_CHROMIUM
) {
555 EXPECT_CALL(*gl
, GetError())
556 .WillOnce(Return(GL_NO_ERROR
))
557 .RetiresOnSaturation();
559 GLsync kGlSync
= reinterpret_cast<GLsync
>(0xdeadbeef);
560 if (query_type
.type
== GL_COMMANDS_COMPLETED_CHROMIUM
) {
561 EXPECT_CALL(*gl
, Flush()).RetiresOnSaturation();
562 EXPECT_CALL(*gl
, FenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE
, 0))
563 .WillOnce(Return(kGlSync
))
564 .RetiresOnSaturation();
566 EXPECT_CALL(*gl
, IsSync(kGlSync
))
567 .WillOnce(Return(GL_TRUE
))
568 .RetiresOnSaturation();
573 end_cmd
.Init(query_type
.type
, 1);
574 error::Error error2
= test
->ExecuteCmd(end_cmd
);
576 if (query_type
.is_gl
) {
578 *gl
, GetQueryObjectuiv(service_id
, GL_QUERY_RESULT_AVAILABLE_EXT
, _
))
579 .WillOnce(SetArgumentPointee
<2>(1))
580 .RetiresOnSaturation();
581 EXPECT_CALL(*gl
, GetQueryObjectuiv(service_id
, GL_QUERY_RESULT_EXT
, _
))
582 .WillOnce(SetArgumentPointee
<2>(1))
583 .RetiresOnSaturation();
585 if (query_type
.type
== GL_COMMANDS_COMPLETED_CHROMIUM
) {
587 EXPECT_CALL(*gl
, IsSync(kGlSync
))
588 .WillOnce(Return(GL_TRUE
))
589 .RetiresOnSaturation();
591 EXPECT_CALL(*gl
, ClientWaitSync(kGlSync
, _
, _
))
592 .WillOnce(Return(GL_ALREADY_SIGNALED
))
593 .RetiresOnSaturation();
596 QueryManager
* query_manager
= test
->GetDecoder()->GetQueryManager();
597 ASSERT_TRUE(query_manager
!= NULL
);
598 bool process_success
= query_manager
->ProcessPendingQueries(false);
600 EXPECT_TRUE(error1
!= error::kNoError
|| error2
!= error::kNoError
||
603 if (query_type
.is_gl
) {
604 EXPECT_CALL(*gl
, DeleteQueries(1, _
)).Times(1).RetiresOnSaturation();
606 if (query_type
.type
== GL_COMMANDS_COMPLETED_CHROMIUM
) {
608 EXPECT_CALL(*gl
, IsSync(kGlSync
))
609 .WillOnce(Return(GL_TRUE
))
610 .RetiresOnSaturation();
612 EXPECT_CALL(*gl
, DeleteSync(kGlSync
)).Times(1).RetiresOnSaturation();
614 test
->ResetDecoder();
617 TEST_P(GLES2DecoderManualInitTest
, BeginEndQueryEXTBadMemoryIdFails
) {
618 for (size_t i
= 0; i
< arraysize(kQueryTypes
); ++i
) {
619 CheckBeginEndQueryBadMemoryFails(this,
623 kInvalidSharedMemoryId
,
624 kSharedMemoryOffset
);
628 TEST_P(GLES2DecoderManualInitTest
, BeginEndQueryEXTBadMemoryOffsetFails
) {
629 for (size_t i
= 0; i
< arraysize(kQueryTypes
); ++i
) {
631 CheckBeginEndQueryBadMemoryFails(this,
636 kInvalidSharedMemoryOffset
);
638 CheckBeginEndQueryBadMemoryFails(this,
647 TEST_P(GLES2DecoderTest
, BeginEndQueryEXTCommandsIssuedCHROMIUM
) {
648 BeginQueryEXT begin_cmd
;
650 GenHelper
<GenQueriesEXTImmediate
>(kNewClientId
);
652 // Test valid parameters work.
653 begin_cmd
.Init(GL_COMMANDS_ISSUED_CHROMIUM
,
656 kSharedMemoryOffset
);
657 EXPECT_EQ(error::kNoError
, ExecuteCmd(begin_cmd
));
658 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
660 QueryManager
* query_manager
= decoder_
->GetQueryManager();
661 ASSERT_TRUE(query_manager
!= NULL
);
662 QueryManager::Query
* query
= query_manager
->GetQuery(kNewClientId
);
663 ASSERT_TRUE(query
!= NULL
);
664 EXPECT_FALSE(query
->pending());
668 end_cmd
.Init(GL_COMMANDS_ISSUED_CHROMIUM
, 1);
669 EXPECT_EQ(error::kNoError
, ExecuteCmd(end_cmd
));
670 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
671 EXPECT_FALSE(query
->pending());
674 TEST_P(GLES2DecoderTest
, BeginEndQueryEXTGetErrorQueryCHROMIUM
) {
675 BeginQueryEXT begin_cmd
;
677 GenHelper
<GenQueriesEXTImmediate
>(kNewClientId
);
679 // Test valid parameters work.
680 begin_cmd
.Init(GL_GET_ERROR_QUERY_CHROMIUM
,
683 kSharedMemoryOffset
);
684 EXPECT_EQ(error::kNoError
, ExecuteCmd(begin_cmd
));
685 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
687 QueryManager
* query_manager
= decoder_
->GetQueryManager();
688 ASSERT_TRUE(query_manager
!= NULL
);
689 QueryManager::Query
* query
= query_manager
->GetQuery(kNewClientId
);
690 ASSERT_TRUE(query
!= NULL
);
691 EXPECT_FALSE(query
->pending());
694 QuerySync
* sync
= static_cast<QuerySync
*>(shared_memory_address_
);
696 EXPECT_CALL(*gl_
, GetError())
697 .WillOnce(Return(GL_INVALID_VALUE
))
698 .RetiresOnSaturation();
701 end_cmd
.Init(GL_GET_ERROR_QUERY_CHROMIUM
, 1);
702 EXPECT_EQ(error::kNoError
, ExecuteCmd(end_cmd
));
703 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
704 EXPECT_FALSE(query
->pending());
705 EXPECT_EQ(static_cast<GLenum
>(GL_INVALID_VALUE
),
706 static_cast<GLenum
>(sync
->result
));
709 TEST_P(GLES2DecoderManualInitTest
, BeginEndQueryEXTCommandsCompletedCHROMIUM
) {
711 init
.extensions
= "GL_EXT_occlusion_query_boolean GL_ARB_sync";
712 init
.gl_version
= "opengl es 2.0";
713 init
.has_alpha
= true;
714 init
.request_alpha
= true;
715 init
.bind_generates_resource
= true;
718 GenHelper
<GenQueriesEXTImmediate
>(kNewClientId
);
720 BeginQueryEXT begin_cmd
;
721 begin_cmd
.Init(GL_COMMANDS_COMPLETED_CHROMIUM
,
724 kSharedMemoryOffset
);
725 EXPECT_EQ(error::kNoError
, ExecuteCmd(begin_cmd
));
726 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
728 QueryManager
* query_manager
= decoder_
->GetQueryManager();
729 ASSERT_TRUE(query_manager
!= NULL
);
730 QueryManager::Query
* query
= query_manager
->GetQuery(kNewClientId
);
731 ASSERT_TRUE(query
!= NULL
);
732 EXPECT_FALSE(query
->pending());
734 GLsync kGlSync
= reinterpret_cast<GLsync
>(0xdeadbeef);
735 EXPECT_CALL(*gl_
, Flush()).RetiresOnSaturation();
736 EXPECT_CALL(*gl_
, FenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE
, 0))
737 .WillOnce(Return(kGlSync
))
738 .RetiresOnSaturation();
740 EXPECT_CALL(*gl_
, IsSync(kGlSync
))
741 .WillOnce(Return(GL_TRUE
))
742 .RetiresOnSaturation();
746 end_cmd
.Init(GL_COMMANDS_COMPLETED_CHROMIUM
, 1);
747 EXPECT_EQ(error::kNoError
, ExecuteCmd(end_cmd
));
748 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
749 EXPECT_TRUE(query
->pending());
752 EXPECT_CALL(*gl_
, IsSync(kGlSync
))
753 .WillOnce(Return(GL_TRUE
))
754 .RetiresOnSaturation();
756 EXPECT_CALL(*gl_
, ClientWaitSync(kGlSync
, _
, _
))
757 .WillOnce(Return(GL_TIMEOUT_EXPIRED
))
758 .RetiresOnSaturation();
759 bool process_success
= query_manager
->ProcessPendingQueries(false);
761 EXPECT_TRUE(process_success
);
762 EXPECT_TRUE(query
->pending());
765 EXPECT_CALL(*gl_
, IsSync(kGlSync
))
766 .WillOnce(Return(GL_TRUE
))
767 .RetiresOnSaturation();
769 EXPECT_CALL(*gl_
, ClientWaitSync(kGlSync
, _
, _
))
770 .WillOnce(Return(GL_ALREADY_SIGNALED
))
771 .RetiresOnSaturation();
772 process_success
= query_manager
->ProcessPendingQueries(false);
774 EXPECT_TRUE(process_success
);
775 EXPECT_FALSE(query
->pending());
778 EXPECT_CALL(*gl_
, IsSync(kGlSync
))
779 .WillOnce(Return(GL_TRUE
))
780 .RetiresOnSaturation();
782 EXPECT_CALL(*gl_
, DeleteSync(kGlSync
)).Times(1).RetiresOnSaturation();
786 TEST_P(GLES2DecoderTest
, IsEnabledReturnsCachedValue
) {
787 // NOTE: There are no expectations because no GL functions should be
788 // called for DEPTH_TEST or STENCIL_TEST
789 static const GLenum kStates
[] = {
790 GL_DEPTH_TEST
, GL_STENCIL_TEST
,
792 for (size_t ii
= 0; ii
< arraysize(kStates
); ++ii
) {
794 GLenum state
= kStates
[ii
];
795 enable_cmd
.Init(state
);
796 EXPECT_EQ(error::kNoError
, ExecuteCmd(enable_cmd
));
797 IsEnabled::Result
* result
=
798 static_cast<IsEnabled::Result
*>(shared_memory_address_
);
799 IsEnabled is_enabled_cmd
;
800 is_enabled_cmd
.Init(state
, shared_memory_id_
, shared_memory_offset_
);
801 EXPECT_EQ(error::kNoError
, ExecuteCmd(is_enabled_cmd
));
802 EXPECT_NE(0u, *result
);
804 disable_cmd
.Init(state
);
805 EXPECT_EQ(error::kNoError
, ExecuteCmd(disable_cmd
));
806 EXPECT_EQ(error::kNoError
, ExecuteCmd(is_enabled_cmd
));
807 EXPECT_EQ(0u, *result
);
811 TEST_P(GLES2DecoderManualInitTest
, GpuMemoryManagerCHROMIUM
) {
813 init
.extensions
= "GL_ARB_texture_rectangle";
814 init
.bind_generates_resource
= true;
817 Texture
* texture
= GetTexture(client_texture_id_
)->texture();
818 EXPECT_TRUE(texture
!= NULL
);
819 EXPECT_TRUE(texture
->pool() == GL_TEXTURE_POOL_UNMANAGED_CHROMIUM
);
821 DoBindTexture(GL_TEXTURE_2D
, client_texture_id_
, kServiceTextureId
);
824 cmd
.Init(GL_TEXTURE_2D
,
825 GL_TEXTURE_POOL_CHROMIUM
,
826 GL_TEXTURE_POOL_UNMANAGED_CHROMIUM
);
827 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
828 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
830 cmd
.Init(GL_TEXTURE_2D
,
831 GL_TEXTURE_POOL_CHROMIUM
,
832 GL_TEXTURE_POOL_MANAGED_CHROMIUM
);
833 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
834 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
836 EXPECT_TRUE(texture
->pool() == GL_TEXTURE_POOL_MANAGED_CHROMIUM
);
838 cmd
.Init(GL_TEXTURE_2D
, GL_TEXTURE_POOL_CHROMIUM
, GL_NONE
);
839 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
840 EXPECT_EQ(GL_INVALID_ENUM
, GetGLError());
845 class SizeOnlyMemoryTracker
: public MemoryTracker
{
847 SizeOnlyMemoryTracker() {
848 // These are the default textures. 1 for TEXTURE_2D and 6 faces for
850 const size_t kInitialUnmanagedPoolSize
= 7 * 4;
851 const size_t kInitialManagedPoolSize
= 0;
852 pool_infos_
[MemoryTracker::kUnmanaged
].initial_size
=
853 kInitialUnmanagedPoolSize
;
854 pool_infos_
[MemoryTracker::kManaged
].initial_size
= kInitialManagedPoolSize
;
857 // Ensure a certain amount of GPU memory is free. Returns true on success.
858 MOCK_METHOD1(EnsureGPUMemoryAvailable
, bool(size_t size_needed
));
860 virtual void TrackMemoryAllocatedChange(size_t old_size
,
863 PoolInfo
& info
= pool_infos_
[pool
];
864 info
.size
+= new_size
- old_size
;
867 size_t GetPoolSize(Pool pool
) {
868 const PoolInfo
& info
= pool_infos_
[pool
];
869 return info
.size
- info
.initial_size
;
873 virtual ~SizeOnlyMemoryTracker() {}
875 PoolInfo() : initial_size(0), size(0) {}
879 std::map
<Pool
, PoolInfo
> pool_infos_
;
882 } // anonymous namespace.
884 TEST_P(GLES2DecoderManualInitTest
, MemoryTrackerInitialSize
) {
885 scoped_refptr
<SizeOnlyMemoryTracker
> memory_tracker
=
886 new SizeOnlyMemoryTracker();
887 set_memory_tracker(memory_tracker
.get());
889 init
.bind_generates_resource
= true;
891 // Expect that initial size - size is 0.
892 EXPECT_EQ(0u, memory_tracker
->GetPoolSize(MemoryTracker::kUnmanaged
));
893 EXPECT_EQ(0u, memory_tracker
->GetPoolSize(MemoryTracker::kManaged
));
896 TEST_P(GLES2DecoderManualInitTest
, MemoryTrackerTexImage2D
) {
897 scoped_refptr
<SizeOnlyMemoryTracker
> memory_tracker
=
898 new SizeOnlyMemoryTracker();
899 set_memory_tracker(memory_tracker
.get());
901 init
.bind_generates_resource
= true;
903 DoBindTexture(GL_TEXTURE_2D
, client_texture_id_
, kServiceTextureId
);
904 EXPECT_CALL(*memory_tracker
.get(), EnsureGPUMemoryAvailable(128))
905 .WillOnce(Return(true))
906 .RetiresOnSaturation();
907 DoTexImage2D(GL_TEXTURE_2D
,
916 kSharedMemoryOffset
);
917 EXPECT_EQ(128u, memory_tracker
->GetPoolSize(MemoryTracker::kUnmanaged
));
918 EXPECT_CALL(*memory_tracker
.get(), EnsureGPUMemoryAvailable(64))
919 .WillOnce(Return(true))
920 .RetiresOnSaturation();
921 DoTexImage2D(GL_TEXTURE_2D
,
930 kSharedMemoryOffset
);
931 EXPECT_EQ(64u, memory_tracker
->GetPoolSize(MemoryTracker::kUnmanaged
));
932 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
933 // Check we get out of memory and no call to glTexImage2D if Ensure fails.
934 EXPECT_CALL(*memory_tracker
.get(), EnsureGPUMemoryAvailable(64))
935 .WillOnce(Return(false))
936 .RetiresOnSaturation();
938 cmd
.Init(GL_TEXTURE_2D
,
946 kSharedMemoryOffset
);
947 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
948 EXPECT_EQ(GL_OUT_OF_MEMORY
, GetGLError());
949 EXPECT_EQ(64u, memory_tracker
->GetPoolSize(MemoryTracker::kUnmanaged
));
952 TEST_P(GLES2DecoderManualInitTest
, MemoryTrackerTexStorage2DEXT
) {
953 scoped_refptr
<SizeOnlyMemoryTracker
> memory_tracker
=
954 new SizeOnlyMemoryTracker();
955 set_memory_tracker(memory_tracker
.get());
957 init
.bind_generates_resource
= true;
959 DoBindTexture(GL_TEXTURE_2D
, client_texture_id_
, kServiceTextureId
);
960 // Check we get out of memory and no call to glTexStorage2DEXT
962 EXPECT_CALL(*memory_tracker
.get(), EnsureGPUMemoryAvailable(128))
963 .WillOnce(Return(false))
964 .RetiresOnSaturation();
966 cmd
.Init(GL_TEXTURE_2D
, 1, GL_RGBA8
, 8, 4);
967 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
968 EXPECT_EQ(0u, memory_tracker
->GetPoolSize(MemoryTracker::kUnmanaged
));
969 EXPECT_EQ(GL_OUT_OF_MEMORY
, GetGLError());
972 TEST_P(GLES2DecoderManualInitTest
, MemoryTrackerCopyTexImage2D
) {
973 GLenum target
= GL_TEXTURE_2D
;
975 GLenum internal_format
= GL_RGBA
;
979 scoped_refptr
<SizeOnlyMemoryTracker
> memory_tracker
=
980 new SizeOnlyMemoryTracker();
981 set_memory_tracker(memory_tracker
.get());
983 init
.has_alpha
= true;
984 init
.request_alpha
= true;
985 init
.bind_generates_resource
= true;
987 DoBindTexture(GL_TEXTURE_2D
, client_texture_id_
, kServiceTextureId
);
988 EXPECT_CALL(*memory_tracker
.get(), EnsureGPUMemoryAvailable(128))
989 .WillOnce(Return(true))
990 .RetiresOnSaturation();
991 EXPECT_CALL(*gl_
, GetError())
992 .WillOnce(Return(GL_NO_ERROR
))
993 .WillOnce(Return(GL_NO_ERROR
))
994 .RetiresOnSaturation();
997 target
, level
, internal_format
, 0, 0, width
, height
, border
))
999 .RetiresOnSaturation();
1001 cmd
.Init(target
, level
, internal_format
, 0, 0, width
, height
);
1002 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
1003 EXPECT_EQ(128u, memory_tracker
->GetPoolSize(MemoryTracker::kUnmanaged
));
1004 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
1005 // Check we get out of memory and no call to glCopyTexImage2D if Ensure fails.
1006 EXPECT_CALL(*memory_tracker
.get(), EnsureGPUMemoryAvailable(128))
1007 .WillOnce(Return(false))
1008 .RetiresOnSaturation();
1009 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
1010 EXPECT_EQ(GL_OUT_OF_MEMORY
, GetGLError());
1011 EXPECT_EQ(128u, memory_tracker
->GetPoolSize(MemoryTracker::kUnmanaged
));
1014 TEST_P(GLES2DecoderManualInitTest
, MemoryTrackerRenderbufferStorage
) {
1015 scoped_refptr
<SizeOnlyMemoryTracker
> memory_tracker
=
1016 new SizeOnlyMemoryTracker();
1017 set_memory_tracker(memory_tracker
.get());
1019 init
.bind_generates_resource
= true;
1022 GL_RENDERBUFFER
, client_renderbuffer_id_
, kServiceRenderbufferId
);
1023 EnsureRenderbufferBound(false);
1024 EXPECT_CALL(*gl_
, GetError())
1025 .WillOnce(Return(GL_NO_ERROR
))
1026 .WillOnce(Return(GL_NO_ERROR
))
1027 .RetiresOnSaturation();
1028 EXPECT_CALL(*memory_tracker
.get(), EnsureGPUMemoryAvailable(128))
1029 .WillOnce(Return(true))
1030 .RetiresOnSaturation();
1031 EXPECT_CALL(*gl_
, RenderbufferStorageEXT(GL_RENDERBUFFER
, GL_RGBA
, 8, 4))
1033 .RetiresOnSaturation();
1034 RenderbufferStorage cmd
;
1035 cmd
.Init(GL_RENDERBUFFER
, GL_RGBA4
, 8, 4);
1036 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
1037 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
1038 EXPECT_EQ(128u, memory_tracker
->GetPoolSize(MemoryTracker::kUnmanaged
));
1039 // Check we get out of memory and no call to glRenderbufferStorage if Ensure
1041 EXPECT_CALL(*memory_tracker
.get(), EnsureGPUMemoryAvailable(128))
1042 .WillOnce(Return(false))
1043 .RetiresOnSaturation();
1044 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
1045 EXPECT_EQ(GL_OUT_OF_MEMORY
, GetGLError());
1046 EXPECT_EQ(128u, memory_tracker
->GetPoolSize(MemoryTracker::kUnmanaged
));
1049 TEST_P(GLES2DecoderManualInitTest
, MemoryTrackerBufferData
) {
1050 scoped_refptr
<SizeOnlyMemoryTracker
> memory_tracker
=
1051 new SizeOnlyMemoryTracker();
1052 set_memory_tracker(memory_tracker
.get());
1054 init
.bind_generates_resource
= true;
1056 DoBindBuffer(GL_ARRAY_BUFFER
, client_buffer_id_
, kServiceBufferId
);
1057 EXPECT_CALL(*gl_
, GetError())
1058 .WillOnce(Return(GL_NO_ERROR
))
1059 .WillOnce(Return(GL_NO_ERROR
))
1060 .RetiresOnSaturation();
1061 EXPECT_CALL(*memory_tracker
.get(), EnsureGPUMemoryAvailable(128))
1062 .WillOnce(Return(true))
1063 .RetiresOnSaturation();
1064 EXPECT_CALL(*gl_
, BufferData(GL_ARRAY_BUFFER
, 128, _
, GL_STREAM_DRAW
))
1066 .RetiresOnSaturation();
1068 cmd
.Init(GL_ARRAY_BUFFER
, 128, 0, 0, GL_STREAM_DRAW
);
1069 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
1070 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
1071 EXPECT_EQ(128u, memory_tracker
->GetPoolSize(MemoryTracker::kManaged
));
1072 // Check we get out of memory and no call to glBufferData if Ensure
1074 EXPECT_CALL(*memory_tracker
.get(), EnsureGPUMemoryAvailable(128))
1075 .WillOnce(Return(false))
1076 .RetiresOnSaturation();
1077 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
1078 EXPECT_EQ(GL_OUT_OF_MEMORY
, GetGLError());
1079 EXPECT_EQ(128u, memory_tracker
->GetPoolSize(MemoryTracker::kManaged
));
1082 TEST_P(GLES2DecoderManualInitTest
, ImmutableCopyTexImage2D
) {
1083 const GLenum kTarget
= GL_TEXTURE_2D
;
1084 const GLint kLevel
= 0;
1085 const GLenum kInternalFormat
= GL_RGBA
;
1086 const GLenum kSizedInternalFormat
= GL_RGBA8
;
1087 const GLsizei kWidth
= 4;
1088 const GLsizei kHeight
= 8;
1089 const GLint kBorder
= 0;
1091 init
.extensions
= "GL_EXT_texture_storage";
1092 init
.has_alpha
= true;
1093 init
.request_alpha
= true;
1094 init
.bind_generates_resource
= true;
1096 DoBindTexture(GL_TEXTURE_2D
, client_texture_id_
, kServiceTextureId
);
1098 // CopyTexImage2D will call arbitrary amount of GetErrors.
1099 EXPECT_CALL(*gl_
, GetError())
1104 kTarget
, kLevel
, kInternalFormat
, 0, 0, kWidth
, kHeight
,
1110 kTarget
, kLevel
, kSizedInternalFormat
, kWidth
, kHeight
))
1112 CopyTexImage2D copy_cmd
;
1113 copy_cmd
.Init(kTarget
, kLevel
, kInternalFormat
, 0, 0, kWidth
, kHeight
);
1114 EXPECT_EQ(error::kNoError
, ExecuteCmd(copy_cmd
));
1115 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
1117 TexStorage2DEXT storage_cmd
;
1118 storage_cmd
.Init(kTarget
, kLevel
, kSizedInternalFormat
, kWidth
, kHeight
);
1119 EXPECT_EQ(error::kNoError
, ExecuteCmd(storage_cmd
));
1120 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
1122 // This should not invoke CopyTexImage2D.
1123 copy_cmd
.Init(kTarget
, kLevel
, kInternalFormat
, 0, 0, kWidth
, kHeight
);
1124 EXPECT_EQ(error::kNoError
, ExecuteCmd(copy_cmd
));
1125 EXPECT_EQ(GL_INVALID_OPERATION
, GetGLError());
1128 TEST_P(GLES2DecoderTest
, LoseContextCHROMIUMValidArgs
) {
1129 EXPECT_CALL(*mock_decoder_
, LoseContext(GL_GUILTY_CONTEXT_RESET_ARB
))
1131 cmds::LoseContextCHROMIUM cmd
;
1132 cmd
.Init(GL_GUILTY_CONTEXT_RESET_ARB
, GL_GUILTY_CONTEXT_RESET_ARB
);
1133 EXPECT_EQ(error::kLostContext
, ExecuteCmd(cmd
));
1134 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
1137 TEST_P(GLES2DecoderTest
, LoseContextCHROMIUMInvalidArgs0_0
) {
1138 EXPECT_CALL(*mock_decoder_
, LoseContext(_
))
1140 cmds::LoseContextCHROMIUM cmd
;
1141 cmd
.Init(GL_NONE
, GL_GUILTY_CONTEXT_RESET_ARB
);
1142 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
1143 EXPECT_EQ(GL_INVALID_ENUM
, GetGLError());
1146 TEST_P(GLES2DecoderTest
, LoseContextCHROMIUMInvalidArgs1_0
) {
1147 EXPECT_CALL(*mock_decoder_
, LoseContext(_
))
1149 cmds::LoseContextCHROMIUM cmd
;
1150 cmd
.Init(GL_GUILTY_CONTEXT_RESET_ARB
, GL_NONE
);
1151 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
1152 EXPECT_EQ(GL_INVALID_ENUM
, GetGLError());
1155 class GLES2DecoderDoCommandsTest
: public GLES2DecoderTest
{
1157 GLES2DecoderDoCommandsTest() {
1158 for (int i
= 0; i
< 3; i
++) {
1159 cmds_
[i
].Init(GL_BLEND
);
1161 entries_per_cmd_
= ComputeNumEntries(cmds_
[0].ComputeSize());
1164 void SetExpectationsForNCommands(int num_commands
) {
1165 for (int i
= 0; i
< num_commands
; i
++)
1166 SetupExpectationsForEnableDisable(GL_BLEND
, true);
1171 int entries_per_cmd_
;
1174 // Test that processing with 0 entries does nothing.
1175 TEST_P(GLES2DecoderDoCommandsTest
, DoCommandsOneOfZero
) {
1176 int num_processed
= -1;
1177 SetExpectationsForNCommands(0);
1180 decoder_
->DoCommands(1, &cmds_
, entries_per_cmd_
* 0, &num_processed
));
1181 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
1182 EXPECT_EQ(0, num_processed
);
1185 // Test processing at granularity of single commands.
1186 TEST_P(GLES2DecoderDoCommandsTest
, DoCommandsOneOfOne
) {
1187 int num_processed
= -1;
1188 SetExpectationsForNCommands(1);
1191 decoder_
->DoCommands(1, &cmds_
, entries_per_cmd_
* 1, &num_processed
));
1192 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
1193 EXPECT_EQ(entries_per_cmd_
, num_processed
);
1196 // Test processing at granularity of multiple commands.
1197 TEST_P(GLES2DecoderDoCommandsTest
, DoCommandsThreeOfThree
) {
1198 int num_processed
= -1;
1199 SetExpectationsForNCommands(3);
1202 decoder_
->DoCommands(3, &cmds_
, entries_per_cmd_
* 3, &num_processed
));
1203 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
1204 EXPECT_EQ(entries_per_cmd_
* 3, num_processed
);
1207 // Test processing a request smaller than available entries.
1208 TEST_P(GLES2DecoderDoCommandsTest
, DoCommandsTwoOfThree
) {
1209 int num_processed
= -1;
1210 SetExpectationsForNCommands(2);
1213 decoder_
->DoCommands(2, &cmds_
, entries_per_cmd_
* 3, &num_processed
));
1214 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
1215 EXPECT_EQ(entries_per_cmd_
* 2, num_processed
);
1218 // Test that processing stops on a command with size 0.
1219 TEST_P(GLES2DecoderDoCommandsTest
, DoCommandsZeroCmdSize
) {
1220 cmds_
[1].header
.size
= 0;
1221 int num_processed
= -1;
1222 SetExpectationsForNCommands(1);
1224 error::kInvalidSize
,
1225 decoder_
->DoCommands(2, &cmds_
, entries_per_cmd_
* 2, &num_processed
));
1226 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
1227 EXPECT_EQ(entries_per_cmd_
, num_processed
);
1230 // Test that processing stops on a command with size greater than available.
1231 TEST_P(GLES2DecoderDoCommandsTest
, DoCommandsOutOfBounds
) {
1232 int num_processed
= -1;
1233 SetExpectationsForNCommands(1);
1234 EXPECT_EQ(error::kOutOfBounds
,
1235 decoder_
->DoCommands(
1236 2, &cmds_
, entries_per_cmd_
* 2 - 1, &num_processed
));
1237 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
1238 EXPECT_EQ(entries_per_cmd_
, num_processed
);
1241 // Test that commands with bad argument size are skipped without processing.
1242 TEST_P(GLES2DecoderDoCommandsTest
, DoCommandsBadArgSize
) {
1243 cmds_
[1].header
.size
+= 1;
1244 int num_processed
= -1;
1245 SetExpectationsForNCommands(1);
1246 EXPECT_EQ(error::kInvalidArguments
,
1247 decoder_
->DoCommands(
1248 2, &cmds_
, entries_per_cmd_
* 2 + 1, &num_processed
));
1249 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
1250 EXPECT_EQ(entries_per_cmd_
+ cmds_
[1].header
.size
, num_processed
);
1253 INSTANTIATE_TEST_CASE_P(Service
, GLES2DecoderTest
, ::testing::Bool());
1255 INSTANTIATE_TEST_CASE_P(Service
, GLES2DecoderWithShaderTest
, ::testing::Bool());
1257 INSTANTIATE_TEST_CASE_P(Service
, GLES2DecoderManualInitTest
, ::testing::Bool());
1259 INSTANTIATE_TEST_CASE_P(Service
,
1260 GLES2DecoderRGBBackbufferTest
,
1263 INSTANTIATE_TEST_CASE_P(Service
, GLES2DecoderDoCommandsTest
, ::testing::Bool());
1265 } // namespace gles2