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