Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(43)

Side by Side Diff: ui/gl/gpu_timing.cc

Issue 1233233002: Added support for TimeStamp queries using QueryCounterEXT. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Removed GetQueryivEXT test with QueryCounter Created 5 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « ui/gl/gpu_timing.h ('k') | ui/gl/gpu_timing_fake.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2015 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2015 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 "ui/gl/gpu_timing.h" 5 #include "ui/gl/gpu_timing.h"
6 6
7 #include "base/time/time.h" 7 #include "base/time/time.h"
8 #include "ui/gl/gl_bindings.h" 8 #include "ui/gl/gl_bindings.h"
9 #include "ui/gl/gl_context.h" 9 #include "ui/gl/gl_context.h"
10 #include "ui/gl/gl_version_info.h" 10 #include "ui/gl/gl_version_info.h"
11 11
12 namespace gfx { 12 namespace gfx {
13 13
14 class TimeElapsedTimerQuery;
15 class TimerQuery;
16
14 int64_t NanoToMicro(uint64_t nano_seconds) { 17 int64_t NanoToMicro(uint64_t nano_seconds) {
15 const uint64_t up = nano_seconds + base::Time::kNanosecondsPerMicrosecond / 2; 18 const uint64_t up = nano_seconds + base::Time::kNanosecondsPerMicrosecond / 2;
16 return static_cast<int64_t>(up / base::Time::kNanosecondsPerMicrosecond); 19 return static_cast<int64_t>(up / base::Time::kNanosecondsPerMicrosecond);
17 } 20 }
18 21
19 class GPUTimingImpl : public GPUTiming { 22 class GPUTimingImpl : public GPUTiming {
20 public: 23 public:
21 GPUTimingImpl(GLContextReal* context); 24 GPUTimingImpl(GLContextReal* context);
22 ~GPUTimingImpl() override; 25 ~GPUTimingImpl() override;
23 26
(...skipping 282 matching lines...) Expand 10 before | Expand all | Expand 10 after
306 DCHECK(context); 309 DCHECK(context);
307 const GLVersionInfo* version_info = context->GetVersionInfo(); 310 const GLVersionInfo* version_info = context->GetVersionInfo();
308 DCHECK(version_info); 311 DCHECK(version_info);
309 if (version_info->is_es3 && // glGetInteger64v is supported under ES3. 312 if (version_info->is_es3 && // glGetInteger64v is supported under ES3.
310 context->HasExtension("GL_EXT_disjoint_timer_query")) { 313 context->HasExtension("GL_EXT_disjoint_timer_query")) {
311 timer_type_ = GPUTiming::kTimerTypeDisjoint; 314 timer_type_ = GPUTiming::kTimerTypeDisjoint;
312 } else if (context->HasExtension("GL_ARB_timer_query")) { 315 } else if (context->HasExtension("GL_ARB_timer_query")) {
313 timer_type_ = GPUTiming::kTimerTypeARB; 316 timer_type_ = GPUTiming::kTimerTypeARB;
314 } else if (context->HasExtension("GL_EXT_timer_query")) { 317 } else if (context->HasExtension("GL_EXT_timer_query")) {
315 timer_type_ = GPUTiming::kTimerTypeEXT; 318 timer_type_ = GPUTiming::kTimerTypeEXT;
319 force_time_elapsed_query_ = true;
316 } 320 }
317 } 321 }
318 322
319 GPUTimingImpl::~GPUTimingImpl() { 323 GPUTimingImpl::~GPUTimingImpl() {
320 } 324 }
321 325
322 uint32_t GPUTimingImpl::GetDisjointCount() { 326 uint32_t GPUTimingImpl::GetDisjointCount() {
323 if (timer_type_ == GPUTiming::kTimerTypeDisjoint) { 327 if (timer_type_ == GPUTiming::kTimerTypeDisjoint) {
324 GLint disjoint_value = 0; 328 GLint disjoint_value = 0;
325 glGetIntegerv(GL_GPU_DISJOINT_EXT, &disjoint_value); 329 glGetIntegerv(GL_GPU_DISJOINT_EXT, &disjoint_value);
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
368 queries_.back().get())->EndQuery(this, result); 372 queries_.back().get())->EndQuery(this, result);
369 } else { 373 } else {
370 // Simply end the query and reset the current offset 374 // Simply end the query and reset the current offset
371 DCHECK(GetLastElapsedQuery().get()); 375 DCHECK(GetLastElapsedQuery().get());
372 GetLastElapsedQuery()->EndQuery(this, result); 376 GetLastElapsedQuery()->EndQuery(this, result);
373 DCHECK(GetLastElapsedQuery().get() == nullptr); 377 DCHECK(GetLastElapsedQuery().get() == nullptr);
374 } 378 }
375 } 379 }
376 380
377 scoped_refptr<QueryResult> GPUTimingImpl::DoTimeStampQuery() { 381 scoped_refptr<QueryResult> GPUTimingImpl::DoTimeStampQuery() {
378 DCHECK(timer_type_ == GPUTiming::kTimerTypeDisjoint || 382 DCHECK(timer_type_ != GPUTiming::kTimerTypeInvalid);
379 timer_type_ == GPUTiming::kTimerTypeARB);
380 383
381 if (force_time_elapsed_query_) { 384 if (force_time_elapsed_query_) {
382 // Replace with elapsed timer queries instead. 385 // Replace with elapsed timer queries instead.
383 scoped_refptr<QueryResult> result = BeginElapsedTimeQuery(); 386 scoped_refptr<QueryResult> result = BeginElapsedTimeQuery();
384 EndElapsedTimeQuery(result); 387 EndElapsedTimeQuery(result);
385 return result; 388 return result;
386 } 389 }
387 390
388 queries_.push_back(new TimeStampTimerQuery(next_timer_query_id_++)); 391 queries_.push_back(new TimeStampTimerQuery(next_timer_query_id_++));
389 return static_cast<TimeStampTimerQuery*>(queries_.back().get())->DoQuery(); 392 return static_cast<TimeStampTimerQuery*>(queries_.back().get())->DoQuery();
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
460 } 463 }
461 464
462 GPUTiming::~GPUTiming() { 465 GPUTiming::~GPUTiming() {
463 } 466 }
464 467
465 GPUTimer::~GPUTimer() { 468 GPUTimer::~GPUTimer() {
466 } 469 }
467 470
468 void GPUTimer::Destroy(bool have_context) { 471 void GPUTimer::Destroy(bool have_context) {
469 if (have_context) { 472 if (have_context) {
470 if (!end_requested_) { 473 if (timer_state_ == kTimerState_WaitingForEnd) {
471 DCHECK(gpu_timing_client_->gpu_timing_); 474 DCHECK(gpu_timing_client_->gpu_timing_);
472 DCHECK(elapsed_timer_result_.get()); 475 DCHECK(elapsed_timer_result_.get());
473 gpu_timing_client_->gpu_timing_->EndElapsedTimeQuery( 476 gpu_timing_client_->gpu_timing_->EndElapsedTimeQuery(
474 elapsed_timer_result_); 477 elapsed_timer_result_);
475 } 478 }
476 } 479 }
477 } 480 }
478 481
482 void GPUTimer::Reset() {
483 // We can reset from any state other than when a Start() is waiting for End().
484 DCHECK(timer_state_ != kTimerState_WaitingForEnd);
485 time_stamp_result_ = nullptr;
486 elapsed_timer_result_ = nullptr;
487 timer_state_ = kTimerState_Ready;
488 }
489
490 void GPUTimer::QueryTimeStamp() {
491 DCHECK(gpu_timing_client_->gpu_timing_);
492 Reset();
493 time_stamp_result_ = gpu_timing_client_->gpu_timing_->DoTimeStampQuery();
494 timer_state_ = kTimerState_WaitingForResult;
495 }
496
479 void GPUTimer::Start() { 497 void GPUTimer::Start() {
480 DCHECK(gpu_timing_client_->gpu_timing_); 498 DCHECK(gpu_timing_client_->gpu_timing_);
499 Reset();
481 if (!use_elapsed_timer_) 500 if (!use_elapsed_timer_)
482 time_stamp_result_ = gpu_timing_client_->gpu_timing_->DoTimeStampQuery(); 501 time_stamp_result_ = gpu_timing_client_->gpu_timing_->DoTimeStampQuery();
483 502
484 elapsed_timer_result_ = 503 elapsed_timer_result_ =
485 gpu_timing_client_->gpu_timing_->BeginElapsedTimeQuery(); 504 gpu_timing_client_->gpu_timing_->BeginElapsedTimeQuery();
505 timer_state_ = kTimerState_WaitingForEnd;
486 } 506 }
487 507
488 void GPUTimer::End() { 508 void GPUTimer::End() {
509 DCHECK(timer_state_ == kTimerState_WaitingForEnd);
489 DCHECK(elapsed_timer_result_.get()); 510 DCHECK(elapsed_timer_result_.get());
490 end_requested_ = true;
491 gpu_timing_client_->gpu_timing_->EndElapsedTimeQuery(elapsed_timer_result_); 511 gpu_timing_client_->gpu_timing_->EndElapsedTimeQuery(elapsed_timer_result_);
512 timer_state_ = kTimerState_WaitingForResult;
492 } 513 }
493 514
494 bool GPUTimer::IsAvailable() { 515 bool GPUTimer::IsAvailable() {
495 if (!end_requested_) 516 if (timer_state_ == kTimerState_WaitingForResult) {
496 return false; 517 // Elapsed timer are only used during start/end queries and always after
497 if (!end_available_) { 518 // the timestamp query. Otherwise only the timestamp is used.
498 DCHECK(elapsed_timer_result_.get()); 519 scoped_refptr<QueryResult> result =
499 if (elapsed_timer_result_->IsAvailable()) { 520 elapsed_timer_result_.get() ?
500 end_available_ = true; 521 elapsed_timer_result_ :
522 time_stamp_result_;
523
524 DCHECK(result.get());
525 if (result->IsAvailable()) {
526 timer_state_ = kTimerState_ResultAvailable;
501 } else { 527 } else {
502 gpu_timing_client_->gpu_timing_->UpdateQueryResults(); 528 gpu_timing_client_->gpu_timing_->UpdateQueryResults();
503 end_available_ = elapsed_timer_result_->IsAvailable(); 529 if (result->IsAvailable())
530 timer_state_ = kTimerState_ResultAvailable;
504 } 531 }
505 } 532 }
506 return end_available_; 533
534 return (timer_state_ == kTimerState_ResultAvailable);
507 } 535 }
508 536
509 void GPUTimer::GetStartEndTimestamps(int64* start, int64* end) { 537 void GPUTimer::GetStartEndTimestamps(int64* start, int64* end) {
510 DCHECK(start && end); 538 DCHECK(start && end);
511 DCHECK(elapsed_timer_result_.get()); 539 DCHECK(elapsed_timer_result_.get() || time_stamp_result_.get());
512 DCHECK(IsAvailable()); 540 DCHECK(IsAvailable());
513 if (time_stamp_result_.get()) { 541 const int64_t time_stamp = time_stamp_result_.get() ?
514 DCHECK(time_stamp_result_->IsAvailable()); 542 time_stamp_result_->GetStartValue() :
515 const int64_t time_stamp = time_stamp_result_->GetStartValue(); 543 elapsed_timer_result_->GetStartValue();
516 *start = time_stamp; 544 const int64_t elapsed_time = elapsed_timer_result_.get() ?
517 *end = time_stamp + elapsed_timer_result_->GetDelta(); 545 elapsed_timer_result_->GetDelta() :
518 } else { 546 0;
519 // Use estimation from elasped timer results. 547
520 *start = elapsed_timer_result_->GetStartValue(); 548 *start = time_stamp;
521 *end = elapsed_timer_result_->GetEndValue(); 549 *end = time_stamp + elapsed_time;
522 }
523 } 550 }
524 551
525 int64 GPUTimer::GetDeltaElapsed() { 552 int64 GPUTimer::GetDeltaElapsed() {
526 DCHECK(elapsed_timer_result_.get());
527 DCHECK(IsAvailable()); 553 DCHECK(IsAvailable());
528 return elapsed_timer_result_->GetDelta(); 554 if (elapsed_timer_result_.get())
555 return elapsed_timer_result_->GetDelta();
556 return 0;
529 } 557 }
530 558
531 GPUTimer::GPUTimer(scoped_refptr<GPUTimingClient> gpu_timing_client, 559 GPUTimer::GPUTimer(scoped_refptr<GPUTimingClient> gpu_timing_client,
532 bool use_elapsed_timer) 560 bool use_elapsed_timer)
533 : use_elapsed_timer_(use_elapsed_timer), 561 : use_elapsed_timer_(use_elapsed_timer),
534 gpu_timing_client_(gpu_timing_client) { 562 gpu_timing_client_(gpu_timing_client) {
535 } 563 }
536 564
537 GPUTimingClient::GPUTimingClient(GPUTimingImpl* gpu_timing) 565 GPUTimingClient::GPUTimingClient(GPUTimingImpl* gpu_timing)
538 : gpu_timing_(gpu_timing) { 566 : gpu_timing_(gpu_timing) {
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
596 624
597 void GPUTimingClient::ForceTimeElapsedQuery() { 625 void GPUTimingClient::ForceTimeElapsedQuery() {
598 DCHECK(gpu_timing_); 626 DCHECK(gpu_timing_);
599 gpu_timing_->ForceTimeElapsedQuery(); 627 gpu_timing_->ForceTimeElapsedQuery();
600 } 628 }
601 629
602 GPUTimingClient::~GPUTimingClient() { 630 GPUTimingClient::~GPUTimingClient() {
603 } 631 }
604 632
605 } // namespace gfx 633 } // namespace gfx
OLDNEW
« no previous file with comments | « ui/gl/gpu_timing.h ('k') | ui/gl/gpu_timing_fake.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698