OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "gpu/command_buffer/service/query_manager.h" | 5 #include "gpu/command_buffer/service/query_manager.h" |
6 | 6 |
7 #include "base/atomicops.h" | 7 #include "base/atomicops.h" |
8 #include "base/bind.h" | 8 #include "base/bind.h" |
9 #include "base/logging.h" | 9 #include "base/logging.h" |
10 #include "base/memory/shared_memory.h" | 10 #include "base/memory/shared_memory.h" |
11 #include "base/numerics/safe_math.h" | 11 #include "base/numerics/safe_math.h" |
12 #include "base/synchronization/lock.h" | 12 #include "base/synchronization/lock.h" |
13 #include "base/time/time.h" | 13 #include "base/time/time.h" |
14 #include "gpu/command_buffer/common/gles2_cmd_format.h" | 14 #include "gpu/command_buffer/common/gles2_cmd_format.h" |
15 #include "gpu/command_buffer/service/async_pixel_transfer_manager.h" | 15 #include "gpu/command_buffer/service/async_pixel_transfer_manager.h" |
16 #include "gpu/command_buffer/service/error_state.h" | 16 #include "gpu/command_buffer/service/error_state.h" |
17 #include "gpu/command_buffer/service/feature_info.h" | 17 #include "gpu/command_buffer/service/feature_info.h" |
18 #include "gpu/command_buffer/service/gles2_cmd_decoder.h" | 18 #include "gpu/command_buffer/service/gles2_cmd_decoder.h" |
19 #include "ui/gl/gl_fence.h" | 19 #include "ui/gl/gl_fence.h" |
| 20 #include "ui/gl/gpu_timing.h" |
20 | 21 |
21 namespace gpu { | 22 namespace gpu { |
22 namespace gles2 { | 23 namespace gles2 { |
23 | 24 |
24 namespace { | 25 namespace { |
25 | 26 |
26 class AsyncPixelTransferCompletionObserverImpl | 27 class AsyncPixelTransferCompletionObserverImpl |
27 : public AsyncPixelTransferCompletionObserver { | 28 : public AsyncPixelTransferCompletionObserver { |
28 public: | 29 public: |
29 AsyncPixelTransferCompletionObserverImpl(base::subtle::Atomic32 submit_count) | 30 AsyncPixelTransferCompletionObserverImpl(base::subtle::Atomic32 submit_count) |
(...skipping 411 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
441 | 442 |
442 void CommandsCompletedQuery::Destroy(bool have_context) { | 443 void CommandsCompletedQuery::Destroy(bool have_context) { |
443 if (have_context && !IsDeleted()) { | 444 if (have_context && !IsDeleted()) { |
444 fence_.reset(); | 445 fence_.reset(); |
445 MarkAsDeleted(); | 446 MarkAsDeleted(); |
446 } | 447 } |
447 } | 448 } |
448 | 449 |
449 CommandsCompletedQuery::~CommandsCompletedQuery() {} | 450 CommandsCompletedQuery::~CommandsCompletedQuery() {} |
450 | 451 |
| 452 class TimeElapsedQuery : public QueryManager::Query { |
| 453 public: |
| 454 TimeElapsedQuery(QueryManager* manager, |
| 455 GLenum target, |
| 456 int32 shm_id, |
| 457 uint32 shm_offset); |
| 458 |
| 459 // Overridden from QueryManager::Query: |
| 460 bool Begin() override; |
| 461 bool End(base::subtle::Atomic32 submit_count) override; |
| 462 bool Process(bool did_finish) override; |
| 463 void Destroy(bool have_context) override; |
| 464 |
| 465 protected: |
| 466 ~TimeElapsedQuery() override; |
| 467 |
| 468 private: |
| 469 scoped_ptr<gfx::GPUTimer> gpu_timer_; |
| 470 }; |
| 471 |
| 472 TimeElapsedQuery::TimeElapsedQuery(QueryManager* manager, |
| 473 GLenum target, |
| 474 int32 shm_id, |
| 475 uint32 shm_offset) |
| 476 : Query(manager, target, shm_id, shm_offset), |
| 477 gpu_timer_(manager->CreateGPUTimer(true)) {} |
| 478 |
| 479 bool TimeElapsedQuery::Begin() { |
| 480 gpu_timer_->Start(); |
| 481 return true; |
| 482 } |
| 483 |
| 484 bool TimeElapsedQuery::End(base::subtle::Atomic32 submit_count) { |
| 485 gpu_timer_->End(); |
| 486 return AddToPendingQueue(submit_count); |
| 487 } |
| 488 |
| 489 bool TimeElapsedQuery::Process(bool did_finish) { |
| 490 if (!gpu_timer_->IsAvailable()) |
| 491 return true; |
| 492 |
| 493 const uint64_t nano_seconds = |
| 494 gpu_timer_->GetDeltaElapsed() * base::Time::kNanosecondsPerMicrosecond; |
| 495 return MarkAsCompleted(nano_seconds); |
| 496 } |
| 497 |
| 498 void TimeElapsedQuery::Destroy(bool have_context) { |
| 499 if (gpu_timer_.get()) { |
| 500 gpu_timer_->Destroy(have_context); |
| 501 gpu_timer_.reset(); |
| 502 } |
| 503 } |
| 504 |
| 505 TimeElapsedQuery::~TimeElapsedQuery() {} |
| 506 |
451 QueryManager::QueryManager( | 507 QueryManager::QueryManager( |
452 GLES2Decoder* decoder, | 508 GLES2Decoder* decoder, |
453 FeatureInfo* feature_info) | 509 FeatureInfo* feature_info) |
454 : decoder_(decoder), | 510 : decoder_(decoder), |
455 use_arb_occlusion_query2_for_occlusion_query_boolean_( | 511 use_arb_occlusion_query2_for_occlusion_query_boolean_( |
456 feature_info->feature_flags( | 512 feature_info->feature_flags( |
457 ).use_arb_occlusion_query2_for_occlusion_query_boolean), | 513 ).use_arb_occlusion_query2_for_occlusion_query_boolean), |
458 use_arb_occlusion_query_for_occlusion_query_boolean_( | 514 use_arb_occlusion_query_for_occlusion_query_boolean_( |
459 feature_info->feature_flags( | 515 feature_info->feature_flags( |
460 ).use_arb_occlusion_query_for_occlusion_query_boolean), | 516 ).use_arb_occlusion_query_for_occlusion_query_boolean), |
461 query_count_(0) { | 517 query_count_(0) { |
462 DCHECK(!(use_arb_occlusion_query_for_occlusion_query_boolean_ && | 518 DCHECK(!(use_arb_occlusion_query_for_occlusion_query_boolean_ && |
463 use_arb_occlusion_query2_for_occlusion_query_boolean_)); | 519 use_arb_occlusion_query2_for_occlusion_query_boolean_)); |
| 520 DCHECK(decoder); |
| 521 gfx::GLContext* context = decoder_->GetGLContext(); |
| 522 if (context) { |
| 523 gpu_timing_client_ = context->CreateGPUTimingClient(); |
| 524 } else { |
| 525 gpu_timing_client_ = new gfx::GPUTimingClient(); |
| 526 } |
464 } | 527 } |
465 | 528 |
466 QueryManager::~QueryManager() { | 529 QueryManager::~QueryManager() { |
467 DCHECK(queries_.empty()); | 530 DCHECK(queries_.empty()); |
468 | 531 |
469 // If this triggers, that means something is keeping a reference to | 532 // If this triggers, that means something is keeping a reference to |
470 // a Query belonging to this. | 533 // a Query belonging to this. |
471 CHECK_EQ(query_count_, 0u); | 534 CHECK_EQ(query_count_, 0u); |
472 } | 535 } |
473 | 536 |
(...skipping 25 matching lines...) Expand all Loading... |
499 case GL_ASYNC_PIXEL_PACK_COMPLETED_CHROMIUM: | 562 case GL_ASYNC_PIXEL_PACK_COMPLETED_CHROMIUM: |
500 query = new AsyncReadPixelsCompletedQuery( | 563 query = new AsyncReadPixelsCompletedQuery( |
501 this, target, shm_id, shm_offset); | 564 this, target, shm_id, shm_offset); |
502 break; | 565 break; |
503 case GL_GET_ERROR_QUERY_CHROMIUM: | 566 case GL_GET_ERROR_QUERY_CHROMIUM: |
504 query = new GetErrorQuery(this, target, shm_id, shm_offset); | 567 query = new GetErrorQuery(this, target, shm_id, shm_offset); |
505 break; | 568 break; |
506 case GL_COMMANDS_COMPLETED_CHROMIUM: | 569 case GL_COMMANDS_COMPLETED_CHROMIUM: |
507 query = new CommandsCompletedQuery(this, target, shm_id, shm_offset); | 570 query = new CommandsCompletedQuery(this, target, shm_id, shm_offset); |
508 break; | 571 break; |
| 572 case GL_TIME_ELAPSED: |
| 573 query = new TimeElapsedQuery(this, target, shm_id, shm_offset); |
| 574 break; |
509 default: { | 575 default: { |
510 GLuint service_id = 0; | 576 GLuint service_id = 0; |
511 glGenQueries(1, &service_id); | 577 glGenQueries(1, &service_id); |
512 DCHECK_NE(0u, service_id); | 578 DCHECK_NE(0u, service_id); |
513 query = new AllSamplesPassedQuery( | 579 query = new AllSamplesPassedQuery( |
514 this, target, shm_id, shm_offset, service_id); | 580 this, target, shm_id, shm_offset, service_id); |
515 break; | 581 break; |
516 } | 582 } |
517 } | 583 } |
518 std::pair<QueryMap::iterator, bool> result = | 584 std::pair<QueryMap::iterator, bool> result = |
519 queries_.insert(std::make_pair(client_id, query)); | 585 queries_.insert(std::make_pair(client_id, query)); |
520 DCHECK(result.second); | 586 DCHECK(result.second); |
521 return query.get(); | 587 return query.get(); |
522 } | 588 } |
523 | 589 |
| 590 scoped_ptr<gfx::GPUTimer> QueryManager::CreateGPUTimer(bool elapsed_time) { |
| 591 return gpu_timing_client_->CreateGPUTimer(elapsed_time); |
| 592 } |
| 593 |
| 594 bool QueryManager::GPUTimingAvailable() { |
| 595 return gpu_timing_client_->IsAvailable(); |
| 596 } |
| 597 |
524 void QueryManager::GenQueries(GLsizei n, const GLuint* queries) { | 598 void QueryManager::GenQueries(GLsizei n, const GLuint* queries) { |
525 DCHECK_GE(n, 0); | 599 DCHECK_GE(n, 0); |
526 for (GLsizei i = 0; i < n; ++i) { | 600 for (GLsizei i = 0; i < n; ++i) { |
527 generated_query_ids_.insert(queries[i]); | 601 generated_query_ids_.insert(queries[i]); |
528 } | 602 } |
529 } | 603 } |
530 | 604 |
531 bool QueryManager::IsValidQuery(GLuint id) { | 605 bool QueryManager::IsValidQuery(GLuint id) { |
532 GeneratedQueryIds::iterator it = generated_query_ids_.find(id); | 606 GeneratedQueryIds::iterator it = generated_query_ids_.find(id); |
533 return it != generated_query_ids_.end(); | 607 return it != generated_query_ids_.end(); |
(...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
747 bool QueryManager::EndQuery(Query* query, base::subtle::Atomic32 submit_count) { | 821 bool QueryManager::EndQuery(Query* query, base::subtle::Atomic32 submit_count) { |
748 DCHECK(query); | 822 DCHECK(query); |
749 if (!RemovePendingQuery(query)) { | 823 if (!RemovePendingQuery(query)) { |
750 return false; | 824 return false; |
751 } | 825 } |
752 return query->End(submit_count); | 826 return query->End(submit_count); |
753 } | 827 } |
754 | 828 |
755 } // namespace gles2 | 829 } // namespace gles2 |
756 } // namespace gpu | 830 } // namespace gpu |
OLD | NEW |