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

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: Reworked GPUTimer so they are reusable, added unit tests to test multiple queries. 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() {
piman 2015/07/16 20:42:25 I think you can add a DCHECK that we're not in Wai
David Yen 2015/07/16 21:19:30 Done.
483 time_stamp_result_ = nullptr;
484 elapsed_timer_result_ = nullptr;
485 timer_state_ = kTimerState_Ready;
486 }
487
488 void GPUTimer::QueryTimeStamp() {
489 DCHECK(gpu_timing_client_->gpu_timing_);
490 Reset();
491 time_stamp_result_ = gpu_timing_client_->gpu_timing_->DoTimeStampQuery();
492 timer_state_ = kTimerState_WaitingForResult;
493 }
494
479 void GPUTimer::Start() { 495 void GPUTimer::Start() {
480 DCHECK(gpu_timing_client_->gpu_timing_); 496 DCHECK(gpu_timing_client_->gpu_timing_);
497 Reset();
481 if (!use_elapsed_timer_) 498 if (!use_elapsed_timer_)
482 time_stamp_result_ = gpu_timing_client_->gpu_timing_->DoTimeStampQuery(); 499 time_stamp_result_ = gpu_timing_client_->gpu_timing_->DoTimeStampQuery();
483 500
484 elapsed_timer_result_ = 501 elapsed_timer_result_ =
485 gpu_timing_client_->gpu_timing_->BeginElapsedTimeQuery(); 502 gpu_timing_client_->gpu_timing_->BeginElapsedTimeQuery();
503 timer_state_ = kTimerState_WaitingForEnd;
486 } 504 }
487 505
488 void GPUTimer::End() { 506 void GPUTimer::End() {
507 DCHECK(timer_state_ == kTimerState_WaitingForEnd);
489 DCHECK(elapsed_timer_result_.get()); 508 DCHECK(elapsed_timer_result_.get());
490 end_requested_ = true;
491 gpu_timing_client_->gpu_timing_->EndElapsedTimeQuery(elapsed_timer_result_); 509 gpu_timing_client_->gpu_timing_->EndElapsedTimeQuery(elapsed_timer_result_);
510 timer_state_ = kTimerState_WaitingForResult;
492 } 511 }
493 512
494 bool GPUTimer::IsAvailable() { 513 bool GPUTimer::IsAvailable() {
495 if (!end_requested_) 514 if (timer_state_ == kTimerState_WaitingForResult) {
496 return false; 515 // Elapsed timer are only used during start/end queries and always after
497 if (!end_available_) { 516 // the timestamp query. Otherwise only the timestamp is used.
498 DCHECK(elapsed_timer_result_.get()); 517 scoped_refptr<QueryResult> result =
499 if (elapsed_timer_result_->IsAvailable()) { 518 elapsed_timer_result_.get() ?
500 end_available_ = true; 519 elapsed_timer_result_ :
520 time_stamp_result_;
521
522 DCHECK(result.get());
523 if (result->IsAvailable()) {
524 timer_state_ = kTimerState_ResultAvailable;
501 } else { 525 } else {
502 gpu_timing_client_->gpu_timing_->UpdateQueryResults(); 526 gpu_timing_client_->gpu_timing_->UpdateQueryResults();
503 end_available_ = elapsed_timer_result_->IsAvailable(); 527 if (result->IsAvailable())
528 timer_state_ = kTimerState_ResultAvailable;
504 } 529 }
505 } 530 }
506 return end_available_; 531
532 return (timer_state_ == kTimerState_ResultAvailable);
507 } 533 }
508 534
509 void GPUTimer::GetStartEndTimestamps(int64* start, int64* end) { 535 void GPUTimer::GetStartEndTimestamps(int64* start, int64* end) {
510 DCHECK(start && end); 536 DCHECK(start && end);
511 DCHECK(elapsed_timer_result_.get()); 537 DCHECK(elapsed_timer_result_.get() || time_stamp_result_.get());
512 DCHECK(IsAvailable()); 538 DCHECK(IsAvailable());
513 if (time_stamp_result_.get()) { 539 const int64_t time_stamp = time_stamp_result_.get() ?
514 DCHECK(time_stamp_result_->IsAvailable()); 540 time_stamp_result_->GetStartValue() :
515 const int64_t time_stamp = time_stamp_result_->GetStartValue(); 541 elapsed_timer_result_->GetStartValue();
516 *start = time_stamp; 542 const int64_t elapsed_time = elapsed_timer_result_.get() ?
517 *end = time_stamp + elapsed_timer_result_->GetDelta(); 543 elapsed_timer_result_->GetDelta() :
518 } else { 544 0;
519 // Use estimation from elasped timer results. 545
520 *start = elapsed_timer_result_->GetStartValue(); 546 *start = time_stamp;
521 *end = elapsed_timer_result_->GetEndValue(); 547 *end = time_stamp + elapsed_time;
522 }
523 } 548 }
524 549
525 int64 GPUTimer::GetDeltaElapsed() { 550 int64 GPUTimer::GetDeltaElapsed() {
526 DCHECK(elapsed_timer_result_.get());
527 DCHECK(IsAvailable()); 551 DCHECK(IsAvailable());
528 return elapsed_timer_result_->GetDelta(); 552 if (elapsed_timer_result_.get())
553 return elapsed_timer_result_->GetDelta();
554 return 0;
529 } 555 }
530 556
531 GPUTimer::GPUTimer(scoped_refptr<GPUTimingClient> gpu_timing_client, 557 GPUTimer::GPUTimer(scoped_refptr<GPUTimingClient> gpu_timing_client,
532 bool use_elapsed_timer) 558 bool use_elapsed_timer)
533 : use_elapsed_timer_(use_elapsed_timer), 559 : use_elapsed_timer_(use_elapsed_timer),
534 gpu_timing_client_(gpu_timing_client) { 560 gpu_timing_client_(gpu_timing_client) {
535 } 561 }
536 562
537 GPUTimingClient::GPUTimingClient(GPUTimingImpl* gpu_timing) 563 GPUTimingClient::GPUTimingClient(GPUTimingImpl* gpu_timing)
538 : gpu_timing_(gpu_timing) { 564 : gpu_timing_(gpu_timing) {
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
596 622
597 void GPUTimingClient::ForceTimeElapsedQuery() { 623 void GPUTimingClient::ForceTimeElapsedQuery() {
598 DCHECK(gpu_timing_); 624 DCHECK(gpu_timing_);
599 gpu_timing_->ForceTimeElapsedQuery(); 625 gpu_timing_->ForceTimeElapsedQuery();
600 } 626 }
601 627
602 GPUTimingClient::~GPUTimingClient() { 628 GPUTimingClient::~GPUTimingClient() {
603 } 629 }
604 630
605 } // namespace gfx 631 } // 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