Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / gpu / command_buffer / service / query_manager_unittest.cc
blob576aa35fd6eaca8001f2d7f187af4939471a70c1
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_context.h"
16 #include "ui/gl/gl_mock.h"
17 #include "ui/gl/gpu_timing.h"
18 #include "ui/gl/gpu_timing_fake.h"
20 using ::testing::_;
21 using ::testing::InSequence;
22 using ::testing::Return;
23 using ::testing::SetArgumentPointee;
25 namespace gpu {
26 namespace gles2 {
28 class QueryManagerTest : public GpuServiceTest {
29 public:
30 static const int32 kSharedMemoryId = 401;
31 static const uint32 kSharedMemoryOffset = 132;
32 static const int32 kSharedMemory2Id = 402;
33 static const uint32 kSharedMemory2Offset = 232;
34 static const size_t kSharedBufferSize = 2048;
35 static const int32 kInvalidSharedMemoryId = 403;
36 static const uint32 kInvalidSharedMemoryOffset = kSharedBufferSize + 1;
37 static const uint32 kInitialResult = 0xBDBDBDBDu;
38 static const uint8 kInitialMemoryValue = 0xBDu;
40 QueryManagerTest() {
42 ~QueryManagerTest() override {}
44 protected:
45 void SetUp() override {
46 GpuServiceTest::SetUpWithGLVersion("3.2",
47 "GL_ARB_occlusion_query, "
48 "GL_ARB_timer_query");
49 SetUpMockGL("GL_EXT_occlusion_query_boolean, GL_ARB_timer_query");
52 void TearDown() override {
53 decoder_.reset();
54 manager_->Destroy(false);
55 manager_.reset();
56 engine_.reset();
57 GpuServiceTest::TearDown();
60 void SetUpMockGL(const char* extension_expectations) {
61 engine_.reset(new MockCommandBufferEngine());
62 decoder_.reset(new MockGLES2Decoder());
63 decoder_->set_engine(engine_.get());
64 TestHelper::SetupFeatureInfoInitExpectations(
65 gl_.get(), extension_expectations);
66 EXPECT_CALL(*decoder_.get(), GetGLContext())
67 .WillRepeatedly(Return(GetGLContext()));
68 scoped_refptr<FeatureInfo> feature_info(new FeatureInfo());
69 feature_info->Initialize();
70 manager_.reset(new QueryManager(decoder_.get(), feature_info.get()));
73 QueryManager::Query* CreateQuery(
74 GLenum target, GLuint client_id, int32 shm_id, uint32 shm_offset,
75 GLuint service_id) {
76 EXPECT_CALL(*gl_, GenQueries(1, _))
77 .WillOnce(SetArgumentPointee<1>(service_id))
78 .RetiresOnSaturation();
79 return manager_->CreateQuery(target, client_id, shm_id, shm_offset);
82 void QueueQuery(QueryManager::Query* query,
83 GLuint service_id,
84 base::subtle::Atomic32 submit_count) {
85 EXPECT_CALL(*gl_, BeginQuery(query->target(), service_id))
86 .Times(1)
87 .RetiresOnSaturation();
88 EXPECT_CALL(*gl_, EndQuery(query->target()))
89 .Times(1)
90 .RetiresOnSaturation();
91 EXPECT_TRUE(manager_->BeginQuery(query));
92 EXPECT_TRUE(manager_->EndQuery(query, submit_count));
95 scoped_ptr<MockGLES2Decoder> decoder_;
96 scoped_ptr<QueryManager> manager_;
98 private:
99 class MockCommandBufferEngine : public CommandBufferEngine {
100 public:
101 MockCommandBufferEngine() {
102 scoped_ptr<base::SharedMemory> shared_memory(new base::SharedMemory());
103 shared_memory->CreateAndMapAnonymous(kSharedBufferSize);
104 valid_buffer_ =
105 MakeBufferFromSharedMemory(shared_memory.Pass(), kSharedBufferSize);
107 scoped_ptr<base::SharedMemory> shared_memory2(new base::SharedMemory());
108 shared_memory2->CreateAndMapAnonymous(kSharedBufferSize);
109 valid_buffer2_ =
110 MakeBufferFromSharedMemory(shared_memory2.Pass(), kSharedBufferSize);
112 ClearSharedMemory();
115 ~MockCommandBufferEngine() override {}
117 scoped_refptr<gpu::Buffer> GetSharedMemoryBuffer(int32 shm_id) override {
118 switch (shm_id) {
119 case kSharedMemoryId: return valid_buffer_;
120 case kSharedMemory2Id: return valid_buffer2_;
121 default: return invalid_buffer_;
125 void ClearSharedMemory() {
126 memset(valid_buffer_->memory(), kInitialMemoryValue, kSharedBufferSize);
127 memset(valid_buffer2_->memory(), kInitialMemoryValue, kSharedBufferSize);
130 void set_token(int32 token) override { DCHECK(false); }
132 bool SetGetBuffer(int32 /* transfer_buffer_id */) override {
133 DCHECK(false);
134 return false;
137 // Overridden from CommandBufferEngine.
138 bool SetGetOffset(int32 offset) override {
139 DCHECK(false);
140 return false;
143 // Overridden from CommandBufferEngine.
144 int32 GetGetOffset() override {
145 DCHECK(false);
146 return 0;
149 private:
150 scoped_refptr<gpu::Buffer> valid_buffer_;
151 scoped_refptr<gpu::Buffer> valid_buffer2_;
152 scoped_refptr<gpu::Buffer> invalid_buffer_;
155 scoped_ptr<MockCommandBufferEngine> engine_;
158 class QueryManagerManualSetupTest : public QueryManagerTest {
159 protected:
160 void SetUp() override {
161 // Let test setup manually.
165 // GCC requires these declarations, but MSVC requires they not be present
166 #ifndef COMPILER_MSVC
167 const int32 QueryManagerTest::kSharedMemoryId;
168 const uint32 QueryManagerTest::kSharedMemoryOffset;
169 const int32 QueryManagerTest::kSharedMemory2Id;
170 const uint32 QueryManagerTest::kSharedMemory2Offset;
171 const size_t QueryManagerTest::kSharedBufferSize;
172 const int32 QueryManagerTest::kInvalidSharedMemoryId;
173 const uint32 QueryManagerTest::kInvalidSharedMemoryOffset;
174 const uint32 QueryManagerTest::kInitialResult;
175 const uint8 QueryManagerTest::kInitialMemoryValue;
176 #endif
178 TEST_F(QueryManagerTest, Basic) {
179 const GLuint kClient1Id = 1;
180 const GLuint kService1Id = 11;
181 const GLuint kClient2Id = 2;
183 EXPECT_FALSE(manager_->HavePendingQueries());
184 // Check we can create a Query.
185 scoped_refptr<QueryManager::Query> query(
186 CreateQuery(GL_ANY_SAMPLES_PASSED_EXT, kClient1Id,
187 kSharedMemoryId, kSharedMemoryOffset, kService1Id));
188 ASSERT_TRUE(query.get() != NULL);
189 // Check we can get the same Query.
190 EXPECT_EQ(query.get(), manager_->GetQuery(kClient1Id));
191 // Check we get nothing for a non-existent query.
192 EXPECT_TRUE(manager_->GetQuery(kClient2Id) == NULL);
193 // Check we can delete the query.
194 EXPECT_CALL(*gl_, DeleteQueries(1, ::testing::Pointee(kService1Id)))
195 .Times(1)
196 .RetiresOnSaturation();
197 manager_->RemoveQuery(kClient1Id);
198 // Check we get nothing for a non-existent query.
199 EXPECT_TRUE(manager_->GetQuery(kClient1Id) == NULL);
200 // Check query is deleted
201 EXPECT_TRUE(query->IsDeleted());
202 EXPECT_FALSE(manager_->HavePendingQueries());
205 TEST_F(QueryManagerTest, Destroy) {
206 const GLuint kClient1Id = 1;
207 const GLuint kService1Id = 11;
209 // Create Query.
210 scoped_refptr<QueryManager::Query> query(
211 CreateQuery(GL_ANY_SAMPLES_PASSED_EXT, kClient1Id,
212 kSharedMemoryId, kSharedMemoryOffset, kService1Id));
213 ASSERT_TRUE(query.get() != NULL);
214 EXPECT_CALL(*gl_, DeleteQueries(1, ::testing::Pointee(kService1Id)))
215 .Times(1)
216 .RetiresOnSaturation();
217 manager_->Destroy(true);
218 // Check we get nothing for a non-existent query.
219 EXPECT_TRUE(manager_->GetQuery(kClient1Id) == NULL);
220 // Check query is deleted
221 EXPECT_TRUE(query->IsDeleted());
224 TEST_F(QueryManagerTest, QueryBasic) {
225 const GLuint kClient1Id = 1;
226 const GLuint kService1Id = 11;
227 const GLenum kTarget = GL_ANY_SAMPLES_PASSED_EXT;
229 // Create Query.
230 scoped_refptr<QueryManager::Query> query(
231 CreateQuery(kTarget, kClient1Id,
232 kSharedMemoryId, kSharedMemoryOffset, kService1Id));
233 ASSERT_TRUE(query.get() != NULL);
235 EXPECT_TRUE(query->IsValid());
236 EXPECT_FALSE(query->IsDeleted());
237 EXPECT_FALSE(query->IsPending());
238 EXPECT_EQ(kTarget, query->target());
239 EXPECT_EQ(kSharedMemoryId, query->shm_id());
240 EXPECT_EQ(kSharedMemoryOffset, query->shm_offset());
243 TEST_F(QueryManagerTest, ProcessPendingQuery) {
244 const GLuint kClient1Id = 1;
245 const GLuint kService1Id = 11;
246 const GLenum kTarget = GL_ANY_SAMPLES_PASSED_EXT;
247 const base::subtle::Atomic32 kSubmitCount = 123;
248 const GLuint kResult = 1;
250 // Check nothing happens if there are no pending queries.
251 EXPECT_TRUE(manager_->ProcessPendingQueries(false));
253 // Create Query.
254 scoped_refptr<QueryManager::Query> query(
255 CreateQuery(kTarget, kClient1Id,
256 kSharedMemoryId, kSharedMemoryOffset, kService1Id));
257 ASSERT_TRUE(query.get() != NULL);
259 // Setup shared memory like client would.
260 QuerySync* sync = decoder_->GetSharedMemoryAs<QuerySync*>(
261 kSharedMemoryId, kSharedMemoryOffset, sizeof(*sync));
262 ASSERT_TRUE(sync != NULL);
263 sync->Reset();
265 // Queue it
266 QueueQuery(query.get(), kService1Id, kSubmitCount);
267 EXPECT_TRUE(query->IsPending());
268 EXPECT_TRUE(manager_->HavePendingQueries());
270 // Process with return not available.
271 // Expect 1 GL command.
272 EXPECT_CALL(*gl_,
273 GetQueryObjectuiv(kService1Id, GL_QUERY_RESULT_AVAILABLE_EXT, _))
274 .WillOnce(SetArgumentPointee<2>(0))
275 .RetiresOnSaturation();
276 EXPECT_TRUE(manager_->ProcessPendingQueries(false));
277 EXPECT_TRUE(query->IsPending());
278 EXPECT_EQ(0, sync->process_count);
279 EXPECT_EQ(0u, sync->result);
281 // Process with return available.
282 // Expect 2 GL commands.
283 EXPECT_CALL(*gl_,
284 GetQueryObjectuiv(kService1Id, GL_QUERY_RESULT_AVAILABLE_EXT, _))
285 .WillOnce(SetArgumentPointee<2>(1))
286 .RetiresOnSaturation();
287 EXPECT_CALL(*gl_,
288 GetQueryObjectuiv(kService1Id, GL_QUERY_RESULT_EXT, _))
289 .WillOnce(SetArgumentPointee<2>(kResult))
290 .RetiresOnSaturation();
291 EXPECT_TRUE(manager_->ProcessPendingQueries(false));
292 EXPECT_FALSE(query->IsPending());
293 EXPECT_EQ(kSubmitCount, sync->process_count);
294 EXPECT_EQ(kResult, sync->result);
295 EXPECT_FALSE(manager_->HavePendingQueries());
297 // Process with no queries.
298 // Expect no GL commands/
299 EXPECT_TRUE(manager_->ProcessPendingQueries(false));
302 TEST_F(QueryManagerTest, ProcessPendingQueries) {
303 const GLuint kClient1Id = 1;
304 const GLuint kService1Id = 11;
305 const GLuint kClient2Id = 2;
306 const GLuint kService2Id = 12;
307 const GLuint kClient3Id = 3;
308 const GLuint kService3Id = 13;
309 const GLenum kTarget = GL_ANY_SAMPLES_PASSED_EXT;
310 const base::subtle::Atomic32 kSubmitCount1 = 123;
311 const base::subtle::Atomic32 kSubmitCount2 = 123;
312 const base::subtle::Atomic32 kSubmitCount3 = 123;
313 const GLuint kResult1 = 1;
314 const GLuint kResult2 = 1;
315 const GLuint kResult3 = 1;
317 // Setup shared memory like client would.
318 QuerySync* sync1 = decoder_->GetSharedMemoryAs<QuerySync*>(
319 kSharedMemoryId, kSharedMemoryOffset, sizeof(*sync1) * 3);
320 ASSERT_TRUE(sync1 != NULL);
321 QuerySync* sync2 = sync1 + 1;
322 QuerySync* sync3 = sync2 + 1;
324 // Create Queries.
325 scoped_refptr<QueryManager::Query> query1(
326 CreateQuery(kTarget, kClient1Id,
327 kSharedMemoryId, kSharedMemoryOffset + sizeof(*sync1) * 0,
328 kService1Id));
329 scoped_refptr<QueryManager::Query> query2(
330 CreateQuery(kTarget, kClient2Id,
331 kSharedMemoryId, kSharedMemoryOffset + sizeof(*sync1) * 1,
332 kService2Id));
333 scoped_refptr<QueryManager::Query> query3(
334 CreateQuery(kTarget, kClient3Id,
335 kSharedMemoryId, kSharedMemoryOffset + sizeof(*sync1) * 2,
336 kService3Id));
337 ASSERT_TRUE(query1.get() != NULL);
338 ASSERT_TRUE(query2.get() != NULL);
339 ASSERT_TRUE(query3.get() != NULL);
340 EXPECT_FALSE(manager_->HavePendingQueries());
342 sync1->Reset();
343 sync2->Reset();
344 sync3->Reset();
346 // Queue them
347 QueueQuery(query1.get(), kService1Id, kSubmitCount1);
348 QueueQuery(query2.get(), kService2Id, kSubmitCount2);
349 QueueQuery(query3.get(), kService3Id, kSubmitCount3);
350 EXPECT_TRUE(query1->IsPending());
351 EXPECT_TRUE(query2->IsPending());
352 EXPECT_TRUE(query3->IsPending());
353 EXPECT_TRUE(manager_->HavePendingQueries());
355 // Process with return available for first 2 queries.
356 // Expect 4 GL commands.
358 InSequence s;
359 EXPECT_CALL(*gl_,
360 GetQueryObjectuiv(kService1Id, GL_QUERY_RESULT_AVAILABLE_EXT, _))
361 .WillOnce(SetArgumentPointee<2>(1))
362 .RetiresOnSaturation();
363 EXPECT_CALL(*gl_,
364 GetQueryObjectuiv(kService1Id, GL_QUERY_RESULT_EXT, _))
365 .WillOnce(SetArgumentPointee<2>(kResult1))
366 .RetiresOnSaturation();
367 EXPECT_CALL(*gl_,
368 GetQueryObjectuiv(kService2Id, GL_QUERY_RESULT_AVAILABLE_EXT, _))
369 .WillOnce(SetArgumentPointee<2>(1))
370 .RetiresOnSaturation();
371 EXPECT_CALL(*gl_,
372 GetQueryObjectuiv(kService2Id, GL_QUERY_RESULT_EXT, _))
373 .WillOnce(SetArgumentPointee<2>(kResult2))
374 .RetiresOnSaturation();
375 EXPECT_CALL(*gl_,
376 GetQueryObjectuiv(kService3Id, GL_QUERY_RESULT_AVAILABLE_EXT, _))
377 .WillOnce(SetArgumentPointee<2>(0))
378 .RetiresOnSaturation();
379 EXPECT_TRUE(manager_->ProcessPendingQueries(false));
381 EXPECT_FALSE(query1->IsPending());
382 EXPECT_FALSE(query2->IsPending());
383 EXPECT_TRUE(query3->IsPending());
384 EXPECT_EQ(kSubmitCount1, sync1->process_count);
385 EXPECT_EQ(kSubmitCount2, sync2->process_count);
386 EXPECT_EQ(kResult1, sync1->result);
387 EXPECT_EQ(kResult2, sync2->result);
388 EXPECT_EQ(0, sync3->process_count);
389 EXPECT_EQ(0u, sync3->result);
390 EXPECT_TRUE(manager_->HavePendingQueries());
392 // Process with renaming query. No result.
393 // Expect 1 GL commands.
394 EXPECT_CALL(*gl_,
395 GetQueryObjectuiv(kService3Id, GL_QUERY_RESULT_AVAILABLE_EXT, _))
396 .WillOnce(SetArgumentPointee<2>(0))
397 .RetiresOnSaturation();
398 EXPECT_TRUE(manager_->ProcessPendingQueries(false));
399 EXPECT_TRUE(query3->IsPending());
400 EXPECT_EQ(0, sync3->process_count);
401 EXPECT_EQ(0u, sync3->result);
402 EXPECT_TRUE(manager_->HavePendingQueries());
404 // Process with renaming query. With result.
405 // Expect 2 GL commands.
406 EXPECT_CALL(*gl_,
407 GetQueryObjectuiv(kService3Id, GL_QUERY_RESULT_AVAILABLE_EXT, _))
408 .WillOnce(SetArgumentPointee<2>(1))
409 .RetiresOnSaturation();
410 EXPECT_CALL(*gl_,
411 GetQueryObjectuiv(kService3Id, GL_QUERY_RESULT_EXT, _))
412 .WillOnce(SetArgumentPointee<2>(kResult3))
413 .RetiresOnSaturation();
414 EXPECT_TRUE(manager_->ProcessPendingQueries(false));
415 EXPECT_FALSE(query3->IsPending());
416 EXPECT_EQ(kSubmitCount3, sync3->process_count);
417 EXPECT_EQ(kResult3, sync3->result);
418 EXPECT_FALSE(manager_->HavePendingQueries());
421 TEST_F(QueryManagerTest, ProcessPendingBadSharedMemoryId) {
422 const GLuint kClient1Id = 1;
423 const GLuint kService1Id = 11;
424 const GLenum kTarget = GL_ANY_SAMPLES_PASSED_EXT;
425 const base::subtle::Atomic32 kSubmitCount = 123;
426 const GLuint kResult = 1;
428 // Create Query.
429 scoped_refptr<QueryManager::Query> query(
430 CreateQuery(kTarget, kClient1Id,
431 kInvalidSharedMemoryId, kSharedMemoryOffset, kService1Id));
432 ASSERT_TRUE(query.get() != NULL);
434 // Queue it
435 QueueQuery(query.get(), kService1Id, kSubmitCount);
437 // Process with return available.
438 // Expect 2 GL commands.
439 EXPECT_CALL(*gl_,
440 GetQueryObjectuiv(kService1Id, GL_QUERY_RESULT_AVAILABLE_EXT, _))
441 .WillOnce(SetArgumentPointee<2>(1))
442 .RetiresOnSaturation();
443 EXPECT_CALL(*gl_,
444 GetQueryObjectuiv(kService1Id, GL_QUERY_RESULT_EXT, _))
445 .WillOnce(SetArgumentPointee<2>(kResult))
446 .RetiresOnSaturation();
447 EXPECT_FALSE(manager_->ProcessPendingQueries(false));
450 TEST_F(QueryManagerTest, ProcessPendingBadSharedMemoryOffset) {
451 const GLuint kClient1Id = 1;
452 const GLuint kService1Id = 11;
453 const GLenum kTarget = GL_ANY_SAMPLES_PASSED_EXT;
454 const base::subtle::Atomic32 kSubmitCount = 123;
455 const GLuint kResult = 1;
457 // Create Query.
458 scoped_refptr<QueryManager::Query> query(
459 CreateQuery(kTarget, kClient1Id,
460 kSharedMemoryId, kInvalidSharedMemoryOffset, kService1Id));
461 ASSERT_TRUE(query.get() != NULL);
463 // Queue it
464 QueueQuery(query.get(), kService1Id, kSubmitCount);
466 // Process with return available.
467 // Expect 2 GL commands.
468 EXPECT_CALL(*gl_,
469 GetQueryObjectuiv(kService1Id, GL_QUERY_RESULT_AVAILABLE_EXT, _))
470 .WillOnce(SetArgumentPointee<2>(1))
471 .RetiresOnSaturation();
472 EXPECT_CALL(*gl_,
473 GetQueryObjectuiv(kService1Id, GL_QUERY_RESULT_EXT, _))
474 .WillOnce(SetArgumentPointee<2>(kResult))
475 .RetiresOnSaturation();
476 EXPECT_FALSE(manager_->ProcessPendingQueries(false));
479 TEST_F(QueryManagerTest, ExitWithPendingQuery) {
480 const GLuint kClient1Id = 1;
481 const GLuint kService1Id = 11;
482 const GLenum kTarget = GL_ANY_SAMPLES_PASSED_EXT;
483 const base::subtle::Atomic32 kSubmitCount = 123;
485 // Create Query.
486 scoped_refptr<QueryManager::Query> query(
487 CreateQuery(kTarget, kClient1Id,
488 kSharedMemoryId, kSharedMemoryOffset, kService1Id));
489 ASSERT_TRUE(query.get() != NULL);
491 // Queue it
492 QueueQuery(query.get(), kService1Id, kSubmitCount);
495 // Test that when based on ARB_occlusion_query2 we use GL_ANY_SAMPLES_PASSED_ARB
496 // for GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT
497 TEST_F(QueryManagerTest, ARBOcclusionQuery2) {
498 const GLuint kClient1Id = 1;
499 const GLuint kService1Id = 11;
500 const GLenum kTarget = GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT;
501 const base::subtle::Atomic32 kSubmitCount = 123;
503 TestHelper::SetupFeatureInfoInitExpectations(
504 gl_.get(),
505 "GL_ARB_occlusion_query2");
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_ANY_SAMPLES_PASSED_EXT, kService1Id))
519 .Times(1)
520 .RetiresOnSaturation();
521 EXPECT_CALL(*gl_, EndQuery(GL_ANY_SAMPLES_PASSED_EXT))
522 .Times(1)
523 .RetiresOnSaturation();
524 EXPECT_TRUE(manager->BeginQuery(query));
525 EXPECT_TRUE(manager->EndQuery(query, kSubmitCount));
526 manager->Destroy(false);
529 // Test that when based on ARB_occlusion_query we use GL_SAMPLES_PASSED_ARB
530 // for GL_ANY_SAMPLES_PASSED_EXT
531 TEST_F(QueryManagerTest, ARBOcclusionQuery) {
532 const GLuint kClient1Id = 1;
533 const GLuint kService1Id = 11;
534 const GLenum kTarget = GL_ANY_SAMPLES_PASSED_EXT;
535 const base::subtle::Atomic32 kSubmitCount = 123;
537 TestHelper::SetupFeatureInfoInitExpectations(
538 gl_.get(),
539 "GL_ARB_occlusion_query");
540 scoped_refptr<FeatureInfo> feature_info(new FeatureInfo());
541 feature_info->Initialize();
542 scoped_ptr<QueryManager> manager(
543 new QueryManager(decoder_.get(), feature_info.get()));
545 EXPECT_CALL(*gl_, GenQueries(1, _))
546 .WillOnce(SetArgumentPointee<1>(kService1Id))
547 .RetiresOnSaturation();
548 QueryManager::Query* query = manager->CreateQuery(
549 kTarget, kClient1Id, kSharedMemoryId, kSharedMemoryOffset);
550 ASSERT_TRUE(query != NULL);
552 EXPECT_CALL(*gl_, BeginQuery(GL_SAMPLES_PASSED_ARB, kService1Id))
553 .Times(1)
554 .RetiresOnSaturation();
555 EXPECT_CALL(*gl_, EndQuery(GL_SAMPLES_PASSED_ARB))
556 .Times(1)
557 .RetiresOnSaturation();
558 EXPECT_TRUE(manager->BeginQuery(query));
559 EXPECT_TRUE(manager->EndQuery(query, kSubmitCount));
560 manager->Destroy(false);
563 TEST_F(QueryManagerTest, ARBOcclusionPauseResume) {
564 const GLuint kClient1Id = 1;
565 const GLuint kService1Id = 11;
566 const GLuint kService2Id = 12;
567 const GLenum kTarget = GL_ANY_SAMPLES_PASSED_EXT;
568 const base::subtle::Atomic32 kSubmitCount = 123;
570 TestHelper::SetupFeatureInfoInitExpectations(
571 gl_.get(),
572 "GL_ARB_occlusion_query");
573 scoped_refptr<FeatureInfo> feature_info(new FeatureInfo());
574 feature_info->Initialize();
575 scoped_ptr<QueryManager> manager(
576 new QueryManager(decoder_.get(), feature_info.get()));
578 EXPECT_CALL(*gl_, GenQueries(1, _))
579 .WillOnce(SetArgumentPointee<1>(kService1Id))
580 .RetiresOnSaturation();
581 QueryManager::Query* query = manager->CreateQuery(
582 kTarget, kClient1Id, kSharedMemoryId, kSharedMemoryOffset);
583 ASSERT_TRUE(query != NULL);
585 EXPECT_CALL(*gl_, BeginQuery(GL_SAMPLES_PASSED_ARB, kService1Id))
586 .Times(1)
587 .RetiresOnSaturation();
588 EXPECT_TRUE(manager->BeginQuery(query));
590 // Pause and Resume the manager.
591 EXPECT_CALL(*gl_, EndQuery(GL_SAMPLES_PASSED_ARB))
592 .Times(1)
593 .RetiresOnSaturation();
594 manager->PauseQueries();
596 EXPECT_CALL(*gl_, GenQueries(1, _))
597 .WillOnce(SetArgumentPointee<1>(kService2Id))
598 .RetiresOnSaturation();
599 EXPECT_CALL(*gl_, BeginQuery(GL_SAMPLES_PASSED_ARB, kService2Id))
600 .Times(1)
601 .RetiresOnSaturation();
602 manager->ResumeQueries();
604 EXPECT_CALL(*gl_, EndQuery(GL_SAMPLES_PASSED_ARB))
605 .Times(1)
606 .RetiresOnSaturation();
607 EXPECT_TRUE(manager->EndQuery(query, kSubmitCount));
609 EXPECT_CALL(*gl_, GetQueryObjectuiv(kService2Id,
610 GL_QUERY_RESULT_AVAILABLE_EXT, _))
611 .WillOnce(SetArgumentPointee<2>(1u))
612 .RetiresOnSaturation();
613 EXPECT_CALL(*gl_, GetQueryObjectuiv(kService1Id,
614 GL_QUERY_RESULT_EXT, _))
615 .WillOnce(SetArgumentPointee<2>(0u))
616 .RetiresOnSaturation();
617 EXPECT_CALL(*gl_, GetQueryObjectuiv(kService2Id,
618 GL_QUERY_RESULT_EXT, _))
619 .WillOnce(SetArgumentPointee<2>(1u))
620 .RetiresOnSaturation();
621 EXPECT_TRUE(manager->ProcessPendingQueries(false));
622 EXPECT_TRUE(query->IsFinished());
624 QuerySync* sync = decoder_->GetSharedMemoryAs<QuerySync*>(
625 kSharedMemoryId, kSharedMemoryOffset, sizeof(*sync));
626 EXPECT_EQ(1u, sync->result);
628 // Make sure new query still works.
629 EXPECT_CALL(*gl_, DeleteQueries(1, ::testing::Pointee(kService2Id)))
630 .Times(1)
631 .RetiresOnSaturation();
632 EXPECT_CALL(*gl_, BeginQuery(GL_SAMPLES_PASSED_ARB, kService1Id))
633 .Times(1)
634 .RetiresOnSaturation();
635 EXPECT_CALL(*gl_, EndQuery(GL_SAMPLES_PASSED_ARB))
636 .Times(1)
637 .RetiresOnSaturation();
638 EXPECT_TRUE(manager->BeginQuery(query));
639 EXPECT_TRUE(manager->EndQuery(query, kSubmitCount + 1));
641 EXPECT_CALL(*gl_, GetQueryObjectuiv(kService1Id,
642 GL_QUERY_RESULT_AVAILABLE_EXT, _))
643 .WillOnce(SetArgumentPointee<2>(1u))
644 .RetiresOnSaturation();
645 EXPECT_CALL(*gl_, GetQueryObjectuiv(kService1Id,
646 GL_QUERY_RESULT_EXT, _))
647 .WillOnce(SetArgumentPointee<2>(0u))
648 .RetiresOnSaturation();
649 EXPECT_TRUE(manager->ProcessPendingQueries(false));
650 EXPECT_TRUE(query->IsFinished());
652 EXPECT_EQ(0u, sync->result);
653 EXPECT_CALL(*gl_, DeleteQueries(1, ::testing::Pointee(kService1Id)))
654 .Times(1)
655 .RetiresOnSaturation();
656 manager->Destroy(true);
659 TEST_F(QueryManagerTest, TimeElapsedQuery) {
660 const GLuint kClient1Id = 1;
661 const GLenum kTarget = GL_TIME_ELAPSED_EXT;
662 const base::subtle::Atomic32 kSubmitCount = 123;
663 gfx::GPUTimingFake fake_timing_queries;
664 decoder_->GetGLContext()->CreateGPUTimingClient()->SetCpuTimeForTesting(
665 base::Bind(&gfx::GPUTimingFake::GetFakeCPUTime));
667 QueryManager::Query* query = manager_->CreateQuery(
668 kTarget, kClient1Id, kSharedMemoryId, kSharedMemoryOffset);
669 ASSERT_TRUE(query != NULL);
671 fake_timing_queries.ExpectGPUTimerQuery(*gl_, true);
672 fake_timing_queries.SetCurrentGLTime(
673 200 * base::Time::kNanosecondsPerMicrosecond);
674 EXPECT_TRUE(manager_->BeginQuery(query));
675 fake_timing_queries.SetCurrentGLTime(
676 300 * base::Time::kNanosecondsPerMicrosecond);
677 EXPECT_TRUE(manager_->EndQuery(query, kSubmitCount));
678 EXPECT_TRUE(manager_->ProcessPendingQueries(false));
680 EXPECT_TRUE(query->IsFinished());
682 QuerySync* sync = decoder_->GetSharedMemoryAs<QuerySync*>(
683 kSharedMemoryId, kSharedMemoryOffset, sizeof(*sync));
684 const uint64_t expected_result =
685 100u * base::Time::kNanosecondsPerMicrosecond;
686 EXPECT_EQ(expected_result, sync->result);
688 manager_->Destroy(false);
691 TEST_F(QueryManagerTest, TimeElapsedPauseResume) {
692 const GLuint kClient1Id = 1;
693 const GLenum kTarget = GL_TIME_ELAPSED_EXT;
694 const base::subtle::Atomic32 kSubmitCount = 123;
695 gfx::GPUTimingFake fake_timing_queries;
696 decoder_->GetGLContext()->CreateGPUTimingClient()->SetCpuTimeForTesting(
697 base::Bind(&gfx::GPUTimingFake::GetFakeCPUTime));
699 QueryManager::Query* query = manager_->CreateQuery(
700 kTarget, kClient1Id, kSharedMemoryId, kSharedMemoryOffset);
701 ASSERT_TRUE(query != NULL);
703 fake_timing_queries.ExpectGPUTimerQuery(*gl_, true);
704 fake_timing_queries.SetCurrentGLTime(
705 200 * base::Time::kNanosecondsPerMicrosecond);
706 EXPECT_TRUE(manager_->BeginQuery(query));
708 // Pause and Resume here.
709 fake_timing_queries.SetCurrentGLTime(
710 300 * base::Time::kNanosecondsPerMicrosecond);
711 manager_->PauseQueries();
713 fake_timing_queries.SetCurrentGLTime(
714 400 * base::Time::kNanosecondsPerMicrosecond);
715 manager_->ResumeQueries();
717 fake_timing_queries.SetCurrentGLTime(
718 500 * base::Time::kNanosecondsPerMicrosecond);
719 EXPECT_TRUE(manager_->EndQuery(query, kSubmitCount));
721 EXPECT_TRUE(manager_->ProcessPendingQueries(false));
722 EXPECT_TRUE(query->IsFinished());
724 QuerySync* sync = decoder_->GetSharedMemoryAs<QuerySync*>(
725 kSharedMemoryId, kSharedMemoryOffset, sizeof(*sync));
726 const uint64_t expected_result =
727 300u * base::Time::kNanosecondsPerMicrosecond;
728 EXPECT_EQ(expected_result, sync->result);
730 // Make sure next query works properly.
731 fake_timing_queries.SetCurrentGLTime(
732 600 * base::Time::kNanosecondsPerMicrosecond);
733 EXPECT_TRUE(manager_->BeginQuery(query));
734 fake_timing_queries.SetCurrentGLTime(
735 700 * base::Time::kNanosecondsPerMicrosecond);
736 EXPECT_TRUE(manager_->EndQuery(query, kSubmitCount + 1));
737 EXPECT_TRUE(manager_->ProcessPendingQueries(false));
739 EXPECT_TRUE(query->IsFinished());
741 const uint64_t expected_result2 =
742 100u * base::Time::kNanosecondsPerMicrosecond;
743 EXPECT_EQ(expected_result2, sync->result);
745 manager_->Destroy(false);
748 TEST_F(QueryManagerManualSetupTest, TimeElapsedDisjoint) {
749 GpuServiceTest::SetUpWithGLVersion("OpenGL ES 3.0",
750 "GL_EXT_disjoint_timer_query");
751 gfx::GPUTimingFake fake_timing_queries;
752 fake_timing_queries.ExpectDisjointCalls(*gl_);
753 SetUpMockGL("GL_EXT_disjoint_timer_query");
755 DisjointValueSync* disjoint_sync =
756 decoder_->GetSharedMemoryAs<DisjointValueSync*>(kSharedMemory2Id,
757 kSharedMemory2Offset,
758 sizeof(*disjoint_sync));
759 manager_->SetDisjointSync(kSharedMemory2Id, kSharedMemory2Offset);
761 const uint32_t current_disjoint_value = disjoint_sync->GetDisjointCount();
762 ASSERT_EQ(0u, current_disjoint_value);
764 const GLuint kClient1Id = 1;
765 const GLenum kTarget = GL_TIME_ELAPSED_EXT;
766 const base::subtle::Atomic32 kSubmitCount = 123;
768 QueryManager::Query* query = manager_->CreateQuery(
769 kTarget, kClient1Id, kSharedMemoryId, kSharedMemoryOffset);
770 ASSERT_TRUE(query != NULL);
772 // Disjoint happening before the query should not trigger a disjoint event.
773 fake_timing_queries.SetDisjoint();
775 fake_timing_queries.ExpectGPUTimerQuery(*gl_, true);
776 EXPECT_TRUE(manager_->BeginQuery(query));
777 EXPECT_TRUE(manager_->EndQuery(query, kSubmitCount));
778 EXPECT_TRUE(manager_->ProcessPendingQueries(false));
780 EXPECT_TRUE(query->IsFinished());
781 EXPECT_EQ(current_disjoint_value, disjoint_sync->GetDisjointCount());
783 // Disjoint happening during query should trigger disjoint event.
784 fake_timing_queries.ExpectGPUTimerQuery(*gl_, true);
785 EXPECT_TRUE(manager_->BeginQuery(query));
786 fake_timing_queries.SetDisjoint();
787 EXPECT_TRUE(manager_->EndQuery(query, kSubmitCount));
788 EXPECT_TRUE(manager_->ProcessPendingQueries(false));
790 EXPECT_TRUE(query->IsFinished());
791 EXPECT_NE(current_disjoint_value, disjoint_sync->GetDisjointCount());
793 manager_->Destroy(false);
796 TEST_F(QueryManagerTest, TimeStampQuery) {
797 const GLuint kClient1Id = 1;
798 const GLenum kTarget = GL_TIMESTAMP_EXT;
799 const base::subtle::Atomic32 kSubmitCount = 123;
800 gfx::GPUTimingFake fake_timing_queries;
802 decoder_->GetGLContext()->CreateGPUTimingClient()->SetCpuTimeForTesting(
803 base::Bind(&gfx::GPUTimingFake::GetFakeCPUTime));
805 QueryManager::Query* query = manager_->CreateQuery(
806 kTarget, kClient1Id, kSharedMemoryId, kSharedMemoryOffset);
807 ASSERT_TRUE(query != NULL);
809 const uint64_t expected_result =
810 100u * base::Time::kNanosecondsPerMicrosecond;
811 fake_timing_queries.SetCurrentGLTime(expected_result);
812 fake_timing_queries.ExpectGPUTimeStampQuery(*gl_, false);
813 EXPECT_TRUE(manager_->QueryCounter(query, kSubmitCount));
814 EXPECT_TRUE(manager_->ProcessPendingQueries(false));
816 QuerySync* sync = decoder_->GetSharedMemoryAs<QuerySync*>(
817 kSharedMemoryId, kSharedMemoryOffset, sizeof(*sync));
818 EXPECT_EQ(expected_result, sync->result);
820 manager_->Destroy(false);
823 TEST_F(QueryManagerManualSetupTest, TimeStampDisjoint) {
824 GpuServiceTest::SetUpWithGLVersion("OpenGL ES 3.0",
825 "GL_EXT_disjoint_timer_query");
826 gfx::GPUTimingFake fake_timing_queries;
827 fake_timing_queries.ExpectDisjointCalls(*gl_);
828 SetUpMockGL("GL_EXT_disjoint_timer_query");
830 DisjointValueSync* disjoint_sync =
831 decoder_->GetSharedMemoryAs<DisjointValueSync*>(kSharedMemory2Id,
832 kSharedMemory2Offset,
833 sizeof(*disjoint_sync));
834 manager_->SetDisjointSync(kSharedMemory2Id, kSharedMemory2Offset);
836 const uint32_t current_disjoint_value = disjoint_sync->GetDisjointCount();
837 ASSERT_EQ(0u, current_disjoint_value);
839 const GLuint kClient1Id = 1;
840 const GLenum kTarget = GL_TIMESTAMP_EXT;
841 const base::subtle::Atomic32 kSubmitCount = 123;
843 QueryManager::Query* query = manager_->CreateQuery(
844 kTarget, kClient1Id, kSharedMemoryId, kSharedMemoryOffset);
845 ASSERT_TRUE(query != NULL);
847 // Disjoint happening before the query should not trigger a disjoint event.
848 fake_timing_queries.SetDisjoint();
850 fake_timing_queries.ExpectGPUTimeStampQuery(*gl_, false);
851 EXPECT_TRUE(manager_->QueryCounter(query, kSubmitCount));
852 EXPECT_TRUE(manager_->ProcessPendingQueries(false));
854 EXPECT_TRUE(query->IsFinished());
855 EXPECT_EQ(current_disjoint_value, disjoint_sync->GetDisjointCount());
857 // Disjoint happening during query should trigger disjoint event.
858 fake_timing_queries.ExpectGPUTimeStampQuery(*gl_, false);
859 EXPECT_TRUE(manager_->QueryCounter(query, kSubmitCount));
860 fake_timing_queries.SetDisjoint();
861 EXPECT_TRUE(manager_->ProcessPendingQueries(false));
863 EXPECT_TRUE(query->IsFinished());
864 EXPECT_NE(current_disjoint_value, disjoint_sync->GetDisjointCount());
866 manager_->Destroy(false);
869 TEST_F(QueryManagerManualSetupTest, DisjointContinualTest) {
870 GpuServiceTest::SetUpWithGLVersion("OpenGL ES 3.0",
871 "GL_EXT_disjoint_timer_query");
872 gfx::GPUTimingFake fake_timing_queries;
873 fake_timing_queries.ExpectDisjointCalls(*gl_);
874 SetUpMockGL("GL_EXT_disjoint_timer_query");
876 DisjointValueSync* disjoint_sync =
877 decoder_->GetSharedMemoryAs<DisjointValueSync*>(kSharedMemory2Id,
878 kSharedMemory2Offset,
879 sizeof(*disjoint_sync));
880 manager_->SetDisjointSync(kSharedMemory2Id, kSharedMemory2Offset);
882 const uint32_t current_disjoint_value = disjoint_sync->GetDisjointCount();
883 ASSERT_EQ(0u, current_disjoint_value);
885 // Disjoint value should not be updated until we have a timestamp query.
886 fake_timing_queries.SetDisjoint();
887 manager_->ProcessFrameBeginUpdates();
888 EXPECT_EQ(current_disjoint_value, disjoint_sync->GetDisjointCount());
890 const GLuint kClient1Id = 1;
891 const GLenum kTarget = GL_TIMESTAMP_EXT;
892 const base::subtle::Atomic32 kSubmitCount = 123;
894 QueryManager::Query* query = manager_->CreateQuery(
895 kTarget, kClient1Id, kSharedMemoryId, kSharedMemoryOffset);
896 ASSERT_TRUE(query != NULL);
898 fake_timing_queries.ExpectGPUTimeStampQuery(*gl_, false);
899 EXPECT_TRUE(manager_->QueryCounter(query, kSubmitCount));
900 EXPECT_TRUE(manager_->ProcessPendingQueries(false));
902 EXPECT_EQ(current_disjoint_value, disjoint_sync->GetDisjointCount());
903 fake_timing_queries.SetDisjoint();
904 manager_->ProcessFrameBeginUpdates();
905 EXPECT_NE(current_disjoint_value, disjoint_sync->GetDisjointCount());
907 manager_->Destroy(false);
910 TEST_F(QueryManagerTest, GetErrorQuery) {
911 const GLuint kClient1Id = 1;
912 const GLenum kTarget = GL_GET_ERROR_QUERY_CHROMIUM;
913 const base::subtle::Atomic32 kSubmitCount = 123;
915 TestHelper::SetupFeatureInfoInitExpectations(gl_.get(), "");
916 scoped_refptr<FeatureInfo> feature_info(new FeatureInfo());
917 feature_info->Initialize();
918 scoped_ptr<QueryManager> manager(
919 new QueryManager(decoder_.get(), feature_info.get()));
921 QueryManager::Query* query = manager->CreateQuery(
922 kTarget, kClient1Id, kSharedMemoryId, kSharedMemoryOffset);
923 ASSERT_TRUE(query != NULL);
925 // Setup shared memory like client would.
926 QuerySync* sync = decoder_->GetSharedMemoryAs<QuerySync*>(
927 kSharedMemoryId, kSharedMemoryOffset, sizeof(*sync));
928 ASSERT_TRUE(sync != NULL);
929 sync->Reset();
931 EXPECT_TRUE(manager->BeginQuery(query));
933 MockErrorState mock_error_state;
934 EXPECT_CALL(*decoder_.get(), GetErrorState())
935 .WillRepeatedly(Return(&mock_error_state));
936 EXPECT_CALL(mock_error_state, GetGLError())
937 .WillOnce(Return(GL_INVALID_ENUM))
938 .RetiresOnSaturation();
940 EXPECT_TRUE(manager->EndQuery(query, kSubmitCount));
941 EXPECT_FALSE(query->IsPending());
943 EXPECT_EQ(static_cast<GLuint>(GL_INVALID_ENUM), sync->result);
945 manager->Destroy(false);
948 } // namespace gles2
949 } // namespace gpu