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