| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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_tracer.h" | 5 #include "gpu/command_buffer/service/gpu_tracer.h" |
| 6 | 6 |
| 7 #include <deque> | 7 #include <deque> |
| 8 | 8 |
| 9 #include "base/bind.h" | 9 #include "base/bind.h" |
| 10 #include "base/debug/trace_event.h" | 10 #include "base/debug/trace_event.h" |
| 11 #include "base/strings/string_util.h" | 11 #include "base/strings/string_util.h" |
| 12 #include "base/time/time.h" | 12 #include "base/time/time.h" |
| 13 #include "gpu/command_buffer/common/gles2_cmd_utils.h" | 13 #include "gpu/command_buffer/common/gles2_cmd_utils.h" |
| 14 | 14 |
| 15 namespace gpu { | 15 namespace gpu { |
| 16 namespace gles2 { | 16 namespace gles2 { |
| 17 | 17 |
| 18 static const unsigned int kProcessInterval = 16; | 18 static const unsigned int kProcessInterval = 16; |
| 19 static TraceOutputter* g_outputter_thread = NULL; | 19 static TraceOutputter* g_outputter_thread = NULL; |
| 20 | 20 |
| 21 CPUTime::CPUTime() { |
| 22 } |
| 23 |
| 24 int64 CPUTime::GetCurrentTime() { |
| 25 return base::TimeTicks::NowFromSystemTraceTime().ToInternalValue(); |
| 26 } |
| 27 |
| 28 CPUTime::~CPUTime() { |
| 29 } |
| 30 |
| 21 TraceMarker::TraceMarker(const std::string& category, const std::string& name) | 31 TraceMarker::TraceMarker(const std::string& category, const std::string& name) |
| 22 : category_(category), | 32 : category_(category), |
| 23 name_(name), | 33 name_(name), |
| 24 trace_(NULL) { | 34 trace_(NULL) { |
| 25 } | 35 } |
| 26 | 36 |
| 27 TraceMarker::~TraceMarker() { | 37 TraceMarker::~TraceMarker() { |
| 28 } | 38 } |
| 29 | 39 |
| 30 scoped_refptr<TraceOutputter> TraceOutputter::Create(const std::string& name) { | 40 scoped_refptr<TraceOutputter> TraceOutputter::Create(const std::string& name) { |
| 31 if (!g_outputter_thread) { | 41 if (!g_outputter_thread) { |
| 32 g_outputter_thread = new TraceOutputter(name); | 42 g_outputter_thread = new TraceOutputter(name); |
| 33 } | 43 } |
| 34 return g_outputter_thread; | 44 return g_outputter_thread; |
| 35 } | 45 } |
| 36 | 46 |
| 37 TraceOutputter::TraceOutputter(const std::string& name) | 47 TraceOutputter::TraceOutputter(const std::string& name) |
| 38 : named_thread_(name.c_str()), local_trace_id_(0) { | 48 : named_thread_(name.c_str()), local_trace_id_(0) { |
| 39 named_thread_.Start(); | 49 named_thread_.Start(); |
| 40 named_thread_.Stop(); | 50 named_thread_.Stop(); |
| 41 } | 51 } |
| 42 | 52 |
| 43 TraceOutputter::~TraceOutputter() { g_outputter_thread = NULL; } | 53 TraceOutputter::~TraceOutputter() { g_outputter_thread = NULL; } |
| 44 | 54 |
| 45 void TraceOutputter::Trace(const std::string& category, | 55 void TraceOutputter::TraceDevice(const std::string& category, |
| 46 const std::string& name, | 56 const std::string& name, |
| 47 int64 start_time, | 57 int64 start_time, |
| 48 int64 end_time) { | 58 int64 end_time) { |
| 49 TRACE_EVENT_COPY_BEGIN_WITH_ID_TID_AND_TIMESTAMP0(category.c_str(), | 59 TRACE_EVENT_COPY_BEGIN_WITH_ID_TID_AND_TIMESTAMP1( |
| 50 name.c_str(), | 60 TRACE_DISABLED_BY_DEFAULT("gpu.device"), |
| 51 local_trace_id_, | 61 name.c_str(), |
| 52 named_thread_.thread_id(), | 62 local_trace_id_, |
| 53 start_time); | 63 named_thread_.thread_id(), |
| 54 TRACE_EVENT_COPY_END_WITH_ID_TID_AND_TIMESTAMP0(category.c_str(), | 64 start_time, |
| 55 name.c_str(), | 65 "gl_category", |
| 56 local_trace_id_, | 66 category.c_str()); |
| 57 named_thread_.thread_id(), | 67 TRACE_EVENT_COPY_END_WITH_ID_TID_AND_TIMESTAMP1( |
| 58 end_time); | 68 TRACE_DISABLED_BY_DEFAULT("gpu.device"), |
| 69 name.c_str(), |
| 70 local_trace_id_, |
| 71 named_thread_.thread_id(), |
| 72 end_time, |
| 73 "gl_category", |
| 74 category.c_str()); |
| 59 ++local_trace_id_; | 75 ++local_trace_id_; |
| 60 } | 76 } |
| 61 | 77 |
| 78 void TraceOutputter::TraceServiceBegin(const std::string& category, |
| 79 const std::string& name, |
| 80 void* id) { |
| 81 TRACE_EVENT_COPY_ASYNC_BEGIN1(TRACE_DISABLED_BY_DEFAULT("gpu.service"), |
| 82 name.c_str(), this, |
| 83 "gl_category", category.c_str()); |
| 84 } |
| 85 |
| 86 void TraceOutputter::TraceServiceEnd(const std::string& category, |
| 87 const std::string& name, |
| 88 void* id) { |
| 89 TRACE_EVENT_COPY_ASYNC_END1(TRACE_DISABLED_BY_DEFAULT("gpu.service"), |
| 90 name.c_str(), this, |
| 91 "gl_category", category.c_str()); |
| 92 } |
| 93 |
| 62 GPUTrace::GPUTrace(scoped_refptr<Outputter> outputter, | 94 GPUTrace::GPUTrace(scoped_refptr<Outputter> outputter, |
| 95 scoped_refptr<CPUTime> cpu_time, |
| 63 const std::string& category, | 96 const std::string& category, |
| 64 const std::string& name, | 97 const std::string& name, |
| 65 int64 offset, | 98 int64 offset, |
| 66 GpuTracerType tracer_type) | 99 GpuTracerType tracer_type) |
| 67 : category_(category), | 100 : category_(category), |
| 68 name_(name), | 101 name_(name), |
| 69 outputter_(outputter), | 102 outputter_(outputter), |
| 103 cpu_time_(cpu_time), |
| 70 offset_(offset), | 104 offset_(offset), |
| 71 start_time_(0), | 105 start_time_(0), |
| 72 end_time_(0), | 106 end_time_(0), |
| 73 tracer_type_(tracer_type), | 107 tracer_type_(tracer_type), |
| 74 end_requested_(false) { | 108 end_requested_(false) { |
| 75 memset(queries_, 0, sizeof(queries_)); | 109 memset(queries_, 0, sizeof(queries_)); |
| 76 switch (tracer_type_) { | 110 switch (tracer_type_) { |
| 77 case kTracerTypeARBTimer: | 111 case kTracerTypeARBTimer: |
| 78 case kTracerTypeDisjointTimer: | 112 case kTracerTypeDisjointTimer: |
| 79 glGenQueriesARB(2, queries_); | 113 glGenQueriesARB(2, queries_); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 91 | 125 |
| 92 case kTracerTypeARBTimer: | 126 case kTracerTypeARBTimer: |
| 93 case kTracerTypeDisjointTimer: | 127 case kTracerTypeDisjointTimer: |
| 94 glDeleteQueriesARB(2, queries_); | 128 glDeleteQueriesARB(2, queries_); |
| 95 break; | 129 break; |
| 96 } | 130 } |
| 97 } | 131 } |
| 98 | 132 |
| 99 void GPUTrace::Start(bool trace_service) { | 133 void GPUTrace::Start(bool trace_service) { |
| 100 if (trace_service) { | 134 if (trace_service) { |
| 101 TRACE_EVENT_COPY_ASYNC_BEGIN0(category().c_str(), name().c_str(), this); | 135 outputter_->TraceServiceBegin(category_, name_, this); |
| 102 } | 136 } |
| 103 | 137 |
| 104 switch (tracer_type_) { | 138 switch (tracer_type_) { |
| 105 case kTracerTypeInvalid: | 139 case kTracerTypeInvalid: |
| 106 break; | 140 break; |
| 107 | 141 |
| 108 case kTracerTypeDisjointTimer: | 142 case kTracerTypeDisjointTimer: |
| 109 // For the disjoint timer, GPU idle time does not seem to increment the | 143 // For the disjoint timer, GPU idle time does not seem to increment the |
| 110 // internal counter. We must calculate the offset before any query. The | 144 // internal counter. We must calculate the offset before any query. The |
| 111 // good news is any device that supports disjoint timer will also support | 145 // good news is any device that supports disjoint timer will also support |
| 112 // glGetInteger64v, so we can query it directly unlike the ARBTimer case. | 146 // glGetInteger64v, so we can query it directly unlike the ARBTimer case. |
| 113 // The "offset_" variable will always be 0 during normal use cases, only | 147 // The "offset_" variable will always be 0 during normal use cases, only |
| 114 // under the unit tests will it be set to specific test values. | 148 // under the unit tests will it be set to specific test values. |
| 115 if (offset_ == 0) { | 149 if (offset_ == 0) { |
| 116 GLint64 gl_now = 0; | 150 GLint64 gl_now = 0; |
| 117 glGetInteger64v(GL_TIMESTAMP, &gl_now); | 151 glGetInteger64v(GL_TIMESTAMP, &gl_now); |
| 118 offset_ = base::TimeTicks::NowFromSystemTraceTime().ToInternalValue() - | 152 offset_ = cpu_time_->GetCurrentTime() - |
| 119 gl_now / base::Time::kNanosecondsPerMicrosecond; | 153 gl_now / base::Time::kNanosecondsPerMicrosecond; |
| 120 } | 154 } |
| 121 // Intentionally fall through to kTracerTypeARBTimer case.xs | 155 // Intentionally fall through to kTracerTypeARBTimer case.xs |
| 122 case kTracerTypeARBTimer: | 156 case kTracerTypeARBTimer: |
| 123 // GL_TIMESTAMP and GL_TIMESTAMP_EXT both have the same value. | 157 // GL_TIMESTAMP and GL_TIMESTAMP_EXT both have the same value. |
| 124 glQueryCounter(queries_[0], GL_TIMESTAMP); | 158 glQueryCounter(queries_[0], GL_TIMESTAMP); |
| 125 break; | 159 break; |
| 126 } | 160 } |
| 127 } | 161 } |
| 128 | 162 |
| 129 void GPUTrace::End(bool tracing_service) { | 163 void GPUTrace::End(bool tracing_service) { |
| 130 end_requested_ = true; | 164 end_requested_ = true; |
| 131 switch (tracer_type_) { | 165 switch (tracer_type_) { |
| 132 case kTracerTypeInvalid: | 166 case kTracerTypeInvalid: |
| 133 break; | 167 break; |
| 134 | 168 |
| 135 case kTracerTypeARBTimer: | 169 case kTracerTypeARBTimer: |
| 136 case kTracerTypeDisjointTimer: | 170 case kTracerTypeDisjointTimer: |
| 137 // GL_TIMESTAMP and GL_TIMESTAMP_EXT both have the same value. | 171 // GL_TIMESTAMP and GL_TIMESTAMP_EXT both have the same value. |
| 138 glQueryCounter(queries_[1], GL_TIMESTAMP); | 172 glQueryCounter(queries_[1], GL_TIMESTAMP); |
| 139 break; | 173 break; |
| 140 } | 174 } |
| 141 | 175 |
| 142 if (tracing_service) { | 176 if (tracing_service) { |
| 143 TRACE_EVENT_COPY_ASYNC_END0(category().c_str(), name().c_str(), this); | 177 outputter_->TraceServiceEnd(category_, name_, this); |
| 144 } | 178 } |
| 145 } | 179 } |
| 146 | 180 |
| 147 bool GPUTrace::IsAvailable() { | 181 bool GPUTrace::IsAvailable() { |
| 148 if (tracer_type_ != kTracerTypeInvalid) { | 182 if (tracer_type_ != kTracerTypeInvalid) { |
| 149 if (!end_requested_) | 183 if (!end_requested_) |
| 150 return false; | 184 return false; |
| 151 | 185 |
| 152 GLint done = 0; | 186 GLint done = 0; |
| 153 glGetQueryObjectiv(queries_[1], GL_QUERY_RESULT_AVAILABLE, &done); | 187 glGetQueryObjectiv(queries_[1], GL_QUERY_RESULT_AVAILABLE, &done); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 168 | 202 |
| 169 // TODO(dsinclair): It's possible for the timer to wrap during the start/end. | 203 // TODO(dsinclair): It's possible for the timer to wrap during the start/end. |
| 170 // We need to detect if the end is less then the start and correct for the | 204 // We need to detect if the end is less then the start and correct for the |
| 171 // wrapping. | 205 // wrapping. |
| 172 glGetQueryObjectui64v(queries_[0], GL_QUERY_RESULT, &begin_stamp); | 206 glGetQueryObjectui64v(queries_[0], GL_QUERY_RESULT, &begin_stamp); |
| 173 glGetQueryObjectui64v(queries_[1], GL_QUERY_RESULT, &end_stamp); | 207 glGetQueryObjectui64v(queries_[1], GL_QUERY_RESULT, &end_stamp); |
| 174 | 208 |
| 175 start_time_ = (begin_stamp / base::Time::kNanosecondsPerMicrosecond) + | 209 start_time_ = (begin_stamp / base::Time::kNanosecondsPerMicrosecond) + |
| 176 offset_; | 210 offset_; |
| 177 end_time_ = (end_stamp / base::Time::kNanosecondsPerMicrosecond) + offset_; | 211 end_time_ = (end_stamp / base::Time::kNanosecondsPerMicrosecond) + offset_; |
| 178 outputter_->Trace(category(), name(), start_time_, end_time_); | 212 outputter_->TraceDevice(category_, name_, start_time_, end_time_); |
| 179 } | 213 } |
| 180 | 214 |
| 181 GPUTracer::GPUTracer(gles2::GLES2Decoder* decoder) | 215 GPUTracer::GPUTracer(gles2::GLES2Decoder* decoder) |
| 182 : gpu_trace_srv_category(TRACE_EVENT_API_GET_CATEGORY_GROUP_ENABLED( | 216 : gpu_trace_srv_category(TRACE_EVENT_API_GET_CATEGORY_GROUP_ENABLED( |
| 183 TRACE_DISABLED_BY_DEFAULT("gpu.service"))), | 217 TRACE_DISABLED_BY_DEFAULT("gpu.service"))), |
| 184 gpu_trace_dev_category(TRACE_EVENT_API_GET_CATEGORY_GROUP_ENABLED( | 218 gpu_trace_dev_category(TRACE_EVENT_API_GET_CATEGORY_GROUP_ENABLED( |
| 185 TRACE_DISABLED_BY_DEFAULT("gpu.device"))), | 219 TRACE_DISABLED_BY_DEFAULT("gpu.device"))), |
| 186 decoder_(decoder), | 220 decoder_(decoder), |
| 187 timer_offset_(0), | 221 timer_offset_(0), |
| 188 last_tracer_source_(kTraceGroupInvalid), | |
| 189 tracer_type_(kTracerTypeInvalid), | 222 tracer_type_(kTracerTypeInvalid), |
| 190 gpu_timing_synced_(false), | 223 gpu_timing_synced_(false), |
| 191 gpu_executing_(false), | 224 gpu_executing_(false), |
| 192 process_posted_(false) { | 225 process_posted_(false) { |
| 193 if (gfx::g_driver_gl.ext.b_GL_EXT_disjoint_timer_query) { | |
| 194 tracer_type_ = kTracerTypeDisjointTimer; | |
| 195 outputter_ = TraceOutputter::Create("GL_EXT_disjoint_timer_query"); | |
| 196 } else if (gfx::g_driver_gl.ext.b_GL_ARB_timer_query) { | |
| 197 tracer_type_ = kTracerTypeARBTimer; | |
| 198 outputter_ = TraceOutputter::Create("GL_ARB_timer_query"); | |
| 199 } | |
| 200 } | 226 } |
| 201 | 227 |
| 202 GPUTracer::~GPUTracer() { | 228 GPUTracer::~GPUTracer() { |
| 203 } | 229 } |
| 204 | 230 |
| 205 bool GPUTracer::BeginDecoding() { | 231 bool GPUTracer::BeginDecoding() { |
| 206 if (gpu_executing_) | 232 if (gpu_executing_) |
| 207 return false; | 233 return false; |
| 208 | 234 |
| 235 if (outputter_ == NULL) { |
| 236 tracer_type_ = DetermineTracerType(); |
| 237 const char* tracer_type_name = "Unknown"; |
| 238 switch (tracer_type_) { |
| 239 case kTracerTypeDisjointTimer: |
| 240 tracer_type_name = "GL_EXT_disjoint_timer_query"; |
| 241 break; |
| 242 case kTracerTypeARBTimer: |
| 243 tracer_type_name = "GL_ARB_timer_query"; |
| 244 break; |
| 245 |
| 246 default: |
| 247 break; |
| 248 } |
| 249 |
| 250 outputter_ = CreateOutputter(tracer_type_name); |
| 251 } |
| 252 |
| 253 if (cpu_time_ == NULL) { |
| 254 cpu_time_ = CreateCPUTime(); |
| 255 } |
| 256 |
| 209 CalculateTimerOffset(); | 257 CalculateTimerOffset(); |
| 210 gpu_executing_ = true; | 258 gpu_executing_ = true; |
| 211 | 259 |
| 212 if (IsTracing()) { | 260 if (IsTracing()) { |
| 213 // Reset disjoint bit for the disjoint timer. | 261 // Reset disjoint bit for the disjoint timer. |
| 214 if (tracer_type_ == kTracerTypeDisjointTimer) { | 262 if (tracer_type_ == kTracerTypeDisjointTimer) { |
| 215 GLint disjoint_value = 0; | 263 GLint disjoint_value = 0; |
| 216 glGetIntegerv(GL_GPU_DISJOINT_EXT, &disjoint_value); | 264 glGetIntegerv(GL_GPU_DISJOINT_EXT, &disjoint_value); |
| 217 } | 265 } |
| 218 | 266 |
| (...skipping 11 matching lines...) Expand all Loading... |
| 230 } | 278 } |
| 231 | 279 |
| 232 bool GPUTracer::EndDecoding() { | 280 bool GPUTracer::EndDecoding() { |
| 233 if (!gpu_executing_) | 281 if (!gpu_executing_) |
| 234 return false; | 282 return false; |
| 235 | 283 |
| 236 // End Trace for all active markers | 284 // End Trace for all active markers |
| 237 if (IsTracing()) { | 285 if (IsTracing()) { |
| 238 for (int n = 0; n < NUM_TRACER_SOURCES; n++) { | 286 for (int n = 0; n < NUM_TRACER_SOURCES; n++) { |
| 239 for (size_t i = 0; i < markers_[n].size(); i++) { | 287 for (size_t i = 0; i < markers_[n].size(); i++) { |
| 240 if (markers_[n][i].trace_.get()) { | 288 TraceMarker& marker = markers_[n][i]; |
| 241 markers_[n][i].trace_->End(*gpu_trace_srv_category != 0); | 289 if (marker.trace_.get()) { |
| 242 if (markers_[n][i].trace_->IsEnabled()) | 290 marker.trace_->End(*gpu_trace_srv_category != 0); |
| 243 traces_.push_back(markers_[n][i].trace_); | 291 if (marker.trace_->IsEnabled()) |
| 292 traces_.push_back(marker.trace_); |
| 293 |
| 244 markers_[n][i].trace_ = 0; | 294 markers_[n][i].trace_ = 0; |
| 245 } | 295 } |
| 246 } | 296 } |
| 247 } | 297 } |
| 248 IssueProcessTask(); | 298 IssueProcessTask(); |
| 249 } | 299 } |
| 250 | 300 |
| 251 gpu_executing_ = false; | 301 gpu_executing_ = false; |
| 252 | 302 |
| 253 // NOTE(vmiura): glFlush() here can help give better trace results, | 303 // NOTE(vmiura): glFlush() here can help give better trace results, |
| 254 // but it distorts the normal device behavior. | 304 // but it distorts the normal device behavior. |
| 255 return true; | 305 return true; |
| 256 } | 306 } |
| 257 | 307 |
| 258 bool GPUTracer::Begin(const std::string& category, const std::string& name, | 308 bool GPUTracer::Begin(const std::string& category, const std::string& name, |
| 259 GpuTracerSource source) { | 309 GpuTracerSource source) { |
| 260 if (!gpu_executing_) | 310 if (!gpu_executing_) |
| 261 return false; | 311 return false; |
| 262 | 312 |
| 263 DCHECK(source >= 0 && source < NUM_TRACER_SOURCES); | 313 DCHECK(source >= 0 && source < NUM_TRACER_SOURCES); |
| 264 | 314 |
| 265 // Push new marker from given 'source' | 315 // Push new marker from given 'source' |
| 266 last_tracer_source_ = source; | |
| 267 markers_[source].push_back(TraceMarker(category, name)); | 316 markers_[source].push_back(TraceMarker(category, name)); |
| 268 | 317 |
| 269 // Create trace | 318 // Create trace |
| 270 if (IsTracing()) { | 319 if (IsTracing()) { |
| 271 scoped_refptr<GPUTrace> trace = CreateTrace(category, name); | 320 scoped_refptr<GPUTrace> trace = CreateTrace(category, name); |
| 272 trace->Start(*gpu_trace_srv_category != 0); | 321 trace->Start(*gpu_trace_srv_category != 0); |
| 273 markers_[source].back().trace_ = trace; | 322 markers_[source].back().trace_ = trace; |
| 274 } | 323 } |
| 275 | 324 |
| 276 return true; | 325 return true; |
| (...skipping 20 matching lines...) Expand all Loading... |
| 297 markers_[source].pop_back(); | 346 markers_[source].pop_back(); |
| 298 return true; | 347 return true; |
| 299 } | 348 } |
| 300 return false; | 349 return false; |
| 301 } | 350 } |
| 302 | 351 |
| 303 bool GPUTracer::IsTracing() { | 352 bool GPUTracer::IsTracing() { |
| 304 return (*gpu_trace_srv_category != 0) || (*gpu_trace_dev_category != 0); | 353 return (*gpu_trace_srv_category != 0) || (*gpu_trace_dev_category != 0); |
| 305 } | 354 } |
| 306 | 355 |
| 307 const std::string& GPUTracer::CurrentCategory() const { | 356 const std::string& GPUTracer::CurrentCategory(GpuTracerSource source) const { |
| 308 if (last_tracer_source_ >= 0 && | 357 if (source >= 0 && |
| 309 last_tracer_source_ < NUM_TRACER_SOURCES && | 358 source < NUM_TRACER_SOURCES && |
| 310 !markers_[last_tracer_source_].empty()) { | 359 !markers_[source].empty()) { |
| 311 return markers_[last_tracer_source_].back().category_; | 360 return markers_[source].back().category_; |
| 312 } | 361 } |
| 313 return base::EmptyString(); | 362 return base::EmptyString(); |
| 314 } | 363 } |
| 315 | 364 |
| 316 const std::string& GPUTracer::CurrentName() const { | 365 const std::string& GPUTracer::CurrentName(GpuTracerSource source) const { |
| 317 if (last_tracer_source_ >= 0 && | 366 if (source >= 0 && |
| 318 last_tracer_source_ < NUM_TRACER_SOURCES && | 367 source < NUM_TRACER_SOURCES && |
| 319 !markers_[last_tracer_source_].empty()) { | 368 !markers_[source].empty()) { |
| 320 return markers_[last_tracer_source_].back().name_; | 369 return markers_[source].back().name_; |
| 321 } | 370 } |
| 322 return base::EmptyString(); | 371 return base::EmptyString(); |
| 323 } | 372 } |
| 324 | 373 |
| 325 scoped_refptr<GPUTrace> GPUTracer::CreateTrace(const std::string& category, | 374 scoped_refptr<GPUTrace> GPUTracer::CreateTrace(const std::string& category, |
| 326 const std::string& name) { | 375 const std::string& name) { |
| 327 GpuTracerType tracer_type = *gpu_trace_dev_category ? tracer_type_ : | 376 GpuTracerType tracer_type = *gpu_trace_dev_category ? tracer_type_ : |
| 328 kTracerTypeInvalid; | 377 kTracerTypeInvalid; |
| 329 | 378 |
| 330 return new GPUTrace(outputter_, category, name, timer_offset_, tracer_type); | 379 return new GPUTrace(outputter_, cpu_time_, category, name, |
| 380 timer_offset_, tracer_type); |
| 381 } |
| 382 |
| 383 scoped_refptr<Outputter> GPUTracer::CreateOutputter(const std::string& name) { |
| 384 return TraceOutputter::Create(name); |
| 385 } |
| 386 |
| 387 scoped_refptr<CPUTime> GPUTracer::CreateCPUTime() { |
| 388 return new CPUTime(); |
| 389 } |
| 390 |
| 391 GpuTracerType GPUTracer::DetermineTracerType() { |
| 392 if (gfx::g_driver_gl.ext.b_GL_EXT_disjoint_timer_query) { |
| 393 return kTracerTypeDisjointTimer; |
| 394 } else if (gfx::g_driver_gl.ext.b_GL_ARB_timer_query) { |
| 395 return kTracerTypeARBTimer; |
| 396 } |
| 397 |
| 398 return kTracerTypeInvalid; |
| 399 } |
| 400 |
| 401 void GPUTracer::PostTask() { |
| 402 base::MessageLoop::current()->PostDelayedTask( |
| 403 FROM_HERE, |
| 404 base::Bind(&GPUTracer::Process, base::AsWeakPtr(this)), |
| 405 base::TimeDelta::FromMilliseconds(kProcessInterval)); |
| 331 } | 406 } |
| 332 | 407 |
| 333 void GPUTracer::Process() { | 408 void GPUTracer::Process() { |
| 334 process_posted_ = false; | 409 process_posted_ = false; |
| 335 ProcessTraces(); | 410 ProcessTraces(); |
| 336 IssueProcessTask(); | 411 IssueProcessTask(); |
| 337 } | 412 } |
| 338 | 413 |
| 339 void GPUTracer::ProcessTraces() { | 414 void GPUTracer::ProcessTraces() { |
| 340 if (tracer_type_ == kTracerTypeInvalid) { | 415 if (tracer_type_ == kTracerTypeInvalid) { |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 394 | 469 |
| 395 glGenQueriesARB(1, &query); | 470 glGenQueriesARB(1, &query); |
| 396 | 471 |
| 397 glFinish(); | 472 glFinish(); |
| 398 glQueryCounter(query, GL_TIMESTAMP); | 473 glQueryCounter(query, GL_TIMESTAMP); |
| 399 glFinish(); | 474 glFinish(); |
| 400 | 475 |
| 401 glGetQueryObjectui64v(query, GL_QUERY_RESULT, &gl_now); | 476 glGetQueryObjectui64v(query, GL_QUERY_RESULT, &gl_now); |
| 402 glDeleteQueriesARB(1, &query); | 477 glDeleteQueriesARB(1, &query); |
| 403 | 478 |
| 404 base::TimeTicks system_now = base::TimeTicks::NowFromSystemTraceTime(); | |
| 405 | |
| 406 gl_now /= base::Time::kNanosecondsPerMicrosecond; | 479 gl_now /= base::Time::kNanosecondsPerMicrosecond; |
| 407 timer_offset_ = system_now.ToInternalValue() - gl_now; | 480 timer_offset_ = cpu_time_->GetCurrentTime() - gl_now; |
| 408 gpu_timing_synced_ = true; | 481 gpu_timing_synced_ = true; |
| 409 } | 482 } |
| 410 } | 483 } |
| 411 | 484 |
| 412 void GPUTracer::IssueProcessTask() { | 485 void GPUTracer::IssueProcessTask() { |
| 413 if (traces_.empty() || process_posted_) | 486 if (traces_.empty() || process_posted_) |
| 414 return; | 487 return; |
| 415 | 488 |
| 416 process_posted_ = true; | 489 process_posted_ = true; |
| 417 base::MessageLoop::current()->PostDelayedTask( | 490 PostTask(); |
| 418 FROM_HERE, | |
| 419 base::Bind(&GPUTracer::Process, base::AsWeakPtr(this)), | |
| 420 base::TimeDelta::FromMilliseconds(kProcessInterval)); | |
| 421 } | 491 } |
| 422 | 492 |
| 423 } // namespace gles2 | 493 } // namespace gles2 |
| 424 } // namespace gpu | 494 } // namespace gpu |
| OLD | NEW |