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