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"
29 #include "ui/gl/gpu_timing_fake.h"
32 #if !defined(GL_DEPTH24_STENCIL8)
33 #define GL_DEPTH24_STENCIL8 0x88F0
36 using ::gfx::MockGLInterface
;
38 using ::testing::AtLeast
;
39 using ::testing::DoAll
;
40 using ::testing::InSequence
;
41 using ::testing::Invoke
;
42 using ::testing::MatcherCast
;
43 using ::testing::Mock
;
44 using ::testing::Pointee
;
45 using ::testing::Return
;
46 using ::testing::SaveArg
;
47 using ::testing::SetArrayArgument
;
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 init
.webgl_version
= 2;
100 InitDecoderWithCommandLine(init
, &command_line
);
104 TEST_P(GLES3DecoderTest
, Basic
) {
105 // Make sure the setup is correct for ES3.
106 EXPECT_TRUE(decoder_
->unsafe_es3_apis_enabled());
107 EXPECT_TRUE(feature_info()->validators()->texture_bind_target
.IsValid(
111 TEST_P(GLES2DecoderTest
, GetIntegervCached
) {
118 GL_MAX_TEXTURE_SIZE
, TestHelper::kMaxTextureSize
,
121 GL_MAX_CUBE_MAP_TEXTURE_SIZE
, TestHelper::kMaxCubeMapTextureSize
,
124 GL_MAX_RENDERBUFFER_SIZE
, TestHelper::kMaxRenderbufferSize
,
127 typedef GetIntegerv::Result Result
;
128 for (size_t ii
= 0; ii
< sizeof(tests
) / sizeof(tests
[0]); ++ii
) {
129 const TestInfo
& test
= tests
[ii
];
130 Result
* result
= static_cast<Result
*>(shared_memory_address_
);
131 EXPECT_CALL(*gl_
, GetError())
132 .WillOnce(Return(GL_NO_ERROR
))
133 .WillOnce(Return(GL_NO_ERROR
))
134 .RetiresOnSaturation();
135 EXPECT_CALL(*gl_
, GetIntegerv(test
.pname
, _
)).Times(0);
138 cmd2
.Init(test
.pname
, shared_memory_id_
, shared_memory_offset_
);
139 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd2
));
140 EXPECT_EQ(decoder_
->GetGLES2Util()->GLGetNumValuesReturned(test
.pname
),
141 result
->GetNumResults());
142 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
143 EXPECT_EQ(test
.expected
, result
->GetData()[0]);
147 TEST_P(GLES2DecoderWithShaderTest
, GetMaxValueInBufferCHROMIUM
) {
149 GetMaxValueInBufferCHROMIUM::Result
* result
=
150 static_cast<GetMaxValueInBufferCHROMIUM::Result
*>(shared_memory_address_
);
153 GetMaxValueInBufferCHROMIUM cmd
;
154 cmd
.Init(client_element_buffer_id_
,
155 kValidIndexRangeCount
,
157 kValidIndexRangeStart
* 2,
159 kSharedMemoryOffset
);
160 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
161 EXPECT_EQ(7u, *result
);
162 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
163 cmd
.Init(client_element_buffer_id_
,
164 kValidIndexRangeCount
+ 1,
166 kValidIndexRangeStart
* 2,
168 kSharedMemoryOffset
);
169 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
170 EXPECT_EQ(100u, *result
);
171 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
173 cmd
.Init(kInvalidClientId
,
174 kValidIndexRangeCount
,
176 kValidIndexRangeStart
* 2,
178 kSharedMemoryOffset
);
179 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
180 EXPECT_EQ(GL_INVALID_VALUE
, GetGLError());
181 cmd
.Init(client_element_buffer_id_
,
182 kOutOfRangeIndexRangeEnd
,
184 kValidIndexRangeStart
* 2,
186 kSharedMemoryOffset
);
187 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
188 EXPECT_EQ(GL_INVALID_OPERATION
, GetGLError());
189 cmd
.Init(client_element_buffer_id_
,
190 kValidIndexRangeCount
+ 1,
192 kOutOfRangeIndexRangeEnd
* 2,
194 kSharedMemoryOffset
);
195 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
196 EXPECT_EQ(GL_INVALID_OPERATION
, GetGLError());
197 cmd
.Init(client_element_buffer_id_
,
198 kValidIndexRangeCount
+ 1,
200 kValidIndexRangeStart
* 2,
202 kSharedMemoryOffset
);
203 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
204 cmd
.Init(client_buffer_id_
,
205 kValidIndexRangeCount
+ 1,
207 kValidIndexRangeStart
* 2,
209 kSharedMemoryOffset
);
210 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
211 EXPECT_EQ(GL_INVALID_OPERATION
, GetGLError());
212 cmd
.Init(client_element_buffer_id_
,
213 kValidIndexRangeCount
+ 1,
215 kValidIndexRangeStart
* 2,
216 kInvalidSharedMemoryId
,
217 kSharedMemoryOffset
);
218 EXPECT_NE(error::kNoError
, ExecuteCmd(cmd
));
219 cmd
.Init(client_element_buffer_id_
,
220 kValidIndexRangeCount
+ 1,
222 kValidIndexRangeStart
* 2,
224 kInvalidSharedMemoryOffset
);
225 EXPECT_NE(error::kNoError
, ExecuteCmd(cmd
));
228 TEST_P(GLES2DecoderTest
, IsBuffer
) {
229 EXPECT_FALSE(DoIsBuffer(client_buffer_id_
));
230 DoBindBuffer(GL_ARRAY_BUFFER
, client_buffer_id_
, kServiceBufferId
);
231 EXPECT_TRUE(DoIsBuffer(client_buffer_id_
));
232 DoDeleteBuffer(client_buffer_id_
, kServiceBufferId
);
233 EXPECT_FALSE(DoIsBuffer(client_buffer_id_
));
236 TEST_P(GLES2DecoderTest
, IsFramebuffer
) {
237 EXPECT_FALSE(DoIsFramebuffer(client_framebuffer_id_
));
239 GL_FRAMEBUFFER
, client_framebuffer_id_
, kServiceFramebufferId
);
240 EXPECT_TRUE(DoIsFramebuffer(client_framebuffer_id_
));
241 DoDeleteFramebuffer(client_framebuffer_id_
,
242 kServiceFramebufferId
,
249 EXPECT_FALSE(DoIsFramebuffer(client_framebuffer_id_
));
252 TEST_P(GLES2DecoderTest
, IsProgram
) {
253 // IsProgram is true as soon as the program is created.
254 EXPECT_TRUE(DoIsProgram(client_program_id_
));
255 EXPECT_CALL(*gl_
, DeleteProgram(kServiceProgramId
))
257 .RetiresOnSaturation();
258 DoDeleteProgram(client_program_id_
, kServiceProgramId
);
259 EXPECT_FALSE(DoIsProgram(client_program_id_
));
262 TEST_P(GLES2DecoderTest
, IsRenderbuffer
) {
263 EXPECT_FALSE(DoIsRenderbuffer(client_renderbuffer_id_
));
265 GL_RENDERBUFFER
, client_renderbuffer_id_
, kServiceRenderbufferId
);
266 EXPECT_TRUE(DoIsRenderbuffer(client_renderbuffer_id_
));
267 DoDeleteRenderbuffer(client_renderbuffer_id_
, kServiceRenderbufferId
);
268 EXPECT_FALSE(DoIsRenderbuffer(client_renderbuffer_id_
));
271 TEST_P(GLES2DecoderTest
, IsShader
) {
272 // IsShader is true as soon as the program is created.
273 EXPECT_TRUE(DoIsShader(client_shader_id_
));
274 DoDeleteShader(client_shader_id_
, kServiceShaderId
);
275 EXPECT_FALSE(DoIsShader(client_shader_id_
));
278 TEST_P(GLES2DecoderTest
, IsTexture
) {
279 EXPECT_FALSE(DoIsTexture(client_texture_id_
));
280 DoBindTexture(GL_TEXTURE_2D
, client_texture_id_
, kServiceTextureId
);
281 EXPECT_TRUE(DoIsTexture(client_texture_id_
));
282 DoDeleteTexture(client_texture_id_
, kServiceTextureId
);
283 EXPECT_FALSE(DoIsTexture(client_texture_id_
));
286 TEST_P(GLES3DecoderTest
, GetInternalformativValidArgsSamples
) {
287 const GLint kNumSampleCounts
= 8;
288 typedef cmds::GetInternalformativ::Result Result
;
289 Result
* result
= static_cast<Result
*>(shared_memory_address_
);
290 EXPECT_CALL(*gl_
, GetInternalformativ(GL_RENDERBUFFER
, GL_RGBA8
,
291 GL_NUM_SAMPLE_COUNTS
, 1, _
))
292 .WillOnce(SetArgPointee
<4>(kNumSampleCounts
))
293 .RetiresOnSaturation();
294 EXPECT_CALL(*gl_
, GetInternalformativ(GL_RENDERBUFFER
, GL_RGBA8
,
295 GL_SAMPLES
, kNumSampleCounts
,
298 .RetiresOnSaturation();
300 cmds::GetInternalformativ cmd
;
301 cmd
.Init(GL_RENDERBUFFER
, GL_RGBA8
, GL_SAMPLES
,
302 shared_memory_id_
, shared_memory_offset_
);
303 decoder_
->set_unsafe_es3_apis_enabled(true);
304 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
305 EXPECT_EQ(kNumSampleCounts
, result
->GetNumResults());
306 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
307 decoder_
->set_unsafe_es3_apis_enabled(false);
308 EXPECT_EQ(error::kUnknownCommand
, ExecuteCmd(cmd
));
311 TEST_P(GLES3DecoderTest
, GetInternalformativValidArgsNumSampleCounts
) {
312 const GLint kNumSampleCounts
= 8;
313 typedef cmds::GetInternalformativ::Result Result
;
314 Result
* result
= static_cast<Result
*>(shared_memory_address_
);
315 EXPECT_CALL(*gl_
, GetInternalformativ(GL_RENDERBUFFER
, GL_RGBA8
,
316 GL_NUM_SAMPLE_COUNTS
, 1, _
))
317 .WillOnce(SetArgPointee
<4>(kNumSampleCounts
))
318 .RetiresOnSaturation();
320 cmds::GetInternalformativ cmd
;
321 cmd
.Init(GL_RENDERBUFFER
, GL_RGBA8
, GL_NUM_SAMPLE_COUNTS
,
322 shared_memory_id_
, shared_memory_offset_
);
323 decoder_
->set_unsafe_es3_apis_enabled(true);
324 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
325 EXPECT_EQ(1, result
->GetNumResults());
326 EXPECT_EQ(kNumSampleCounts
, result
->GetData()[0]);
327 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
328 decoder_
->set_unsafe_es3_apis_enabled(false);
329 EXPECT_EQ(error::kUnknownCommand
, ExecuteCmd(cmd
));
332 TEST_P(GLES3DecoderTest
, ClientWaitSyncValid
) {
333 typedef cmds::ClientWaitSync::Result Result
;
334 Result
* result
= static_cast<Result
*>(shared_memory_address_
);
335 cmds::ClientWaitSync cmd
;
336 uint32_t v32_0
= 0, v32_1
= 0;
337 GLES2Util::MapUint64ToTwoUint32(0, &v32_0
, &v32_1
);
338 cmd
.Init(client_sync_id_
, GL_SYNC_FLUSH_COMMANDS_BIT
, v32_0
, v32_1
,
339 shared_memory_id_
, shared_memory_offset_
);
341 ClientWaitSync(reinterpret_cast<GLsync
>(kServiceSyncId
),
342 GL_SYNC_FLUSH_COMMANDS_BIT
, 0))
343 .WillOnce(Return(GL_CONDITION_SATISFIED
))
344 .RetiresOnSaturation();
345 *result
= GL_WAIT_FAILED
;
346 decoder_
->set_unsafe_es3_apis_enabled(true);
347 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
348 EXPECT_EQ(static_cast<GLenum
>(GL_CONDITION_SATISFIED
), *result
);
349 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
350 decoder_
->set_unsafe_es3_apis_enabled(false);
351 EXPECT_EQ(error::kUnknownCommand
, ExecuteCmd(cmd
));
354 TEST_P(GLES2DecoderTest
, ClientWaitSyncNonZeroTimeoutValid
) {
355 typedef cmds::ClientWaitSync::Result Result
;
356 Result
* result
= static_cast<Result
*>(shared_memory_address_
);
357 cmds::ClientWaitSync cmd
;
358 const GLuint64 kTimeout
= 0xABCDEF0123456789;
359 uint32_t v32_0
= 0, v32_1
= 0;
360 GLES2Util::MapUint64ToTwoUint32(kTimeout
, &v32_0
, &v32_1
);
361 cmd
.Init(client_sync_id_
, GL_SYNC_FLUSH_COMMANDS_BIT
, v32_0
, v32_1
,
362 shared_memory_id_
, shared_memory_offset_
);
364 ClientWaitSync(reinterpret_cast<GLsync
>(kServiceSyncId
),
365 GL_SYNC_FLUSH_COMMANDS_BIT
, kTimeout
))
366 .WillOnce(Return(GL_CONDITION_SATISFIED
))
367 .RetiresOnSaturation();
368 *result
= GL_WAIT_FAILED
;
369 decoder_
->set_unsafe_es3_apis_enabled(true);
370 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
371 EXPECT_EQ(static_cast<GLenum
>(GL_CONDITION_SATISFIED
), *result
);
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(GLES2DecoderTest
, ClientWaitSyncInvalidSyncFails
) {
378 typedef cmds::ClientWaitSync::Result Result
;
379 Result
* result
= static_cast<Result
*>(shared_memory_address_
);
380 cmds::ClientWaitSync cmd
;
381 uint32_t v32_0
= 0, v32_1
= 0;
382 GLES2Util::MapUint64ToTwoUint32(0, &v32_0
, &v32_1
);
383 decoder_
->set_unsafe_es3_apis_enabled(true);
384 cmd
.Init(kInvalidClientId
, GL_SYNC_FLUSH_COMMANDS_BIT
, v32_0
, v32_1
,
385 shared_memory_id_
, shared_memory_offset_
);
386 *result
= GL_WAIT_FAILED
;
387 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
388 EXPECT_EQ(static_cast<GLenum
>(GL_WAIT_FAILED
), *result
);
389 EXPECT_EQ(GL_INVALID_VALUE
, GetGLError());
392 TEST_P(GLES2DecoderTest
, ClientWaitSyncResultNotInitFails
) {
393 typedef cmds::ClientWaitSync::Result Result
;
394 Result
* result
= static_cast<Result
*>(shared_memory_address_
);
395 cmds::ClientWaitSync cmd
;
396 uint32_t v32_0
= 0, v32_1
= 0;
397 GLES2Util::MapUint64ToTwoUint32(0, &v32_0
, &v32_1
);
398 decoder_
->set_unsafe_es3_apis_enabled(true);
399 cmd
.Init(client_sync_id_
, GL_SYNC_FLUSH_COMMANDS_BIT
, v32_0
, v32_1
,
400 shared_memory_id_
, shared_memory_offset_
);
401 *result
= 1; // Any value other than GL_WAIT_FAILED
402 EXPECT_NE(error::kNoError
, ExecuteCmd(cmd
));
405 TEST_P(GLES2DecoderTest
, ClientWaitSyncBadSharedMemoryFails
) {
406 typedef cmds::ClientWaitSync::Result Result
;
407 Result
* result
= static_cast<Result
*>(shared_memory_address_
);
408 cmds::ClientWaitSync cmd
;
409 uint32_t v32_0
= 0, v32_1
= 0;
410 GLES2Util::MapUint64ToTwoUint32(0, &v32_0
, &v32_1
);
411 decoder_
->set_unsafe_es3_apis_enabled(true);
412 *result
= GL_WAIT_FAILED
;
413 cmd
.Init(client_sync_id_
, GL_SYNC_FLUSH_COMMANDS_BIT
, v32_0
, v32_1
,
414 kInvalidSharedMemoryId
, shared_memory_offset_
);
415 EXPECT_NE(error::kNoError
, ExecuteCmd(cmd
));
417 *result
= GL_WAIT_FAILED
;
418 cmd
.Init(client_sync_id_
, GL_SYNC_FLUSH_COMMANDS_BIT
, v32_0
, v32_1
,
419 shared_memory_id_
, kInvalidSharedMemoryOffset
);
420 EXPECT_NE(error::kNoError
, ExecuteCmd(cmd
));
423 TEST_P(GLES2DecoderTest
, WaitSyncValidArgs
) {
424 const GLuint64 kTimeout
= GL_TIMEOUT_IGNORED
;
425 EXPECT_CALL(*gl_
, WaitSync(reinterpret_cast<GLsync
>(kServiceSyncId
),
428 .RetiresOnSaturation();
430 uint32_t v32_0
= 0, v32_1
= 0;
431 GLES2Util::MapUint64ToTwoUint32(kTimeout
, &v32_0
, &v32_1
);
433 cmd
.Init(client_sync_id_
, 0, v32_0
, v32_1
);
434 decoder_
->set_unsafe_es3_apis_enabled(true);
435 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
436 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
437 decoder_
->set_unsafe_es3_apis_enabled(false);
438 EXPECT_EQ(error::kUnknownCommand
, ExecuteCmd(cmd
));
441 TEST_P(GLES2DecoderManualInitTest
, BindGeneratesResourceFalse
) {
446 cmd1
.Init(GL_TEXTURE_2D
, kInvalidClientId
);
447 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd1
));
448 EXPECT_EQ(GL_INVALID_OPERATION
, GetGLError());
451 cmd2
.Init(GL_ARRAY_BUFFER
, kInvalidClientId
);
452 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd2
));
453 EXPECT_EQ(GL_INVALID_OPERATION
, GetGLError());
455 BindFramebuffer cmd3
;
456 cmd3
.Init(GL_FRAMEBUFFER
, kInvalidClientId
);
457 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd3
));
458 EXPECT_EQ(GL_INVALID_OPERATION
, GetGLError());
460 BindRenderbuffer cmd4
;
461 cmd4
.Init(GL_RENDERBUFFER
, kInvalidClientId
);
462 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd4
));
463 EXPECT_EQ(GL_INVALID_OPERATION
, GetGLError());
466 TEST_P(GLES2DecoderTest
, EnableFeatureCHROMIUMBadBucket
) {
467 const uint32 kBadBucketId
= 123;
468 EnableFeatureCHROMIUM cmd
;
469 cmd
.Init(kBadBucketId
, shared_memory_id_
, shared_memory_offset_
);
470 EXPECT_NE(error::kNoError
, ExecuteCmd(cmd
));
473 TEST_P(GLES2DecoderTest
, RequestExtensionCHROMIUMBadBucket
) {
474 const uint32 kBadBucketId
= 123;
475 RequestExtensionCHROMIUM cmd
;
476 cmd
.Init(kBadBucketId
);
477 EXPECT_NE(error::kNoError
, ExecuteCmd(cmd
));
480 TEST_P(GLES2DecoderTest
, BeginQueryEXTDisabled
) {
481 // Test something fails if off.
484 TEST_P(GLES2DecoderManualInitTest
, BeginEndQueryEXT
) {
486 init
.extensions
= "GL_EXT_occlusion_query_boolean";
487 init
.gl_version
= "opengl es 2.0";
488 init
.has_alpha
= true;
489 init
.request_alpha
= true;
490 init
.bind_generates_resource
= true;
493 // Test end fails if no begin.
495 end_cmd
.Init(GL_ANY_SAMPLES_PASSED_EXT
, 1);
496 EXPECT_EQ(error::kNoError
, ExecuteCmd(end_cmd
));
497 EXPECT_EQ(GL_INVALID_OPERATION
, GetGLError());
499 BeginQueryEXT begin_cmd
;
501 // Test id = 0 fails.
503 GL_ANY_SAMPLES_PASSED_EXT
, 0, kSharedMemoryId
, kSharedMemoryOffset
);
504 EXPECT_EQ(error::kNoError
, ExecuteCmd(begin_cmd
));
505 EXPECT_EQ(GL_INVALID_OPERATION
, GetGLError());
507 GenHelper
<GenQueriesEXTImmediate
>(kNewClientId
);
509 // Test valid parameters work.
510 EXPECT_CALL(*gl_
, GenQueries(1, _
))
511 .WillOnce(SetArgPointee
<1>(kNewServiceId
))
512 .RetiresOnSaturation();
513 EXPECT_CALL(*gl_
, BeginQuery(GL_ANY_SAMPLES_PASSED_EXT
, kNewServiceId
))
515 .RetiresOnSaturation();
517 // Query object should not be created untill BeginQueriesEXT.
518 QueryManager
* query_manager
= decoder_
->GetQueryManager();
519 ASSERT_TRUE(query_manager
!= NULL
);
520 QueryManager::Query
* query
= query_manager
->GetQuery(kNewClientId
);
521 EXPECT_TRUE(query
== NULL
);
523 // BeginQueryEXT should fail if id is not generated from GenQueriesEXT.
524 begin_cmd
.Init(GL_ANY_SAMPLES_PASSED_EXT
,
527 kSharedMemoryOffset
);
528 EXPECT_EQ(error::kNoError
, ExecuteCmd(begin_cmd
));
529 EXPECT_EQ(GL_INVALID_OPERATION
, GetGLError());
531 begin_cmd
.Init(GL_ANY_SAMPLES_PASSED_EXT
,
534 kSharedMemoryOffset
);
535 EXPECT_EQ(error::kNoError
, ExecuteCmd(begin_cmd
));
536 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
538 // After BeginQueriesEXT id name should have query object associated with it.
539 query
= query_manager
->GetQuery(kNewClientId
);
540 ASSERT_TRUE(query
!= NULL
);
541 EXPECT_FALSE(query
->IsPending());
543 // Test trying begin again fails
544 EXPECT_EQ(error::kNoError
, ExecuteCmd(begin_cmd
));
545 EXPECT_EQ(GL_INVALID_OPERATION
, GetGLError());
547 // Test end fails with different target
548 end_cmd
.Init(GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT
, 1);
549 EXPECT_EQ(error::kNoError
, ExecuteCmd(end_cmd
));
550 EXPECT_EQ(GL_INVALID_OPERATION
, GetGLError());
553 EXPECT_CALL(*gl_
, EndQuery(GL_ANY_SAMPLES_PASSED_EXT
))
555 .RetiresOnSaturation();
556 end_cmd
.Init(GL_ANY_SAMPLES_PASSED_EXT
, 1);
557 EXPECT_EQ(error::kNoError
, ExecuteCmd(end_cmd
));
558 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
559 EXPECT_TRUE(query
->IsPending());
561 EXPECT_CALL(*gl_
, DeleteQueries(1, _
)).Times(1).RetiresOnSaturation();
569 const QueryType kQueryTypes
[] = {
570 {GL_COMMANDS_ISSUED_CHROMIUM
, false},
571 {GL_LATENCY_QUERY_CHROMIUM
, false},
572 {GL_ASYNC_PIXEL_UNPACK_COMPLETED_CHROMIUM
, false},
573 {GL_ASYNC_PIXEL_PACK_COMPLETED_CHROMIUM
, false},
574 {GL_GET_ERROR_QUERY_CHROMIUM
, false},
575 {GL_COMMANDS_COMPLETED_CHROMIUM
, false},
576 {GL_ANY_SAMPLES_PASSED_EXT
, false},
577 {GL_TIME_ELAPSED
, false},
578 {GL_TIMESTAMP
, true},
580 const GLsync kGlSync
= reinterpret_cast<GLsync
>(0xdeadbeef);
582 static void ExecuteGenerateQueryCmd(GLES2DecoderTestBase
* test
,
583 ::gfx::MockGLInterface
* gl
,
587 test
->GenHelper
<GenQueriesEXTImmediate
>(client_id
);
588 if (GL_ANY_SAMPLES_PASSED_EXT
== target
) {
589 EXPECT_CALL(*gl
, GenQueries(1, _
))
590 .WillOnce(SetArgPointee
<1>(service_id
))
591 .RetiresOnSaturation();
595 static error::Error
ExecuteBeginQueryCmd(GLES2DecoderTestBase
* test
,
596 ::gfx::MockGLInterface
* gl
,
597 ::gfx::GPUTimingFake
* timing_queries
,
603 if (GL_ANY_SAMPLES_PASSED_EXT
== target
) {
604 EXPECT_CALL(*gl
, BeginQuery(target
, service_id
))
606 .RetiresOnSaturation();
607 } else if (GL_TIME_ELAPSED
== target
) {
608 timing_queries
->ExpectGPUTimerQuery(*gl
, true);
611 BeginQueryEXT begin_cmd
;
612 begin_cmd
.Init(target
, client_id
, shm_id
, shm_offset
);
613 return test
->ExecuteCmd(begin_cmd
);
616 static error::Error
ExecuteEndQueryCmd(GLES2DecoderTestBase
* test
,
617 ::gfx::MockGLInterface
* gl
,
619 uint32_t submit_count
) {
620 if (GL_ANY_SAMPLES_PASSED_EXT
== target
) {
621 EXPECT_CALL(*gl
, EndQuery(target
))
623 .RetiresOnSaturation();
624 } else if (GL_GET_ERROR_QUERY_CHROMIUM
== target
) {
625 EXPECT_CALL(*gl
, GetError())
626 .WillOnce(Return(GL_NO_ERROR
))
627 .RetiresOnSaturation();
628 } else if (GL_COMMANDS_COMPLETED_CHROMIUM
== target
) {
629 EXPECT_CALL(*gl
, Flush()).RetiresOnSaturation();
630 EXPECT_CALL(*gl
, FenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE
, 0))
631 .WillOnce(Return(kGlSync
))
632 .RetiresOnSaturation();
634 EXPECT_CALL(*gl
, IsSync(kGlSync
))
635 .WillRepeatedly(Return(GL_TRUE
));
640 end_cmd
.Init(target
, submit_count
);
641 return test
->ExecuteCmd(end_cmd
);
644 static error::Error
ExecuteQueryCounterCmd(GLES2DecoderTestBase
* test
,
645 ::gfx::MockGLInterface
* gl
,
646 ::gfx::GPUTimingFake
* timing_queries
,
652 uint32_t submit_count
) {
653 if (GL_TIMESTAMP
== target
) {
654 timing_queries
->ExpectGPUTimeStampQuery(*gl
, false);
657 QueryCounterEXT query_counter_cmd
;
658 query_counter_cmd
.Init(client_id
,
663 return test
->ExecuteCmd(query_counter_cmd
);
666 static bool ProcessQuery(GLES2DecoderTestBase
* test
,
667 ::gfx::MockGLInterface
* gl
,
670 if (GL_ANY_SAMPLES_PASSED_EXT
== target
) {
672 *gl
, GetQueryObjectuiv(service_id
, GL_QUERY_RESULT_AVAILABLE_EXT
, _
))
673 .WillOnce(SetArgPointee
<2>(1))
674 .RetiresOnSaturation();
675 EXPECT_CALL(*gl
, GetQueryObjectuiv(service_id
, GL_QUERY_RESULT_EXT
, _
))
676 .WillOnce(SetArgPointee
<2>(1))
677 .RetiresOnSaturation();
678 } else if (GL_COMMANDS_COMPLETED_CHROMIUM
== target
) {
679 EXPECT_CALL(*gl
, ClientWaitSync(kGlSync
, _
, _
))
680 .WillOnce(Return(GL_ALREADY_SIGNALED
))
681 .RetiresOnSaturation();
682 EXPECT_CALL(*gl
, DeleteSync(kGlSync
)).Times(1).RetiresOnSaturation();
685 QueryManager
* query_manager
= test
->GetDecoder()->GetQueryManager();
686 EXPECT_TRUE(nullptr != query_manager
);
690 return query_manager
->ProcessPendingQueries(false);
693 static void CheckBeginEndQueryBadMemoryFails(GLES2DecoderTestBase
* test
,
696 const QueryType
& query_type
,
699 // We need to reset the decoder on each iteration, because we lose the
700 // context every time.
701 GLES2DecoderTestBase::InitState init
;
702 init
.extensions
= "GL_EXT_occlusion_query_boolean"
704 " GL_ARB_timer_query";
705 init
.gl_version
= "opengl es 3.0";
706 init
.has_alpha
= true;
707 init
.request_alpha
= true;
708 init
.bind_generates_resource
= true;
709 test
->InitDecoder(init
);
710 ::testing::StrictMock
< ::gfx::MockGLInterface
>* gl
= test
->GetGLMock();
711 ::gfx::GPUTimingFake gpu_timing_queries
;
713 ExecuteGenerateQueryCmd(test
, gl
, query_type
.type
,
714 client_id
, service_id
);
716 // Test bad shared memory fails
717 error::Error error1
= error::kNoError
;
718 error::Error error2
= error::kNoError
;
719 if (query_type
.is_counter
) {
720 error1
= ExecuteQueryCounterCmd(test
, gl
, &gpu_timing_queries
,
722 client_id
, service_id
,
723 shm_id
, shm_offset
, 1);
725 error1
= ExecuteBeginQueryCmd(test
, gl
, &gpu_timing_queries
,
727 client_id
, service_id
,
729 error2
= ExecuteEndQueryCmd(test
, gl
, query_type
.type
, 1);
732 bool process_success
= ProcessQuery(test
, gl
, query_type
.type
, service_id
);
734 EXPECT_TRUE(error1
!= error::kNoError
|| error2
!= error::kNoError
||
737 if (GL_ANY_SAMPLES_PASSED_EXT
== query_type
.type
)
738 EXPECT_CALL(*gl
, DeleteQueries(1, _
)).Times(1).RetiresOnSaturation();
739 test
->ResetDecoder();
742 TEST_P(GLES2DecoderManualInitTest
, BeginEndQueryEXTBadMemoryIdFails
) {
743 for (size_t i
= 0; i
< arraysize(kQueryTypes
); ++i
) {
744 CheckBeginEndQueryBadMemoryFails(this,
748 kInvalidSharedMemoryId
,
749 kSharedMemoryOffset
);
753 TEST_P(GLES2DecoderManualInitTest
, BeginEndQueryEXTBadMemoryOffsetFails
) {
754 for (size_t i
= 0; i
< arraysize(kQueryTypes
); ++i
) {
756 CheckBeginEndQueryBadMemoryFails(this,
761 kInvalidSharedMemoryOffset
);
763 CheckBeginEndQueryBadMemoryFails(this,
772 TEST_P(GLES2DecoderManualInitTest
, QueryReuseTest
) {
773 for (size_t i
= 0; i
< arraysize(kQueryTypes
); ++i
) {
774 const QueryType
& query_type
= kQueryTypes
[i
];
776 GLES2DecoderTestBase::InitState init
;
777 init
.extensions
= "GL_EXT_occlusion_query_boolean"
779 " GL_ARB_timer_query";
780 init
.gl_version
= "opengl es 3.0";
781 init
.has_alpha
= true;
782 init
.request_alpha
= true;
783 init
.bind_generates_resource
= true;
785 ::testing::StrictMock
< ::gfx::MockGLInterface
>* gl
= GetGLMock();
786 ::gfx::GPUTimingFake gpu_timing_queries
;
788 ExecuteGenerateQueryCmd(this, gl
, query_type
.type
,
789 kNewClientId
, kNewServiceId
);
792 if (query_type
.is_counter
) {
793 EXPECT_EQ(error::kNoError
, ExecuteQueryCounterCmd(this, gl
,
802 EXPECT_EQ(error::kNoError
, ExecuteBeginQueryCmd(this, gl
,
808 kSharedMemoryOffset
));
809 EXPECT_EQ(error::kNoError
, ExecuteEndQueryCmd(this, gl
,
810 query_type
.type
, 1));
813 EXPECT_TRUE(ProcessQuery(this, gl
, query_type
.type
, kNewServiceId
));
816 if (query_type
.is_counter
) {
817 EXPECT_EQ(error::kNoError
, ExecuteQueryCounterCmd(this, gl
,
826 EXPECT_EQ(error::kNoError
, ExecuteBeginQueryCmd(this, gl
,
832 kSharedMemoryOffset
));
833 EXPECT_EQ(error::kNoError
, ExecuteEndQueryCmd(this, gl
,
834 query_type
.type
, 2));
837 EXPECT_TRUE(ProcessQuery(this, gl
, query_type
.type
, kNewServiceId
));
839 if (GL_ANY_SAMPLES_PASSED_EXT
== query_type
.type
)
840 EXPECT_CALL(*gl
, DeleteQueries(1, _
)).Times(1).RetiresOnSaturation();
845 TEST_P(GLES2DecoderTest
, BeginEndQueryEXTCommandsIssuedCHROMIUM
) {
846 BeginQueryEXT begin_cmd
;
848 GenHelper
<GenQueriesEXTImmediate
>(kNewClientId
);
850 // Test valid parameters work.
851 begin_cmd
.Init(GL_COMMANDS_ISSUED_CHROMIUM
,
854 kSharedMemoryOffset
);
855 EXPECT_EQ(error::kNoError
, ExecuteCmd(begin_cmd
));
856 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
858 QueryManager
* query_manager
= decoder_
->GetQueryManager();
859 ASSERT_TRUE(query_manager
!= NULL
);
860 QueryManager::Query
* query
= query_manager
->GetQuery(kNewClientId
);
861 ASSERT_TRUE(query
!= NULL
);
862 EXPECT_FALSE(query
->IsPending());
866 end_cmd
.Init(GL_COMMANDS_ISSUED_CHROMIUM
, 1);
867 EXPECT_EQ(error::kNoError
, ExecuteCmd(end_cmd
));
868 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
869 EXPECT_FALSE(query
->IsPending());
872 TEST_P(GLES2DecoderTest
, BeginEndQueryEXTGetErrorQueryCHROMIUM
) {
873 BeginQueryEXT begin_cmd
;
875 GenHelper
<GenQueriesEXTImmediate
>(kNewClientId
);
877 // Test valid parameters work.
878 begin_cmd
.Init(GL_GET_ERROR_QUERY_CHROMIUM
,
881 kSharedMemoryOffset
);
882 EXPECT_EQ(error::kNoError
, ExecuteCmd(begin_cmd
));
883 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
885 QueryManager
* query_manager
= decoder_
->GetQueryManager();
886 ASSERT_TRUE(query_manager
!= NULL
);
887 QueryManager::Query
* query
= query_manager
->GetQuery(kNewClientId
);
888 ASSERT_TRUE(query
!= NULL
);
889 EXPECT_FALSE(query
->IsPending());
892 QuerySync
* sync
= static_cast<QuerySync
*>(shared_memory_address_
);
894 EXPECT_CALL(*gl_
, GetError())
895 .WillOnce(Return(GL_INVALID_VALUE
))
896 .RetiresOnSaturation();
899 end_cmd
.Init(GL_GET_ERROR_QUERY_CHROMIUM
, 1);
900 EXPECT_EQ(error::kNoError
, ExecuteCmd(end_cmd
));
901 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
902 EXPECT_FALSE(query
->IsPending());
903 EXPECT_EQ(static_cast<GLenum
>(GL_INVALID_VALUE
),
904 static_cast<GLenum
>(sync
->result
));
907 TEST_P(GLES2DecoderManualInitTest
, BeginEndQueryEXTCommandsCompletedCHROMIUM
) {
909 init
.extensions
= "GL_EXT_occlusion_query_boolean GL_ARB_sync";
910 init
.gl_version
= "opengl es 2.0";
911 init
.has_alpha
= true;
912 init
.request_alpha
= true;
913 init
.bind_generates_resource
= true;
916 GenHelper
<GenQueriesEXTImmediate
>(kNewClientId
);
918 BeginQueryEXT begin_cmd
;
919 begin_cmd
.Init(GL_COMMANDS_COMPLETED_CHROMIUM
,
922 kSharedMemoryOffset
);
923 EXPECT_EQ(error::kNoError
, ExecuteCmd(begin_cmd
));
924 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
926 QueryManager
* query_manager
= decoder_
->GetQueryManager();
927 ASSERT_TRUE(query_manager
!= NULL
);
928 QueryManager::Query
* query
= query_manager
->GetQuery(kNewClientId
);
929 ASSERT_TRUE(query
!= NULL
);
930 EXPECT_FALSE(query
->IsPending());
932 EXPECT_CALL(*gl_
, Flush()).RetiresOnSaturation();
933 EXPECT_CALL(*gl_
, FenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE
, 0))
934 .WillOnce(Return(kGlSync
))
935 .RetiresOnSaturation();
937 EXPECT_CALL(*gl_
, IsSync(kGlSync
))
938 .WillOnce(Return(GL_TRUE
))
939 .RetiresOnSaturation();
943 end_cmd
.Init(GL_COMMANDS_COMPLETED_CHROMIUM
, 1);
944 EXPECT_EQ(error::kNoError
, ExecuteCmd(end_cmd
));
945 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
946 EXPECT_TRUE(query
->IsPending());
949 EXPECT_CALL(*gl_
, IsSync(kGlSync
))
950 .WillOnce(Return(GL_TRUE
))
951 .RetiresOnSaturation();
953 EXPECT_CALL(*gl_
, ClientWaitSync(kGlSync
, _
, _
))
954 .WillOnce(Return(GL_TIMEOUT_EXPIRED
))
955 .RetiresOnSaturation();
956 bool process_success
= query_manager
->ProcessPendingQueries(false);
958 EXPECT_TRUE(process_success
);
959 EXPECT_TRUE(query
->IsPending());
962 EXPECT_CALL(*gl_
, IsSync(kGlSync
))
963 .WillOnce(Return(GL_TRUE
))
964 .RetiresOnSaturation();
966 EXPECT_CALL(*gl_
, ClientWaitSync(kGlSync
, _
, _
))
967 .WillOnce(Return(GL_ALREADY_SIGNALED
))
968 .RetiresOnSaturation();
969 process_success
= query_manager
->ProcessPendingQueries(false);
971 EXPECT_TRUE(process_success
);
972 EXPECT_FALSE(query
->IsPending());
975 EXPECT_CALL(*gl_
, IsSync(kGlSync
))
976 .WillOnce(Return(GL_TRUE
))
977 .RetiresOnSaturation();
979 EXPECT_CALL(*gl_
, DeleteSync(kGlSync
)).Times(1).RetiresOnSaturation();
983 TEST_P(GLES2DecoderManualInitTest
, BeginInvalidTargetQueryFails
) {
985 init
.extensions
= "";
986 init
.gl_version
= "opengl es 2.0";
987 init
.has_alpha
= true;
988 init
.request_alpha
= true;
989 init
.bind_generates_resource
= true;
992 GenHelper
<GenQueriesEXTImmediate
>(kNewClientId
);
994 BeginQueryEXT begin_cmd
;
995 begin_cmd
.Init(GL_COMMANDS_COMPLETED_CHROMIUM
,
998 kSharedMemoryOffset
);
999 EXPECT_EQ(error::kNoError
, ExecuteCmd(begin_cmd
));
1000 EXPECT_EQ(GL_INVALID_OPERATION
, GetGLError());
1002 begin_cmd
.Init(GL_ANY_SAMPLES_PASSED
,
1005 kSharedMemoryOffset
);
1006 EXPECT_EQ(error::kNoError
, ExecuteCmd(begin_cmd
));
1007 EXPECT_EQ(GL_INVALID_OPERATION
, GetGLError());
1009 begin_cmd
.Init(GL_ANY_SAMPLES_PASSED_CONSERVATIVE
,
1012 kSharedMemoryOffset
);
1013 EXPECT_EQ(error::kNoError
, ExecuteCmd(begin_cmd
));
1014 EXPECT_EQ(GL_INVALID_OPERATION
, GetGLError());
1016 begin_cmd
.Init(GL_TIME_ELAPSED
,
1019 kSharedMemoryOffset
);
1020 EXPECT_EQ(error::kNoError
, ExecuteCmd(begin_cmd
));
1021 EXPECT_EQ(GL_INVALID_OPERATION
, GetGLError());
1023 begin_cmd
.Init(0xdeadbeef,
1026 kSharedMemoryOffset
);
1027 EXPECT_EQ(error::kNoError
, ExecuteCmd(begin_cmd
));
1028 EXPECT_EQ(GL_INVALID_ENUM
, GetGLError());
1031 TEST_P(GLES2DecoderManualInitTest
, QueryCounterEXTTimeStamp
) {
1033 init
.extensions
= "GL_ARB_timer_query";
1034 init
.gl_version
= "opengl 2.0";
1035 init
.has_alpha
= true;
1036 init
.request_alpha
= true;
1037 init
.bind_generates_resource
= true;
1040 GenHelper
<GenQueriesEXTImmediate
>(kNewClientId
);
1042 EXPECT_CALL(*gl_
, GenQueries(1, _
))
1043 .WillOnce(SetArgPointee
<1>(kNewServiceId
))
1044 .RetiresOnSaturation();
1045 EXPECT_CALL(*gl_
, QueryCounter(kNewServiceId
, GL_TIMESTAMP
))
1047 .RetiresOnSaturation();
1048 QueryCounterEXT query_counter_cmd
;
1049 query_counter_cmd
.Init(kNewClientId
,
1052 kSharedMemoryOffset
,
1054 EXPECT_EQ(error::kNoError
, ExecuteCmd(query_counter_cmd
));
1055 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
1057 QueryManager
* query_manager
= decoder_
->GetQueryManager();
1058 ASSERT_TRUE(query_manager
!= NULL
);
1059 QueryManager::Query
* query
= query_manager
->GetQuery(kNewClientId
);
1060 ASSERT_TRUE(query
!= NULL
);
1061 EXPECT_TRUE(query
->IsPending());
1064 TEST_P(GLES2DecoderManualInitTest
, InvalidTargetQueryCounterFails
) {
1066 init
.extensions
= "";
1067 init
.gl_version
= "opengl es 2.0";
1068 init
.has_alpha
= true;
1069 init
.request_alpha
= true;
1070 init
.bind_generates_resource
= true;
1073 GenHelper
<GenQueriesEXTImmediate
>(kNewClientId
);
1075 QueryCounterEXT query_counter_cmd
;
1076 query_counter_cmd
.Init(kNewClientId
,
1079 kSharedMemoryOffset
,
1081 EXPECT_EQ(error::kNoError
, ExecuteCmd(query_counter_cmd
));
1082 EXPECT_EQ(GL_INVALID_OPERATION
, GetGLError());
1084 query_counter_cmd
.Init(kNewClientId
,
1087 kSharedMemoryOffset
,
1089 EXPECT_EQ(error::kNoError
, ExecuteCmd(query_counter_cmd
));
1090 EXPECT_EQ(GL_INVALID_ENUM
, GetGLError());
1093 TEST_P(GLES2DecoderTest
, IsEnabledReturnsCachedValue
) {
1094 // NOTE: There are no expectations because no GL functions should be
1095 // called for DEPTH_TEST or STENCIL_TEST
1096 static const GLenum kStates
[] = {
1097 GL_DEPTH_TEST
, GL_STENCIL_TEST
,
1099 for (size_t ii
= 0; ii
< arraysize(kStates
); ++ii
) {
1101 GLenum state
= kStates
[ii
];
1102 enable_cmd
.Init(state
);
1103 EXPECT_EQ(error::kNoError
, ExecuteCmd(enable_cmd
));
1104 IsEnabled::Result
* result
=
1105 static_cast<IsEnabled::Result
*>(shared_memory_address_
);
1106 IsEnabled is_enabled_cmd
;
1107 is_enabled_cmd
.Init(state
, shared_memory_id_
, shared_memory_offset_
);
1108 EXPECT_EQ(error::kNoError
, ExecuteCmd(is_enabled_cmd
));
1109 EXPECT_NE(0u, *result
);
1110 Disable disable_cmd
;
1111 disable_cmd
.Init(state
);
1112 EXPECT_EQ(error::kNoError
, ExecuteCmd(disable_cmd
));
1113 EXPECT_EQ(error::kNoError
, ExecuteCmd(is_enabled_cmd
));
1114 EXPECT_EQ(0u, *result
);
1118 TEST_P(GLES2DecoderManualInitTest
, GpuMemoryManagerCHROMIUM
) {
1120 init
.extensions
= "GL_ARB_texture_rectangle";
1121 init
.bind_generates_resource
= true;
1124 Texture
* texture
= GetTexture(client_texture_id_
)->texture();
1125 EXPECT_TRUE(texture
!= NULL
);
1126 EXPECT_TRUE(texture
->pool() == GL_TEXTURE_POOL_UNMANAGED_CHROMIUM
);
1128 DoBindTexture(GL_TEXTURE_2D
, client_texture_id_
, kServiceTextureId
);
1131 cmd
.Init(GL_TEXTURE_2D
,
1132 GL_TEXTURE_POOL_CHROMIUM
,
1133 GL_TEXTURE_POOL_UNMANAGED_CHROMIUM
);
1134 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
1135 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
1137 cmd
.Init(GL_TEXTURE_2D
,
1138 GL_TEXTURE_POOL_CHROMIUM
,
1139 GL_TEXTURE_POOL_MANAGED_CHROMIUM
);
1140 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
1141 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
1143 EXPECT_TRUE(texture
->pool() == GL_TEXTURE_POOL_MANAGED_CHROMIUM
);
1145 cmd
.Init(GL_TEXTURE_2D
, GL_TEXTURE_POOL_CHROMIUM
, GL_NONE
);
1146 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
1147 EXPECT_EQ(GL_INVALID_ENUM
, GetGLError());
1152 class SizeOnlyMemoryTracker
: public MemoryTracker
{
1154 SizeOnlyMemoryTracker() {
1155 // These are the default textures. 1 for TEXTURE_2D and 6 faces for
1156 // TEXTURE_CUBE_MAP.
1157 const size_t kInitialUnmanagedPoolSize
= 7 * 4;
1158 const size_t kInitialManagedPoolSize
= 0;
1159 pool_infos_
[MemoryTracker::kUnmanaged
].initial_size
=
1160 kInitialUnmanagedPoolSize
;
1161 pool_infos_
[MemoryTracker::kManaged
].initial_size
= kInitialManagedPoolSize
;
1164 // Ensure a certain amount of GPU memory is free. Returns true on success.
1165 MOCK_METHOD1(EnsureGPUMemoryAvailable
, bool(size_t size_needed
));
1167 virtual void TrackMemoryAllocatedChange(size_t old_size
,
1170 PoolInfo
& info
= pool_infos_
[pool
];
1171 info
.size
+= new_size
- old_size
;
1174 size_t GetPoolSize(Pool pool
) {
1175 const PoolInfo
& info
= pool_infos_
[pool
];
1176 return info
.size
- info
.initial_size
;
1179 uint64_t ClientTracingId() const override
{ return 0; }
1180 int ClientId() const override
{ return 0; }
1183 virtual ~SizeOnlyMemoryTracker() {}
1185 PoolInfo() : initial_size(0), size(0) {}
1186 size_t initial_size
;
1189 std::map
<Pool
, PoolInfo
> pool_infos_
;
1192 } // anonymous namespace.
1194 TEST_P(GLES2DecoderManualInitTest
, MemoryTrackerInitialSize
) {
1195 scoped_refptr
<SizeOnlyMemoryTracker
> memory_tracker
=
1196 new SizeOnlyMemoryTracker();
1197 set_memory_tracker(memory_tracker
.get());
1199 init
.bind_generates_resource
= true;
1201 // Expect that initial size - size is 0.
1202 EXPECT_EQ(0u, memory_tracker
->GetPoolSize(MemoryTracker::kUnmanaged
));
1203 EXPECT_EQ(0u, memory_tracker
->GetPoolSize(MemoryTracker::kManaged
));
1206 TEST_P(GLES2DecoderManualInitTest
, MemoryTrackerTexImage2D
) {
1207 scoped_refptr
<SizeOnlyMemoryTracker
> memory_tracker
=
1208 new SizeOnlyMemoryTracker();
1209 set_memory_tracker(memory_tracker
.get());
1211 init
.bind_generates_resource
= true;
1213 DoBindTexture(GL_TEXTURE_2D
, client_texture_id_
, kServiceTextureId
);
1214 EXPECT_CALL(*memory_tracker
.get(), EnsureGPUMemoryAvailable(128))
1215 .WillOnce(Return(true))
1216 .RetiresOnSaturation();
1217 DoTexImage2D(GL_TEXTURE_2D
,
1226 kSharedMemoryOffset
);
1227 EXPECT_EQ(128u, memory_tracker
->GetPoolSize(MemoryTracker::kUnmanaged
));
1228 EXPECT_CALL(*memory_tracker
.get(), EnsureGPUMemoryAvailable(64))
1229 .WillOnce(Return(true))
1230 .RetiresOnSaturation();
1231 DoTexImage2D(GL_TEXTURE_2D
,
1240 kSharedMemoryOffset
);
1241 EXPECT_EQ(64u, memory_tracker
->GetPoolSize(MemoryTracker::kUnmanaged
));
1242 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
1243 // Check we get out of memory and no call to glTexImage2D if Ensure fails.
1244 EXPECT_CALL(*memory_tracker
.get(), EnsureGPUMemoryAvailable(64))
1245 .WillOnce(Return(false))
1246 .RetiresOnSaturation();
1248 cmd
.Init(GL_TEXTURE_2D
,
1256 kSharedMemoryOffset
);
1257 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
1258 EXPECT_EQ(GL_OUT_OF_MEMORY
, GetGLError());
1259 EXPECT_EQ(64u, memory_tracker
->GetPoolSize(MemoryTracker::kUnmanaged
));
1262 TEST_P(GLES2DecoderManualInitTest
, MemoryTrackerTexStorage2DEXT
) {
1263 scoped_refptr
<SizeOnlyMemoryTracker
> memory_tracker
=
1264 new SizeOnlyMemoryTracker();
1265 set_memory_tracker(memory_tracker
.get());
1267 init
.bind_generates_resource
= true;
1269 DoBindTexture(GL_TEXTURE_2D
, client_texture_id_
, kServiceTextureId
);
1270 // Check we get out of memory and no call to glTexStorage2DEXT
1272 EXPECT_CALL(*memory_tracker
.get(), EnsureGPUMemoryAvailable(128))
1273 .WillOnce(Return(false))
1274 .RetiresOnSaturation();
1275 TexStorage2DEXT cmd
;
1276 cmd
.Init(GL_TEXTURE_2D
, 1, GL_RGBA8
, 8, 4);
1277 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
1278 EXPECT_EQ(0u, memory_tracker
->GetPoolSize(MemoryTracker::kUnmanaged
));
1279 EXPECT_EQ(GL_OUT_OF_MEMORY
, GetGLError());
1282 TEST_P(GLES2DecoderManualInitTest
, MemoryTrackerCopyTexImage2D
) {
1283 GLenum target
= GL_TEXTURE_2D
;
1285 GLenum internal_format
= GL_RGBA
;
1289 scoped_refptr
<SizeOnlyMemoryTracker
> memory_tracker
=
1290 new SizeOnlyMemoryTracker();
1291 set_memory_tracker(memory_tracker
.get());
1293 init
.has_alpha
= true;
1294 init
.request_alpha
= true;
1295 init
.bind_generates_resource
= true;
1297 DoBindTexture(GL_TEXTURE_2D
, client_texture_id_
, kServiceTextureId
);
1298 EXPECT_CALL(*memory_tracker
.get(), EnsureGPUMemoryAvailable(128))
1299 .WillOnce(Return(true))
1300 .RetiresOnSaturation();
1301 EXPECT_CALL(*gl_
, GetError())
1302 .WillOnce(Return(GL_NO_ERROR
))
1303 .WillOnce(Return(GL_NO_ERROR
))
1304 .RetiresOnSaturation();
1307 target
, level
, internal_format
, 0, 0, width
, height
, border
))
1309 .RetiresOnSaturation();
1311 cmd
.Init(target
, level
, internal_format
, 0, 0, width
, height
);
1312 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
1313 EXPECT_EQ(128u, memory_tracker
->GetPoolSize(MemoryTracker::kUnmanaged
));
1314 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
1315 // Check we get out of memory and no call to glCopyTexImage2D if Ensure fails.
1316 EXPECT_CALL(*memory_tracker
.get(), EnsureGPUMemoryAvailable(128))
1317 .WillOnce(Return(false))
1318 .RetiresOnSaturation();
1319 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
1320 EXPECT_EQ(GL_OUT_OF_MEMORY
, GetGLError());
1321 EXPECT_EQ(128u, memory_tracker
->GetPoolSize(MemoryTracker::kUnmanaged
));
1324 TEST_P(GLES2DecoderManualInitTest
, MemoryTrackerRenderbufferStorage
) {
1325 scoped_refptr
<SizeOnlyMemoryTracker
> memory_tracker
=
1326 new SizeOnlyMemoryTracker();
1327 set_memory_tracker(memory_tracker
.get());
1329 init
.bind_generates_resource
= true;
1332 GL_RENDERBUFFER
, client_renderbuffer_id_
, kServiceRenderbufferId
);
1333 EnsureRenderbufferBound(false);
1334 EXPECT_CALL(*gl_
, GetError())
1335 .WillOnce(Return(GL_NO_ERROR
))
1336 .WillOnce(Return(GL_NO_ERROR
))
1337 .RetiresOnSaturation();
1338 EXPECT_CALL(*memory_tracker
.get(), EnsureGPUMemoryAvailable(128))
1339 .WillOnce(Return(true))
1340 .RetiresOnSaturation();
1341 EXPECT_CALL(*gl_
, RenderbufferStorageEXT(GL_RENDERBUFFER
, GL_RGBA
, 8, 4))
1343 .RetiresOnSaturation();
1344 RenderbufferStorage cmd
;
1345 cmd
.Init(GL_RENDERBUFFER
, GL_RGBA4
, 8, 4);
1346 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
1347 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
1348 EXPECT_EQ(128u, memory_tracker
->GetPoolSize(MemoryTracker::kUnmanaged
));
1349 // Check we get out of memory and no call to glRenderbufferStorage if Ensure
1351 EXPECT_CALL(*memory_tracker
.get(), EnsureGPUMemoryAvailable(128))
1352 .WillOnce(Return(false))
1353 .RetiresOnSaturation();
1354 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
1355 EXPECT_EQ(GL_OUT_OF_MEMORY
, GetGLError());
1356 EXPECT_EQ(128u, memory_tracker
->GetPoolSize(MemoryTracker::kUnmanaged
));
1359 TEST_P(GLES2DecoderManualInitTest
, MemoryTrackerBufferData
) {
1360 scoped_refptr
<SizeOnlyMemoryTracker
> memory_tracker
=
1361 new SizeOnlyMemoryTracker();
1362 set_memory_tracker(memory_tracker
.get());
1364 init
.bind_generates_resource
= true;
1366 DoBindBuffer(GL_ARRAY_BUFFER
, client_buffer_id_
, kServiceBufferId
);
1367 EXPECT_CALL(*gl_
, GetError())
1368 .WillOnce(Return(GL_NO_ERROR
))
1369 .WillOnce(Return(GL_NO_ERROR
))
1370 .RetiresOnSaturation();
1371 EXPECT_CALL(*memory_tracker
.get(), EnsureGPUMemoryAvailable(128))
1372 .WillOnce(Return(true))
1373 .RetiresOnSaturation();
1374 EXPECT_CALL(*gl_
, BufferData(GL_ARRAY_BUFFER
, 128, _
, GL_STREAM_DRAW
))
1376 .RetiresOnSaturation();
1378 cmd
.Init(GL_ARRAY_BUFFER
, 128, 0, 0, GL_STREAM_DRAW
);
1379 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
1380 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
1381 EXPECT_EQ(128u, memory_tracker
->GetPoolSize(MemoryTracker::kManaged
));
1382 // Check we get out of memory and no call to glBufferData if Ensure
1384 EXPECT_CALL(*memory_tracker
.get(), EnsureGPUMemoryAvailable(128))
1385 .WillOnce(Return(false))
1386 .RetiresOnSaturation();
1387 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
1388 EXPECT_EQ(GL_OUT_OF_MEMORY
, GetGLError());
1389 EXPECT_EQ(128u, memory_tracker
->GetPoolSize(MemoryTracker::kManaged
));
1392 TEST_P(GLES2DecoderManualInitTest
, ImmutableCopyTexImage2D
) {
1393 const GLenum kTarget
= GL_TEXTURE_2D
;
1394 const GLint kLevel
= 0;
1395 const GLenum kInternalFormat
= GL_RGBA
;
1396 const GLenum kSizedInternalFormat
= GL_RGBA8
;
1397 const GLsizei kWidth
= 4;
1398 const GLsizei kHeight
= 8;
1399 const GLint kBorder
= 0;
1401 init
.extensions
= "GL_EXT_texture_storage";
1402 init
.has_alpha
= true;
1403 init
.request_alpha
= true;
1404 init
.bind_generates_resource
= true;
1406 DoBindTexture(GL_TEXTURE_2D
, client_texture_id_
, kServiceTextureId
);
1408 // CopyTexImage2D will call arbitrary amount of GetErrors.
1409 EXPECT_CALL(*gl_
, GetError())
1414 kTarget
, kLevel
, kInternalFormat
, 0, 0, kWidth
, kHeight
,
1420 kTarget
, kLevel
, kSizedInternalFormat
, kWidth
, kHeight
))
1422 CopyTexImage2D copy_cmd
;
1423 copy_cmd
.Init(kTarget
, kLevel
, kInternalFormat
, 0, 0, kWidth
, kHeight
);
1424 EXPECT_EQ(error::kNoError
, ExecuteCmd(copy_cmd
));
1425 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
1427 TexStorage2DEXT storage_cmd
;
1428 storage_cmd
.Init(kTarget
, kLevel
, kSizedInternalFormat
, kWidth
, kHeight
);
1429 EXPECT_EQ(error::kNoError
, ExecuteCmd(storage_cmd
));
1430 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
1432 // This should not invoke CopyTexImage2D.
1433 copy_cmd
.Init(kTarget
, kLevel
, kInternalFormat
, 0, 0, kWidth
, kHeight
);
1434 EXPECT_EQ(error::kNoError
, ExecuteCmd(copy_cmd
));
1435 EXPECT_EQ(GL_INVALID_OPERATION
, GetGLError());
1438 TEST_P(GLES2DecoderTest
, LoseContextCHROMIUMGuilty
) {
1439 EXPECT_CALL(*mock_decoder_
, MarkContextLost(error::kInnocent
))
1441 cmds::LoseContextCHROMIUM cmd
;
1442 cmd
.Init(GL_GUILTY_CONTEXT_RESET_ARB
, GL_INNOCENT_CONTEXT_RESET_ARB
);
1443 EXPECT_EQ(error::kLostContext
, ExecuteCmd(cmd
));
1444 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
1445 EXPECT_TRUE(decoder_
->WasContextLost());
1446 EXPECT_TRUE(decoder_
->WasContextLostByRobustnessExtension());
1449 TEST_P(GLES2DecoderTest
, LoseContextCHROMIUMUnkown
) {
1450 EXPECT_CALL(*mock_decoder_
, MarkContextLost(error::kUnknown
))
1452 cmds::LoseContextCHROMIUM cmd
;
1453 cmd
.Init(GL_UNKNOWN_CONTEXT_RESET_ARB
, GL_UNKNOWN_CONTEXT_RESET_ARB
);
1454 EXPECT_EQ(error::kLostContext
, ExecuteCmd(cmd
));
1455 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
1456 EXPECT_TRUE(decoder_
->WasContextLost());
1457 EXPECT_TRUE(decoder_
->WasContextLostByRobustnessExtension());
1460 TEST_P(GLES2DecoderTest
, LoseContextCHROMIUMInvalidArgs0_0
) {
1461 EXPECT_CALL(*mock_decoder_
, MarkContextLost(_
))
1463 cmds::LoseContextCHROMIUM cmd
;
1464 cmd
.Init(GL_NONE
, GL_GUILTY_CONTEXT_RESET_ARB
);
1465 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
1466 EXPECT_EQ(GL_INVALID_ENUM
, GetGLError());
1469 TEST_P(GLES2DecoderTest
, LoseContextCHROMIUMInvalidArgs1_0
) {
1470 EXPECT_CALL(*mock_decoder_
, MarkContextLost(_
))
1472 cmds::LoseContextCHROMIUM cmd
;
1473 cmd
.Init(GL_GUILTY_CONTEXT_RESET_ARB
, GL_NONE
);
1474 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
1475 EXPECT_EQ(GL_INVALID_ENUM
, GetGLError());
1478 class GLES2DecoderDoCommandsTest
: public GLES2DecoderTest
{
1480 GLES2DecoderDoCommandsTest() {
1481 for (int i
= 0; i
< 3; i
++) {
1482 cmds_
[i
].Init(GL_BLEND
);
1484 entries_per_cmd_
= ComputeNumEntries(cmds_
[0].ComputeSize());
1487 void SetExpectationsForNCommands(int num_commands
) {
1488 for (int i
= 0; i
< num_commands
; i
++)
1489 SetupExpectationsForEnableDisable(GL_BLEND
, true);
1494 int entries_per_cmd_
;
1497 // Test that processing with 0 entries does nothing.
1498 TEST_P(GLES2DecoderDoCommandsTest
, DoCommandsOneOfZero
) {
1499 int num_processed
= -1;
1500 SetExpectationsForNCommands(0);
1503 decoder_
->DoCommands(1, &cmds_
, entries_per_cmd_
* 0, &num_processed
));
1504 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
1505 EXPECT_EQ(0, num_processed
);
1508 // Test processing at granularity of single commands.
1509 TEST_P(GLES2DecoderDoCommandsTest
, DoCommandsOneOfOne
) {
1510 int num_processed
= -1;
1511 SetExpectationsForNCommands(1);
1514 decoder_
->DoCommands(1, &cmds_
, entries_per_cmd_
* 1, &num_processed
));
1515 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
1516 EXPECT_EQ(entries_per_cmd_
, num_processed
);
1519 // Test processing at granularity of multiple commands.
1520 TEST_P(GLES2DecoderDoCommandsTest
, DoCommandsThreeOfThree
) {
1521 int num_processed
= -1;
1522 SetExpectationsForNCommands(3);
1525 decoder_
->DoCommands(3, &cmds_
, entries_per_cmd_
* 3, &num_processed
));
1526 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
1527 EXPECT_EQ(entries_per_cmd_
* 3, num_processed
);
1530 // Test processing a request smaller than available entries.
1531 TEST_P(GLES2DecoderDoCommandsTest
, DoCommandsTwoOfThree
) {
1532 int num_processed
= -1;
1533 SetExpectationsForNCommands(2);
1536 decoder_
->DoCommands(2, &cmds_
, entries_per_cmd_
* 3, &num_processed
));
1537 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
1538 EXPECT_EQ(entries_per_cmd_
* 2, num_processed
);
1541 // Test that processing stops on a command with size 0.
1542 TEST_P(GLES2DecoderDoCommandsTest
, DoCommandsZeroCmdSize
) {
1543 cmds_
[1].header
.size
= 0;
1544 int num_processed
= -1;
1545 SetExpectationsForNCommands(1);
1547 error::kInvalidSize
,
1548 decoder_
->DoCommands(2, &cmds_
, entries_per_cmd_
* 2, &num_processed
));
1549 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
1550 EXPECT_EQ(entries_per_cmd_
, num_processed
);
1553 // Test that processing stops on a command with size greater than available.
1554 TEST_P(GLES2DecoderDoCommandsTest
, DoCommandsOutOfBounds
) {
1555 int num_processed
= -1;
1556 SetExpectationsForNCommands(1);
1557 EXPECT_EQ(error::kOutOfBounds
,
1558 decoder_
->DoCommands(
1559 2, &cmds_
, entries_per_cmd_
* 2 - 1, &num_processed
));
1560 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
1561 EXPECT_EQ(entries_per_cmd_
, num_processed
);
1564 // Test that commands with bad argument size are skipped without processing.
1565 TEST_P(GLES2DecoderDoCommandsTest
, DoCommandsBadArgSize
) {
1566 cmds_
[1].header
.size
+= 1;
1567 int num_processed
= -1;
1568 SetExpectationsForNCommands(1);
1569 EXPECT_EQ(error::kInvalidArguments
,
1570 decoder_
->DoCommands(
1571 2, &cmds_
, entries_per_cmd_
* 2 + 1, &num_processed
));
1572 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
1573 EXPECT_EQ(entries_per_cmd_
+ cmds_
[1].header
.size
, num_processed
);
1576 INSTANTIATE_TEST_CASE_P(Service
, GLES2DecoderTest
, ::testing::Bool());
1578 INSTANTIATE_TEST_CASE_P(Service
, GLES2DecoderWithShaderTest
, ::testing::Bool());
1580 INSTANTIATE_TEST_CASE_P(Service
, GLES2DecoderManualInitTest
, ::testing::Bool());
1582 INSTANTIATE_TEST_CASE_P(Service
,
1583 GLES2DecoderRGBBackbufferTest
,
1586 INSTANTIATE_TEST_CASE_P(Service
, GLES2DecoderDoCommandsTest
, ::testing::Bool());
1588 INSTANTIATE_TEST_CASE_P(Service
, GLES3DecoderTest
, ::testing::Bool());
1590 } // namespace gles2