ozone: evdev: Sync caps lock LED state to evdev
[chromium-blink-merge.git] / ui / gl / gpu_timing.cc
bloba3b697fe306b0afaaac1c48787e8049c76276163
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
3 // found in the LICENSE file.
5 #include "ui/gl/gpu_timing.h"
7 #include "base/time/time.h"
8 #include "ui/gl/gl_bindings.h"
9 #include "ui/gl/gl_context.h"
10 #include "ui/gl/gl_version_info.h"
12 namespace gfx {
14 GPUTiming::GPUTiming(GLContextReal* context) {
15 DCHECK(context);
16 const GLVersionInfo* version_info = context->GetVersionInfo();
17 DCHECK(version_info);
18 if (version_info->is_es3 && // glGetInteger64v is supported under ES3.
19 context->HasExtension("GL_EXT_disjoint_timer_query")) {
20 timer_type_ = kTimerTypeDisjoint;
21 } else if (context->HasExtension("GL_ARB_timer_query")) {
22 timer_type_ = kTimerTypeARB;
26 GPUTiming::~GPUTiming() {
29 scoped_refptr<GPUTimingClient> GPUTiming::CreateGPUTimingClient() {
30 return new GPUTimingClient(this);
33 uint32_t GPUTiming::GetDisjointCount() {
34 if (timer_type_ == kTimerTypeDisjoint) {
35 GLint disjoint_value = 0;
36 glGetIntegerv(GL_GPU_DISJOINT_EXT, &disjoint_value);
37 if (disjoint_value) {
38 disjoint_counter_++;
41 return disjoint_counter_;
44 GPUTimer::~GPUTimer() {
45 glDeleteQueriesARB(2, queries_);
48 void GPUTimer::Start() {
49 // GL_TIMESTAMP and GL_TIMESTAMP_EXT both have the same value.
50 glQueryCounter(queries_[0], GL_TIMESTAMP);
53 void GPUTimer::End() {
54 end_requested_ = true;
55 offset_ = gpu_timing_client_->CalculateTimerOffset();
56 glQueryCounter(queries_[1], GL_TIMESTAMP);
59 bool GPUTimer::IsAvailable() {
60 if (!gpu_timing_client_->IsAvailable() || !end_requested_) {
61 return false;
63 GLint done = 0;
64 glGetQueryObjectivARB(queries_[1], GL_QUERY_RESULT_AVAILABLE, &done);
65 return done != 0;
68 void GPUTimer::GetStartEndTimestamps(int64* start, int64* end) {
69 DCHECK(start && end);
70 DCHECK(IsAvailable());
71 GLuint64 begin_stamp = 0;
72 GLuint64 end_stamp = 0;
73 // TODO(dsinclair): It's possible for the timer to wrap during the start/end.
74 // We need to detect if the end is less then the start and correct for the
75 // wrapping.
76 glGetQueryObjectui64v(queries_[0], GL_QUERY_RESULT, &begin_stamp);
77 glGetQueryObjectui64v(queries_[1], GL_QUERY_RESULT, &end_stamp);
79 *start = (begin_stamp / base::Time::kNanosecondsPerMicrosecond) + offset_;
80 *end = (end_stamp / base::Time::kNanosecondsPerMicrosecond) + offset_;
83 int64 GPUTimer::GetDeltaElapsed() {
84 int64 start = 0;
85 int64 end = 0;
86 GetStartEndTimestamps(&start, &end);
87 return end - start;
90 GPUTimer::GPUTimer(scoped_refptr<GPUTimingClient> gpu_timing_client)
91 : gpu_timing_client_(gpu_timing_client) {
92 DCHECK(gpu_timing_client_);
93 memset(queries_, 0, sizeof(queries_));
94 glGenQueriesARB(2, queries_);
97 GPUTimingClient::GPUTimingClient(GPUTiming* gpu_timing)
98 : gpu_timing_(gpu_timing) {
99 if (gpu_timing) {
100 timer_type_ = gpu_timing->GetTimerType();
101 disjoint_counter_ = gpu_timing_->GetDisjointCount();
105 scoped_ptr<GPUTimer> GPUTimingClient::CreateGPUTimer() {
106 return make_scoped_ptr(new GPUTimer(this));
109 bool GPUTimingClient::IsAvailable() {
110 return timer_type_ != GPUTiming::kTimerTypeInvalid;
113 const char* GPUTimingClient::GetTimerTypeName() const {
114 switch (timer_type_) {
115 case GPUTiming::kTimerTypeDisjoint:
116 return "GL_EXT_disjoint_timer_query";
117 case GPUTiming::kTimerTypeARB:
118 return "GL_ARB_timer_query";
119 default:
120 return "Unknown";
124 bool GPUTimingClient::CheckAndResetTimerErrors() {
125 if (timer_type_ == GPUTiming::kTimerTypeDisjoint) {
126 DCHECK(gpu_timing_ != nullptr);
127 const uint32_t total_disjoint_count = gpu_timing_->GetDisjointCount();
128 const bool disjoint_triggered = total_disjoint_count != disjoint_counter_;
129 disjoint_counter_ = total_disjoint_count;
130 return disjoint_triggered;
132 return false;
135 int64 GPUTimingClient::CalculateTimerOffset() {
136 if (!offset_valid_) {
137 GLint64 gl_now = 0;
138 glGetInteger64v(GL_TIMESTAMP, &gl_now);
139 int64 now =
140 cpu_time_for_testing_.is_null()
141 ? base::TimeTicks::NowFromSystemTraceTime().ToInternalValue()
142 : cpu_time_for_testing_.Run();
143 offset_ = now - gl_now / base::Time::kNanosecondsPerMicrosecond;
144 offset_valid_ = timer_type_ == GPUTiming::kTimerTypeARB;
146 return offset_;
149 void GPUTimingClient::InvalidateTimerOffset() {
150 offset_valid_ = false;
153 void GPUTimingClient::SetCpuTimeForTesting(
154 const base::Callback<int64(void)>& cpu_time) {
155 cpu_time_for_testing_ = cpu_time;
158 GPUTimingClient::~GPUTimingClient() {
161 } // namespace gfx