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/macros.h" |
8 #include "base/time/time.h" | 8 #include "base/time/time.h" |
9 #include "ui/gl/gl_bindings.h" | 9 #include "ui/gl/gl_bindings.h" |
10 #include "ui/gl/gl_context.h" | 10 #include "ui/gl/gl_context.h" |
11 #include "ui/gl/gl_version_info.h" | 11 #include "ui/gl/gl_version_info.h" |
12 | 12 |
13 namespace gfx { | 13 namespace gfx { |
14 | 14 |
15 class TimeElapsedTimerQuery; | 15 class TimeElapsedTimerQuery; |
16 class TimerQuery; | 16 class TimerQuery; |
17 | 17 |
18 int64_t NanoToMicro(uint64_t nano_seconds) { | 18 int64_t NanoToMicro(uint64_t nano_seconds) { |
19 const uint64_t up = nano_seconds + base::Time::kNanosecondsPerMicrosecond / 2; | 19 const uint64_t up = nano_seconds + base::Time::kNanosecondsPerMicrosecond / 2; |
20 return static_cast<int64_t>(up / base::Time::kNanosecondsPerMicrosecond); | 20 return static_cast<int64_t>(up / base::Time::kNanosecondsPerMicrosecond); |
21 } | 21 } |
22 | 22 |
23 int32_t QueryTimestampBits() { | |
24 GLint timestamp_bits; | |
25 glGetQueryiv(GL_TIMESTAMP, GL_QUERY_COUNTER_BITS, ×tamp_bits); | |
26 return static_cast<int32_t>(timestamp_bits); | |
27 } | |
28 | |
23 class GPUTimingImpl : public GPUTiming { | 29 class GPUTimingImpl : public GPUTiming { |
24 public: | 30 public: |
25 GPUTimingImpl(GLContextReal* context); | 31 GPUTimingImpl(GLContextReal* context); |
26 ~GPUTimingImpl() override; | 32 ~GPUTimingImpl() override; |
27 | 33 |
28 void ForceTimeElapsedQuery() { force_time_elapsed_query_ = true; } | 34 void ForceTimeElapsedQuery() { force_time_elapsed_query_ = true; } |
29 bool IsForceTimeElapsedQuery() { return force_time_elapsed_query_; } | 35 bool IsForceTimeElapsedQuery() { return force_time_elapsed_query_; } |
30 | 36 |
31 GPUTiming::TimerType GetTimerType() const { return timer_type_; } | 37 GPUTiming::TimerType GetTimerType() const { return timer_type_; } |
32 | 38 |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
66 | 72 |
67 private: | 73 private: |
68 scoped_refptr<GPUTimingClient> CreateGPUTimingClient() override; | 74 scoped_refptr<GPUTimingClient> CreateGPUTimingClient() override; |
69 | 75 |
70 base::Callback<int64_t(void)> cpu_time_for_testing_; | 76 base::Callback<int64_t(void)> cpu_time_for_testing_; |
71 GPUTiming::TimerType timer_type_ = GPUTiming::kTimerTypeInvalid; | 77 GPUTiming::TimerType timer_type_ = GPUTiming::kTimerTypeInvalid; |
72 uint32_t disjoint_counter_ = 0; | 78 uint32_t disjoint_counter_ = 0; |
73 int64_t offset_ = 0; // offset cache when timer_type_ == kTimerTypeARB | 79 int64_t offset_ = 0; // offset cache when timer_type_ == kTimerTypeARB |
74 bool offset_valid_ = false; | 80 bool offset_valid_ = false; |
75 bool force_time_elapsed_query_ = false; | 81 bool force_time_elapsed_query_ = false; |
82 int32_t timestamp_bit_count_gl_ = -1; // gl implementation timestamp bits | |
76 | 83 |
77 uint32_t next_timer_query_id_ = 0; | 84 uint32_t next_timer_query_id_ = 0; |
78 uint32_t next_good_timer_query_id_ = 0; // identify bad ids for disjoints. | 85 uint32_t next_good_timer_query_id_ = 0; // identify bad ids for disjoints. |
79 uint32_t query_disjoint_count_ = 0; | 86 uint32_t query_disjoint_count_ = 0; |
80 | 87 |
81 // Extra state tracking data for elapsed timer queries. | 88 // Extra state tracking data for elapsed timer queries. |
82 int64_t max_time_stamp_ = 0; | 89 int64_t max_time_stamp_ = 0; |
83 uint32_t elapsed_query_count_ = 0; | 90 uint32_t elapsed_query_count_ = 0; |
84 scoped_refptr<TimeElapsedTimerQuery> last_elapsed_query_; | 91 scoped_refptr<TimeElapsedTimerQuery> last_elapsed_query_; |
85 | 92 |
(...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
311 const GLVersionInfo* version_info = context->GetVersionInfo(); | 318 const GLVersionInfo* version_info = context->GetVersionInfo(); |
312 DCHECK(version_info); | 319 DCHECK(version_info); |
313 if (version_info->is_es3 && // glGetInteger64v is supported under ES3. | 320 if (version_info->is_es3 && // glGetInteger64v is supported under ES3. |
314 context->HasExtension("GL_EXT_disjoint_timer_query")) { | 321 context->HasExtension("GL_EXT_disjoint_timer_query")) { |
315 timer_type_ = GPUTiming::kTimerTypeDisjoint; | 322 timer_type_ = GPUTiming::kTimerTypeDisjoint; |
316 } else if (context->HasExtension("GL_ARB_timer_query")) { | 323 } else if (context->HasExtension("GL_ARB_timer_query")) { |
317 timer_type_ = GPUTiming::kTimerTypeARB; | 324 timer_type_ = GPUTiming::kTimerTypeARB; |
318 } else if (context->HasExtension("GL_EXT_timer_query")) { | 325 } else if (context->HasExtension("GL_EXT_timer_query")) { |
319 timer_type_ = GPUTiming::kTimerTypeEXT; | 326 timer_type_ = GPUTiming::kTimerTypeEXT; |
320 force_time_elapsed_query_ = true; | 327 force_time_elapsed_query_ = true; |
328 timestamp_bit_count_gl_ = 0; | |
321 } | 329 } |
322 } | 330 } |
323 | 331 |
324 GPUTimingImpl::~GPUTimingImpl() { | 332 GPUTimingImpl::~GPUTimingImpl() { |
325 } | 333 } |
326 | 334 |
327 uint32_t GPUTimingImpl::GetDisjointCount() { | 335 uint32_t GPUTimingImpl::GetDisjointCount() { |
328 if (timer_type_ == GPUTiming::kTimerTypeDisjoint) { | 336 if (timer_type_ == GPUTiming::kTimerTypeDisjoint) { |
329 GLint disjoint_value = 0; | 337 GLint disjoint_value = 0; |
330 glGetIntegerv(GL_GPU_DISJOINT_EXT, &disjoint_value); | 338 glGetIntegerv(GL_GPU_DISJOINT_EXT, &disjoint_value); |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
385 // Simply end the query and reset the current offset | 393 // Simply end the query and reset the current offset |
386 DCHECK(GetLastElapsedQuery().get()); | 394 DCHECK(GetLastElapsedQuery().get()); |
387 GetLastElapsedQuery()->EndQuery(this, result); | 395 GetLastElapsedQuery()->EndQuery(this, result); |
388 DCHECK(GetLastElapsedQuery().get() == nullptr); | 396 DCHECK(GetLastElapsedQuery().get() == nullptr); |
389 } | 397 } |
390 } | 398 } |
391 | 399 |
392 scoped_refptr<QueryResult> GPUTimingImpl::DoTimeStampQuery() { | 400 scoped_refptr<QueryResult> GPUTimingImpl::DoTimeStampQuery() { |
393 DCHECK(timer_type_ != GPUTiming::kTimerTypeInvalid); | 401 DCHECK(timer_type_ != GPUTiming::kTimerTypeInvalid); |
394 | 402 |
403 // Certain GL drivers have timestamp bit count set to 0 which means timestamps | |
404 // aren't supported. Emulate them with time elapsed queries if that is the | |
405 // case. | |
406 if (timestamp_bit_count_gl_ == -1) { | |
407 DCHECK(timer_type_ != GPUTiming::kTimerTypeEXT); | |
408 timestamp_bit_count_gl_ = QueryTimestampBits(); | |
no sievers
2016/02/17 23:08:45
Do you have to do that every time though? Isn't GL
David Yen
2016/02/17 23:10:52
It only lazily initializes it once. It's done lazi
Ian Ewell
2016/02/17 23:11:53
It is only called once and then timestamp_bit_coun
| |
409 force_time_elapsed_query_ = (timestamp_bit_count_gl_ == 0); | |
410 } | |
411 | |
395 if (force_time_elapsed_query_) { | 412 if (force_time_elapsed_query_) { |
396 // Replace with elapsed timer queries instead. | 413 // Replace with elapsed timer queries instead. |
397 scoped_refptr<QueryResult> result = BeginElapsedTimeQuery(); | 414 scoped_refptr<QueryResult> result = BeginElapsedTimeQuery(); |
398 EndElapsedTimeQuery(result); | 415 EndElapsedTimeQuery(result); |
399 return result; | 416 return result; |
400 } | 417 } |
401 | 418 |
402 queries_.push_back(new TimeStampTimerQuery(next_timer_query_id_++)); | 419 queries_.push_back(new TimeStampTimerQuery(next_timer_query_id_++)); |
403 return static_cast<TimeStampTimerQuery*>(queries_.back().get())->DoQuery(); | 420 return static_cast<TimeStampTimerQuery*>(queries_.back().get())->DoQuery(); |
404 } | 421 } |
(...skipping 230 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
635 | 652 |
636 void GPUTimingClient::ForceTimeElapsedQuery() { | 653 void GPUTimingClient::ForceTimeElapsedQuery() { |
637 DCHECK(gpu_timing_); | 654 DCHECK(gpu_timing_); |
638 gpu_timing_->ForceTimeElapsedQuery(); | 655 gpu_timing_->ForceTimeElapsedQuery(); |
639 } | 656 } |
640 | 657 |
641 GPUTimingClient::~GPUTimingClient() { | 658 GPUTimingClient::~GPUTimingClient() { |
642 } | 659 } |
643 | 660 |
644 } // namespace gfx | 661 } // namespace gfx |
OLD | NEW |