12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file. 42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "gpu/command_buffer/service/gpu_tracer.h" 62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <deque> 82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/bind.h" 102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/debug/trace_event.h" 11868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string_util.h" 12eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/time/time.h" 135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "gpu/command_buffer/common/gles2_cmd_utils.h" 142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace gpu { 162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace gles2 { 172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)static const unsigned int kProcessInterval = 16; 195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)static TraceOutputter* g_outputter_thread = NULL; 202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)TraceMarker::TraceMarker(const std::string& name) 2203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) : name_(name), 2303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) trace_(NULL) { 2403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)} 2503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 2603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)TraceMarker::~TraceMarker() { 2703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)} 2803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)scoped_refptr<TraceOutputter> TraceOutputter::Create(const std::string& name) { 305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!g_outputter_thread) { 315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) g_outputter_thread = new TraceOutputter(name); 322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return g_outputter_thread; 345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TraceOutputter::TraceOutputter(const std::string& name) 375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) : named_thread_(name.c_str()), local_trace_id_(0) { 385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) named_thread_.Start(); 395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) named_thread_.Stop(); 405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TraceOutputter::~TraceOutputter() { g_outputter_thread = NULL; } 435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void TraceOutputter::Trace(const std::string& name, 455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int64 start_time, 465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int64 end_time) { 475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) TRACE_EVENT_COPY_BEGIN_WITH_ID_TID_AND_TIMESTAMP0( 485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) TRACE_DISABLED_BY_DEFAULT("gpu.device"), 495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) name.c_str(), 505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) local_trace_id_, 515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) named_thread_.thread_id(), 525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) start_time); 535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) TRACE_EVENT_COPY_END_WITH_ID_TID_AND_TIMESTAMP0( 545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) TRACE_DISABLED_BY_DEFAULT("gpu.device"), 555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) name.c_str(), 565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) local_trace_id_, 575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) named_thread_.thread_id(), 585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) end_time); 595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ++local_trace_id_; 605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)GPUTrace::GPUTrace(scoped_refptr<Outputter> outputter, 635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const std::string& name, 641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci int64 offset, 651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci GpuTracerType tracer_type) 665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) : name_(name), 675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) outputter_(outputter), 685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) offset_(offset), 695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) start_time_(0), 705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) end_time_(0), 711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci tracer_type_(tracer_type), 721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci end_requested_(false) { 731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci memset(queries_, 0, sizeof(queries_)); 741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci switch (tracer_type_) { 751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci case kTracerTypeARBTimer: 761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci case kTracerTypeDisjointTimer: 771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci glGenQueriesARB(2, queries_); 781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci break; 791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci default: 811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci tracer_type_ = kTracerTypeInvalid; 821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)GPUTrace::~GPUTrace() { 861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci switch (tracer_type_) { 871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci case kTracerTypeInvalid: 881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci break; 891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci case kTracerTypeARBTimer: 911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci case kTracerTypeDisjointTimer: 921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci glDeleteQueriesARB(2, queries_); 931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci break; 941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void GPUTrace::Start() { 985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) TRACE_EVENT_COPY_ASYNC_BEGIN0( 995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) TRACE_DISABLED_BY_DEFAULT("gpu.service"), name().c_str(), this); 1001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci switch (tracer_type_) { 1021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci case kTracerTypeInvalid: 1031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci break; 1041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci case kTracerTypeDisjointTimer: 1061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // For the disjoint timer, GPU idle time does not seem to increment the 1071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // internal counter. We must calculate the offset before any query. The 1081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // good news is any device that supports disjoint timer will also support 1091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // glGetInteger64v, so we can query it directly unlike the ARBTimer case. 1101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // The "offset_" variable will always be 0 during normal use cases, only 1111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // under the unit tests will it be set to specific test values. 1121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (offset_ == 0) { 1131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci GLint64 gl_now = 0; 1141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci glGetInteger64v(GL_TIMESTAMP, &gl_now); 1151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci offset_ = base::TimeTicks::NowFromSystemTraceTime().ToInternalValue() - 1161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci gl_now / base::Time::kNanosecondsPerMicrosecond; 1171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 1181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Intentionally fall through to kTracerTypeARBTimer case.xs 1191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci case kTracerTypeARBTimer: 1201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // GL_TIMESTAMP and GL_TIMESTAMP_EXT both have the same value. 1211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci glQueryCounter(queries_[0], GL_TIMESTAMP); 1221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci break; 1235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 1255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void GPUTrace::End() { 1271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci end_requested_ = true; 1281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci switch (tracer_type_) { 1291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci case kTracerTypeInvalid: 1301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci break; 1311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci case kTracerTypeARBTimer: 1331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci case kTracerTypeDisjointTimer: 1341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // GL_TIMESTAMP and GL_TIMESTAMP_EXT both have the same value. 1351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci glQueryCounter(queries_[1], GL_TIMESTAMP); 1361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci break; 1375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) TRACE_EVENT_COPY_ASYNC_END0( 1405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) TRACE_DISABLED_BY_DEFAULT("gpu.service"), name().c_str(), this); 1415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)bool GPUTrace::IsAvailable() { 1441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (tracer_type_ != kTracerTypeInvalid) { 1451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (!end_requested_) 1461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return false; 1471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci GLint done = 0; 1491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci glGetQueryObjectiv(queries_[1], GL_QUERY_RESULT_AVAILABLE, &done); 1501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return !!done; 1511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 1525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return true; 1545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 1555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void GPUTrace::Process() { 1571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (tracer_type_ == kTracerTypeInvalid) 1585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return; 1595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) DCHECK(IsAvailable()); 1615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci GLuint64 begin_stamp = 0; 1631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci GLuint64 end_stamp = 0; 1645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // TODO(dsinclair): It's possible for the timer to wrap during the start/end. 1665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // We need to detect if the end is less then the start and correct for the 1675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // wrapping. 1681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci glGetQueryObjectui64v(queries_[0], GL_QUERY_RESULT, &begin_stamp); 1691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci glGetQueryObjectui64v(queries_[1], GL_QUERY_RESULT, &end_stamp); 1705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci start_time_ = (begin_stamp / base::Time::kNanosecondsPerMicrosecond) + 1721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci offset_; 1731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci end_time_ = (end_stamp / base::Time::kNanosecondsPerMicrosecond) + offset_; 1745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) outputter_->Trace(name(), start_time_, end_time_); 1755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 17703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)GPUTracer::GPUTracer(gles2::GLES2Decoder* decoder) 17803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) : gpu_trace_srv_category(TRACE_EVENT_API_GET_CATEGORY_GROUP_ENABLED( 17903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) TRACE_DISABLED_BY_DEFAULT("gpu.service"))), 18003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) gpu_trace_dev_category(TRACE_EVENT_API_GET_CATEGORY_GROUP_ENABLED( 18103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) TRACE_DISABLED_BY_DEFAULT("gpu.device"))), 18203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) decoder_(decoder), 18303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) timer_offset_(0), 18403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) last_tracer_source_(kTraceGroupInvalid), 1851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci tracer_type_(kTracerTypeInvalid), 18603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) gpu_timing_synced_(false), 18703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) gpu_executing_(false), 18803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) process_posted_(false) { 1891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (gfx::g_driver_gl.ext.b_GL_EXT_disjoint_timer_query) { 1901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci tracer_type_ = kTracerTypeDisjointTimer; 1911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci outputter_ = TraceOutputter::Create("GL_EXT_disjoint_timer_query"); 1921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } else if (gfx::g_driver_gl.ext.b_GL_ARB_timer_query) { 1931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci tracer_type_ = kTracerTypeARBTimer; 19403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) outputter_ = TraceOutputter::Create("GL_ARB_timer_query"); 1955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 19603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)} 1975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 19803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)GPUTracer::~GPUTracer() { 19903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)} 2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 20103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)bool GPUTracer::BeginDecoding() { 2025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (gpu_executing_) 2035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return false; 2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci CalculateTimerOffset(); 2065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) gpu_executing_ = true; 2075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (IsTracing()) { 2091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Reset disjoint bit for the disjoint timer. 2101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (tracer_type_ == kTracerTypeDisjointTimer) { 2111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci GLint disjoint_value = 0; 2121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci glGetIntegerv(GL_GPU_DISJOINT_EXT, &disjoint_value); 2131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 2141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 2155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Begin a Trace for all active markers 21603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) for (int n = 0; n < NUM_TRACER_SOURCES; n++) { 21703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) for (size_t i = 0; i < markers_[n].size(); i++) { 21803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) markers_[n][i].trace_ = CreateTrace(markers_[n][i].name_); 21903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) markers_[n][i].trace_->Start(); 22003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) } 2215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 2225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 2235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return true; 2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 22603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)bool GPUTracer::EndDecoding() { 2275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!gpu_executing_) 2282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 2292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // End Trace for all active markers 2315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (IsTracing()) { 23203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) for (int n = 0; n < NUM_TRACER_SOURCES; n++) { 23303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) for (size_t i = 0; i < markers_[n].size(); i++) { 2341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (markers_[n][i].trace_.get()) { 23503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) markers_[n][i].trace_->End(); 23603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) if (markers_[n][i].trace_->IsEnabled()) 23703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) traces_.push_back(markers_[n][i].trace_); 23803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) markers_[n][i].trace_ = 0; 23903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) } 2405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 2415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 2425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) IssueProcessTask(); 2435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 2445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) gpu_executing_ = false; 24603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 24703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // NOTE(vmiura): glFlush() here can help give better trace results, 24803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // but it distorts the normal device behavior. 2492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 2502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 25203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)bool GPUTracer::Begin(const std::string& name, GpuTracerSource source) { 2535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!gpu_executing_) 2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 2552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 25603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) DCHECK(source >= 0 && source < NUM_TRACER_SOURCES); 25703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 2585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Push new marker from given 'source' 25903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) last_tracer_source_ = source; 26003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) markers_[source].push_back(TraceMarker(name)); 2612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Create trace 2635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (IsTracing()) { 2645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) scoped_refptr<GPUTrace> trace = CreateTrace(name); 2655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) trace->Start(); 26603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) markers_[source].back().trace_ = trace; 2675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 26803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 2692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 2702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 27203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)bool GPUTracer::End(GpuTracerSource source) { 2735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!gpu_executing_) 2745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return false; 2755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 27603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) DCHECK(source >= 0 && source < NUM_TRACER_SOURCES); 27703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 2785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Pop last marker with matching 'source' 27903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) if (!markers_[source].empty()) { 28003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) if (IsTracing()) { 28103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) scoped_refptr<GPUTrace> trace = markers_[source].back().trace_; 2821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (trace.get()) { 28303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) trace->End(); 28403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) if (trace->IsEnabled()) 28503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) traces_.push_back(trace); 28603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) IssueProcessTask(); 2875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 2885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 28903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 29003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) markers_[source].pop_back(); 29103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) return true; 2925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 2935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return false; 2945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 2955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 29603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)bool GPUTracer::IsTracing() { 29703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) return (*gpu_trace_srv_category != 0) || (*gpu_trace_dev_category != 0); 2985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 2992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 30003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)const std::string& GPUTracer::CurrentName() const { 30103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) if (last_tracer_source_ >= 0 && 30203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) last_tracer_source_ < NUM_TRACER_SOURCES && 30303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) !markers_[last_tracer_source_].empty()) { 30403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) return markers_[last_tracer_source_].back().name_; 3052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 30603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) return base::EmptyString(); 3072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 30903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)scoped_refptr<GPUTrace> GPUTracer::CreateTrace(const std::string& name) { 3101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci GpuTracerType tracer_type = *gpu_trace_dev_category ? tracer_type_ : 3111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci kTracerTypeInvalid; 3121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 3131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return new GPUTrace(outputter_, name, timer_offset_, tracer_type); 3142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 31603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)void GPUTracer::Process() { 31703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) process_posted_ = false; 31803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) ProcessTraces(); 31903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) IssueProcessTask(); 3202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 32203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)void GPUTracer::ProcessTraces() { 3231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (tracer_type_ == kTracerTypeInvalid) { 3241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci traces_.clear(); 32503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) return; 3265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 3272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 32803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) TRACE_EVENT0("gpu", "GPUTracer::ProcessTraces"); 3295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Make owning decoder's GL context current 3315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!decoder_->MakeCurrent()) { 3325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Skip subsequent GL calls if MakeCurrent fails 3335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) traces_.clear(); 3345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return; 3355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 3365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Check if disjoint operation has occurred, discard ongoing traces if so. 3381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (tracer_type_ == kTracerTypeDisjointTimer) { 3391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci GLint disjoint_value = 0; 3401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci glGetIntegerv(GL_GPU_DISJOINT_EXT, &disjoint_value); 3411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (disjoint_value) 3421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci traces_.clear(); 3431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 3441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 3455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) while (!traces_.empty() && traces_.front()->IsAvailable()) { 3465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) traces_.front()->Process(); 3475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) traces_.pop_front(); 3485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 3495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Clear pending traces if there were are any errors 3515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) GLenum err = glGetError(); 3525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (err != GL_NO_ERROR) 3535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) traces_.clear(); 3542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 35603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)void GPUTracer::CalculateTimerOffset() { 3571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (tracer_type_ != kTracerTypeInvalid) { 3581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (*gpu_trace_dev_category == '\0') { 3591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // If GPU device category is off, invalidate timing sync. 3601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci gpu_timing_synced_ = false; 3611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return; 3621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } else if (tracer_type_ == kTracerTypeDisjointTimer) { 3631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Disjoint timers offsets should be calculated before every query. 3641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci gpu_timing_synced_ = true; 3651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci timer_offset_ = 0; 3661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 3671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 3681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (gpu_timing_synced_) 3691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return; 3701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 37103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) TRACE_EVENT0("gpu", "GPUTracer::CalculateTimerOffset"); 37203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 37303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // NOTE(vmiura): It would be better to use glGetInteger64v, however 37403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) // it's not available everywhere. 37503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) GLuint64 gl_now = 0; 37603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) GLuint query; 3771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 3781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci glGenQueriesARB(1, &query); 3791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 38003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) glFinish(); 38103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) glQueryCounter(query, GL_TIMESTAMP); 38203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) glFinish(); 3831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 38403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) glGetQueryObjectui64v(query, GL_QUERY_RESULT, &gl_now); 3851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci glDeleteQueriesARB(1, &query); 3861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 38703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) base::TimeTicks system_now = base::TimeTicks::NowFromSystemTraceTime(); 38803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) 38903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) gl_now /= base::Time::kNanosecondsPerMicrosecond; 39003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) timer_offset_ = system_now.ToInternalValue() - gl_now; 3911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci gpu_timing_synced_ = true; 39203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) } 3932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 39503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)void GPUTracer::IssueProcessTask() { 39603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) if (traces_.empty() || process_posted_) 39703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) return; 3982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 39903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) process_posted_ = true; 40003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) base::MessageLoop::current()->PostDelayedTask( 40103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) FROM_HERE, 40203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) base::Bind(&GPUTracer::Process, base::AsWeakPtr(this)), 40303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) base::TimeDelta::FromMilliseconds(kProcessInterval)); 4042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace gles2 4072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace gpu 408