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/query_manager.h"
6 #include "gpu/command_buffer/common/gles2_cmd_format.h"
7 #include "gpu/command_buffer/service/cmd_buffer_engine.h"
8 #include "gpu/command_buffer/service/error_state_mock.h"
9 #include "gpu/command_buffer/service/feature_info.h"
10 #include "gpu/command_buffer/service/gles2_cmd_decoder.h"
11 #include "gpu/command_buffer/service/gles2_cmd_decoder_mock.h"
12 #include "gpu/command_buffer/service/gpu_service_test.h"
13 #include "gpu/command_buffer/service/test_helper.h"
14 #include "testing/gtest/include/gtest/gtest.h"
15 #include "ui/gl/gl_mock.h"
18 using ::testing::InSequence
;
19 using ::testing::Return
;
20 using ::testing::SetArgumentPointee
;
25 class QueryManagerTest
: public GpuServiceTest
{
27 static const int32 kSharedMemoryId
= 401;
28 static const size_t kSharedBufferSize
= 2048;
29 static const uint32 kSharedMemoryOffset
= 132;
30 static const int32 kInvalidSharedMemoryId
= 402;
31 static const uint32 kInvalidSharedMemoryOffset
= kSharedBufferSize
+ 1;
32 static const uint32 kInitialResult
= 0xBDBDBDBDu
;
33 static const uint8 kInitialMemoryValue
= 0xBDu
;
37 ~QueryManagerTest() override
{}
40 void SetUp() override
{
41 GpuServiceTest::SetUpWithGLVersion("2.1", "GL_ARB_occlusion_query");
42 engine_
.reset(new MockCommandBufferEngine());
43 decoder_
.reset(new MockGLES2Decoder());
44 decoder_
->set_engine(engine_
.get());
45 TestHelper::SetupFeatureInfoInitExpectations(
47 "GL_EXT_occlusion_query_boolean");
48 scoped_refptr
<FeatureInfo
> feature_info(new FeatureInfo());
49 feature_info
->Initialize();
50 manager_
.reset(new QueryManager(decoder_
.get(), feature_info
.get()));
53 void TearDown() override
{
55 manager_
->Destroy(false);
58 GpuServiceTest::TearDown();
61 QueryManager::Query
* CreateQuery(
62 GLenum target
, GLuint client_id
, int32 shm_id
, uint32 shm_offset
,
64 EXPECT_CALL(*gl_
, GenQueries(1, _
))
65 .WillOnce(SetArgumentPointee
<1>(service_id
))
66 .RetiresOnSaturation();
67 return manager_
->CreateQuery(target
, client_id
, shm_id
, shm_offset
);
70 void QueueQuery(QueryManager::Query
* query
,
72 base::subtle::Atomic32 submit_count
) {
73 EXPECT_CALL(*gl_
, BeginQuery(query
->target(), service_id
))
75 .RetiresOnSaturation();
76 EXPECT_CALL(*gl_
, EndQuery(query
->target()))
78 .RetiresOnSaturation();
79 EXPECT_TRUE(manager_
->BeginQuery(query
));
80 EXPECT_TRUE(manager_
->EndQuery(query
, submit_count
));
83 scoped_ptr
<MockGLES2Decoder
> decoder_
;
84 scoped_ptr
<QueryManager
> manager_
;
87 class MockCommandBufferEngine
: public CommandBufferEngine
{
89 MockCommandBufferEngine() {
90 scoped_ptr
<base::SharedMemory
> shared_memory(new base::SharedMemory());
91 shared_memory
->CreateAndMapAnonymous(kSharedBufferSize
);
93 MakeBufferFromSharedMemory(shared_memory
.Pass(), kSharedBufferSize
);
94 data_
= static_cast<uint8
*>(valid_buffer_
->memory());
98 ~MockCommandBufferEngine() override
{}
100 scoped_refptr
<gpu::Buffer
> GetSharedMemoryBuffer(int32 shm_id
) override
{
101 return shm_id
== kSharedMemoryId
? valid_buffer_
: invalid_buffer_
;
104 void ClearSharedMemory() {
105 memset(data_
, kInitialMemoryValue
, kSharedBufferSize
);
108 void set_token(int32 token
) override
{ DCHECK(false); }
110 bool SetGetBuffer(int32
/* transfer_buffer_id */) override
{
115 // Overridden from CommandBufferEngine.
116 bool SetGetOffset(int32 offset
) override
{
121 // Overridden from CommandBufferEngine.
122 int32
GetGetOffset() override
{
129 scoped_refptr
<gpu::Buffer
> valid_buffer_
;
130 scoped_refptr
<gpu::Buffer
> invalid_buffer_
;
133 scoped_ptr
<MockCommandBufferEngine
> engine_
;
136 // GCC requires these declarations, but MSVC requires they not be present
137 #ifndef COMPILER_MSVC
138 const int32
QueryManagerTest::kSharedMemoryId
;
139 const size_t QueryManagerTest::kSharedBufferSize
;
140 const uint32
QueryManagerTest::kSharedMemoryOffset
;
141 const int32
QueryManagerTest::kInvalidSharedMemoryId
;
142 const uint32
QueryManagerTest::kInvalidSharedMemoryOffset
;
143 const uint32
QueryManagerTest::kInitialResult
;
144 const uint8
QueryManagerTest::kInitialMemoryValue
;
147 TEST_F(QueryManagerTest
, Basic
) {
148 const GLuint kClient1Id
= 1;
149 const GLuint kService1Id
= 11;
150 const GLuint kClient2Id
= 2;
152 EXPECT_FALSE(manager_
->HavePendingQueries());
153 // Check we can create a Query.
154 scoped_refptr
<QueryManager::Query
> query(
155 CreateQuery(GL_ANY_SAMPLES_PASSED_EXT
, kClient1Id
,
156 kSharedMemoryId
, kSharedMemoryOffset
, kService1Id
));
157 ASSERT_TRUE(query
.get() != NULL
);
158 // Check we can get the same Query.
159 EXPECT_EQ(query
.get(), manager_
->GetQuery(kClient1Id
));
160 // Check we get nothing for a non-existent query.
161 EXPECT_TRUE(manager_
->GetQuery(kClient2Id
) == NULL
);
162 // Check we can delete the query.
163 manager_
->RemoveQuery(kClient1Id
);
164 // Check we get nothing for a non-existent query.
165 EXPECT_TRUE(manager_
->GetQuery(kClient1Id
) == NULL
);
166 // Check query is deleted
167 EXPECT_TRUE(query
->IsDeleted());
168 EXPECT_FALSE(manager_
->HavePendingQueries());
171 TEST_F(QueryManagerTest
, Destroy
) {
172 const GLuint kClient1Id
= 1;
173 const GLuint kService1Id
= 11;
176 scoped_refptr
<QueryManager::Query
> query(
177 CreateQuery(GL_ANY_SAMPLES_PASSED_EXT
, kClient1Id
,
178 kSharedMemoryId
, kSharedMemoryOffset
, kService1Id
));
179 ASSERT_TRUE(query
.get() != NULL
);
180 EXPECT_CALL(*gl_
, DeleteQueries(1, ::testing::Pointee(kService1Id
)))
182 .RetiresOnSaturation();
183 manager_
->Destroy(true);
184 // Check we get nothing for a non-existent query.
185 EXPECT_TRUE(manager_
->GetQuery(kClient1Id
) == NULL
);
186 // Check query is deleted
187 EXPECT_TRUE(query
->IsDeleted());
190 TEST_F(QueryManagerTest
, QueryBasic
) {
191 const GLuint kClient1Id
= 1;
192 const GLuint kService1Id
= 11;
193 const GLenum kTarget
= GL_ANY_SAMPLES_PASSED_EXT
;
196 scoped_refptr
<QueryManager::Query
> query(
197 CreateQuery(kTarget
, kClient1Id
,
198 kSharedMemoryId
, kSharedMemoryOffset
, kService1Id
));
199 ASSERT_TRUE(query
.get() != NULL
);
201 EXPECT_TRUE(query
->IsValid());
202 EXPECT_FALSE(query
->IsDeleted());
203 EXPECT_FALSE(query
->pending());
204 EXPECT_EQ(kTarget
, query
->target());
205 EXPECT_EQ(kSharedMemoryId
, query
->shm_id());
206 EXPECT_EQ(kSharedMemoryOffset
, query
->shm_offset());
209 TEST_F(QueryManagerTest
, ProcessPendingQuery
) {
210 const GLuint kClient1Id
= 1;
211 const GLuint kService1Id
= 11;
212 const GLenum kTarget
= GL_ANY_SAMPLES_PASSED_EXT
;
213 const base::subtle::Atomic32 kSubmitCount
= 123;
214 const GLuint kResult
= 1;
216 // Check nothing happens if there are no pending queries.
217 EXPECT_TRUE(manager_
->ProcessPendingQueries(false));
220 scoped_refptr
<QueryManager::Query
> query(
221 CreateQuery(kTarget
, kClient1Id
,
222 kSharedMemoryId
, kSharedMemoryOffset
, kService1Id
));
223 ASSERT_TRUE(query
.get() != NULL
);
225 // Setup shared memory like client would.
226 QuerySync
* sync
= decoder_
->GetSharedMemoryAs
<QuerySync
*>(
227 kSharedMemoryId
, kSharedMemoryOffset
, sizeof(*sync
));
228 ASSERT_TRUE(sync
!= NULL
);
232 QueueQuery(query
.get(), kService1Id
, kSubmitCount
);
233 EXPECT_TRUE(query
->pending());
234 EXPECT_TRUE(manager_
->HavePendingQueries());
236 // Process with return not available.
237 // Expect 1 GL command.
239 GetQueryObjectuiv(kService1Id
, GL_QUERY_RESULT_AVAILABLE_EXT
, _
))
240 .WillOnce(SetArgumentPointee
<2>(0))
241 .RetiresOnSaturation();
242 EXPECT_TRUE(manager_
->ProcessPendingQueries(false));
243 EXPECT_TRUE(query
->pending());
244 EXPECT_EQ(0, sync
->process_count
);
245 EXPECT_EQ(0u, sync
->result
);
247 // Process with return available.
248 // Expect 2 GL commands.
250 GetQueryObjectuiv(kService1Id
, GL_QUERY_RESULT_AVAILABLE_EXT
, _
))
251 .WillOnce(SetArgumentPointee
<2>(1))
252 .RetiresOnSaturation();
254 GetQueryObjectuiv(kService1Id
, GL_QUERY_RESULT_EXT
, _
))
255 .WillOnce(SetArgumentPointee
<2>(kResult
))
256 .RetiresOnSaturation();
257 EXPECT_TRUE(manager_
->ProcessPendingQueries(false));
258 EXPECT_FALSE(query
->pending());
259 EXPECT_EQ(kSubmitCount
, sync
->process_count
);
260 EXPECT_EQ(kResult
, sync
->result
);
261 EXPECT_FALSE(manager_
->HavePendingQueries());
263 // Process with no queries.
264 // Expect no GL commands/
265 EXPECT_TRUE(manager_
->ProcessPendingQueries(false));
268 TEST_F(QueryManagerTest
, ProcessPendingQueries
) {
269 const GLuint kClient1Id
= 1;
270 const GLuint kService1Id
= 11;
271 const GLuint kClient2Id
= 2;
272 const GLuint kService2Id
= 12;
273 const GLuint kClient3Id
= 3;
274 const GLuint kService3Id
= 13;
275 const GLenum kTarget
= GL_ANY_SAMPLES_PASSED_EXT
;
276 const base::subtle::Atomic32 kSubmitCount1
= 123;
277 const base::subtle::Atomic32 kSubmitCount2
= 123;
278 const base::subtle::Atomic32 kSubmitCount3
= 123;
279 const GLuint kResult1
= 1;
280 const GLuint kResult2
= 1;
281 const GLuint kResult3
= 1;
283 // Setup shared memory like client would.
284 QuerySync
* sync1
= decoder_
->GetSharedMemoryAs
<QuerySync
*>(
285 kSharedMemoryId
, kSharedMemoryOffset
, sizeof(*sync1
) * 3);
286 ASSERT_TRUE(sync1
!= NULL
);
287 QuerySync
* sync2
= sync1
+ 1;
288 QuerySync
* sync3
= sync2
+ 1;
291 scoped_refptr
<QueryManager::Query
> query1(
292 CreateQuery(kTarget
, kClient1Id
,
293 kSharedMemoryId
, kSharedMemoryOffset
+ sizeof(*sync1
) * 0,
295 scoped_refptr
<QueryManager::Query
> query2(
296 CreateQuery(kTarget
, kClient2Id
,
297 kSharedMemoryId
, kSharedMemoryOffset
+ sizeof(*sync1
) * 1,
299 scoped_refptr
<QueryManager::Query
> query3(
300 CreateQuery(kTarget
, kClient3Id
,
301 kSharedMemoryId
, kSharedMemoryOffset
+ sizeof(*sync1
) * 2,
303 ASSERT_TRUE(query1
.get() != NULL
);
304 ASSERT_TRUE(query2
.get() != NULL
);
305 ASSERT_TRUE(query3
.get() != NULL
);
306 EXPECT_FALSE(manager_
->HavePendingQueries());
313 QueueQuery(query1
.get(), kService1Id
, kSubmitCount1
);
314 QueueQuery(query2
.get(), kService2Id
, kSubmitCount2
);
315 QueueQuery(query3
.get(), kService3Id
, kSubmitCount3
);
316 EXPECT_TRUE(query1
->pending());
317 EXPECT_TRUE(query2
->pending());
318 EXPECT_TRUE(query3
->pending());
319 EXPECT_TRUE(manager_
->HavePendingQueries());
321 // Process with return available for first 2 queries.
322 // Expect 4 GL commands.
326 GetQueryObjectuiv(kService1Id
, GL_QUERY_RESULT_AVAILABLE_EXT
, _
))
327 .WillOnce(SetArgumentPointee
<2>(1))
328 .RetiresOnSaturation();
330 GetQueryObjectuiv(kService1Id
, GL_QUERY_RESULT_EXT
, _
))
331 .WillOnce(SetArgumentPointee
<2>(kResult1
))
332 .RetiresOnSaturation();
334 GetQueryObjectuiv(kService2Id
, GL_QUERY_RESULT_AVAILABLE_EXT
, _
))
335 .WillOnce(SetArgumentPointee
<2>(1))
336 .RetiresOnSaturation();
338 GetQueryObjectuiv(kService2Id
, GL_QUERY_RESULT_EXT
, _
))
339 .WillOnce(SetArgumentPointee
<2>(kResult2
))
340 .RetiresOnSaturation();
342 GetQueryObjectuiv(kService3Id
, GL_QUERY_RESULT_AVAILABLE_EXT
, _
))
343 .WillOnce(SetArgumentPointee
<2>(0))
344 .RetiresOnSaturation();
345 EXPECT_TRUE(manager_
->ProcessPendingQueries(false));
347 EXPECT_FALSE(query1
->pending());
348 EXPECT_FALSE(query2
->pending());
349 EXPECT_TRUE(query3
->pending());
350 EXPECT_EQ(kSubmitCount1
, sync1
->process_count
);
351 EXPECT_EQ(kSubmitCount2
, sync2
->process_count
);
352 EXPECT_EQ(kResult1
, sync1
->result
);
353 EXPECT_EQ(kResult2
, sync2
->result
);
354 EXPECT_EQ(0, sync3
->process_count
);
355 EXPECT_EQ(0u, sync3
->result
);
356 EXPECT_TRUE(manager_
->HavePendingQueries());
358 // Process with renaming query. No result.
359 // Expect 1 GL commands.
361 GetQueryObjectuiv(kService3Id
, GL_QUERY_RESULT_AVAILABLE_EXT
, _
))
362 .WillOnce(SetArgumentPointee
<2>(0))
363 .RetiresOnSaturation();
364 EXPECT_TRUE(manager_
->ProcessPendingQueries(false));
365 EXPECT_TRUE(query3
->pending());
366 EXPECT_EQ(0, sync3
->process_count
);
367 EXPECT_EQ(0u, sync3
->result
);
368 EXPECT_TRUE(manager_
->HavePendingQueries());
370 // Process with renaming query. With result.
371 // Expect 2 GL commands.
373 GetQueryObjectuiv(kService3Id
, GL_QUERY_RESULT_AVAILABLE_EXT
, _
))
374 .WillOnce(SetArgumentPointee
<2>(1))
375 .RetiresOnSaturation();
377 GetQueryObjectuiv(kService3Id
, GL_QUERY_RESULT_EXT
, _
))
378 .WillOnce(SetArgumentPointee
<2>(kResult3
))
379 .RetiresOnSaturation();
380 EXPECT_TRUE(manager_
->ProcessPendingQueries(false));
381 EXPECT_FALSE(query3
->pending());
382 EXPECT_EQ(kSubmitCount3
, sync3
->process_count
);
383 EXPECT_EQ(kResult3
, sync3
->result
);
384 EXPECT_FALSE(manager_
->HavePendingQueries());
387 TEST_F(QueryManagerTest
, ProcessPendingBadSharedMemoryId
) {
388 const GLuint kClient1Id
= 1;
389 const GLuint kService1Id
= 11;
390 const GLenum kTarget
= GL_ANY_SAMPLES_PASSED_EXT
;
391 const base::subtle::Atomic32 kSubmitCount
= 123;
392 const GLuint kResult
= 1;
395 scoped_refptr
<QueryManager::Query
> query(
396 CreateQuery(kTarget
, kClient1Id
,
397 kInvalidSharedMemoryId
, kSharedMemoryOffset
, kService1Id
));
398 ASSERT_TRUE(query
.get() != NULL
);
401 QueueQuery(query
.get(), kService1Id
, kSubmitCount
);
403 // Process with return available.
404 // Expect 2 GL commands.
406 GetQueryObjectuiv(kService1Id
, GL_QUERY_RESULT_AVAILABLE_EXT
, _
))
407 .WillOnce(SetArgumentPointee
<2>(1))
408 .RetiresOnSaturation();
410 GetQueryObjectuiv(kService1Id
, GL_QUERY_RESULT_EXT
, _
))
411 .WillOnce(SetArgumentPointee
<2>(kResult
))
412 .RetiresOnSaturation();
413 EXPECT_FALSE(manager_
->ProcessPendingQueries(false));
416 TEST_F(QueryManagerTest
, ProcessPendingBadSharedMemoryOffset
) {
417 const GLuint kClient1Id
= 1;
418 const GLuint kService1Id
= 11;
419 const GLenum kTarget
= GL_ANY_SAMPLES_PASSED_EXT
;
420 const base::subtle::Atomic32 kSubmitCount
= 123;
421 const GLuint kResult
= 1;
424 scoped_refptr
<QueryManager::Query
> query(
425 CreateQuery(kTarget
, kClient1Id
,
426 kSharedMemoryId
, kInvalidSharedMemoryOffset
, kService1Id
));
427 ASSERT_TRUE(query
.get() != NULL
);
430 QueueQuery(query
.get(), kService1Id
, kSubmitCount
);
432 // Process with return available.
433 // Expect 2 GL commands.
435 GetQueryObjectuiv(kService1Id
, GL_QUERY_RESULT_AVAILABLE_EXT
, _
))
436 .WillOnce(SetArgumentPointee
<2>(1))
437 .RetiresOnSaturation();
439 GetQueryObjectuiv(kService1Id
, GL_QUERY_RESULT_EXT
, _
))
440 .WillOnce(SetArgumentPointee
<2>(kResult
))
441 .RetiresOnSaturation();
442 EXPECT_FALSE(manager_
->ProcessPendingQueries(false));
445 TEST_F(QueryManagerTest
, ExitWithPendingQuery
) {
446 const GLuint kClient1Id
= 1;
447 const GLuint kService1Id
= 11;
448 const GLenum kTarget
= GL_ANY_SAMPLES_PASSED_EXT
;
449 const base::subtle::Atomic32 kSubmitCount
= 123;
452 scoped_refptr
<QueryManager::Query
> query(
453 CreateQuery(kTarget
, kClient1Id
,
454 kSharedMemoryId
, kSharedMemoryOffset
, kService1Id
));
455 ASSERT_TRUE(query
.get() != NULL
);
458 QueueQuery(query
.get(), kService1Id
, kSubmitCount
);
461 // Test that when based on ARB_occlusion_query2 we use GL_ANY_SAMPLES_PASSED_ARB
462 // for GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT
463 TEST_F(QueryManagerTest
, ARBOcclusionQuery2
) {
464 const GLuint kClient1Id
= 1;
465 const GLuint kService1Id
= 11;
466 const GLenum kTarget
= GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT
;
467 const base::subtle::Atomic32 kSubmitCount
= 123;
469 TestHelper::SetupFeatureInfoInitExpectations(
471 "GL_ARB_occlusion_query2");
472 scoped_refptr
<FeatureInfo
> feature_info(new FeatureInfo());
473 feature_info
->Initialize();
474 scoped_ptr
<QueryManager
> manager(
475 new QueryManager(decoder_
.get(), feature_info
.get()));
477 EXPECT_CALL(*gl_
, GenQueries(1, _
))
478 .WillOnce(SetArgumentPointee
<1>(kService1Id
))
479 .RetiresOnSaturation();
480 QueryManager::Query
* query
= manager
->CreateQuery(
481 kTarget
, kClient1Id
, kSharedMemoryId
, kSharedMemoryOffset
);
482 ASSERT_TRUE(query
!= NULL
);
484 EXPECT_CALL(*gl_
, BeginQuery(GL_ANY_SAMPLES_PASSED_EXT
, kService1Id
))
486 .RetiresOnSaturation();
487 EXPECT_CALL(*gl_
, EndQuery(GL_ANY_SAMPLES_PASSED_EXT
))
489 .RetiresOnSaturation();
490 EXPECT_TRUE(manager
->BeginQuery(query
));
491 EXPECT_TRUE(manager
->EndQuery(query
, kSubmitCount
));
492 manager
->Destroy(false);
495 // Test that when based on ARB_occlusion_query we use GL_SAMPLES_PASSED_ARB
496 // for GL_ANY_SAMPLES_PASSED_EXT
497 TEST_F(QueryManagerTest
, ARBOcclusionQuery
) {
498 const GLuint kClient1Id
= 1;
499 const GLuint kService1Id
= 11;
500 const GLenum kTarget
= GL_ANY_SAMPLES_PASSED_EXT
;
501 const base::subtle::Atomic32 kSubmitCount
= 123;
503 TestHelper::SetupFeatureInfoInitExpectations(
505 "GL_ARB_occlusion_query");
506 scoped_refptr
<FeatureInfo
> feature_info(new FeatureInfo());
507 feature_info
->Initialize();
508 scoped_ptr
<QueryManager
> manager(
509 new QueryManager(decoder_
.get(), feature_info
.get()));
511 EXPECT_CALL(*gl_
, GenQueries(1, _
))
512 .WillOnce(SetArgumentPointee
<1>(kService1Id
))
513 .RetiresOnSaturation();
514 QueryManager::Query
* query
= manager
->CreateQuery(
515 kTarget
, kClient1Id
, kSharedMemoryId
, kSharedMemoryOffset
);
516 ASSERT_TRUE(query
!= NULL
);
518 EXPECT_CALL(*gl_
, BeginQuery(GL_SAMPLES_PASSED_ARB
, kService1Id
))
520 .RetiresOnSaturation();
521 EXPECT_CALL(*gl_
, EndQuery(GL_SAMPLES_PASSED_ARB
))
523 .RetiresOnSaturation();
524 EXPECT_TRUE(manager
->BeginQuery(query
));
525 EXPECT_TRUE(manager
->EndQuery(query
, kSubmitCount
));
526 manager
->Destroy(false);
529 TEST_F(QueryManagerTest
, GetErrorQuery
) {
530 const GLuint kClient1Id
= 1;
531 const GLenum kTarget
= GL_GET_ERROR_QUERY_CHROMIUM
;
532 const base::subtle::Atomic32 kSubmitCount
= 123;
534 TestHelper::SetupFeatureInfoInitExpectations(gl_
.get(), "");
535 scoped_refptr
<FeatureInfo
> feature_info(new FeatureInfo());
536 feature_info
->Initialize();
537 scoped_ptr
<QueryManager
> manager(
538 new QueryManager(decoder_
.get(), feature_info
.get()));
540 QueryManager::Query
* query
= manager
->CreateQuery(
541 kTarget
, kClient1Id
, kSharedMemoryId
, kSharedMemoryOffset
);
542 ASSERT_TRUE(query
!= NULL
);
544 // Setup shared memory like client would.
545 QuerySync
* sync
= decoder_
->GetSharedMemoryAs
<QuerySync
*>(
546 kSharedMemoryId
, kSharedMemoryOffset
, sizeof(*sync
));
547 ASSERT_TRUE(sync
!= NULL
);
550 EXPECT_TRUE(manager
->BeginQuery(query
));
552 MockErrorState mock_error_state
;
553 EXPECT_CALL(*decoder_
.get(), GetErrorState())
554 .WillRepeatedly(Return(&mock_error_state
));
555 EXPECT_CALL(mock_error_state
, GetGLError())
556 .WillOnce(Return(GL_INVALID_ENUM
))
557 .RetiresOnSaturation();
559 EXPECT_TRUE(manager
->EndQuery(query
, kSubmitCount
));
560 EXPECT_FALSE(query
->pending());
562 EXPECT_EQ(static_cast<GLuint
>(GL_INVALID_ENUM
), sync
->result
);
564 manager
->Destroy(false);