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 |