// Copyright (c) 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "ui/gl/gpu_timing.h"

#include "base/containers/circular_deque.h"
#include "base/macros.h"
#include "base/memory/ptr_util.h"
#include "base/time/time.h"
#include "ui/gl/gl_bindings.h"
#include "ui/gl/gl_context.h"
#include "ui/gl/gl_version_info.h"

namespace gl {

class TimeElapsedTimerQuery;
class TimerQuery;

int64_t NanoToMicro(uint64_t nano_seconds) {
  const uint64_t up = nano_seconds + base::Time::kNanosecondsPerMicrosecond / 2;
  return static_cast<int64_t>(up / base::Time::kNanosecondsPerMicrosecond);
}

int32_t QueryTimestampBits() {
  GLint timestamp_bits = 0;
  glGetQueryiv(GL_TIMESTAMP, GL_QUERY_COUNTER_BITS, &timestamp_bits);
  return static_cast<int32_t>(timestamp_bits);
}

class GPUTimingImpl : public GPUTiming {
 public:
   GPUTimingImpl(GLContextReal* context);
  ~GPUTimingImpl() override;

  void ForceTimeElapsedQuery() { force_time_elapsed_query_ = true; }
  bool IsForceTimeElapsedQuery() { return force_time_elapsed_query_; }

  GPUTiming::TimerType GetTimerType() const { return timer_type_; }

  uint32_t GetDisjointCount();
  int64_t CalculateTimerOffset();

  scoped_refptr<QueryResult> BeginElapsedTimeQuery();
  void EndElapsedTimeQuery(scoped_refptr<QueryResult> result);

  scoped_refptr<QueryResult> DoTimeStampQuery();

  int64_t GetCurrentCPUTime() {
    return cpu_time_for_testing_.is_null()
           ? (base::TimeTicks::Now() - base::TimeTicks()).InMicroseconds()
           : cpu_time_for_testing_.Run();
  }
  void SetCpuTimeForTesting(const base::Callback<int64_t(void)>& cpu_time) {
    cpu_time_for_testing_ = cpu_time;
  }

  void UpdateQueryResults();

  int64_t GetMaxTimeStamp() { return max_time_stamp_; }
  void UpdateMaxTimeStamp(int64_t value) {
    max_time_stamp_ = std::max(max_time_stamp_, value);
  }

  uint32_t GetElapsedQueryCount() { return elapsed_query_count_; }
  void IncElapsedQueryCount() { elapsed_query_count_++; }
  void DecElapsedQueryCount() { elapsed_query_count_--; }

  void SetLastElapsedQuery(scoped_refptr<TimeElapsedTimerQuery> query);
  scoped_refptr<TimeElapsedTimerQuery> GetLastElapsedQuery();

  void HandleBadQuery();
  bool IsGoodQueryID(uint32_t query_id);

 private:
  scoped_refptr<GPUTimingClient> CreateGPUTimingClient() override;

  base::Callback<int64_t(void)> cpu_time_for_testing_;
  GPUTiming::TimerType timer_type_ = GPUTiming::kTimerTypeInvalid;
  uint32_t disjoint_counter_ = 0;
  int64_t offset_ = 0;  // offset cache when timer_type_ == kTimerTypeARB
  bool offset_valid_ = false;
  bool force_time_elapsed_query_ = false;
  int32_t timestamp_bit_count_gl_ = -1;  // gl implementation timestamp bits

  uint32_t next_timer_query_id_ = 0;
  uint32_t next_good_timer_query_id_ = 0; // identify bad ids for disjoints.
  uint32_t query_disjoint_count_ = 0;

  // Extra state tracking data for elapsed timer queries.
  int64_t max_time_stamp_ = 0;
  uint32_t elapsed_query_count_ = 0;
  scoped_refptr<TimeElapsedTimerQuery> last_elapsed_query_;

  base::circular_deque<scoped_refptr<TimerQuery>> queries_;

  DISALLOW_COPY_AND_ASSIGN(GPUTimingImpl);
};

class QueryResult : public base::RefCounted<QueryResult> {
 public:
  QueryResult() {}

  bool IsAvailable() const { return available_; }
  int64_t GetDelta() const { return end_value_ - start_value_; }
  int64_t GetStartValue() const { return start_value_; }
  int64_t GetEndValue() const { return end_value_; }

  void SetStartValue(int64_t value) { start_value_ = value; }
  void SetEndValue(int64_t value) { available_ = true; end_value_ = value; }

 private:
  friend class base::RefCounted<QueryResult>;
  ~QueryResult() {}

  bool available_ = false;
  int64_t start_value_ = 0;
  int64_t end_value_ = 0;

  DISALLOW_COPY_AND_ASSIGN(QueryResult);
};

class TimerQuery : public base::RefCounted<TimerQuery> {
 public:
  TimerQuery(uint32_t next_id);
  virtual void Destroy() = 0;

  // Returns true when UpdateQueryResults() is ready to be called.
  virtual bool IsAvailable(GPUTimingImpl* gpu_timing) = 0;

  // Fills out query result start and end, called after IsAvailable() is true.
  virtual void UpdateQueryResults(GPUTimingImpl* gpu_timing) = 0;

  // Called when Query is next in line, used to transition states.
  virtual void PrepareNextUpdate(scoped_refptr<TimerQuery> prev) {}

  uint32_t timer_query_id_ = 0;
  int64_t time_stamp_ = 0; // Timestamp of the query, could be estimated.

 protected:
  friend class base::RefCounted<TimerQuery>;
  virtual ~TimerQuery();
  DISALLOW_COPY_AND_ASSIGN(TimerQuery);
};

TimerQuery::TimerQuery(uint32_t next_id)
    : timer_query_id_(next_id) {
}

TimerQuery::~TimerQuery() {
}

class TimeElapsedTimerQuery : public TimerQuery {
 public:
  TimeElapsedTimerQuery(GPUTimingImpl* gpu_timing, uint32_t next_id)
      : TimerQuery(next_id) {
    glGenQueries(1, &gl_query_id_);
  }

  void Destroy() override {
    glDeleteQueries(1, &gl_query_id_);
  }

  scoped_refptr<QueryResult> StartQuery(GPUTimingImpl* gpu_timing) {
    DCHECK(query_result_start_.get() == nullptr);
    query_begin_cpu_time_ = gpu_timing->GetCurrentCPUTime();
    if (gpu_timing->GetElapsedQueryCount() == 0) {
      first_top_level_query_ = true;
    } else {
      // Stop the current timer query.
      glEndQuery(GL_TIME_ELAPSED);
    }

    // begin a new one time elapsed query.
    glBeginQuery(GL_TIME_ELAPSED, gl_query_id_);
    query_result_start_ = new QueryResult();

    // Update GPUTiming state.
    gpu_timing->SetLastElapsedQuery(this);
    gpu_timing->IncElapsedQueryCount();

    return query_result_start_;
  }

  void EndQuery(GPUTimingImpl* gpu_timing,
                scoped_refptr<QueryResult> result) {
    DCHECK(gpu_timing->GetElapsedQueryCount() != 0);

    scoped_refptr<TimeElapsedTimerQuery> last_query =
        gpu_timing->GetLastElapsedQuery();
    DCHECK(last_query.get());
    DCHECK(last_query->query_result_end_.get() == nullptr);

    last_query->query_result_end_ = result;
    gpu_timing->DecElapsedQueryCount();

    if (gpu_timing->GetElapsedQueryCount() != 0) {
      // Continue timer if there are still ongoing queries.
      glEndQuery(GL_TIME_ELAPSED);
      glBeginQuery(GL_TIME_ELAPSED, gl_query_id_);
      gpu_timing->SetLastElapsedQuery(this);
    } else {
      // Simply end the query and reset the current offset
      glEndQuery(GL_TIME_ELAPSED);
      gpu_timing->SetLastElapsedQuery(nullptr);
    }
  }

  // Returns true when UpdateQueryResults() is ready to be called.
  bool IsAvailable(GPUTimingImpl* gpu_timing) override {
    if (gpu_timing->GetElapsedQueryCount() != 0 &&
        gpu_timing->GetLastElapsedQuery() == this) {
      // Cannot query if result is available if EndQuery has not been called.
      // Since only one query is going on at a time, the end query is only not
      // called for the very last query when ongoing query counter is not 0.
      return false;
    }

    GLuint done = 0;
    glGetQueryObjectuiv(gl_query_id_, GL_QUERY_RESULT_AVAILABLE, &done);
    return !!done;
  }

  // Fills out query result start and end, called after IsAvailable() is true.
  void UpdateQueryResults(GPUTimingImpl* gpu_timing) override {
    GLuint64 result_value = 0;
    glGetQueryObjectui64v(gl_query_id_, GL_QUERY_RESULT, &result_value);
    const int64_t micro_results = NanoToMicro(result_value);

    // Adjust prev query end time if it is before the current max.
    const int64_t start_time =
        std::max(first_top_level_query_ ? query_begin_cpu_time_ : 0,
                 std::max(prev_query_end_time_,
                          gpu_timing->GetMaxTimeStamp()));

    // As a sanity check, is result value is greater than the time allotted we
    // can safely say this is garbage data
    const int64_t max_possible_time =
        gpu_timing->GetCurrentCPUTime() - query_begin_cpu_time_;
    if (micro_results > max_possible_time) {
      gpu_timing->HandleBadQuery();
    }

    // Elapsed queries need to be adjusted so they are relative to one another.
    // Absolute timer queries are already relative to one another absolutely.
    time_stamp_ = start_time + micro_results;

    if (query_result_start_.get()) {
      query_result_start_->SetStartValue(start_time);
    }
    if (query_result_end_.get()) {
      query_result_end_->SetEndValue(time_stamp_);
    }
  }

  // Called when Query is next in line, used to transition states.
  void PrepareNextUpdate(scoped_refptr<TimerQuery> prev) override {
    prev_query_end_time_ = prev->time_stamp_;
  }

 private:
  ~TimeElapsedTimerQuery() override {}

  bool first_top_level_query_ = false;
  uint32_t gl_query_id_ = 0;
  int64_t prev_query_end_time_ = 0;
  int64_t query_begin_cpu_time_ = 0;
  scoped_refptr<QueryResult> query_result_start_;
  scoped_refptr<QueryResult> query_result_end_;
};

class TimeStampTimerQuery : public TimerQuery {
 public:
  TimeStampTimerQuery(uint32_t next_id)
      : TimerQuery(next_id) {
    glGenQueries(1, &gl_query_id_);
  }

  void Destroy() override {
    glDeleteQueries(1, &gl_query_id_);
  }

  scoped_refptr<QueryResult> DoQuery() {
    glQueryCounter(gl_query_id_, GL_TIMESTAMP);
    query_result_ = new QueryResult();
    return query_result_;
  }

  // Returns true when UpdateQueryResults() is ready to be called.
  bool IsAvailable(GPUTimingImpl* gpu_timing) override {
    GLuint done = 0;
    glGetQueryObjectuiv(gl_query_id_, GL_QUERY_RESULT_AVAILABLE, &done);
    return !!done;
  }

  // Fills out query result start and end, called after IsAvailable() is true.
  void UpdateQueryResults(GPUTimingImpl* gpu_timing) override {
    DCHECK(IsAvailable(gpu_timing));

    GLuint64 result_value = 0;
    glGetQueryObjectui64v(gl_query_id_, GL_QUERY_RESULT, &result_value);
    const int64_t micro_results = NanoToMicro(result_value);

    const int64_t offset = gpu_timing->CalculateTimerOffset();
    const int64_t adjusted_result = micro_results + offset;
    DCHECK(query_result_.get());
    query_result_->SetStartValue(adjusted_result);
    query_result_->SetEndValue(adjusted_result);
    time_stamp_ = adjusted_result;
  }

 private:
  ~TimeStampTimerQuery() override {}
  uint32_t gl_query_id_ = 0;
  scoped_refptr<QueryResult> query_result_;
};

GPUTimingImpl::GPUTimingImpl(GLContextReal* context) {
  DCHECK(context);
  const GLVersionInfo* version_info = context->GetVersionInfo();
  DCHECK(version_info);
  if (context->HasExtension("GL_EXT_disjoint_timer_query")) {
    timer_type_ = GPUTiming::kTimerTypeDisjoint;
  } else if (context->HasExtension("GL_ARB_timer_query")) {
    timer_type_ = GPUTiming::kTimerTypeARB;
  } else if (context->HasExtension("GL_EXT_timer_query")) {
    timer_type_ = GPUTiming::kTimerTypeEXT;
    force_time_elapsed_query_ = true;
    timestamp_bit_count_gl_ = 0;
  }
  // The command glGetInteger64v is only supported under ES3 and GL3.2. Since it
  // is only used for timestamps, we workaround this by emulating timestamps
  // so WebGL 1.0 will still have access to the extension.
  if (!version_info->IsAtLeastGLES(3, 0) && !version_info->IsAtLeastGL(3, 2)) {
    force_time_elapsed_query_ = true;
    timestamp_bit_count_gl_ = 0;
  }
}

GPUTimingImpl::~GPUTimingImpl() {
}

uint32_t GPUTimingImpl::GetDisjointCount() {
  if (timer_type_ == GPUTiming::kTimerTypeDisjoint) {
    GLint disjoint_value = 0;
    glGetIntegerv(GL_GPU_DISJOINT_EXT, &disjoint_value);
    if (disjoint_value) {
      offset_valid_ = false;
      disjoint_counter_++;
    }
  }
  return disjoint_counter_;
}

int64_t GPUTimingImpl::CalculateTimerOffset() {
  if (!offset_valid_) {
    if (timer_type_ == GPUTiming::kTimerTypeDisjoint ||
        timer_type_ == GPUTiming::kTimerTypeARB) {
      GLint64 gl_now = 0;
      glGetInteger64v(GL_TIMESTAMP, &gl_now);
      const int64_t cpu_time = GetCurrentCPUTime();
      const int64_t micro_offset = cpu_time - NanoToMicro(gl_now);

      // We cannot expect these instructions to run with the accuracy
      // within 1 microsecond, instead discard differences which are less
      // than a single millisecond.
      base::TimeDelta delta =
          base::TimeDelta::FromMicroseconds(micro_offset - offset_);

      if (delta.magnitude().InMilliseconds() >= 1) {
        offset_ = micro_offset;
        offset_valid_ = (timer_type_ == GPUTiming::kTimerTypeARB);
      }
    } else {
      offset_ = 0;
      offset_valid_ = true;
    }
  }
  return offset_;
}

scoped_refptr<QueryResult> GPUTimingImpl::BeginElapsedTimeQuery() {
  DCHECK(timer_type_ != GPUTiming::kTimerTypeInvalid);

  queries_.push_back(new TimeElapsedTimerQuery(this, next_timer_query_id_++));
  return static_cast<TimeElapsedTimerQuery*>(
      queries_.back().get())->StartQuery(this);
}

void GPUTimingImpl::EndElapsedTimeQuery(scoped_refptr<QueryResult> result) {
  DCHECK(timer_type_ != GPUTiming::kTimerTypeInvalid);
  DCHECK(result.get());

  if (GetElapsedQueryCount() > 1) {
    // Create new elapsed timer query if there are still ongoing queries.
    queries_.push_back(new TimeElapsedTimerQuery(this,
                                                 next_timer_query_id_++));
    static_cast<TimeElapsedTimerQuery*>(
        queries_.back().get())->EndQuery(this, result);
  } else {
    // Simply end the query and reset the current offset
    DCHECK(GetLastElapsedQuery().get());
    GetLastElapsedQuery()->EndQuery(this, result);
    DCHECK(GetLastElapsedQuery().get() == nullptr);
  }
}

scoped_refptr<QueryResult> GPUTimingImpl::DoTimeStampQuery() {
  DCHECK(timer_type_ != GPUTiming::kTimerTypeInvalid);

  // Certain GL drivers have timestamp bit count set to 0 which means timestamps
  // aren't supported. Emulate them with time elapsed queries if that is the
  // case.
  if (timestamp_bit_count_gl_ == -1) {
    DCHECK(timer_type_ != GPUTiming::kTimerTypeEXT);
    timestamp_bit_count_gl_ = QueryTimestampBits();
    force_time_elapsed_query_ |= (timestamp_bit_count_gl_ == 0);
  }

  if (force_time_elapsed_query_) {
    // Replace with elapsed timer queries instead.
    scoped_refptr<QueryResult> result = BeginElapsedTimeQuery();
    EndElapsedTimeQuery(result);
    return result;
  }

  queries_.push_back(new TimeStampTimerQuery(next_timer_query_id_++));
  return static_cast<TimeStampTimerQuery*>(queries_.back().get())->DoQuery();
}

void GPUTimingImpl::UpdateQueryResults() {
  // Query availability of and count the queries that are available.
  int available_queries = 0;
  for (const scoped_refptr<TimerQuery>& query : queries_) {
    if (!query->IsAvailable(this))
      break;
    available_queries++;
  }

  // Check for disjoints, this must be done after we checked for availability.
  const uint32_t disjoint_counter = GetDisjointCount();
  if (disjoint_counter != query_disjoint_count_) {
    next_good_timer_query_id_ = next_timer_query_id_;
    query_disjoint_count_ = disjoint_counter;
  }

  // Fill in the query result data once we know the disjoint value is updated.
  // Note that even if disjoint happened and the values may or may not be
  // garbage, we still fill it in and let GPUTimingClient's detect and disgard
  // bad query data. The only thing we need to account for here is to not
  // use garbade timer data to fill states such as max query times.
  for (int i = 0; i < available_queries; ++i) {
    scoped_refptr<TimerQuery> query = queries_.front();

    query->UpdateQueryResults(this);
    DCHECK(query->time_stamp_) << "Query Timestamp was not updated.";

    // For good queries, keep track of the max valid time stamps.
    if (IsGoodQueryID(query->timer_query_id_))
      UpdateMaxTimeStamp(query->time_stamp_);

    query->Destroy();
    queries_.pop_front();

    if (!queries_.empty())
      queries_.front()->PrepareNextUpdate(query);
  }
}

void GPUTimingImpl::SetLastElapsedQuery(
    scoped_refptr<TimeElapsedTimerQuery> query) {
  last_elapsed_query_ = query;
}

scoped_refptr<TimeElapsedTimerQuery> GPUTimingImpl::GetLastElapsedQuery() {
  return last_elapsed_query_;
}

void GPUTimingImpl::HandleBadQuery() {
  // Mark all queries as bad and signal an artificial disjoint value.
  next_good_timer_query_id_ = next_timer_query_id_;
  offset_valid_ = false;
  query_disjoint_count_ = ++disjoint_counter_;
}

bool GPUTimingImpl::IsGoodQueryID(uint32_t query_id) {
  return query_id >= next_good_timer_query_id_;
}

scoped_refptr<GPUTimingClient> GPUTimingImpl::CreateGPUTimingClient() {
  return new GPUTimingClient(this);
}

GPUTiming* GPUTiming::CreateGPUTiming(GLContextReal* context) {
  return new GPUTimingImpl(context);
}

GPUTiming::GPUTiming() {
}

GPUTiming::~GPUTiming() {
}

GPUTimer::~GPUTimer() {
}

void GPUTimer::Destroy(bool have_context) {
  if (have_context) {
    if (timer_state_ == kTimerState_WaitingForEnd) {
      DCHECK(gpu_timing_client_->gpu_timing_);
      DCHECK(elapsed_timer_result_.get());
      gpu_timing_client_->gpu_timing_->EndElapsedTimeQuery(
          elapsed_timer_result_);
    }
  }
}

void GPUTimer::Reset() {
  // We can reset from any state other than when a Start() is waiting for End().
  DCHECK(timer_state_ != kTimerState_WaitingForEnd);
  time_stamp_result_ = nullptr;
  elapsed_timer_result_ = nullptr;
  timer_state_ = kTimerState_Ready;
}

void GPUTimer::QueryTimeStamp() {
  DCHECK(gpu_timing_client_->gpu_timing_);
  Reset();
  time_stamp_result_ = gpu_timing_client_->gpu_timing_->DoTimeStampQuery();
  timer_state_ = kTimerState_WaitingForResult;
}

void GPUTimer::Start() {
  DCHECK(gpu_timing_client_->gpu_timing_);
  Reset();
  if (!use_elapsed_timer_)
    time_stamp_result_ = gpu_timing_client_->gpu_timing_->DoTimeStampQuery();

  elapsed_timer_result_ =
      gpu_timing_client_->gpu_timing_->BeginElapsedTimeQuery();
  timer_state_ = kTimerState_WaitingForEnd;
}

void GPUTimer::End() {
  DCHECK(timer_state_ == kTimerState_WaitingForEnd);
  DCHECK(elapsed_timer_result_.get());
  gpu_timing_client_->gpu_timing_->EndElapsedTimeQuery(elapsed_timer_result_);
  timer_state_ = kTimerState_WaitingForResult;
}

bool GPUTimer::IsAvailable() {
  if (timer_state_ == kTimerState_WaitingForResult) {
    // Elapsed timer are only used during start/end queries and always after
    // the timestamp query. Otherwise only the timestamp is used.
    scoped_refptr<QueryResult> result =
        elapsed_timer_result_.get() ?
        elapsed_timer_result_ :
        time_stamp_result_;

    DCHECK(result.get());
    if (result->IsAvailable()) {
      timer_state_ = kTimerState_ResultAvailable;
    } else {
      gpu_timing_client_->gpu_timing_->UpdateQueryResults();
      if (result->IsAvailable())
        timer_state_ = kTimerState_ResultAvailable;
    }
  }

  return (timer_state_ == kTimerState_ResultAvailable);
}

void GPUTimer::GetStartEndTimestamps(int64_t* start, int64_t* end) {
  DCHECK(start && end);
  DCHECK(elapsed_timer_result_.get() || time_stamp_result_.get());
  DCHECK(IsAvailable());
  const int64_t time_stamp = time_stamp_result_.get() ?
                             time_stamp_result_->GetStartValue() :
                             elapsed_timer_result_->GetStartValue();
  const int64_t elapsed_time = elapsed_timer_result_.get() ?
                               elapsed_timer_result_->GetDelta() :
                               0;

  *start = time_stamp;
  *end = time_stamp + elapsed_time;
}

int64_t GPUTimer::GetDeltaElapsed() {
  DCHECK(IsAvailable());
  if (elapsed_timer_result_.get())
    return elapsed_timer_result_->GetDelta();
  return 0;
}

GPUTimer::GPUTimer(scoped_refptr<GPUTimingClient> gpu_timing_client,
                   bool use_elapsed_timer)
    : use_elapsed_timer_(use_elapsed_timer),
      gpu_timing_client_(gpu_timing_client) {
}

GPUTimingClient::GPUTimingClient(GPUTimingImpl* gpu_timing)
    : gpu_timing_(gpu_timing) {
  if (gpu_timing) {
    timer_type_ = gpu_timing->GetTimerType();
    disjoint_counter_ = gpu_timing_->GetDisjointCount();
  }
}

std::unique_ptr<GPUTimer> GPUTimingClient::CreateGPUTimer(
    bool prefer_elapsed_time) {
  prefer_elapsed_time |= (timer_type_ == GPUTiming::kTimerTypeEXT);
  if (gpu_timing_)
    prefer_elapsed_time |= gpu_timing_->IsForceTimeElapsedQuery();

  return base::WrapUnique(new GPUTimer(this, prefer_elapsed_time));
}

bool GPUTimingClient::IsAvailable() {
  return timer_type_ != GPUTiming::kTimerTypeInvalid;
}

const char* GPUTimingClient::GetTimerTypeName() const {
  switch (timer_type_) {
    case GPUTiming::kTimerTypeDisjoint:
      return "GL_EXT_disjoint_timer_query";
    case GPUTiming::kTimerTypeARB:
      return "GL_ARB_timer_query";
    case GPUTiming::kTimerTypeEXT:
      return "GL_EXT_timer_query";
    default:
      return "Unknown";
  }
}

bool GPUTimingClient::CheckAndResetTimerErrors() {
  if (timer_type_ == GPUTiming::kTimerTypeDisjoint) {
    DCHECK(gpu_timing_ != nullptr);
    const uint32_t total_disjoint_count = gpu_timing_->GetDisjointCount();
    const bool disjoint_triggered = total_disjoint_count != disjoint_counter_;
    disjoint_counter_ = total_disjoint_count;
    return disjoint_triggered;
  }
  return false;
}

int64_t GPUTimingClient::GetCurrentCPUTime() {
  DCHECK(gpu_timing_);
  return gpu_timing_->GetCurrentCPUTime();
}

void GPUTimingClient::SetCpuTimeForTesting(
    const base::Callback<int64_t(void)>& cpu_time) {
  DCHECK(gpu_timing_);
  gpu_timing_->SetCpuTimeForTesting(cpu_time);
}

bool GPUTimingClient::IsForceTimeElapsedQuery() {
  DCHECK(gpu_timing_);
  return gpu_timing_->IsForceTimeElapsedQuery();
}

void GPUTimingClient::ForceTimeElapsedQuery() {
  DCHECK(gpu_timing_);
  gpu_timing_->ForceTimeElapsedQuery();
}

GPUTimingClient::~GPUTimingClient() {
}

}  // namespace gl
