// 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/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_;

  std::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
