OLD | NEW |
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/macros.h" |
7 #include "base/time/time.h" | 8 #include "base/time/time.h" |
8 #include "ui/gl/gl_bindings.h" | 9 #include "ui/gl/gl_bindings.h" |
9 #include "ui/gl/gl_context.h" | 10 #include "ui/gl/gl_context.h" |
10 #include "ui/gl/gl_version_info.h" | 11 #include "ui/gl/gl_version_info.h" |
11 | 12 |
12 namespace gfx { | 13 namespace gfx { |
13 | 14 |
14 class TimeElapsedTimerQuery; | 15 class TimeElapsedTimerQuery; |
15 class TimerQuery; | 16 class TimerQuery; |
16 | 17 |
17 int64_t NanoToMicro(uint64_t nano_seconds) { | 18 int64_t NanoToMicro(uint64_t nano_seconds) { |
18 const uint64_t up = nano_seconds + base::Time::kNanosecondsPerMicrosecond / 2; | 19 const uint64_t up = nano_seconds + base::Time::kNanosecondsPerMicrosecond / 2; |
19 return static_cast<int64_t>(up / base::Time::kNanosecondsPerMicrosecond); | 20 return static_cast<int64_t>(up / base::Time::kNanosecondsPerMicrosecond); |
20 } | 21 } |
21 | 22 |
22 class GPUTimingImpl : public GPUTiming { | 23 class GPUTimingImpl : public GPUTiming { |
23 public: | 24 public: |
24 GPUTimingImpl(GLContextReal* context); | 25 GPUTimingImpl(GLContextReal* context); |
25 ~GPUTimingImpl() override; | 26 ~GPUTimingImpl() override; |
26 | 27 |
27 void ForceTimeElapsedQuery() { force_time_elapsed_query_ = true; } | 28 void ForceTimeElapsedQuery() { force_time_elapsed_query_ = true; } |
28 bool IsForceTimeElapsedQuery() { return force_time_elapsed_query_; } | 29 bool IsForceTimeElapsedQuery() { return force_time_elapsed_query_; } |
29 | 30 |
30 GPUTiming::TimerType GetTimerType() const { return timer_type_; } | 31 GPUTiming::TimerType GetTimerType() const { return timer_type_; } |
31 | 32 |
32 uint32_t GetDisjointCount(); | 33 uint32_t GetDisjointCount(); |
33 int64 CalculateTimerOffset(); | 34 int64_t CalculateTimerOffset(); |
34 | 35 |
35 scoped_refptr<QueryResult> BeginElapsedTimeQuery(); | 36 scoped_refptr<QueryResult> BeginElapsedTimeQuery(); |
36 void EndElapsedTimeQuery(scoped_refptr<QueryResult> result); | 37 void EndElapsedTimeQuery(scoped_refptr<QueryResult> result); |
37 | 38 |
38 scoped_refptr<QueryResult> DoTimeStampQuery(); | 39 scoped_refptr<QueryResult> DoTimeStampQuery(); |
39 | 40 |
40 int64 GetCurrentCPUTime() { | 41 int64_t GetCurrentCPUTime() { |
41 return cpu_time_for_testing_.is_null() | 42 return cpu_time_for_testing_.is_null() |
42 ? (base::TimeTicks::Now() - base::TimeTicks()).InMicroseconds() | 43 ? (base::TimeTicks::Now() - base::TimeTicks()).InMicroseconds() |
43 : cpu_time_for_testing_.Run(); | 44 : cpu_time_for_testing_.Run(); |
44 } | 45 } |
45 void SetCpuTimeForTesting(const base::Callback<int64(void)>& cpu_time) { | 46 void SetCpuTimeForTesting(const base::Callback<int64_t(void)>& cpu_time) { |
46 cpu_time_for_testing_ = cpu_time; | 47 cpu_time_for_testing_ = cpu_time; |
47 } | 48 } |
48 | 49 |
49 void UpdateQueryResults(); | 50 void UpdateQueryResults(); |
50 | 51 |
51 int64_t GetMaxTimeStamp() { return max_time_stamp_; } | 52 int64_t GetMaxTimeStamp() { return max_time_stamp_; } |
52 void UpdateMaxTimeStamp(int64_t value) { | 53 void UpdateMaxTimeStamp(int64_t value) { |
53 max_time_stamp_ = std::max(max_time_stamp_, value); | 54 max_time_stamp_ = std::max(max_time_stamp_, value); |
54 } | 55 } |
55 | 56 |
56 uint32_t GetElapsedQueryCount() { return elapsed_query_count_; } | 57 uint32_t GetElapsedQueryCount() { return elapsed_query_count_; } |
57 void IncElapsedQueryCount() { elapsed_query_count_++; } | 58 void IncElapsedQueryCount() { elapsed_query_count_++; } |
58 void DecElapsedQueryCount() { elapsed_query_count_--; } | 59 void DecElapsedQueryCount() { elapsed_query_count_--; } |
59 | 60 |
60 void SetLastElapsedQuery(scoped_refptr<TimeElapsedTimerQuery> query); | 61 void SetLastElapsedQuery(scoped_refptr<TimeElapsedTimerQuery> query); |
61 scoped_refptr<TimeElapsedTimerQuery> GetLastElapsedQuery(); | 62 scoped_refptr<TimeElapsedTimerQuery> GetLastElapsedQuery(); |
62 | 63 |
63 void HandleBadQuery(); | 64 void HandleBadQuery(); |
64 bool IsGoodQueryID(uint32_t query_id); | 65 bool IsGoodQueryID(uint32_t query_id); |
65 | 66 |
66 private: | 67 private: |
67 scoped_refptr<GPUTimingClient> CreateGPUTimingClient() override; | 68 scoped_refptr<GPUTimingClient> CreateGPUTimingClient() override; |
68 | 69 |
69 base::Callback<int64(void)> cpu_time_for_testing_; | 70 base::Callback<int64_t(void)> cpu_time_for_testing_; |
70 GPUTiming::TimerType timer_type_ = GPUTiming::kTimerTypeInvalid; | 71 GPUTiming::TimerType timer_type_ = GPUTiming::kTimerTypeInvalid; |
71 uint32_t disjoint_counter_ = 0; | 72 uint32_t disjoint_counter_ = 0; |
72 int64 offset_ = 0; // offset cache when timer_type_ == kTimerTypeARB | 73 int64_t offset_ = 0; // offset cache when timer_type_ == kTimerTypeARB |
73 bool offset_valid_ = false; | 74 bool offset_valid_ = false; |
74 bool force_time_elapsed_query_ = false; | 75 bool force_time_elapsed_query_ = false; |
75 | 76 |
76 uint32_t next_timer_query_id_ = 0; | 77 uint32_t next_timer_query_id_ = 0; |
77 uint32_t next_good_timer_query_id_ = 0; // identify bad ids for disjoints. | 78 uint32_t next_good_timer_query_id_ = 0; // identify bad ids for disjoints. |
78 uint32_t query_disjoint_count_ = 0; | 79 uint32_t query_disjoint_count_ = 0; |
79 | 80 |
80 // Extra state tracking data for elapsed timer queries. | 81 // Extra state tracking data for elapsed timer queries. |
81 int64_t max_time_stamp_ = 0; | 82 int64_t max_time_stamp_ = 0; |
82 uint32_t elapsed_query_count_ = 0; | 83 uint32_t elapsed_query_count_ = 0; |
(...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
284 } | 285 } |
285 | 286 |
286 // Fills out query result start and end, called after IsAvailable() is true. | 287 // Fills out query result start and end, called after IsAvailable() is true. |
287 void UpdateQueryResults(GPUTimingImpl* gpu_timing) override { | 288 void UpdateQueryResults(GPUTimingImpl* gpu_timing) override { |
288 DCHECK(IsAvailable(gpu_timing)); | 289 DCHECK(IsAvailable(gpu_timing)); |
289 | 290 |
290 GLuint64 result_value = 0; | 291 GLuint64 result_value = 0; |
291 glGetQueryObjectui64v(gl_query_id_, GL_QUERY_RESULT, &result_value); | 292 glGetQueryObjectui64v(gl_query_id_, GL_QUERY_RESULT, &result_value); |
292 const int64_t micro_results = NanoToMicro(result_value); | 293 const int64_t micro_results = NanoToMicro(result_value); |
293 | 294 |
294 const int64 offset = gpu_timing->CalculateTimerOffset(); | 295 const int64_t offset = gpu_timing->CalculateTimerOffset(); |
295 const int64_t adjusted_result = micro_results + offset; | 296 const int64_t adjusted_result = micro_results + offset; |
296 DCHECK(query_result_.get()); | 297 DCHECK(query_result_.get()); |
297 query_result_->SetStartValue(adjusted_result); | 298 query_result_->SetStartValue(adjusted_result); |
298 query_result_->SetEndValue(adjusted_result); | 299 query_result_->SetEndValue(adjusted_result); |
299 time_stamp_ = adjusted_result; | 300 time_stamp_ = adjusted_result; |
300 } | 301 } |
301 | 302 |
302 private: | 303 private: |
303 ~TimeStampTimerQuery() override {} | 304 ~TimeStampTimerQuery() override {} |
304 uint32_t gl_query_id_ = 0; | 305 uint32_t gl_query_id_ = 0; |
(...skipping 23 matching lines...) Expand all Loading... |
328 GLint disjoint_value = 0; | 329 GLint disjoint_value = 0; |
329 glGetIntegerv(GL_GPU_DISJOINT_EXT, &disjoint_value); | 330 glGetIntegerv(GL_GPU_DISJOINT_EXT, &disjoint_value); |
330 if (disjoint_value) { | 331 if (disjoint_value) { |
331 offset_valid_ = false; | 332 offset_valid_ = false; |
332 disjoint_counter_++; | 333 disjoint_counter_++; |
333 } | 334 } |
334 } | 335 } |
335 return disjoint_counter_; | 336 return disjoint_counter_; |
336 } | 337 } |
337 | 338 |
338 int64 GPUTimingImpl::CalculateTimerOffset() { | 339 int64_t GPUTimingImpl::CalculateTimerOffset() { |
339 if (!offset_valid_) { | 340 if (!offset_valid_) { |
340 if (timer_type_ == GPUTiming::kTimerTypeDisjoint || | 341 if (timer_type_ == GPUTiming::kTimerTypeDisjoint || |
341 timer_type_ == GPUTiming::kTimerTypeARB) { | 342 timer_type_ == GPUTiming::kTimerTypeARB) { |
342 GLint64 gl_now = 0; | 343 GLint64 gl_now = 0; |
343 glGetInteger64v(GL_TIMESTAMP, &gl_now); | 344 glGetInteger64v(GL_TIMESTAMP, &gl_now); |
344 int64_t micro_now = NanoToMicro(gl_now); | 345 int64_t micro_now = NanoToMicro(gl_now); |
345 offset_ = GetCurrentCPUTime() - micro_now; | 346 offset_ = GetCurrentCPUTime() - micro_now; |
346 offset_valid_ = (timer_type_ == GPUTiming::kTimerTypeARB); | 347 offset_valid_ = (timer_type_ == GPUTiming::kTimerTypeARB); |
347 } else { | 348 } else { |
348 offset_ = 0; | 349 offset_ = 0; |
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
527 } else { | 528 } else { |
528 gpu_timing_client_->gpu_timing_->UpdateQueryResults(); | 529 gpu_timing_client_->gpu_timing_->UpdateQueryResults(); |
529 if (result->IsAvailable()) | 530 if (result->IsAvailable()) |
530 timer_state_ = kTimerState_ResultAvailable; | 531 timer_state_ = kTimerState_ResultAvailable; |
531 } | 532 } |
532 } | 533 } |
533 | 534 |
534 return (timer_state_ == kTimerState_ResultAvailable); | 535 return (timer_state_ == kTimerState_ResultAvailable); |
535 } | 536 } |
536 | 537 |
537 void GPUTimer::GetStartEndTimestamps(int64* start, int64* end) { | 538 void GPUTimer::GetStartEndTimestamps(int64_t* start, int64_t* end) { |
538 DCHECK(start && end); | 539 DCHECK(start && end); |
539 DCHECK(elapsed_timer_result_.get() || time_stamp_result_.get()); | 540 DCHECK(elapsed_timer_result_.get() || time_stamp_result_.get()); |
540 DCHECK(IsAvailable()); | 541 DCHECK(IsAvailable()); |
541 const int64_t time_stamp = time_stamp_result_.get() ? | 542 const int64_t time_stamp = time_stamp_result_.get() ? |
542 time_stamp_result_->GetStartValue() : | 543 time_stamp_result_->GetStartValue() : |
543 elapsed_timer_result_->GetStartValue(); | 544 elapsed_timer_result_->GetStartValue(); |
544 const int64_t elapsed_time = elapsed_timer_result_.get() ? | 545 const int64_t elapsed_time = elapsed_timer_result_.get() ? |
545 elapsed_timer_result_->GetDelta() : | 546 elapsed_timer_result_->GetDelta() : |
546 0; | 547 0; |
547 | 548 |
548 *start = time_stamp; | 549 *start = time_stamp; |
549 *end = time_stamp + elapsed_time; | 550 *end = time_stamp + elapsed_time; |
550 } | 551 } |
551 | 552 |
552 int64 GPUTimer::GetDeltaElapsed() { | 553 int64_t GPUTimer::GetDeltaElapsed() { |
553 DCHECK(IsAvailable()); | 554 DCHECK(IsAvailable()); |
554 if (elapsed_timer_result_.get()) | 555 if (elapsed_timer_result_.get()) |
555 return elapsed_timer_result_->GetDelta(); | 556 return elapsed_timer_result_->GetDelta(); |
556 return 0; | 557 return 0; |
557 } | 558 } |
558 | 559 |
559 GPUTimer::GPUTimer(scoped_refptr<GPUTimingClient> gpu_timing_client, | 560 GPUTimer::GPUTimer(scoped_refptr<GPUTimingClient> gpu_timing_client, |
560 bool use_elapsed_timer) | 561 bool use_elapsed_timer) |
561 : use_elapsed_timer_(use_elapsed_timer), | 562 : use_elapsed_timer_(use_elapsed_timer), |
562 gpu_timing_client_(gpu_timing_client) { | 563 gpu_timing_client_(gpu_timing_client) { |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
599 if (timer_type_ == GPUTiming::kTimerTypeDisjoint) { | 600 if (timer_type_ == GPUTiming::kTimerTypeDisjoint) { |
600 DCHECK(gpu_timing_ != nullptr); | 601 DCHECK(gpu_timing_ != nullptr); |
601 const uint32_t total_disjoint_count = gpu_timing_->GetDisjointCount(); | 602 const uint32_t total_disjoint_count = gpu_timing_->GetDisjointCount(); |
602 const bool disjoint_triggered = total_disjoint_count != disjoint_counter_; | 603 const bool disjoint_triggered = total_disjoint_count != disjoint_counter_; |
603 disjoint_counter_ = total_disjoint_count; | 604 disjoint_counter_ = total_disjoint_count; |
604 return disjoint_triggered; | 605 return disjoint_triggered; |
605 } | 606 } |
606 return false; | 607 return false; |
607 } | 608 } |
608 | 609 |
609 int64 GPUTimingClient::GetCurrentCPUTime() { | 610 int64_t GPUTimingClient::GetCurrentCPUTime() { |
610 DCHECK(gpu_timing_); | 611 DCHECK(gpu_timing_); |
611 return gpu_timing_->GetCurrentCPUTime(); | 612 return gpu_timing_->GetCurrentCPUTime(); |
612 } | 613 } |
613 | 614 |
614 void GPUTimingClient::SetCpuTimeForTesting( | 615 void GPUTimingClient::SetCpuTimeForTesting( |
615 const base::Callback<int64(void)>& cpu_time) { | 616 const base::Callback<int64_t(void)>& cpu_time) { |
616 DCHECK(gpu_timing_); | 617 DCHECK(gpu_timing_); |
617 gpu_timing_->SetCpuTimeForTesting(cpu_time); | 618 gpu_timing_->SetCpuTimeForTesting(cpu_time); |
618 } | 619 } |
619 | 620 |
620 bool GPUTimingClient::IsForceTimeElapsedQuery() { | 621 bool GPUTimingClient::IsForceTimeElapsedQuery() { |
621 DCHECK(gpu_timing_); | 622 DCHECK(gpu_timing_); |
622 return gpu_timing_->IsForceTimeElapsedQuery(); | 623 return gpu_timing_->IsForceTimeElapsedQuery(); |
623 } | 624 } |
624 | 625 |
625 void GPUTimingClient::ForceTimeElapsedQuery() { | 626 void GPUTimingClient::ForceTimeElapsedQuery() { |
626 DCHECK(gpu_timing_); | 627 DCHECK(gpu_timing_); |
627 gpu_timing_->ForceTimeElapsedQuery(); | 628 gpu_timing_->ForceTimeElapsedQuery(); |
628 } | 629 } |
629 | 630 |
630 GPUTimingClient::~GPUTimingClient() { | 631 GPUTimingClient::~GPUTimingClient() { |
631 } | 632 } |
632 | 633 |
633 } // namespace gfx | 634 } // namespace gfx |
OLD | NEW |