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 "gpu/command_buffer/service/gpu_timing.h" | 5 #include "gpu/command_buffer/service/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" |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
56 *end = (end_stamp / base::Time::kNanosecondsPerMicrosecond) + offset_; | 56 *end = (end_stamp / base::Time::kNanosecondsPerMicrosecond) + offset_; |
57 } | 57 } |
58 | 58 |
59 int64 GPUTimer::GetDeltaElapsed() { | 59 int64 GPUTimer::GetDeltaElapsed() { |
60 int64 start = 0; | 60 int64 start = 0; |
61 int64 end = 0; | 61 int64 end = 0; |
62 GetStartEndTimestamps(&start, &end); | 62 GetStartEndTimestamps(&start, &end); |
63 return end - start; | 63 return end - start; |
64 } | 64 } |
65 | 65 |
66 GPUTiming::GPUTiming() : cpu_time_for_testing_() { | 66 GPUTiming::GPUTiming(gfx::GLContext* gl_context) { |
67 Initialize(gl_context); | |
67 } | 68 } |
68 | 69 |
69 GPUTiming::~GPUTiming() { | 70 GPUTiming::~GPUTiming() { |
70 } | 71 } |
71 | 72 |
72 bool GPUTiming::Initialize(gfx::GLContext* gl_context) { | 73 void GPUTiming::Initialize(gfx::GLContext* gl_context) { |
73 DCHECK(gl_context); | 74 timer_type_ = kTimerTypeInvalid; |
74 DCHECK_EQ(kTimerTypeInvalid, timer_type_); | 75 offset_ = 0; // offset cache when timer_type_ == kTimerTypeARB |
76 offset_valid_ = false; | |
77 disjoint_occurred_ = false; | |
78 disjoint_contexts_.clear(); | |
79 cpu_time_for_testing_.Reset(); | |
75 | 80 |
76 const gfx::GLVersionInfo* version_info = gl_context->GetVersionInfo(); | 81 if (gl_context) { |
77 DCHECK(version_info); | 82 const gfx::GLVersionInfo* version_info = gl_context->GetVersionInfo(); |
78 if (version_info->is_es3 && // glGetInteger64v is supported under ES3. | 83 DCHECK(version_info); |
79 gfx::g_driver_gl.ext.b_GL_EXT_disjoint_timer_query) { | 84 |
80 timer_type_ = kTimerTypeDisjoint; | 85 timer_type_ = kTimerTypeInvalid; |
81 return true; | 86 if (version_info->is_es3 && // glGetInteger64v is supported under ES3. |
82 } else if (gfx::g_driver_gl.ext.b_GL_ARB_timer_query) { | 87 gfx::g_driver_gl.ext.b_GL_EXT_disjoint_timer_query) { |
83 timer_type_ = kTimerTypeARB; | 88 timer_type_ = kTimerTypeDisjoint; |
84 return true; | 89 } else if (gfx::g_driver_gl.ext.b_GL_ARB_timer_query) { |
90 timer_type_ = kTimerTypeARB; | |
91 } | |
85 } | 92 } |
86 return false; | |
87 } | 93 } |
88 | 94 |
89 bool GPUTiming::IsAvailable() { | 95 bool GPUTiming::IsAvailable() { |
90 return timer_type_ != kTimerTypeInvalid; | 96 return timer_type_ != kTimerTypeInvalid; |
91 } | 97 } |
92 | 98 |
99 int GPUTiming::CreateDisjointContextID() { | |
100 const int num_contexts = static_cast<int>(disjoint_contexts_.size()); | |
101 for (int i = 0; i < num_contexts; ++i) { | |
102 DisjointContext& context = disjoint_contexts_[i]; | |
103 if (!context.valid_) { | |
104 context.valid_ = true; | |
105 context.disjoint_value_ = disjoint_occurred_; | |
106 return i; | |
107 } | |
108 } | |
109 disjoint_contexts_.push_back(DisjointContext(disjoint_occurred_)); | |
110 return num_contexts; | |
111 } | |
112 | |
113 bool GPUTiming::ReleaseDisjointContextID(int disjoint_context_id) { | |
114 if (disjoint_context_id >= 0 && | |
115 disjoint_context_id < static_cast<int>(disjoint_contexts_.size()) && | |
116 disjoint_contexts_[disjoint_context_id].valid_) { | |
117 disjoint_contexts_[disjoint_context_id].valid_ = false; | |
Daniele Castagna
2015/02/23 22:21:19
Why do you want to reuse it instead of simply remo
| |
118 return true; | |
119 } | |
120 return false; | |
121 } | |
122 | |
123 bool GPUTiming::CheckAndResetTimerErrors(int disjoint_context_id) { | |
Daniele Castagna
2015/02/23 22:21:18
This forces every user of GPUTiming to have a disj
| |
124 if (timer_type_ == kTimerTypeDisjoint && | |
125 disjoint_context_id >= 0 && | |
Daniele Castagna
2015/02/23 22:21:18
Why do silently ignore invalid values?
Isn't it be
| |
126 disjoint_context_id < static_cast<int>(disjoint_contexts_.size()) && | |
127 disjoint_contexts_[disjoint_context_id].valid_) { | |
128 GLint disjoint_value = 0; | |
129 glGetIntegerv(GL_GPU_DISJOINT_EXT, &disjoint_value); | |
130 if (disjoint_value != 0) { | |
131 disjoint_occurred_ = true; | |
132 for (DisjointContext& context : disjoint_contexts_) { | |
133 context.disjoint_value_ = true; | |
134 } | |
135 } | |
136 | |
137 DisjointContext& context = disjoint_contexts_[disjoint_context_id]; | |
138 const bool prev_disjoint_value = context.disjoint_value_; | |
139 context.disjoint_value_ = false; | |
140 return prev_disjoint_value; | |
141 } | |
142 return false; | |
143 } | |
144 | |
93 const char* GPUTiming::GetTimerTypeName() const { | 145 const char* GPUTiming::GetTimerTypeName() const { |
94 switch (timer_type_) { | 146 switch (timer_type_) { |
95 case kTimerTypeDisjoint: | 147 case kTimerTypeDisjoint: |
96 return "GL_EXT_disjoint_timer_query"; | 148 return "GL_EXT_disjoint_timer_query"; |
97 case kTimerTypeARB: | 149 case kTimerTypeARB: |
98 return "GL_ARB_timer_query"; | 150 return "GL_ARB_timer_query"; |
99 default: | 151 default: |
100 return "Unknown"; | 152 return "Unknown"; |
101 } | 153 } |
102 } | 154 } |
103 | 155 |
104 bool GPUTiming::CheckAndResetTimerErrors() { | |
105 if (timer_type_ == kTimerTypeDisjoint) { | |
106 GLint disjoint_value = 0; | |
107 glGetIntegerv(GL_GPU_DISJOINT_EXT, &disjoint_value); | |
108 return disjoint_value != 0; | |
109 } else { | |
110 return false; | |
111 } | |
112 } | |
113 | |
114 int64 GPUTiming::CalculateTimerOffset() { | 156 int64 GPUTiming::CalculateTimerOffset() { |
115 if (!offset_valid_) { | 157 if (!offset_valid_) { |
116 GLint64 gl_now = 0; | 158 GLint64 gl_now = 0; |
117 glGetInteger64v(GL_TIMESTAMP, &gl_now); | 159 glGetInteger64v(GL_TIMESTAMP, &gl_now); |
118 int64 now = | 160 int64 now = |
119 cpu_time_for_testing_.is_null() | 161 cpu_time_for_testing_.is_null() |
120 ? base::TimeTicks::NowFromSystemTraceTime().ToInternalValue() | 162 ? base::TimeTicks::NowFromSystemTraceTime().ToInternalValue() |
121 : cpu_time_for_testing_.Run(); | 163 : cpu_time_for_testing_.Run(); |
122 offset_ = now - gl_now / base::Time::kNanosecondsPerMicrosecond; | 164 offset_ = now - gl_now / base::Time::kNanosecondsPerMicrosecond; |
123 offset_valid_ = timer_type_ == kTimerTypeARB; | 165 offset_valid_ = timer_type_ == kTimerTypeARB; |
124 } | 166 } |
125 return offset_; | 167 return offset_; |
126 } | 168 } |
127 | 169 |
128 void GPUTiming::InvalidateTimerOffset() { | 170 void GPUTiming::InvalidateTimerOffset() { |
129 offset_valid_ = false; | 171 offset_valid_ = false; |
130 } | 172 } |
131 | 173 |
132 void GPUTiming::SetCpuTimeForTesting( | 174 void GPUTiming::SetCpuTimeForTesting( |
133 const base::Callback<int64(void)>& cpu_time) { | 175 const base::Callback<int64(void)>& cpu_time) { |
134 cpu_time_for_testing_ = cpu_time; | 176 cpu_time_for_testing_ = cpu_time; |
135 } | 177 } |
136 | 178 |
137 void GPUTiming::SetOffsetForTesting(int64 offset, bool cache_it) { | |
138 offset_ = offset; | |
139 offset_valid_ = cache_it; | |
140 } | |
141 | |
142 void GPUTiming::SetTimerTypeForTesting(TimerType type) { | |
143 timer_type_ = type; | |
144 } | |
145 | |
146 } // namespace gpu | 179 } // namespace gpu |
OLD | NEW |