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/cmd_buffer_engine.h"
12 #include "gpu/command_buffer/service/context_group.h"
13 #include "gpu/command_buffer/service/context_state.h"
14 #include "gpu/command_buffer/service/gl_surface_mock.h"
15 #include "gpu/command_buffer/service/gles2_cmd_decoder.h"
16 #include "gpu/command_buffer/service/image_manager.h"
17 #include "gpu/command_buffer/service/mailbox_manager.h"
18 #include "gpu/command_buffer/service/mocks.h"
19 #include "gpu/command_buffer/service/program_manager.h"
20 #include "gpu/command_buffer/service/test_helper.h"
21 #include "gpu/config/gpu_switches.h"
22 #include "testing/gtest/include/gtest/gtest.h"
23 #include "ui/gl/gl_implementation.h"
24 #include "ui/gl/gl_mock.h"
25 #include "ui/gl/gl_surface_stub.h"
26 #include "ui/gl/gpu_timing_fake.h"
29 #if !defined(GL_DEPTH24_STENCIL8)
30 #define GL_DEPTH24_STENCIL8 0x88F0
33 using ::gfx::MockGLInterface
;
35 using ::testing::AtLeast
;
36 using ::testing::DoAll
;
37 using ::testing::InSequence
;
38 using ::testing::Invoke
;
39 using ::testing::MatcherCast
;
40 using ::testing::Mock
;
41 using ::testing::Pointee
;
42 using ::testing::Return
;
43 using ::testing::SaveArg
;
44 using ::testing::SetArrayArgument
;
45 using ::testing::SetArgPointee
;
46 using ::testing::StrEq
;
47 using ::testing::StrictMock
;
54 void GLES2DecoderRGBBackbufferTest::SetUp() {
55 // Test codepath with workaround clear_alpha_in_readpixels because
56 // ReadPixelsEmulator emulates the incorrect driver behavior.
57 base::CommandLine
command_line(0, NULL
);
58 command_line
.AppendSwitchASCII(
59 switches::kGpuDriverBugWorkarounds
,
60 base::IntToString(gpu::CLEAR_ALPHA_IN_READPIXELS
));
62 init
.bind_generates_resource
= true;
63 InitDecoderWithCommandLine(init
, &command_line
);
64 SetupDefaultProgram();
67 // Override default setup so nothing gets setup.
68 void GLES2DecoderManualInitTest::SetUp() {
71 void GLES2DecoderManualInitTest::EnableDisableTest(GLenum cap
,
75 SetupExpectationsForEnableDisable(cap
, enable
);
80 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
81 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
85 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
86 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
90 void GLES3DecoderTest::SetUp() {
91 base::CommandLine
command_line(0, NULL
);
92 command_line
.AppendSwitch(switches::kEnableUnsafeES3APIs
);
94 init
.gl_version
= "OpenGL ES 3.0";
95 init
.bind_generates_resource
= true;
96 init
.webgl_version
= 2;
97 InitDecoderWithCommandLine(init
, &command_line
);
101 TEST_P(GLES3DecoderTest
, Basic
) {
102 // Make sure the setup is correct for ES3.
103 EXPECT_TRUE(decoder_
->unsafe_es3_apis_enabled());
104 EXPECT_TRUE(feature_info()->validators()->texture_bind_target
.IsValid(
108 TEST_P(GLES2DecoderTest
, GetIntegervCached
) {
115 GL_MAX_TEXTURE_SIZE
, TestHelper::kMaxTextureSize
,
118 GL_MAX_CUBE_MAP_TEXTURE_SIZE
, TestHelper::kMaxCubeMapTextureSize
,
121 GL_MAX_RENDERBUFFER_SIZE
, TestHelper::kMaxRenderbufferSize
,
124 typedef GetIntegerv::Result Result
;
125 for (size_t ii
= 0; ii
< sizeof(tests
) / sizeof(tests
[0]); ++ii
) {
126 const TestInfo
& test
= tests
[ii
];
127 Result
* result
= static_cast<Result
*>(shared_memory_address_
);
128 EXPECT_CALL(*gl_
, GetError())
129 .WillOnce(Return(GL_NO_ERROR
))
130 .WillOnce(Return(GL_NO_ERROR
))
131 .RetiresOnSaturation();
132 EXPECT_CALL(*gl_
, GetIntegerv(test
.pname
, _
)).Times(0);
135 cmd2
.Init(test
.pname
, shared_memory_id_
, shared_memory_offset_
);
136 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd2
));
137 EXPECT_EQ(decoder_
->GetGLES2Util()->GLGetNumValuesReturned(test
.pname
),
138 result
->GetNumResults());
139 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
140 EXPECT_EQ(test
.expected
, result
->GetData()[0]);
144 TEST_P(GLES2DecoderWithShaderTest
, GetMaxValueInBufferCHROMIUM
) {
146 GetMaxValueInBufferCHROMIUM::Result
* result
=
147 static_cast<GetMaxValueInBufferCHROMIUM::Result
*>(shared_memory_address_
);
150 GetMaxValueInBufferCHROMIUM cmd
;
151 cmd
.Init(client_element_buffer_id_
,
152 kValidIndexRangeCount
,
154 kValidIndexRangeStart
* 2,
156 kSharedMemoryOffset
);
157 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
158 EXPECT_EQ(7u, *result
);
159 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
160 cmd
.Init(client_element_buffer_id_
,
161 kValidIndexRangeCount
+ 1,
163 kValidIndexRangeStart
* 2,
165 kSharedMemoryOffset
);
166 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
167 EXPECT_EQ(100u, *result
);
168 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
170 cmd
.Init(kInvalidClientId
,
171 kValidIndexRangeCount
,
173 kValidIndexRangeStart
* 2,
175 kSharedMemoryOffset
);
176 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
177 EXPECT_EQ(GL_INVALID_VALUE
, GetGLError());
178 cmd
.Init(client_element_buffer_id_
,
179 kOutOfRangeIndexRangeEnd
,
181 kValidIndexRangeStart
* 2,
183 kSharedMemoryOffset
);
184 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
185 EXPECT_EQ(GL_INVALID_OPERATION
, GetGLError());
186 cmd
.Init(client_element_buffer_id_
,
187 kValidIndexRangeCount
+ 1,
189 kOutOfRangeIndexRangeEnd
* 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,
199 kSharedMemoryOffset
);
200 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
201 cmd
.Init(client_buffer_id_
,
202 kValidIndexRangeCount
+ 1,
204 kValidIndexRangeStart
* 2,
206 kSharedMemoryOffset
);
207 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
208 EXPECT_EQ(GL_INVALID_OPERATION
, GetGLError());
209 cmd
.Init(client_element_buffer_id_
,
210 kValidIndexRangeCount
+ 1,
212 kValidIndexRangeStart
* 2,
213 kInvalidSharedMemoryId
,
214 kSharedMemoryOffset
);
215 EXPECT_NE(error::kNoError
, ExecuteCmd(cmd
));
216 cmd
.Init(client_element_buffer_id_
,
217 kValidIndexRangeCount
+ 1,
219 kValidIndexRangeStart
* 2,
221 kInvalidSharedMemoryOffset
);
222 EXPECT_NE(error::kNoError
, ExecuteCmd(cmd
));
225 TEST_P(GLES2DecoderTest
, IsBuffer
) {
226 EXPECT_FALSE(DoIsBuffer(client_buffer_id_
));
227 DoBindBuffer(GL_ARRAY_BUFFER
, client_buffer_id_
, kServiceBufferId
);
228 EXPECT_TRUE(DoIsBuffer(client_buffer_id_
));
229 DoDeleteBuffer(client_buffer_id_
, kServiceBufferId
);
230 EXPECT_FALSE(DoIsBuffer(client_buffer_id_
));
233 TEST_P(GLES2DecoderTest
, IsFramebuffer
) {
234 EXPECT_FALSE(DoIsFramebuffer(client_framebuffer_id_
));
236 GL_FRAMEBUFFER
, client_framebuffer_id_
, kServiceFramebufferId
);
237 EXPECT_TRUE(DoIsFramebuffer(client_framebuffer_id_
));
238 DoDeleteFramebuffer(client_framebuffer_id_
,
239 kServiceFramebufferId
,
246 EXPECT_FALSE(DoIsFramebuffer(client_framebuffer_id_
));
249 TEST_P(GLES2DecoderTest
, IsProgram
) {
250 // IsProgram is true as soon as the program is created.
251 EXPECT_TRUE(DoIsProgram(client_program_id_
));
252 EXPECT_CALL(*gl_
, DeleteProgram(kServiceProgramId
))
254 .RetiresOnSaturation();
255 DoDeleteProgram(client_program_id_
, kServiceProgramId
);
256 EXPECT_FALSE(DoIsProgram(client_program_id_
));
259 TEST_P(GLES2DecoderTest
, IsRenderbuffer
) {
260 EXPECT_FALSE(DoIsRenderbuffer(client_renderbuffer_id_
));
262 GL_RENDERBUFFER
, client_renderbuffer_id_
, kServiceRenderbufferId
);
263 EXPECT_TRUE(DoIsRenderbuffer(client_renderbuffer_id_
));
264 DoDeleteRenderbuffer(client_renderbuffer_id_
, kServiceRenderbufferId
);
265 EXPECT_FALSE(DoIsRenderbuffer(client_renderbuffer_id_
));
268 TEST_P(GLES2DecoderTest
, IsShader
) {
269 // IsShader is true as soon as the program is created.
270 EXPECT_TRUE(DoIsShader(client_shader_id_
));
271 DoDeleteShader(client_shader_id_
, kServiceShaderId
);
272 EXPECT_FALSE(DoIsShader(client_shader_id_
));
275 TEST_P(GLES2DecoderTest
, IsTexture
) {
276 EXPECT_FALSE(DoIsTexture(client_texture_id_
));
277 DoBindTexture(GL_TEXTURE_2D
, client_texture_id_
, kServiceTextureId
);
278 EXPECT_TRUE(DoIsTexture(client_texture_id_
));
279 DoDeleteTexture(client_texture_id_
, kServiceTextureId
);
280 EXPECT_FALSE(DoIsTexture(client_texture_id_
));
283 TEST_P(GLES3DecoderTest
, GetInternalformativValidArgsSamples
) {
284 const GLint kNumSampleCounts
= 8;
285 typedef cmds::GetInternalformativ::Result Result
;
286 Result
* result
= static_cast<Result
*>(shared_memory_address_
);
287 EXPECT_CALL(*gl_
, GetInternalformativ(GL_RENDERBUFFER
, GL_RGBA8
,
288 GL_NUM_SAMPLE_COUNTS
, 1, _
))
289 .WillOnce(SetArgPointee
<4>(kNumSampleCounts
))
290 .RetiresOnSaturation();
291 EXPECT_CALL(*gl_
, GetInternalformativ(GL_RENDERBUFFER
, GL_RGBA8
,
292 GL_SAMPLES
, kNumSampleCounts
,
295 .RetiresOnSaturation();
297 cmds::GetInternalformativ cmd
;
298 cmd
.Init(GL_RENDERBUFFER
, GL_RGBA8
, GL_SAMPLES
,
299 shared_memory_id_
, shared_memory_offset_
);
300 decoder_
->set_unsafe_es3_apis_enabled(true);
301 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
302 EXPECT_EQ(kNumSampleCounts
, result
->GetNumResults());
303 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
304 decoder_
->set_unsafe_es3_apis_enabled(false);
305 EXPECT_EQ(error::kUnknownCommand
, ExecuteCmd(cmd
));
308 TEST_P(GLES3DecoderTest
, GetInternalformativValidArgsNumSampleCounts
) {
309 const GLint kNumSampleCounts
= 8;
310 typedef cmds::GetInternalformativ::Result Result
;
311 Result
* result
= static_cast<Result
*>(shared_memory_address_
);
312 EXPECT_CALL(*gl_
, GetInternalformativ(GL_RENDERBUFFER
, GL_RGBA8
,
313 GL_NUM_SAMPLE_COUNTS
, 1, _
))
314 .WillOnce(SetArgPointee
<4>(kNumSampleCounts
))
315 .RetiresOnSaturation();
317 cmds::GetInternalformativ cmd
;
318 cmd
.Init(GL_RENDERBUFFER
, GL_RGBA8
, GL_NUM_SAMPLE_COUNTS
,
319 shared_memory_id_
, shared_memory_offset_
);
320 decoder_
->set_unsafe_es3_apis_enabled(true);
321 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
322 EXPECT_EQ(1, result
->GetNumResults());
323 EXPECT_EQ(kNumSampleCounts
, result
->GetData()[0]);
324 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
325 decoder_
->set_unsafe_es3_apis_enabled(false);
326 EXPECT_EQ(error::kUnknownCommand
, ExecuteCmd(cmd
));
329 TEST_P(GLES3DecoderTest
, ClientWaitSyncValid
) {
330 typedef cmds::ClientWaitSync::Result Result
;
331 Result
* result
= static_cast<Result
*>(shared_memory_address_
);
332 cmds::ClientWaitSync cmd
;
333 uint32_t v32_0
= 0, v32_1
= 0;
334 GLES2Util::MapUint64ToTwoUint32(0, &v32_0
, &v32_1
);
335 cmd
.Init(client_sync_id_
, GL_SYNC_FLUSH_COMMANDS_BIT
, v32_0
, v32_1
,
336 shared_memory_id_
, shared_memory_offset_
);
338 ClientWaitSync(reinterpret_cast<GLsync
>(kServiceSyncId
),
339 GL_SYNC_FLUSH_COMMANDS_BIT
, 0))
340 .WillOnce(Return(GL_CONDITION_SATISFIED
))
341 .RetiresOnSaturation();
342 *result
= GL_WAIT_FAILED
;
343 decoder_
->set_unsafe_es3_apis_enabled(true);
344 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
345 EXPECT_EQ(static_cast<GLenum
>(GL_CONDITION_SATISFIED
), *result
);
346 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
347 decoder_
->set_unsafe_es3_apis_enabled(false);
348 EXPECT_EQ(error::kUnknownCommand
, ExecuteCmd(cmd
));
351 TEST_P(GLES2DecoderTest
, ClientWaitSyncNonZeroTimeoutValid
) {
352 typedef cmds::ClientWaitSync::Result Result
;
353 Result
* result
= static_cast<Result
*>(shared_memory_address_
);
354 cmds::ClientWaitSync cmd
;
355 const GLuint64 kTimeout
= 0xABCDEF0123456789;
356 uint32_t v32_0
= 0, v32_1
= 0;
357 GLES2Util::MapUint64ToTwoUint32(kTimeout
, &v32_0
, &v32_1
);
358 cmd
.Init(client_sync_id_
, GL_SYNC_FLUSH_COMMANDS_BIT
, v32_0
, v32_1
,
359 shared_memory_id_
, shared_memory_offset_
);
361 ClientWaitSync(reinterpret_cast<GLsync
>(kServiceSyncId
),
362 GL_SYNC_FLUSH_COMMANDS_BIT
, kTimeout
))
363 .WillOnce(Return(GL_CONDITION_SATISFIED
))
364 .RetiresOnSaturation();
365 *result
= GL_WAIT_FAILED
;
366 decoder_
->set_unsafe_es3_apis_enabled(true);
367 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
368 EXPECT_EQ(static_cast<GLenum
>(GL_CONDITION_SATISFIED
), *result
);
369 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
370 decoder_
->set_unsafe_es3_apis_enabled(false);
371 EXPECT_EQ(error::kUnknownCommand
, ExecuteCmd(cmd
));
374 TEST_P(GLES2DecoderTest
, ClientWaitSyncInvalidSyncFails
) {
375 typedef cmds::ClientWaitSync::Result Result
;
376 Result
* result
= static_cast<Result
*>(shared_memory_address_
);
377 cmds::ClientWaitSync cmd
;
378 uint32_t v32_0
= 0, v32_1
= 0;
379 GLES2Util::MapUint64ToTwoUint32(0, &v32_0
, &v32_1
);
380 decoder_
->set_unsafe_es3_apis_enabled(true);
381 cmd
.Init(kInvalidClientId
, GL_SYNC_FLUSH_COMMANDS_BIT
, v32_0
, v32_1
,
382 shared_memory_id_
, shared_memory_offset_
);
383 *result
= GL_WAIT_FAILED
;
384 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
385 EXPECT_EQ(static_cast<GLenum
>(GL_WAIT_FAILED
), *result
);
386 EXPECT_EQ(GL_INVALID_VALUE
, GetGLError());
389 TEST_P(GLES2DecoderTest
, ClientWaitSyncResultNotInitFails
) {
390 typedef cmds::ClientWaitSync::Result Result
;
391 Result
* result
= static_cast<Result
*>(shared_memory_address_
);
392 cmds::ClientWaitSync cmd
;
393 uint32_t v32_0
= 0, v32_1
= 0;
394 GLES2Util::MapUint64ToTwoUint32(0, &v32_0
, &v32_1
);
395 decoder_
->set_unsafe_es3_apis_enabled(true);
396 cmd
.Init(client_sync_id_
, GL_SYNC_FLUSH_COMMANDS_BIT
, v32_0
, v32_1
,
397 shared_memory_id_
, shared_memory_offset_
);
398 *result
= 1; // Any value other than GL_WAIT_FAILED
399 EXPECT_NE(error::kNoError
, ExecuteCmd(cmd
));
402 TEST_P(GLES2DecoderTest
, ClientWaitSyncBadSharedMemoryFails
) {
403 typedef cmds::ClientWaitSync::Result Result
;
404 Result
* result
= static_cast<Result
*>(shared_memory_address_
);
405 cmds::ClientWaitSync cmd
;
406 uint32_t v32_0
= 0, v32_1
= 0;
407 GLES2Util::MapUint64ToTwoUint32(0, &v32_0
, &v32_1
);
408 decoder_
->set_unsafe_es3_apis_enabled(true);
409 *result
= GL_WAIT_FAILED
;
410 cmd
.Init(client_sync_id_
, GL_SYNC_FLUSH_COMMANDS_BIT
, v32_0
, v32_1
,
411 kInvalidSharedMemoryId
, shared_memory_offset_
);
412 EXPECT_NE(error::kNoError
, ExecuteCmd(cmd
));
414 *result
= GL_WAIT_FAILED
;
415 cmd
.Init(client_sync_id_
, GL_SYNC_FLUSH_COMMANDS_BIT
, v32_0
, v32_1
,
416 shared_memory_id_
, kInvalidSharedMemoryOffset
);
417 EXPECT_NE(error::kNoError
, ExecuteCmd(cmd
));
420 TEST_P(GLES2DecoderTest
, WaitSyncValidArgs
) {
421 const GLuint64 kTimeout
= GL_TIMEOUT_IGNORED
;
422 EXPECT_CALL(*gl_
, WaitSync(reinterpret_cast<GLsync
>(kServiceSyncId
),
425 .RetiresOnSaturation();
427 uint32_t v32_0
= 0, v32_1
= 0;
428 GLES2Util::MapUint64ToTwoUint32(kTimeout
, &v32_0
, &v32_1
);
430 cmd
.Init(client_sync_id_
, 0, v32_0
, v32_1
);
431 decoder_
->set_unsafe_es3_apis_enabled(true);
432 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
433 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
434 decoder_
->set_unsafe_es3_apis_enabled(false);
435 EXPECT_EQ(error::kUnknownCommand
, ExecuteCmd(cmd
));
438 TEST_P(GLES2DecoderManualInitTest
, BindGeneratesResourceFalse
) {
443 cmd1
.Init(GL_TEXTURE_2D
, kInvalidClientId
);
444 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd1
));
445 EXPECT_EQ(GL_INVALID_OPERATION
, GetGLError());
448 cmd2
.Init(GL_ARRAY_BUFFER
, kInvalidClientId
);
449 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd2
));
450 EXPECT_EQ(GL_INVALID_OPERATION
, GetGLError());
452 BindFramebuffer cmd3
;
453 cmd3
.Init(GL_FRAMEBUFFER
, kInvalidClientId
);
454 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd3
));
455 EXPECT_EQ(GL_INVALID_OPERATION
, GetGLError());
457 BindRenderbuffer cmd4
;
458 cmd4
.Init(GL_RENDERBUFFER
, kInvalidClientId
);
459 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd4
));
460 EXPECT_EQ(GL_INVALID_OPERATION
, GetGLError());
463 TEST_P(GLES2DecoderTest
, EnableFeatureCHROMIUMBadBucket
) {
464 const uint32 kBadBucketId
= 123;
465 EnableFeatureCHROMIUM cmd
;
466 cmd
.Init(kBadBucketId
, shared_memory_id_
, shared_memory_offset_
);
467 EXPECT_NE(error::kNoError
, ExecuteCmd(cmd
));
470 TEST_P(GLES2DecoderTest
, RequestExtensionCHROMIUMBadBucket
) {
471 const uint32 kBadBucketId
= 123;
472 RequestExtensionCHROMIUM cmd
;
473 cmd
.Init(kBadBucketId
);
474 EXPECT_NE(error::kNoError
, ExecuteCmd(cmd
));
477 TEST_P(GLES2DecoderTest
, BeginQueryEXTDisabled
) {
478 // Test something fails if off.
481 TEST_P(GLES2DecoderManualInitTest
, BeginEndQueryEXT
) {
483 init
.extensions
= "GL_EXT_occlusion_query_boolean";
484 init
.gl_version
= "opengl es 2.0";
485 init
.has_alpha
= true;
486 init
.request_alpha
= true;
487 init
.bind_generates_resource
= true;
490 // Test end fails if no begin.
492 end_cmd
.Init(GL_ANY_SAMPLES_PASSED_EXT
, 1);
493 EXPECT_EQ(error::kNoError
, ExecuteCmd(end_cmd
));
494 EXPECT_EQ(GL_INVALID_OPERATION
, GetGLError());
496 BeginQueryEXT begin_cmd
;
498 // Test id = 0 fails.
500 GL_ANY_SAMPLES_PASSED_EXT
, 0, kSharedMemoryId
, kSharedMemoryOffset
);
501 EXPECT_EQ(error::kNoError
, ExecuteCmd(begin_cmd
));
502 EXPECT_EQ(GL_INVALID_OPERATION
, GetGLError());
504 GenHelper
<GenQueriesEXTImmediate
>(kNewClientId
);
506 // Test valid parameters work.
507 EXPECT_CALL(*gl_
, GenQueries(1, _
))
508 .WillOnce(SetArgPointee
<1>(kNewServiceId
))
509 .RetiresOnSaturation();
510 EXPECT_CALL(*gl_
, BeginQuery(GL_ANY_SAMPLES_PASSED_EXT
, kNewServiceId
))
512 .RetiresOnSaturation();
514 // Query object should not be created untill BeginQueriesEXT.
515 QueryManager
* query_manager
= decoder_
->GetQueryManager();
516 ASSERT_TRUE(query_manager
!= NULL
);
517 QueryManager::Query
* query
= query_manager
->GetQuery(kNewClientId
);
518 EXPECT_TRUE(query
== NULL
);
520 // BeginQueryEXT should fail if id is not generated from GenQueriesEXT.
521 begin_cmd
.Init(GL_ANY_SAMPLES_PASSED_EXT
,
524 kSharedMemoryOffset
);
525 EXPECT_EQ(error::kNoError
, ExecuteCmd(begin_cmd
));
526 EXPECT_EQ(GL_INVALID_OPERATION
, GetGLError());
528 begin_cmd
.Init(GL_ANY_SAMPLES_PASSED_EXT
,
531 kSharedMemoryOffset
);
532 EXPECT_EQ(error::kNoError
, ExecuteCmd(begin_cmd
));
533 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
535 // After BeginQueriesEXT id name should have query object associated with it.
536 query
= query_manager
->GetQuery(kNewClientId
);
537 ASSERT_TRUE(query
!= NULL
);
538 EXPECT_FALSE(query
->IsPending());
540 // Test trying begin again fails
541 EXPECT_EQ(error::kNoError
, ExecuteCmd(begin_cmd
));
542 EXPECT_EQ(GL_INVALID_OPERATION
, GetGLError());
544 // Test end fails with different target
545 end_cmd
.Init(GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT
, 1);
546 EXPECT_EQ(error::kNoError
, ExecuteCmd(end_cmd
));
547 EXPECT_EQ(GL_INVALID_OPERATION
, GetGLError());
550 EXPECT_CALL(*gl_
, EndQuery(GL_ANY_SAMPLES_PASSED_EXT
))
552 .RetiresOnSaturation();
553 end_cmd
.Init(GL_ANY_SAMPLES_PASSED_EXT
, 1);
554 EXPECT_EQ(error::kNoError
, ExecuteCmd(end_cmd
));
555 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
556 EXPECT_TRUE(query
->IsPending());
558 EXPECT_CALL(*gl_
, DeleteQueries(1, _
)).Times(1).RetiresOnSaturation();
566 const QueryType kQueryTypes
[] = {
567 {GL_COMMANDS_ISSUED_CHROMIUM
, false},
568 {GL_LATENCY_QUERY_CHROMIUM
, false},
569 {GL_ASYNC_PIXEL_PACK_COMPLETED_CHROMIUM
, false},
570 {GL_GET_ERROR_QUERY_CHROMIUM
, false},
571 {GL_COMMANDS_COMPLETED_CHROMIUM
, false},
572 {GL_ANY_SAMPLES_PASSED_EXT
, false},
573 {GL_TIME_ELAPSED
, false},
574 {GL_TIMESTAMP
, true},
576 const GLsync kGlSync
= reinterpret_cast<GLsync
>(0xdeadbeef);
578 static void ExecuteGenerateQueryCmd(GLES2DecoderTestBase
* test
,
579 ::gfx::MockGLInterface
* gl
,
583 test
->GenHelper
<GenQueriesEXTImmediate
>(client_id
);
584 if (GL_ANY_SAMPLES_PASSED_EXT
== target
) {
585 EXPECT_CALL(*gl
, GenQueries(1, _
))
586 .WillOnce(SetArgPointee
<1>(service_id
))
587 .RetiresOnSaturation();
591 static error::Error
ExecuteBeginQueryCmd(GLES2DecoderTestBase
* test
,
592 ::gfx::MockGLInterface
* gl
,
593 ::gfx::GPUTimingFake
* timing_queries
,
599 if (GL_ANY_SAMPLES_PASSED_EXT
== target
) {
600 EXPECT_CALL(*gl
, BeginQuery(target
, service_id
))
602 .RetiresOnSaturation();
603 } else if (GL_TIME_ELAPSED
== target
) {
604 timing_queries
->ExpectGPUTimerQuery(*gl
, true);
607 BeginQueryEXT begin_cmd
;
608 begin_cmd
.Init(target
, client_id
, shm_id
, shm_offset
);
609 return test
->ExecuteCmd(begin_cmd
);
612 static error::Error
ExecuteEndQueryCmd(GLES2DecoderTestBase
* test
,
613 ::gfx::MockGLInterface
* gl
,
615 uint32_t submit_count
) {
616 if (GL_ANY_SAMPLES_PASSED_EXT
== target
) {
617 EXPECT_CALL(*gl
, EndQuery(target
))
619 .RetiresOnSaturation();
620 } else if (GL_GET_ERROR_QUERY_CHROMIUM
== target
) {
621 EXPECT_CALL(*gl
, GetError())
622 .WillOnce(Return(GL_NO_ERROR
))
623 .RetiresOnSaturation();
624 } else if (GL_COMMANDS_COMPLETED_CHROMIUM
== target
) {
625 EXPECT_CALL(*gl
, Flush()).RetiresOnSaturation();
626 EXPECT_CALL(*gl
, FenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE
, 0))
627 .WillOnce(Return(kGlSync
))
628 .RetiresOnSaturation();
630 EXPECT_CALL(*gl
, IsSync(kGlSync
))
631 .WillRepeatedly(Return(GL_TRUE
));
636 end_cmd
.Init(target
, submit_count
);
637 return test
->ExecuteCmd(end_cmd
);
640 static error::Error
ExecuteQueryCounterCmd(GLES2DecoderTestBase
* test
,
641 ::gfx::MockGLInterface
* gl
,
642 ::gfx::GPUTimingFake
* timing_queries
,
648 uint32_t submit_count
) {
649 if (GL_TIMESTAMP
== target
) {
650 timing_queries
->ExpectGPUTimeStampQuery(*gl
, false);
653 QueryCounterEXT query_counter_cmd
;
654 query_counter_cmd
.Init(client_id
,
659 return test
->ExecuteCmd(query_counter_cmd
);
662 static bool ProcessQuery(GLES2DecoderTestBase
* test
,
663 ::gfx::MockGLInterface
* gl
,
666 if (GL_ANY_SAMPLES_PASSED_EXT
== target
) {
668 *gl
, GetQueryObjectuiv(service_id
, GL_QUERY_RESULT_AVAILABLE_EXT
, _
))
669 .WillOnce(SetArgPointee
<2>(1))
670 .RetiresOnSaturation();
671 EXPECT_CALL(*gl
, GetQueryObjectuiv(service_id
, GL_QUERY_RESULT_EXT
, _
))
672 .WillOnce(SetArgPointee
<2>(1))
673 .RetiresOnSaturation();
674 } else if (GL_COMMANDS_COMPLETED_CHROMIUM
== target
) {
675 EXPECT_CALL(*gl
, ClientWaitSync(kGlSync
, _
, _
))
676 .WillOnce(Return(GL_ALREADY_SIGNALED
))
677 .RetiresOnSaturation();
678 EXPECT_CALL(*gl
, DeleteSync(kGlSync
)).Times(1).RetiresOnSaturation();
681 QueryManager
* query_manager
= test
->GetDecoder()->GetQueryManager();
682 EXPECT_TRUE(nullptr != query_manager
);
686 return query_manager
->ProcessPendingQueries(false);
689 static void CheckBeginEndQueryBadMemoryFails(GLES2DecoderTestBase
* test
,
692 const QueryType
& query_type
,
695 // We need to reset the decoder on each iteration, because we lose the
696 // context every time.
697 GLES2DecoderTestBase::InitState init
;
698 init
.extensions
= "GL_EXT_occlusion_query_boolean"
700 " GL_ARB_timer_query";
701 init
.gl_version
= "opengl es 3.0";
702 init
.has_alpha
= true;
703 init
.request_alpha
= true;
704 init
.bind_generates_resource
= true;
705 test
->InitDecoder(init
);
706 ::testing::StrictMock
< ::gfx::MockGLInterface
>* gl
= test
->GetGLMock();
707 ::gfx::GPUTimingFake gpu_timing_queries
;
709 ExecuteGenerateQueryCmd(test
, gl
, query_type
.type
,
710 client_id
, service_id
);
712 // Test bad shared memory fails
713 error::Error error1
= error::kNoError
;
714 error::Error error2
= error::kNoError
;
715 if (query_type
.is_counter
) {
716 error1
= ExecuteQueryCounterCmd(test
, gl
, &gpu_timing_queries
,
718 client_id
, service_id
,
719 shm_id
, shm_offset
, 1);
721 error1
= ExecuteBeginQueryCmd(test
, gl
, &gpu_timing_queries
,
723 client_id
, service_id
,
725 error2
= ExecuteEndQueryCmd(test
, gl
, query_type
.type
, 1);
728 bool process_success
= ProcessQuery(test
, gl
, query_type
.type
, service_id
);
730 EXPECT_TRUE(error1
!= error::kNoError
|| error2
!= error::kNoError
||
733 if (GL_ANY_SAMPLES_PASSED_EXT
== query_type
.type
)
734 EXPECT_CALL(*gl
, DeleteQueries(1, _
)).Times(1).RetiresOnSaturation();
735 test
->ResetDecoder();
738 TEST_P(GLES2DecoderManualInitTest
, BeginEndQueryEXTBadMemoryIdFails
) {
739 for (size_t i
= 0; i
< arraysize(kQueryTypes
); ++i
) {
740 CheckBeginEndQueryBadMemoryFails(this,
744 kInvalidSharedMemoryId
,
745 kSharedMemoryOffset
);
749 TEST_P(GLES2DecoderManualInitTest
, BeginEndQueryEXTBadMemoryOffsetFails
) {
750 for (size_t i
= 0; i
< arraysize(kQueryTypes
); ++i
) {
752 CheckBeginEndQueryBadMemoryFails(this,
757 kInvalidSharedMemoryOffset
);
759 CheckBeginEndQueryBadMemoryFails(this,
768 TEST_P(GLES2DecoderManualInitTest
, QueryReuseTest
) {
769 for (size_t i
= 0; i
< arraysize(kQueryTypes
); ++i
) {
770 const QueryType
& query_type
= kQueryTypes
[i
];
772 GLES2DecoderTestBase::InitState init
;
773 init
.extensions
= "GL_EXT_occlusion_query_boolean"
775 " GL_ARB_timer_query";
776 init
.gl_version
= "opengl es 3.0";
777 init
.has_alpha
= true;
778 init
.request_alpha
= true;
779 init
.bind_generates_resource
= true;
781 ::testing::StrictMock
< ::gfx::MockGLInterface
>* gl
= GetGLMock();
782 ::gfx::GPUTimingFake gpu_timing_queries
;
784 ExecuteGenerateQueryCmd(this, gl
, query_type
.type
,
785 kNewClientId
, kNewServiceId
);
788 if (query_type
.is_counter
) {
789 EXPECT_EQ(error::kNoError
, ExecuteQueryCounterCmd(this, gl
,
798 EXPECT_EQ(error::kNoError
, ExecuteBeginQueryCmd(this, gl
,
804 kSharedMemoryOffset
));
805 EXPECT_EQ(error::kNoError
, ExecuteEndQueryCmd(this, gl
,
806 query_type
.type
, 1));
809 EXPECT_TRUE(ProcessQuery(this, gl
, query_type
.type
, kNewServiceId
));
812 if (query_type
.is_counter
) {
813 EXPECT_EQ(error::kNoError
, ExecuteQueryCounterCmd(this, gl
,
822 EXPECT_EQ(error::kNoError
, ExecuteBeginQueryCmd(this, gl
,
828 kSharedMemoryOffset
));
829 EXPECT_EQ(error::kNoError
, ExecuteEndQueryCmd(this, gl
,
830 query_type
.type
, 2));
833 EXPECT_TRUE(ProcessQuery(this, gl
, query_type
.type
, kNewServiceId
));
835 if (GL_ANY_SAMPLES_PASSED_EXT
== query_type
.type
)
836 EXPECT_CALL(*gl
, DeleteQueries(1, _
)).Times(1).RetiresOnSaturation();
841 TEST_P(GLES2DecoderTest
, BeginEndQueryEXTCommandsIssuedCHROMIUM
) {
842 BeginQueryEXT begin_cmd
;
844 GenHelper
<GenQueriesEXTImmediate
>(kNewClientId
);
846 // Test valid parameters work.
847 begin_cmd
.Init(GL_COMMANDS_ISSUED_CHROMIUM
,
850 kSharedMemoryOffset
);
851 EXPECT_EQ(error::kNoError
, ExecuteCmd(begin_cmd
));
852 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
854 QueryManager
* query_manager
= decoder_
->GetQueryManager();
855 ASSERT_TRUE(query_manager
!= NULL
);
856 QueryManager::Query
* query
= query_manager
->GetQuery(kNewClientId
);
857 ASSERT_TRUE(query
!= NULL
);
858 EXPECT_FALSE(query
->IsPending());
862 end_cmd
.Init(GL_COMMANDS_ISSUED_CHROMIUM
, 1);
863 EXPECT_EQ(error::kNoError
, ExecuteCmd(end_cmd
));
864 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
865 EXPECT_FALSE(query
->IsPending());
868 TEST_P(GLES2DecoderTest
, BeginEndQueryEXTGetErrorQueryCHROMIUM
) {
869 BeginQueryEXT begin_cmd
;
871 GenHelper
<GenQueriesEXTImmediate
>(kNewClientId
);
873 // Test valid parameters work.
874 begin_cmd
.Init(GL_GET_ERROR_QUERY_CHROMIUM
,
877 kSharedMemoryOffset
);
878 EXPECT_EQ(error::kNoError
, ExecuteCmd(begin_cmd
));
879 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
881 QueryManager
* query_manager
= decoder_
->GetQueryManager();
882 ASSERT_TRUE(query_manager
!= NULL
);
883 QueryManager::Query
* query
= query_manager
->GetQuery(kNewClientId
);
884 ASSERT_TRUE(query
!= NULL
);
885 EXPECT_FALSE(query
->IsPending());
888 QuerySync
* sync
= static_cast<QuerySync
*>(shared_memory_address_
);
890 EXPECT_CALL(*gl_
, GetError())
891 .WillOnce(Return(GL_INVALID_VALUE
))
892 .RetiresOnSaturation();
895 end_cmd
.Init(GL_GET_ERROR_QUERY_CHROMIUM
, 1);
896 EXPECT_EQ(error::kNoError
, ExecuteCmd(end_cmd
));
897 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
898 EXPECT_FALSE(query
->IsPending());
899 EXPECT_EQ(static_cast<GLenum
>(GL_INVALID_VALUE
),
900 static_cast<GLenum
>(sync
->result
));
903 TEST_P(GLES2DecoderManualInitTest
, BeginEndQueryEXTCommandsCompletedCHROMIUM
) {
905 init
.extensions
= "GL_EXT_occlusion_query_boolean GL_ARB_sync";
906 init
.gl_version
= "opengl es 2.0";
907 init
.has_alpha
= true;
908 init
.request_alpha
= true;
909 init
.bind_generates_resource
= true;
912 GenHelper
<GenQueriesEXTImmediate
>(kNewClientId
);
914 BeginQueryEXT begin_cmd
;
915 begin_cmd
.Init(GL_COMMANDS_COMPLETED_CHROMIUM
,
918 kSharedMemoryOffset
);
919 EXPECT_EQ(error::kNoError
, ExecuteCmd(begin_cmd
));
920 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
922 QueryManager
* query_manager
= decoder_
->GetQueryManager();
923 ASSERT_TRUE(query_manager
!= NULL
);
924 QueryManager::Query
* query
= query_manager
->GetQuery(kNewClientId
);
925 ASSERT_TRUE(query
!= NULL
);
926 EXPECT_FALSE(query
->IsPending());
928 EXPECT_CALL(*gl_
, Flush()).RetiresOnSaturation();
929 EXPECT_CALL(*gl_
, FenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE
, 0))
930 .WillOnce(Return(kGlSync
))
931 .RetiresOnSaturation();
933 EXPECT_CALL(*gl_
, IsSync(kGlSync
))
934 .WillOnce(Return(GL_TRUE
))
935 .RetiresOnSaturation();
939 end_cmd
.Init(GL_COMMANDS_COMPLETED_CHROMIUM
, 1);
940 EXPECT_EQ(error::kNoError
, ExecuteCmd(end_cmd
));
941 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
942 EXPECT_TRUE(query
->IsPending());
945 EXPECT_CALL(*gl_
, IsSync(kGlSync
))
946 .WillOnce(Return(GL_TRUE
))
947 .RetiresOnSaturation();
949 EXPECT_CALL(*gl_
, ClientWaitSync(kGlSync
, _
, _
))
950 .WillOnce(Return(GL_TIMEOUT_EXPIRED
))
951 .RetiresOnSaturation();
952 bool process_success
= query_manager
->ProcessPendingQueries(false);
954 EXPECT_TRUE(process_success
);
955 EXPECT_TRUE(query
->IsPending());
958 EXPECT_CALL(*gl_
, IsSync(kGlSync
))
959 .WillOnce(Return(GL_TRUE
))
960 .RetiresOnSaturation();
962 EXPECT_CALL(*gl_
, ClientWaitSync(kGlSync
, _
, _
))
963 .WillOnce(Return(GL_ALREADY_SIGNALED
))
964 .RetiresOnSaturation();
965 process_success
= query_manager
->ProcessPendingQueries(false);
967 EXPECT_TRUE(process_success
);
968 EXPECT_FALSE(query
->IsPending());
971 EXPECT_CALL(*gl_
, IsSync(kGlSync
))
972 .WillOnce(Return(GL_TRUE
))
973 .RetiresOnSaturation();
975 EXPECT_CALL(*gl_
, DeleteSync(kGlSync
)).Times(1).RetiresOnSaturation();
979 TEST_P(GLES2DecoderManualInitTest
, BeginInvalidTargetQueryFails
) {
981 init
.extensions
= "";
982 init
.gl_version
= "opengl es 2.0";
983 init
.has_alpha
= true;
984 init
.request_alpha
= true;
985 init
.bind_generates_resource
= true;
988 GenHelper
<GenQueriesEXTImmediate
>(kNewClientId
);
990 BeginQueryEXT begin_cmd
;
991 begin_cmd
.Init(GL_COMMANDS_COMPLETED_CHROMIUM
,
994 kSharedMemoryOffset
);
995 EXPECT_EQ(error::kNoError
, ExecuteCmd(begin_cmd
));
996 EXPECT_EQ(GL_INVALID_OPERATION
, GetGLError());
998 begin_cmd
.Init(GL_ANY_SAMPLES_PASSED
,
1001 kSharedMemoryOffset
);
1002 EXPECT_EQ(error::kNoError
, ExecuteCmd(begin_cmd
));
1003 EXPECT_EQ(GL_INVALID_OPERATION
, GetGLError());
1005 begin_cmd
.Init(GL_ANY_SAMPLES_PASSED_CONSERVATIVE
,
1008 kSharedMemoryOffset
);
1009 EXPECT_EQ(error::kNoError
, ExecuteCmd(begin_cmd
));
1010 EXPECT_EQ(GL_INVALID_OPERATION
, GetGLError());
1012 begin_cmd
.Init(GL_TIME_ELAPSED
,
1015 kSharedMemoryOffset
);
1016 EXPECT_EQ(error::kNoError
, ExecuteCmd(begin_cmd
));
1017 EXPECT_EQ(GL_INVALID_OPERATION
, GetGLError());
1019 begin_cmd
.Init(0xdeadbeef,
1022 kSharedMemoryOffset
);
1023 EXPECT_EQ(error::kNoError
, ExecuteCmd(begin_cmd
));
1024 EXPECT_EQ(GL_INVALID_ENUM
, GetGLError());
1027 TEST_P(GLES2DecoderManualInitTest
, QueryCounterEXTTimeStamp
) {
1029 init
.extensions
= "GL_ARB_timer_query";
1030 init
.gl_version
= "opengl 2.0";
1031 init
.has_alpha
= true;
1032 init
.request_alpha
= true;
1033 init
.bind_generates_resource
= true;
1036 GenHelper
<GenQueriesEXTImmediate
>(kNewClientId
);
1038 EXPECT_CALL(*gl_
, GenQueries(1, _
))
1039 .WillOnce(SetArgPointee
<1>(kNewServiceId
))
1040 .RetiresOnSaturation();
1041 EXPECT_CALL(*gl_
, QueryCounter(kNewServiceId
, GL_TIMESTAMP
))
1043 .RetiresOnSaturation();
1044 QueryCounterEXT query_counter_cmd
;
1045 query_counter_cmd
.Init(kNewClientId
,
1048 kSharedMemoryOffset
,
1050 EXPECT_EQ(error::kNoError
, ExecuteCmd(query_counter_cmd
));
1051 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
1053 QueryManager
* query_manager
= decoder_
->GetQueryManager();
1054 ASSERT_TRUE(query_manager
!= NULL
);
1055 QueryManager::Query
* query
= query_manager
->GetQuery(kNewClientId
);
1056 ASSERT_TRUE(query
!= NULL
);
1057 EXPECT_TRUE(query
->IsPending());
1060 TEST_P(GLES2DecoderManualInitTest
, InvalidTargetQueryCounterFails
) {
1062 init
.extensions
= "";
1063 init
.gl_version
= "opengl es 2.0";
1064 init
.has_alpha
= true;
1065 init
.request_alpha
= true;
1066 init
.bind_generates_resource
= true;
1069 GenHelper
<GenQueriesEXTImmediate
>(kNewClientId
);
1071 QueryCounterEXT query_counter_cmd
;
1072 query_counter_cmd
.Init(kNewClientId
,
1075 kSharedMemoryOffset
,
1077 EXPECT_EQ(error::kNoError
, ExecuteCmd(query_counter_cmd
));
1078 EXPECT_EQ(GL_INVALID_OPERATION
, GetGLError());
1080 query_counter_cmd
.Init(kNewClientId
,
1083 kSharedMemoryOffset
,
1085 EXPECT_EQ(error::kNoError
, ExecuteCmd(query_counter_cmd
));
1086 EXPECT_EQ(GL_INVALID_ENUM
, GetGLError());
1089 TEST_P(GLES2DecoderTest
, IsEnabledReturnsCachedValue
) {
1090 // NOTE: There are no expectations because no GL functions should be
1091 // called for DEPTH_TEST or STENCIL_TEST
1092 static const GLenum kStates
[] = {
1093 GL_DEPTH_TEST
, GL_STENCIL_TEST
,
1095 for (size_t ii
= 0; ii
< arraysize(kStates
); ++ii
) {
1097 GLenum state
= kStates
[ii
];
1098 enable_cmd
.Init(state
);
1099 EXPECT_EQ(error::kNoError
, ExecuteCmd(enable_cmd
));
1100 IsEnabled::Result
* result
=
1101 static_cast<IsEnabled::Result
*>(shared_memory_address_
);
1102 IsEnabled is_enabled_cmd
;
1103 is_enabled_cmd
.Init(state
, shared_memory_id_
, shared_memory_offset_
);
1104 EXPECT_EQ(error::kNoError
, ExecuteCmd(is_enabled_cmd
));
1105 EXPECT_NE(0u, *result
);
1106 Disable disable_cmd
;
1107 disable_cmd
.Init(state
);
1108 EXPECT_EQ(error::kNoError
, ExecuteCmd(disable_cmd
));
1109 EXPECT_EQ(error::kNoError
, ExecuteCmd(is_enabled_cmd
));
1110 EXPECT_EQ(0u, *result
);
1114 TEST_P(GLES2DecoderManualInitTest
, GpuMemoryManagerCHROMIUM
) {
1116 init
.extensions
= "GL_ARB_texture_rectangle";
1117 init
.bind_generates_resource
= true;
1120 Texture
* texture
= GetTexture(client_texture_id_
)->texture();
1121 EXPECT_TRUE(texture
!= NULL
);
1122 EXPECT_TRUE(texture
->pool() == GL_TEXTURE_POOL_UNMANAGED_CHROMIUM
);
1124 DoBindTexture(GL_TEXTURE_2D
, client_texture_id_
, kServiceTextureId
);
1127 cmd
.Init(GL_TEXTURE_2D
,
1128 GL_TEXTURE_POOL_CHROMIUM
,
1129 GL_TEXTURE_POOL_UNMANAGED_CHROMIUM
);
1130 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
1131 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
1133 cmd
.Init(GL_TEXTURE_2D
,
1134 GL_TEXTURE_POOL_CHROMIUM
,
1135 GL_TEXTURE_POOL_MANAGED_CHROMIUM
);
1136 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
1137 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
1139 EXPECT_TRUE(texture
->pool() == GL_TEXTURE_POOL_MANAGED_CHROMIUM
);
1141 cmd
.Init(GL_TEXTURE_2D
, GL_TEXTURE_POOL_CHROMIUM
, GL_NONE
);
1142 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
1143 EXPECT_EQ(GL_INVALID_ENUM
, GetGLError());
1148 class SizeOnlyMemoryTracker
: public MemoryTracker
{
1150 SizeOnlyMemoryTracker() {
1151 // These are the default textures. 1 for TEXTURE_2D and 6 faces for
1152 // TEXTURE_CUBE_MAP.
1153 const size_t kInitialUnmanagedPoolSize
= 7 * 4;
1154 const size_t kInitialManagedPoolSize
= 0;
1155 pool_infos_
[MemoryTracker::kUnmanaged
].initial_size
=
1156 kInitialUnmanagedPoolSize
;
1157 pool_infos_
[MemoryTracker::kManaged
].initial_size
= kInitialManagedPoolSize
;
1160 // Ensure a certain amount of GPU memory is free. Returns true on success.
1161 MOCK_METHOD1(EnsureGPUMemoryAvailable
, bool(size_t size_needed
));
1163 virtual void TrackMemoryAllocatedChange(size_t old_size
,
1166 PoolInfo
& info
= pool_infos_
[pool
];
1167 info
.size
+= new_size
- old_size
;
1170 size_t GetPoolSize(Pool pool
) {
1171 const PoolInfo
& info
= pool_infos_
[pool
];
1172 return info
.size
- info
.initial_size
;
1175 uint64_t ClientTracingId() const override
{ return 0; }
1176 int ClientId() const override
{ return 0; }
1177 uint64_t ShareGroupTracingGUID() const override
{ return 0; }
1180 virtual ~SizeOnlyMemoryTracker() {}
1182 PoolInfo() : initial_size(0), size(0) {}
1183 size_t initial_size
;
1186 std::map
<Pool
, PoolInfo
> pool_infos_
;
1189 } // anonymous namespace.
1191 TEST_P(GLES2DecoderManualInitTest
, MemoryTrackerInitialSize
) {
1192 scoped_refptr
<SizeOnlyMemoryTracker
> memory_tracker
=
1193 new SizeOnlyMemoryTracker();
1194 set_memory_tracker(memory_tracker
.get());
1196 init
.bind_generates_resource
= true;
1198 // Expect that initial size - size is 0.
1199 EXPECT_EQ(0u, memory_tracker
->GetPoolSize(MemoryTracker::kUnmanaged
));
1200 EXPECT_EQ(0u, memory_tracker
->GetPoolSize(MemoryTracker::kManaged
));
1203 TEST_P(GLES2DecoderManualInitTest
, MemoryTrackerTexImage2D
) {
1204 scoped_refptr
<SizeOnlyMemoryTracker
> memory_tracker
=
1205 new SizeOnlyMemoryTracker();
1206 set_memory_tracker(memory_tracker
.get());
1208 init
.bind_generates_resource
= true;
1210 DoBindTexture(GL_TEXTURE_2D
, client_texture_id_
, kServiceTextureId
);
1211 EXPECT_CALL(*memory_tracker
.get(), EnsureGPUMemoryAvailable(128))
1212 .WillOnce(Return(true))
1213 .RetiresOnSaturation();
1214 DoTexImage2D(GL_TEXTURE_2D
,
1223 kSharedMemoryOffset
);
1224 EXPECT_EQ(128u, memory_tracker
->GetPoolSize(MemoryTracker::kUnmanaged
));
1225 EXPECT_CALL(*memory_tracker
.get(), EnsureGPUMemoryAvailable(64))
1226 .WillOnce(Return(true))
1227 .RetiresOnSaturation();
1228 DoTexImage2D(GL_TEXTURE_2D
,
1237 kSharedMemoryOffset
);
1238 EXPECT_EQ(64u, memory_tracker
->GetPoolSize(MemoryTracker::kUnmanaged
));
1239 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
1240 // Check we get out of memory and no call to glTexImage2D if Ensure fails.
1241 EXPECT_CALL(*memory_tracker
.get(), EnsureGPUMemoryAvailable(64))
1242 .WillOnce(Return(false))
1243 .RetiresOnSaturation();
1245 cmd
.Init(GL_TEXTURE_2D
,
1253 kSharedMemoryOffset
);
1254 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
1255 EXPECT_EQ(GL_OUT_OF_MEMORY
, GetGLError());
1256 EXPECT_EQ(64u, memory_tracker
->GetPoolSize(MemoryTracker::kUnmanaged
));
1259 TEST_P(GLES2DecoderManualInitTest
, MemoryTrackerTexStorage2DEXT
) {
1260 scoped_refptr
<SizeOnlyMemoryTracker
> memory_tracker
=
1261 new SizeOnlyMemoryTracker();
1262 set_memory_tracker(memory_tracker
.get());
1264 init
.bind_generates_resource
= true;
1266 DoBindTexture(GL_TEXTURE_2D
, client_texture_id_
, kServiceTextureId
);
1267 // Check we get out of memory and no call to glTexStorage2DEXT
1269 EXPECT_CALL(*memory_tracker
.get(), EnsureGPUMemoryAvailable(128))
1270 .WillOnce(Return(false))
1271 .RetiresOnSaturation();
1272 TexStorage2DEXT cmd
;
1273 cmd
.Init(GL_TEXTURE_2D
, 1, GL_RGBA8
, 8, 4);
1274 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
1275 EXPECT_EQ(0u, memory_tracker
->GetPoolSize(MemoryTracker::kUnmanaged
));
1276 EXPECT_EQ(GL_OUT_OF_MEMORY
, GetGLError());
1279 TEST_P(GLES2DecoderManualInitTest
, MemoryTrackerCopyTexImage2D
) {
1280 GLenum target
= GL_TEXTURE_2D
;
1282 GLenum internal_format
= GL_RGBA
;
1286 scoped_refptr
<SizeOnlyMemoryTracker
> memory_tracker
=
1287 new SizeOnlyMemoryTracker();
1288 set_memory_tracker(memory_tracker
.get());
1290 init
.has_alpha
= true;
1291 init
.request_alpha
= true;
1292 init
.bind_generates_resource
= true;
1294 DoBindTexture(GL_TEXTURE_2D
, client_texture_id_
, kServiceTextureId
);
1295 EXPECT_CALL(*memory_tracker
.get(), EnsureGPUMemoryAvailable(128))
1296 .WillOnce(Return(true))
1297 .RetiresOnSaturation();
1298 EXPECT_CALL(*gl_
, GetError())
1299 .WillOnce(Return(GL_NO_ERROR
))
1300 .WillOnce(Return(GL_NO_ERROR
))
1301 .RetiresOnSaturation();
1304 target
, level
, internal_format
, 0, 0, width
, height
, border
))
1306 .RetiresOnSaturation();
1308 cmd
.Init(target
, level
, internal_format
, 0, 0, width
, height
);
1309 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
1310 EXPECT_EQ(128u, memory_tracker
->GetPoolSize(MemoryTracker::kUnmanaged
));
1311 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
1312 // Check we get out of memory and no call to glCopyTexImage2D if Ensure fails.
1313 EXPECT_CALL(*memory_tracker
.get(), EnsureGPUMemoryAvailable(128))
1314 .WillOnce(Return(false))
1315 .RetiresOnSaturation();
1316 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
1317 EXPECT_EQ(GL_OUT_OF_MEMORY
, GetGLError());
1318 EXPECT_EQ(128u, memory_tracker
->GetPoolSize(MemoryTracker::kUnmanaged
));
1321 TEST_P(GLES2DecoderManualInitTest
, MemoryTrackerRenderbufferStorage
) {
1322 scoped_refptr
<SizeOnlyMemoryTracker
> memory_tracker
=
1323 new SizeOnlyMemoryTracker();
1324 set_memory_tracker(memory_tracker
.get());
1326 init
.bind_generates_resource
= true;
1329 GL_RENDERBUFFER
, client_renderbuffer_id_
, kServiceRenderbufferId
);
1330 EnsureRenderbufferBound(false);
1331 EXPECT_CALL(*gl_
, GetError())
1332 .WillOnce(Return(GL_NO_ERROR
))
1333 .WillOnce(Return(GL_NO_ERROR
))
1334 .RetiresOnSaturation();
1335 EXPECT_CALL(*memory_tracker
.get(), EnsureGPUMemoryAvailable(128))
1336 .WillOnce(Return(true))
1337 .RetiresOnSaturation();
1338 EXPECT_CALL(*gl_
, RenderbufferStorageEXT(GL_RENDERBUFFER
, GL_RGBA
, 8, 4))
1340 .RetiresOnSaturation();
1341 RenderbufferStorage cmd
;
1342 cmd
.Init(GL_RENDERBUFFER
, GL_RGBA4
, 8, 4);
1343 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
1344 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
1345 EXPECT_EQ(128u, memory_tracker
->GetPoolSize(MemoryTracker::kUnmanaged
));
1346 // Check we get out of memory and no call to glRenderbufferStorage if Ensure
1348 EXPECT_CALL(*memory_tracker
.get(), EnsureGPUMemoryAvailable(128))
1349 .WillOnce(Return(false))
1350 .RetiresOnSaturation();
1351 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
1352 EXPECT_EQ(GL_OUT_OF_MEMORY
, GetGLError());
1353 EXPECT_EQ(128u, memory_tracker
->GetPoolSize(MemoryTracker::kUnmanaged
));
1356 TEST_P(GLES2DecoderManualInitTest
, MemoryTrackerBufferData
) {
1357 scoped_refptr
<SizeOnlyMemoryTracker
> memory_tracker
=
1358 new SizeOnlyMemoryTracker();
1359 set_memory_tracker(memory_tracker
.get());
1361 init
.bind_generates_resource
= true;
1363 DoBindBuffer(GL_ARRAY_BUFFER
, client_buffer_id_
, kServiceBufferId
);
1364 EXPECT_CALL(*gl_
, GetError())
1365 .WillOnce(Return(GL_NO_ERROR
))
1366 .WillOnce(Return(GL_NO_ERROR
))
1367 .RetiresOnSaturation();
1368 EXPECT_CALL(*memory_tracker
.get(), EnsureGPUMemoryAvailable(128))
1369 .WillOnce(Return(true))
1370 .RetiresOnSaturation();
1371 EXPECT_CALL(*gl_
, BufferData(GL_ARRAY_BUFFER
, 128, _
, GL_STREAM_DRAW
))
1373 .RetiresOnSaturation();
1375 cmd
.Init(GL_ARRAY_BUFFER
, 128, 0, 0, GL_STREAM_DRAW
);
1376 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
1377 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
1378 EXPECT_EQ(128u, memory_tracker
->GetPoolSize(MemoryTracker::kManaged
));
1379 // Check we get out of memory and no call to glBufferData if Ensure
1381 EXPECT_CALL(*memory_tracker
.get(), EnsureGPUMemoryAvailable(128))
1382 .WillOnce(Return(false))
1383 .RetiresOnSaturation();
1384 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
1385 EXPECT_EQ(GL_OUT_OF_MEMORY
, GetGLError());
1386 EXPECT_EQ(128u, memory_tracker
->GetPoolSize(MemoryTracker::kManaged
));
1389 TEST_P(GLES2DecoderManualInitTest
, ImmutableCopyTexImage2D
) {
1390 const GLenum kTarget
= GL_TEXTURE_2D
;
1391 const GLint kLevel
= 0;
1392 const GLenum kInternalFormat
= GL_RGBA
;
1393 const GLenum kSizedInternalFormat
= GL_RGBA8
;
1394 const GLsizei kWidth
= 4;
1395 const GLsizei kHeight
= 8;
1396 const GLint kBorder
= 0;
1398 init
.extensions
= "GL_EXT_texture_storage";
1399 init
.has_alpha
= true;
1400 init
.request_alpha
= true;
1401 init
.bind_generates_resource
= true;
1403 DoBindTexture(GL_TEXTURE_2D
, client_texture_id_
, kServiceTextureId
);
1405 // CopyTexImage2D will call arbitrary amount of GetErrors.
1406 EXPECT_CALL(*gl_
, GetError())
1411 kTarget
, kLevel
, kInternalFormat
, 0, 0, kWidth
, kHeight
,
1417 kTarget
, kLevel
, kSizedInternalFormat
, kWidth
, kHeight
))
1419 CopyTexImage2D copy_cmd
;
1420 copy_cmd
.Init(kTarget
, kLevel
, kInternalFormat
, 0, 0, kWidth
, kHeight
);
1421 EXPECT_EQ(error::kNoError
, ExecuteCmd(copy_cmd
));
1422 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
1424 TexStorage2DEXT storage_cmd
;
1425 storage_cmd
.Init(kTarget
, kLevel
, kSizedInternalFormat
, kWidth
, kHeight
);
1426 EXPECT_EQ(error::kNoError
, ExecuteCmd(storage_cmd
));
1427 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
1429 // This should not invoke CopyTexImage2D.
1430 copy_cmd
.Init(kTarget
, kLevel
, kInternalFormat
, 0, 0, kWidth
, kHeight
);
1431 EXPECT_EQ(error::kNoError
, ExecuteCmd(copy_cmd
));
1432 EXPECT_EQ(GL_INVALID_OPERATION
, GetGLError());
1435 TEST_P(GLES2DecoderTest
, LoseContextCHROMIUMGuilty
) {
1436 EXPECT_CALL(*mock_decoder_
, MarkContextLost(error::kInnocent
))
1438 cmds::LoseContextCHROMIUM cmd
;
1439 cmd
.Init(GL_GUILTY_CONTEXT_RESET_ARB
, GL_INNOCENT_CONTEXT_RESET_ARB
);
1440 EXPECT_EQ(error::kLostContext
, ExecuteCmd(cmd
));
1441 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
1442 EXPECT_TRUE(decoder_
->WasContextLost());
1443 EXPECT_TRUE(decoder_
->WasContextLostByRobustnessExtension());
1446 TEST_P(GLES2DecoderTest
, LoseContextCHROMIUMUnkown
) {
1447 EXPECT_CALL(*mock_decoder_
, MarkContextLost(error::kUnknown
))
1449 cmds::LoseContextCHROMIUM cmd
;
1450 cmd
.Init(GL_UNKNOWN_CONTEXT_RESET_ARB
, GL_UNKNOWN_CONTEXT_RESET_ARB
);
1451 EXPECT_EQ(error::kLostContext
, ExecuteCmd(cmd
));
1452 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
1453 EXPECT_TRUE(decoder_
->WasContextLost());
1454 EXPECT_TRUE(decoder_
->WasContextLostByRobustnessExtension());
1457 TEST_P(GLES2DecoderTest
, LoseContextCHROMIUMInvalidArgs0_0
) {
1458 EXPECT_CALL(*mock_decoder_
, MarkContextLost(_
))
1460 cmds::LoseContextCHROMIUM cmd
;
1461 cmd
.Init(GL_NONE
, GL_GUILTY_CONTEXT_RESET_ARB
);
1462 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
1463 EXPECT_EQ(GL_INVALID_ENUM
, GetGLError());
1466 TEST_P(GLES2DecoderTest
, LoseContextCHROMIUMInvalidArgs1_0
) {
1467 EXPECT_CALL(*mock_decoder_
, MarkContextLost(_
))
1469 cmds::LoseContextCHROMIUM cmd
;
1470 cmd
.Init(GL_GUILTY_CONTEXT_RESET_ARB
, GL_NONE
);
1471 EXPECT_EQ(error::kNoError
, ExecuteCmd(cmd
));
1472 EXPECT_EQ(GL_INVALID_ENUM
, GetGLError());
1475 class GLES2DecoderDoCommandsTest
: public GLES2DecoderTest
{
1477 GLES2DecoderDoCommandsTest() {
1478 for (int i
= 0; i
< 3; i
++) {
1479 cmds_
[i
].Init(GL_BLEND
);
1481 entries_per_cmd_
= ComputeNumEntries(cmds_
[0].ComputeSize());
1484 void SetExpectationsForNCommands(int num_commands
) {
1485 for (int i
= 0; i
< num_commands
; i
++)
1486 SetupExpectationsForEnableDisable(GL_BLEND
, true);
1491 int entries_per_cmd_
;
1494 // Test that processing with 0 entries does nothing.
1495 TEST_P(GLES2DecoderDoCommandsTest
, DoCommandsOneOfZero
) {
1496 int num_processed
= -1;
1497 SetExpectationsForNCommands(0);
1500 decoder_
->DoCommands(1, &cmds_
, entries_per_cmd_
* 0, &num_processed
));
1501 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
1502 EXPECT_EQ(0, num_processed
);
1505 // Test processing at granularity of single commands.
1506 TEST_P(GLES2DecoderDoCommandsTest
, DoCommandsOneOfOne
) {
1507 int num_processed
= -1;
1508 SetExpectationsForNCommands(1);
1511 decoder_
->DoCommands(1, &cmds_
, entries_per_cmd_
* 1, &num_processed
));
1512 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
1513 EXPECT_EQ(entries_per_cmd_
, num_processed
);
1516 // Test processing at granularity of multiple commands.
1517 TEST_P(GLES2DecoderDoCommandsTest
, DoCommandsThreeOfThree
) {
1518 int num_processed
= -1;
1519 SetExpectationsForNCommands(3);
1522 decoder_
->DoCommands(3, &cmds_
, entries_per_cmd_
* 3, &num_processed
));
1523 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
1524 EXPECT_EQ(entries_per_cmd_
* 3, num_processed
);
1527 // Test processing a request smaller than available entries.
1528 TEST_P(GLES2DecoderDoCommandsTest
, DoCommandsTwoOfThree
) {
1529 int num_processed
= -1;
1530 SetExpectationsForNCommands(2);
1533 decoder_
->DoCommands(2, &cmds_
, entries_per_cmd_
* 3, &num_processed
));
1534 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
1535 EXPECT_EQ(entries_per_cmd_
* 2, num_processed
);
1538 // Test that processing stops on a command with size 0.
1539 TEST_P(GLES2DecoderDoCommandsTest
, DoCommandsZeroCmdSize
) {
1540 cmds_
[1].header
.size
= 0;
1541 int num_processed
= -1;
1542 SetExpectationsForNCommands(1);
1544 error::kInvalidSize
,
1545 decoder_
->DoCommands(2, &cmds_
, entries_per_cmd_
* 2, &num_processed
));
1546 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
1547 EXPECT_EQ(entries_per_cmd_
, num_processed
);
1550 // Test that processing stops on a command with size greater than available.
1551 TEST_P(GLES2DecoderDoCommandsTest
, DoCommandsOutOfBounds
) {
1552 int num_processed
= -1;
1553 SetExpectationsForNCommands(1);
1554 EXPECT_EQ(error::kOutOfBounds
,
1555 decoder_
->DoCommands(
1556 2, &cmds_
, entries_per_cmd_
* 2 - 1, &num_processed
));
1557 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
1558 EXPECT_EQ(entries_per_cmd_
, num_processed
);
1561 // Test that commands with bad argument size are skipped without processing.
1562 TEST_P(GLES2DecoderDoCommandsTest
, DoCommandsBadArgSize
) {
1563 cmds_
[1].header
.size
+= 1;
1564 int num_processed
= -1;
1565 SetExpectationsForNCommands(1);
1566 EXPECT_EQ(error::kInvalidArguments
,
1567 decoder_
->DoCommands(
1568 2, &cmds_
, entries_per_cmd_
* 2 + 1, &num_processed
));
1569 EXPECT_EQ(GL_NO_ERROR
, GetGLError());
1570 EXPECT_EQ(entries_per_cmd_
+ cmds_
[1].header
.size
, num_processed
);
1573 INSTANTIATE_TEST_CASE_P(Service
, GLES2DecoderTest
, ::testing::Bool());
1575 INSTANTIATE_TEST_CASE_P(Service
, GLES2DecoderWithShaderTest
, ::testing::Bool());
1577 INSTANTIATE_TEST_CASE_P(Service
, GLES2DecoderManualInitTest
, ::testing::Bool());
1579 INSTANTIATE_TEST_CASE_P(Service
,
1580 GLES2DecoderRGBBackbufferTest
,
1583 INSTANTIATE_TEST_CASE_P(Service
, GLES2DecoderDoCommandsTest
, ::testing::Bool());
1585 INSTANTIATE_TEST_CASE_P(Service
, GLES3DecoderTest
, ::testing::Bool());
1587 } // namespace gles2