summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordyen <dyen@chromium.org>2015-02-25 17:54:00 -0800
committerCommit bot <commit-bot@chromium.org>2015-02-26 01:55:12 +0000
commit5b1c02ff50ebb8af95b50b4ea1658eef2bb89546 (patch)
tree506eb5b7e32d346b1587f56a9e22d6081ea8837c
parent362ae2101b8a3710e1a07066746ed98bc577b52d (diff)
downloadchromium_src-5b1c02ff50ebb8af95b50b4ea1658eef2bb89546.zip
chromium_src-5b1c02ff50ebb8af95b50b4ea1658eef2bb89546.tar.gz
chromium_src-5b1c02ff50ebb8af95b50b4ea1658eef2bb89546.tar.bz2
Refactored GLContext to own GPUTiming which spawn GPUTimingClients.
GPUTiming is our abstraction layer for various GL timing extensions. It makes more sense for this abstraction layer to be owned by GLContext instead. Clients that want to do GPU Timing calls (GPUTracer, eventual support of WebGL tracer calls). One of the main reasons for this differentiation is to support disjoint queries across multiple virtual contexts. The actual support of this will be completed in another CL. BUG=451211 TEST=trybots Review URL: https://codereview.chromium.org/937263006 Cr-Commit-Position: refs/heads/master@{#318174}
-rw-r--r--gpu/command_buffer/service/BUILD.gn2
-rw-r--r--gpu/command_buffer/service/gl_context_virtual.cc5
-rw-r--r--gpu/command_buffer/service/gl_context_virtual.h1
-rw-r--r--gpu/command_buffer/service/gles2_cmd_decoder.cc4
-rw-r--r--gpu/command_buffer/service/gpu_timing.h87
-rw-r--r--gpu/command_buffer/service/gpu_tracer.cc36
-rw-r--r--gpu/command_buffer/service/gpu_tracer.h12
-rw-r--r--gpu/command_buffer/service/gpu_tracer_unittest.cc66
-rw-r--r--gpu/command_buffer_service.gypi2
-rw-r--r--gpu/perftests/measurements.cc10
-rw-r--r--gpu/perftests/measurements.h12
-rw-r--r--gpu/perftests/texture_upload_perftest.cc23
-rw-r--r--ui/gl/BUILD.gn2
-rw-r--r--ui/gl/gl.gyp2
-rw-r--r--ui/gl/gl_context.cc8
-rw-r--r--ui/gl/gl_context.h8
-rw-r--r--ui/gl/gpu_timing.cc (renamed from gpu/command_buffer/service/gpu_timing.cc)90
-rw-r--r--ui/gl/gpu_timing.h136
18 files changed, 298 insertions, 208 deletions
diff --git a/gpu/command_buffer/service/BUILD.gn b/gpu/command_buffer/service/BUILD.gn
index 219a4c6d..ee92509 100644
--- a/gpu/command_buffer/service/BUILD.gn
+++ b/gpu/command_buffer/service/BUILD.gn
@@ -67,8 +67,6 @@ source_set("service") {
"gpu_state_tracer.h",
"gpu_switches.cc",
"gpu_switches.h",
- "gpu_timing.cc",
- "gpu_timing.h",
"gpu_tracer.cc",
"gpu_tracer.h",
"id_manager.cc",
diff --git a/gpu/command_buffer/service/gl_context_virtual.cc b/gpu/command_buffer/service/gl_context_virtual.cc
index 765dbee..7747407 100644
--- a/gpu/command_buffer/service/gl_context_virtual.cc
+++ b/gpu/command_buffer/service/gl_context_virtual.cc
@@ -7,6 +7,7 @@
#include "gpu/command_buffer/service/gl_state_restorer_impl.h"
#include "gpu/command_buffer/service/gles2_cmd_decoder.h"
#include "ui/gl/gl_surface.h"
+#include "ui/gl/gpu_timing.h"
namespace gpu {
@@ -82,6 +83,10 @@ void* GLContextVirtual::GetHandle() {
return shared_context_->GetHandle();
}
+scoped_refptr<gfx::GPUTimingClient> GLContextVirtual::CreateGPUTimingClient() {
+ return shared_context_->CreateGPUTimingClient();
+}
+
void GLContextVirtual::OnSetSwapInterval(int interval) {
shared_context_->SetSwapInterval(interval);
}
diff --git a/gpu/command_buffer/service/gl_context_virtual.h b/gpu/command_buffer/service/gl_context_virtual.h
index 7a79928..42c6d42 100644
--- a/gpu/command_buffer/service/gl_context_virtual.h
+++ b/gpu/command_buffer/service/gl_context_virtual.h
@@ -41,6 +41,7 @@ class GPU_EXPORT GLContextVirtual : public gfx::GLContext {
void ReleaseCurrent(gfx::GLSurface* surface) override;
bool IsCurrent(gfx::GLSurface* surface) override;
void* GetHandle() override;
+ scoped_refptr<gfx::GPUTimingClient> CreateGPUTimingClient() override;
void OnSetSwapInterval(int interval) override;
std::string GetExtensions() override;
bool GetTotalGpuMemory(size_t* bytes) override;
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc
index 8f4a624..8c24d3c 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc
@@ -2444,7 +2444,6 @@ bool GLES2DecoderImpl::Initialize(
surfaceless_ = surface->IsSurfaceless() && !offscreen;
set_initialized();
- gpu_tracer_.reset(new GPUTracer(this));
gpu_state_tracer_ = GPUStateTracer::Create(&state_);
if (base::CommandLine::ForCurrentProcess()->HasSwitch(
@@ -2475,6 +2474,9 @@ bool GLES2DecoderImpl::Initialize(
if (!attrib_parser.Parse(attribs))
return false;
+ // Create GPU Tracer for timing values.
+ gpu_tracer_.reset(new GPUTracer(this));
+
// Save the loseContextWhenOutOfMemory context creation attribute.
lose_context_when_out_of_memory_ =
attrib_parser.lose_context_when_out_of_memory;
diff --git a/gpu/command_buffer/service/gpu_timing.h b/gpu/command_buffer/service/gpu_timing.h
deleted file mode 100644
index 726ac4e..0000000
--- a/gpu/command_buffer/service/gpu_timing.h
+++ /dev/null
@@ -1,87 +0,0 @@
-// 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.
-
-#ifndef GPU_COMMAND_BUFFER_SERVICE_GPU_TIMING_H_
-#define GPU_COMMAND_BUFFER_SERVICE_GPU_TIMING_H_
-
-#include "base/callback.h"
-#include "base/memory/scoped_ptr.h"
-#include "gpu/gpu_export.h"
-
-namespace gfx {
-class GLContext;
-}
-
-namespace gpu {
-class GPUTiming;
-
-// Class to compute the amount of time it takes to fully
-// complete a set of GL commands
-class GPU_EXPORT GPUTimer {
- public:
- // gpu_timing must outlive GPUTimer instance we're creating.
- explicit GPUTimer(GPUTiming* gpu_timing);
- ~GPUTimer();
-
- void Start();
- void End();
- bool IsAvailable();
-
- void GetStartEndTimestamps(int64* start, int64* end);
- int64 GetDeltaElapsed();
-
- private:
- unsigned int queries_[2];
- int64 offset_ = 0;
- bool end_requested_ = false;
- GPUTiming* gpu_timing_;
-
- DISALLOW_COPY_AND_ASSIGN(GPUTimer);
-};
-
-// GPUTiming contains all the gl timing logic that is not specific
-// to a single GPUTimer.
-class GPU_EXPORT GPUTiming {
- public:
- enum TimerType {
- kTimerTypeInvalid = -1,
-
- kTimerTypeARB, // ARB_timer_query
- kTimerTypeDisjoint // EXT_disjoint_timer_query
- };
-
- GPUTiming();
- virtual ~GPUTiming();
-
- bool Initialize(gfx::GLContext* context);
- bool IsAvailable();
-
- // CheckAndResetTimerErrors has to be called before reading timestamps
- // from GPUTimers instances and after making sure all the timers
- // were available.
- // If the returned value is false, all the previous timers should be
- // discarded.
- bool CheckAndResetTimerErrors();
-
- const char* GetTimerTypeName() const;
-
- // Returns the offset between the current gpu time and the cpu time.
- int64 CalculateTimerOffset();
- void InvalidateTimerOffset();
-
- void SetCpuTimeForTesting(const base::Callback<int64(void)>& cpu_time);
- void SetOffsetForTesting(int64 offset, bool cache_it);
- void SetTimerTypeForTesting(TimerType type);
-
- private:
- TimerType timer_type_ = kTimerTypeInvalid;
- int64 offset_ = 0; // offset cache when timer_type_ == kTimerTypeARB
- bool offset_valid_ = false;
- base::Callback<int64(void)> cpu_time_for_testing_;
- friend class GPUTimer;
- DISALLOW_COPY_AND_ASSIGN(GPUTiming);
-};
-} // namespace gpu
-
-#endif // GPU_COMMAND_BUFFER_SERVICE_GPU_TIMING_H_
diff --git a/gpu/command_buffer/service/gpu_tracer.cc b/gpu/command_buffer/service/gpu_tracer.cc
index cc484dc..2fbf46c 100644
--- a/gpu/command_buffer/service/gpu_tracer.cc
+++ b/gpu/command_buffer/service/gpu_tracer.cc
@@ -14,6 +14,7 @@
#include "gpu/command_buffer/service/context_group.h"
#include "ui/gl/gl_bindings.h"
#include "ui/gl/gl_version_info.h"
+#include "ui/gl/gpu_timing.h"
namespace gpu {
namespace gles2 {
@@ -81,7 +82,7 @@ void TraceOutputter::TraceServiceEnd(const std::string& category,
}
GPUTrace::GPUTrace(scoped_refptr<Outputter> outputter,
- gpu::GPUTiming* gpu_timing,
+ gfx::GPUTimingClient* gpu_timing_client,
const std::string& category,
const std::string& name,
const bool enabled)
@@ -89,8 +90,8 @@ GPUTrace::GPUTrace(scoped_refptr<Outputter> outputter,
name_(name),
outputter_(outputter),
enabled_(enabled) {
- if (gpu_timing->IsAvailable()) {
- gpu_timer_.reset(new GPUTimer(gpu_timing));
+ if (gpu_timing_client->IsAvailable()) {
+ gpu_timer_ = gpu_timing_client->CreateGPUTimer();
}
}
@@ -136,9 +137,15 @@ GPUTracer::GPUTracer(gles2::GLES2Decoder* decoder)
gpu_trace_dev_category(TRACE_EVENT_API_GET_CATEGORY_GROUP_ENABLED(
TRACE_DISABLED_BY_DEFAULT("gpu.device"))),
decoder_(decoder),
- gpu_timing_(),
gpu_executing_(false),
process_posted_(false) {
+ DCHECK(decoder_);
+ gfx::GLContext* context = decoder_->GetGLContext();
+ if (context) {
+ gpu_timing_client_ = context->CreateGPUTimingClient();
+ } else {
+ gpu_timing_client_ = new gfx::GPUTimingClient();
+ }
}
GPUTracer::~GPUTracer() {
@@ -148,26 +155,26 @@ bool GPUTracer::BeginDecoding() {
if (gpu_executing_)
return false;
- if (outputter_ == NULL) {
- outputter_ = CreateOutputter(gpu_timing_.GetTimerTypeName());
- gpu_timing_.Initialize(decoder_->GetGLContext());
+ if (!outputter_) {
+ outputter_ = CreateOutputter(gpu_timing_client_->GetTimerTypeName());
}
if (*gpu_trace_dev_category == '\0') {
// If GPU device category is off, invalidate timing sync.
- gpu_timing_.InvalidateTimerOffset();
+ gpu_timing_client_->InvalidateTimerOffset();
}
gpu_executing_ = true;
if (IsTracing()) {
- gpu_timing_.CheckAndResetTimerErrors();
+ gpu_timing_client_->CheckAndResetTimerErrors();
// Begin a Trace for all active markers
for (int n = 0; n < NUM_TRACER_SOURCES; n++) {
for (size_t i = 0; i < markers_[n].size(); i++) {
TraceMarker& trace_marker = markers_[n][i];
trace_marker.trace_ =
- new GPUTrace(outputter_, &gpu_timing_, trace_marker.category_,
- trace_marker.name_, *gpu_trace_dev_category != 0);
+ new GPUTrace(outputter_, gpu_timing_client_.get(),
+ trace_marker.category_, trace_marker.name_,
+ *gpu_trace_dev_category != 0);
trace_marker.trace_->Start(*gpu_trace_srv_category != 0);
}
}
@@ -216,7 +223,8 @@ bool GPUTracer::Begin(const std::string& category, const std::string& name,
// Create trace
if (IsTracing()) {
scoped_refptr<GPUTrace> trace = new GPUTrace(
- outputter_, &gpu_timing_, category, name, *gpu_trace_dev_category != 0);
+ outputter_, gpu_timing_client_.get(), category, name,
+ *gpu_trace_dev_category != 0);
trace->Start(*gpu_trace_srv_category != 0);
markers_[source].back().trace_ = trace;
}
@@ -288,7 +296,7 @@ void GPUTracer::Process() {
}
void GPUTracer::ProcessTraces() {
- if (!gpu_timing_.IsAvailable()) {
+ if (!gpu_timing_client_->IsAvailable()) {
traces_.clear();
return;
}
@@ -304,7 +312,7 @@ void GPUTracer::ProcessTraces() {
// Check if timers are still valid (e.g: a disjoint operation
// might have occurred.)
- if (gpu_timing_.CheckAndResetTimerErrors())
+ if (gpu_timing_client_->CheckAndResetTimerErrors())
traces_.clear();
while (!traces_.empty() && traces_.front()->IsAvailable()) {
diff --git a/gpu/command_buffer/service/gpu_tracer.h b/gpu/command_buffer/service/gpu_tracer.h
index 7aba612..1b2c315 100644
--- a/gpu/command_buffer/service/gpu_tracer.h
+++ b/gpu/command_buffer/service/gpu_tracer.h
@@ -15,9 +15,13 @@
#include "base/memory/weak_ptr.h"
#include "base/threading/thread.h"
#include "gpu/command_buffer/service/gles2_cmd_decoder.h"
-#include "gpu/command_buffer/service/gpu_timing.h"
#include "gpu/gpu_export.h"
+namespace gfx {
+ class GPUTimingClient;
+ class GPUTimer;
+}
+
namespace gpu {
namespace gles2 {
@@ -82,6 +86,7 @@ class GPU_EXPORT GPUTracer
void IssueProcessTask();
+ scoped_refptr<gfx::GPUTimingClient> gpu_timing_client_;
scoped_refptr<Outputter> outputter_;
std::vector<TraceMarker> markers_[NUM_TRACER_SOURCES];
std::deque<scoped_refptr<GPUTrace> > traces_;
@@ -89,7 +94,6 @@ class GPU_EXPORT GPUTracer
const unsigned char* gpu_trace_srv_category;
const unsigned char* gpu_trace_dev_category;
gles2::GLES2Decoder* decoder_;
- gpu::GPUTiming gpu_timing_;
bool gpu_executing_;
bool process_posted_;
@@ -146,7 +150,7 @@ class GPU_EXPORT GPUTrace
: public base::RefCounted<GPUTrace> {
public:
GPUTrace(scoped_refptr<Outputter> outputter,
- gpu::GPUTiming* gpu_timing,
+ gfx::GPUTimingClient* gpu_timing_client,
const std::string& category,
const std::string& name,
const bool enabled);
@@ -167,7 +171,7 @@ class GPU_EXPORT GPUTrace
std::string category_;
std::string name_;
scoped_refptr<Outputter> outputter_;
- scoped_ptr<gpu::GPUTimer> gpu_timer_;
+ scoped_ptr<gfx::GPUTimer> gpu_timer_;
const bool enabled_ = false;
DISALLOW_COPY_AND_ASSIGN(GPUTrace);
diff --git a/gpu/command_buffer/service/gpu_tracer_unittest.cc b/gpu/command_buffer/service/gpu_tracer_unittest.cc
index ba61ba3..6566f6a 100644
--- a/gpu/command_buffer/service/gpu_tracer_unittest.cc
+++ b/gpu/command_buffer/service/gpu_tracer_unittest.cc
@@ -8,10 +8,10 @@
#include "base/bind.h"
#include "gpu/command_buffer/service/gles2_cmd_decoder_mock.h"
#include "gpu/command_buffer/service/gpu_service_test.h"
-#include "gpu/command_buffer/service/gpu_timing.h"
#include "gpu/command_buffer/service/gpu_tracer.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/gl/gl_mock.h"
+#include "ui/gl/gpu_timing.h"
namespace gpu {
namespace gles2 {
@@ -152,7 +152,7 @@ class GPUTracerTester : public GPUTracer {
public:
explicit GPUTracerTester(gles2::GLES2Decoder* decoder)
: GPUTracer(decoder), tracing_enabled_(0) {
- gpu_timing_.SetCpuTimeForTesting(base::Bind(&FakeCpuTime));
+ gpu_timing_client_->SetCpuTimeForTesting(base::Bind(&FakeCpuTime));
// Force tracing to be dependent on our mock variable here.
gpu_trace_srv_category = &tracing_enabled_;
@@ -189,10 +189,8 @@ class GPUTracerTester : public GPUTracer {
class BaseGpuTest : public GpuServiceTest {
public:
- explicit BaseGpuTest(GPUTiming::TimerType test_timer_type)
+ explicit BaseGpuTest(gfx::GPUTiming::TimerType test_timer_type)
: test_timer_type_(test_timer_type) {
- gpu_timing_.SetCpuTimeForTesting(base::Bind(&FakeCpuTime));
- gpu_timing_.SetTimerTypeForTesting(test_timer_type);
}
protected:
@@ -200,15 +198,17 @@ class BaseGpuTest : public GpuServiceTest {
g_fakeCPUTime = 0;
const char* gl_version = "3.2";
const char* extensions = "";
- if (GetTimerType() == GPUTiming::kTimerTypeDisjoint) {
+ if (GetTimerType() == gfx::GPUTiming::kTimerTypeDisjoint) {
gl_version = "opengl es 3.0";
extensions = "GL_EXT_disjoint_timer_query";
- } else if (GetTimerType() == GPUTiming::kTimerTypeARB) {
+ } else if (GetTimerType() == gfx::GPUTiming::kTimerTypeARB) {
// TODO(sievers): The tracer should not depend on ARB_occlusion_query.
// Try merge Query APIs (core, ARB, EXT) into a single binding each.
extensions = "GL_ARB_timer_query GL_ARB_occlusion_query";
}
GpuServiceTest::SetUpWithGLVersion(gl_version, extensions);
+ gpu_timing_client_ = GetGLContext()->CreateGPUTimingClient();
+ gpu_timing_client_->SetCpuTimeForTesting(base::Bind(&FakeCpuTime));
gl_fake_queries_.Reset();
outputter_ref_ = new MockOutputter();
@@ -222,22 +222,20 @@ class BaseGpuTest : public GpuServiceTest {
}
void ExpectTraceQueryMocks() {
- if (GetTimerType() != GPUTiming::kTimerTypeInvalid) {
+ if (GetTimerType() != gfx::GPUTiming::kTimerTypeInvalid) {
// Delegate query APIs used by GPUTrace to a GlFakeQueries
EXPECT_CALL(*gl_, GenQueriesARB(2, NotNull())).Times(AtLeast(1))
.WillRepeatedly(
Invoke(&gl_fake_queries_, &GlFakeQueries::GenQueriesARB));
EXPECT_CALL(*gl_, GetQueryObjectivARB(_, GL_QUERY_RESULT_AVAILABLE,
- NotNull()))
+ NotNull()))
.WillRepeatedly(
- Invoke(&gl_fake_queries_, &GlFakeQueries::GetQueryObjectivARB));
+ Invoke(&gl_fake_queries_, &GlFakeQueries::GetQueryObjectivARB));
- if (GetTimerType() == GPUTiming::kTimerTypeDisjoint) {
- EXPECT_CALL(*gl_, GetInteger64v(GL_TIMESTAMP, _))
+ EXPECT_CALL(*gl_, GetInteger64v(GL_TIMESTAMP, _))
.WillRepeatedly(
- Invoke(&gl_fake_queries_, &GlFakeQueries::GetInteger64v));
- }
+ Invoke(&gl_fake_queries_, &GlFakeQueries::GetInteger64v));
EXPECT_CALL(*gl_, QueryCounter(_, GL_TIMESTAMP)).Times(AtLeast(2))
.WillRepeatedly(
@@ -286,14 +284,14 @@ class BaseGpuTest : public GpuServiceTest {
const std::string& name, int64 expect_start_time,
int64 expect_end_time) {
ExpectOutputterBeginMocks(outputter, category, name);
+ bool valid_timer = GetTimerType() != gfx::GPUTiming::kTimerTypeInvalid;
ExpectOutputterEndMocks(outputter, category, name, expect_start_time,
- expect_end_time,
- GetTimerType() != GPUTiming::kTimerTypeInvalid);
+ expect_end_time, valid_timer);
}
void ExpectTracerOffsetQueryMocks() {
// Disjoint check should only be called by kTracerTypeDisjointTimer type.
- if (GetTimerType() == GPUTiming::kTimerTypeDisjoint) {
+ if (GetTimerType() == gfx::GPUTiming::kTimerTypeDisjoint) {
EXPECT_CALL(*gl_, GetIntegerv(GL_GPU_DISJOINT_EXT, _)).Times(AtLeast(1))
.WillRepeatedly(
Invoke(&gl_fake_queries_, &GlFakeQueries::GetIntegerv));
@@ -301,7 +299,7 @@ class BaseGpuTest : public GpuServiceTest {
EXPECT_CALL(*gl_, GetIntegerv(GL_GPU_DISJOINT_EXT, _)).Times(Exactly(0));
}
- if (GetTimerType() != GPUTiming::kTimerTypeARB) {
+ if (GetTimerType() != gfx::GPUTiming::kTimerTypeARB) {
EXPECT_CALL(*gl_, GetInteger64v(GL_TIMESTAMP, NotNull()))
.Times(Exactly(0));
} else {
@@ -312,19 +310,19 @@ class BaseGpuTest : public GpuServiceTest {
}
}
- GPUTiming::TimerType GetTimerType() { return test_timer_type_; }
+ gfx::GPUTiming::TimerType GetTimerType() { return test_timer_type_; }
- GPUTiming::TimerType test_timer_type_;
+ gfx::GPUTiming::TimerType test_timer_type_;
GlFakeQueries gl_fake_queries_;
- GPUTiming gpu_timing_;
+ scoped_refptr<gfx::GPUTimingClient> gpu_timing_client_;
scoped_refptr<MockOutputter> outputter_ref_;
};
// Test GPUTrace calls all the correct gl calls.
class BaseGpuTraceTest : public BaseGpuTest {
public:
- explicit BaseGpuTraceTest(GPUTiming::TimerType test_timer_type)
+ explicit BaseGpuTraceTest(gfx::GPUTiming::TimerType test_timer_type)
: BaseGpuTest(test_timer_type) {}
void DoTraceTest() {
@@ -345,10 +343,8 @@ class BaseGpuTraceTest : public BaseGpuTest {
expect_start_time, expect_end_time);
scoped_refptr<GPUTrace> trace = new GPUTrace(
- outputter_ref_, &gpu_timing_, category_name, trace_name, true);
-
- gpu_timing_.SetOffsetForTesting(
- offset_time, test_timer_type_ == GPUTiming::kTimerTypeARB);
+ outputter_ref_, gpu_timing_client_.get(),
+ category_name, trace_name, true);
gl_fake_queries_.SetCurrentGLTime(start_timestamp);
g_fakeCPUTime = expect_start_time;
@@ -379,13 +375,13 @@ class BaseGpuTraceTest : public BaseGpuTest {
class GpuARBTimerTraceTest : public BaseGpuTraceTest {
public:
- GpuARBTimerTraceTest() : BaseGpuTraceTest(GPUTiming::kTimerTypeARB) {}
+ GpuARBTimerTraceTest() : BaseGpuTraceTest(gfx::GPUTiming::kTimerTypeARB) {}
};
class GpuDisjointTimerTraceTest : public BaseGpuTraceTest {
public:
GpuDisjointTimerTraceTest()
- : BaseGpuTraceTest(GPUTiming::kTimerTypeDisjoint) {}
+ : BaseGpuTraceTest(gfx::GPUTiming::kTimerTypeDisjoint) {}
};
TEST_F(GpuARBTimerTraceTest, ARBTimerTraceTest) {
@@ -399,7 +395,7 @@ TEST_F(GpuDisjointTimerTraceTest, DisjointTimerTraceTest) {
// Test GPUTracer calls all the correct gl calls.
class BaseGpuTracerTest : public BaseGpuTest {
public:
- explicit BaseGpuTracerTest(GPUTiming::TimerType test_timer_type)
+ explicit BaseGpuTracerTest(gfx::GPUTiming::TimerType test_timer_type)
: BaseGpuTest(test_timer_type) {}
void DoBasicTracerTest() {
@@ -482,10 +478,10 @@ class BaseGpuTracerTest : public BaseGpuTest {
std::string source_category = category_name + num_char;
std::string source_trace_name = trace_name + num_char;
+ bool valid_timer = GetTimerType() != gfx::GPUTiming::kTimerTypeInvalid;
ExpectOutputterEndMocks(outputter_ref_.get(), source_category,
source_trace_name, expect_start_time + i,
- expect_end_time + i,
- GetTimerType() != GPUTiming::kTimerTypeInvalid);
+ expect_end_time + i, valid_timer);
const GpuTracerSource source = static_cast<GpuTracerSource>(i);
@@ -555,18 +551,20 @@ class BaseGpuTracerTest : public BaseGpuTest {
class InvalidTimerTracerTest : public BaseGpuTracerTest {
public:
- InvalidTimerTracerTest() : BaseGpuTracerTest(GPUTiming::kTimerTypeInvalid) {}
+ InvalidTimerTracerTest()
+ : BaseGpuTracerTest(gfx::GPUTiming::kTimerTypeInvalid) {}
};
class GpuARBTimerTracerTest : public BaseGpuTracerTest {
public:
- GpuARBTimerTracerTest() : BaseGpuTracerTest(GPUTiming::kTimerTypeARB) {}
+ GpuARBTimerTracerTest()
+ : BaseGpuTracerTest(gfx::GPUTiming::kTimerTypeARB) {}
};
class GpuDisjointTimerTracerTest : public BaseGpuTracerTest {
public:
GpuDisjointTimerTracerTest()
- : BaseGpuTracerTest(GPUTiming::kTimerTypeDisjoint) {}
+ : BaseGpuTracerTest(gfx::GPUTiming::kTimerTypeDisjoint) {}
};
TEST_F(InvalidTimerTracerTest, InvalidTimerBasicTracerTest) {
diff --git a/gpu/command_buffer_service.gypi b/gpu/command_buffer_service.gypi
index 5cb2a45..95a0aa2 100644
--- a/gpu/command_buffer_service.gypi
+++ b/gpu/command_buffer_service.gypi
@@ -85,8 +85,6 @@
'command_buffer/service/gpu_state_tracer.h',
'command_buffer/service/gpu_switches.cc',
'command_buffer/service/gpu_switches.h',
- 'command_buffer/service/gpu_timing.cc',
- 'command_buffer/service/gpu_timing.h',
'command_buffer/service/gpu_tracer.cc',
'command_buffer/service/gpu_tracer.h',
'command_buffer/service/id_manager.cc',
diff --git a/gpu/perftests/measurements.cc b/gpu/perftests/measurements.cc
index 527ce1b..db26fb3 100644
--- a/gpu/perftests/measurements.cc
+++ b/gpu/perftests/measurements.cc
@@ -5,8 +5,8 @@
#include "gpu/perftests/measurements.h"
#include "base/logging.h"
-#include "gpu/command_buffer/service/gpu_timing.h"
#include "testing/perf/perf_test.h"
+#include "ui/gl/gpu_timing.h"
namespace gpu {
@@ -52,9 +52,9 @@ Measurement Measurement::Divide(int a) const {
Measurement::~Measurement() {
}
-MeasurementTimers::MeasurementTimers(GPUTiming* gpu_timing)
+MeasurementTimers::MeasurementTimers(gfx::GPUTimingClient* gpu_timing_client)
: wall_time_start_(), cpu_time_start_(), gpu_timer_() {
- DCHECK(gpu_timing);
+ DCHECK(gpu_timing_client);
wall_time_start_ = base::TimeTicks::NowFromSystemTraceTime();
if (base::TimeTicks::IsThreadNowSupported()) {
cpu_time_start_ = base::TimeTicks::ThreadNow();
@@ -64,8 +64,8 @@ MeasurementTimers::MeasurementTimers(GPUTiming* gpu_timing)
logged_once = true;
}
- if (gpu_timing->IsAvailable()) {
- gpu_timer_.reset(new GPUTimer(gpu_timing));
+ if (gpu_timing_client->IsAvailable()) {
+ gpu_timer_ = gpu_timing_client->CreateGPUTimer();
gpu_timer_->Start();
}
}
diff --git a/gpu/perftests/measurements.h b/gpu/perftests/measurements.h
index 8cdcb30..35ede22 100644
--- a/gpu/perftests/measurements.h
+++ b/gpu/perftests/measurements.h
@@ -10,9 +10,13 @@
#include "base/memory/scoped_ptr.h"
#include "base/time/time.h"
+namespace gfx {
+ class GPUTimingClient;
+ class GPUTimer;
+}
+
namespace gpu {
-class GPUTiming;
-class GPUTimer;
+
struct Measurement {
Measurement();
Measurement(const Measurement& m);
@@ -37,7 +41,7 @@ struct Measurement {
// creation up to when Record is called.
class MeasurementTimers {
public:
- explicit MeasurementTimers(GPUTiming* gpu_timing);
+ explicit MeasurementTimers(gfx::GPUTimingClient* gpu_timing_client);
void Record();
Measurement GetAsMeasurement(const std::string& name);
~MeasurementTimers();
@@ -45,7 +49,7 @@ class MeasurementTimers {
private:
base::TimeTicks wall_time_start_;
base::TimeTicks cpu_time_start_;
- scoped_ptr<gpu::GPUTimer> gpu_timer_;
+ scoped_ptr<gfx::GPUTimer> gpu_timer_;
base::TimeDelta wall_time_;
base::TimeDelta cpu_time_;
diff --git a/gpu/perftests/texture_upload_perftest.cc b/gpu/perftests/texture_upload_perftest.cc
index 487f9b2..495ef86 100644
--- a/gpu/perftests/texture_upload_perftest.cc
+++ b/gpu/perftests/texture_upload_perftest.cc
@@ -10,7 +10,6 @@
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/strings/stringprintf.h"
-#include "gpu/command_buffer/service/gpu_timing.h"
#include "gpu/perftests/measurements.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "testing/perf/perf_test.h"
@@ -18,6 +17,7 @@
#include "ui/gl/gl_bindings.h"
#include "ui/gl/gl_context.h"
#include "ui/gl/gl_surface.h"
+#include "ui/gl/gpu_timing.h"
#include "ui/gl/scoped_make_current.h"
namespace gpu {
@@ -124,12 +124,12 @@ class TextureUploadPerfTest : public testing::Test {
glCheckFramebufferStatusEXT(GL_FRAMEBUFFER));
glViewport(0, 0, fbo_size_.width(), fbo_size_.height());
+ gpu_timing_client_ = gl_context_->CreateGPUTimingClient();
- if (gpu_timing_.Initialize(gl_context_.get())) {
+ if (gpu_timing_client_->IsAvailable()) {
LOG(INFO) << "Gpu timing initialized with timer type: "
- << gpu_timing_.GetTimerTypeName();
- gpu_timing_.CheckAndResetTimerErrors();
- gpu_timing_.InvalidateTimerOffset();
+ << gpu_timing_client_->GetTimerTypeName();
+ gpu_timing_client_->InvalidateTimerOffset();
} else {
LOG(WARNING) << "Can't initialize gpu timing";
}
@@ -205,10 +205,10 @@ class TextureUploadPerfTest : public testing::Test {
const std::vector<uint8>& pixels,
const GLenum format,
const GLenum type) {
- MeasurementTimers total_timers(&gpu_timing_);
+ MeasurementTimers total_timers(gpu_timing_client_.get());
GLuint texture_id = 0;
- MeasurementTimers tex_timers(&gpu_timing_);
+ MeasurementTimers tex_timers(gpu_timing_client_.get());
glActiveTexture(GL_TEXTURE0);
glGenTextures(1, &texture_id);
glBindTexture(GL_TEXTURE_2D, texture_id);
@@ -222,7 +222,7 @@ class TextureUploadPerfTest : public testing::Test {
CheckNoGlError();
tex_timers.Record();
- MeasurementTimers draw_timers(&gpu_timing_);
+ MeasurementTimers draw_timers(gpu_timing_client_.get());
glUseProgram(program_object_);
glUniform1i(sampler_location_, 0);
@@ -237,7 +237,7 @@ class TextureUploadPerfTest : public testing::Test {
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
draw_timers.Record();
- MeasurementTimers finish_timers(&gpu_timing_);
+ MeasurementTimers finish_timers(gpu_timing_client_.get());
glFinish();
CheckNoGlError();
finish_timers.Record();
@@ -257,7 +257,8 @@ class TextureUploadPerfTest : public testing::Test {
std::vector<Measurement> measurements;
bool gpu_timer_errors =
- gpu_timing_.IsAvailable() && gpu_timing_.CheckAndResetTimerErrors();
+ gpu_timing_client_->IsAvailable() &&
+ gpu_timing_client_->CheckAndResetTimerErrors();
if (!gpu_timer_errors) {
measurements.push_back(total_timers.GetAsMeasurement("total"));
measurements.push_back(tex_timers.GetAsMeasurement("teximage2d"));
@@ -298,7 +299,7 @@ class TextureUploadPerfTest : public testing::Test {
const gfx::Size fbo_size_; // for the fbo
scoped_refptr<gfx::GLContext> gl_context_;
scoped_refptr<gfx::GLSurface> surface_;
- GPUTiming gpu_timing_;
+ scoped_refptr<gfx::GPUTimingClient> gpu_timing_client_;
GLuint color_texture_ = 0;
GLuint framebuffer_object_ = 0;
diff --git a/ui/gl/BUILD.gn b/ui/gl/BUILD.gn
index c596f53..12a44cc 100644
--- a/ui/gl/BUILD.gn
+++ b/ui/gl/BUILD.gn
@@ -92,6 +92,8 @@ component("gl") {
"gl_version_info.h",
"gpu_switching_manager.cc",
"gpu_switching_manager.h",
+ "gpu_timing.cc",
+ "gpu_timing.h",
"scoped_binders.cc",
"scoped_binders.h",
"scoped_make_current.cc",
diff --git a/ui/gl/gl.gyp b/ui/gl/gl.gyp
index 6b173f4..05381078 100644
--- a/ui/gl/gl.gyp
+++ b/ui/gl/gl.gyp
@@ -113,6 +113,8 @@
'gpu_switching_manager.cc',
'gpu_switching_manager.h',
'gpu_switching_observer.h',
+ 'gpu_timing.cc',
+ 'gpu_timing.h',
'scoped_binders.cc',
'scoped_binders.h',
'scoped_make_current.cc',
diff --git a/ui/gl/gl_context.cc b/ui/gl/gl_context.cc
index 720e8e2..dd8aa26 100644
--- a/ui/gl/gl_context.cc
+++ b/ui/gl/gl_context.cc
@@ -15,6 +15,7 @@
#include "ui/gl/gl_surface.h"
#include "ui/gl/gl_switches.h"
#include "ui/gl/gl_version_info.h"
+#include "ui/gl/gpu_timing.h"
namespace gfx {
@@ -212,6 +213,13 @@ void GLContext::SetRealGLApi() {
GLContextReal::GLContextReal(GLShareGroup* share_group)
: GLContext(share_group) {}
+scoped_refptr<gfx::GPUTimingClient> GLContextReal::CreateGPUTimingClient() {
+ if (!gpu_timing_) {
+ gpu_timing_.reset(new gfx::GPUTiming(this));
+ }
+ return gpu_timing_->CreateGPUTimingClient();
+}
+
GLContextReal::~GLContextReal() {}
void GLContextReal::SetCurrent(GLSurface* surface) {
diff --git a/ui/gl/gl_context.h b/ui/gl/gl_context.h
index 5eac838..4577be3 100644
--- a/ui/gl/gl_context.h
+++ b/ui/gl/gl_context.h
@@ -19,9 +19,12 @@
namespace gfx {
class GLSurface;
+class GPUTiming;
+class GPUTimingClient;
class VirtualGLApi;
struct GLVersionInfo;
+
// Encapsulates an OpenGL context, hiding platform specific management.
class GL_EXPORT GLContext : public base::RefCounted<GLContext> {
public:
@@ -50,6 +53,9 @@ class GL_EXPORT GLContext : public base::RefCounted<GLContext> {
// Get the underlying platform specific GL context "handle".
virtual void* GetHandle() = 0;
+ // Creates a GPUTimingClient class which abstracts various GPU Timing exts.
+ virtual scoped_refptr<gfx::GPUTimingClient> CreateGPUTimingClient() = 0;
+
// Gets the GLStateRestorer for the context.
GLStateRestorer* GetGLStateRestorer();
@@ -173,6 +179,7 @@ class GL_EXPORT GLContext : public base::RefCounted<GLContext> {
class GL_EXPORT GLContextReal : public GLContext {
public:
explicit GLContextReal(GLShareGroup* share_group);
+ scoped_refptr<gfx::GPUTimingClient> CreateGPUTimingClient() override;
protected:
~GLContextReal() override;
@@ -180,6 +187,7 @@ class GL_EXPORT GLContextReal : public GLContext {
void SetCurrent(GLSurface* surface) override;
private:
+ scoped_ptr<gfx::GPUTiming> gpu_timing_;
DISALLOW_COPY_AND_ASSIGN(GLContextReal);
};
diff --git a/gpu/command_buffer/service/gpu_timing.cc b/ui/gl/gpu_timing.cc
index 6ab3e83..22a4a64 100644
--- a/gpu/command_buffer/service/gpu_timing.cc
+++ b/ui/gl/gpu_timing.cc
@@ -2,19 +2,32 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "gpu/command_buffer/service/gpu_timing.h"
+#include "ui/gl/gpu_timing.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 gpu {
+namespace gfx {
-GPUTimer::GPUTimer(GPUTiming* gpu_timing) : gpu_timing_(gpu_timing) {
- DCHECK(gpu_timing_);
- memset(queries_, 0, sizeof(queries_));
- glGenQueriesARB(2, queries_);
+GPUTiming::GPUTiming(GLContextReal* context) {
+ DCHECK(context);
+ const GLVersionInfo* version_info = context->GetVersionInfo();
+ DCHECK(version_info);
+ if (version_info->is_es3 && // glGetInteger64v is supported under ES3.
+ context->HasExtension("GL_EXT_disjoint_timer_query")) {
+ timer_type_ = kTimerTypeDisjoint;
+ } else if (context->HasExtension("GL_ARB_timer_query")) {
+ timer_type_ = kTimerTypeARB;
+ }
+}
+
+GPUTiming::~GPUTiming() {
+}
+
+scoped_refptr<GPUTimingClient> GPUTiming::CreateGPUTimingClient() {
+ return new GPUTimingClient(this);
}
GPUTimer::~GPUTimer() {
@@ -28,12 +41,12 @@ void GPUTimer::Start() {
void GPUTimer::End() {
end_requested_ = true;
- offset_ = gpu_timing_->CalculateTimerOffset();
+ offset_ = gpu_timing_client_->CalculateTimerOffset();
glQueryCounter(queries_[1], GL_TIMESTAMP);
}
bool GPUTimer::IsAvailable() {
- if (!gpu_timing_->IsAvailable() || !end_requested_) {
+ if (!gpu_timing_client_->IsAvailable() || !end_requested_) {
return false;
}
GLint done = 0;
@@ -63,46 +76,41 @@ int64 GPUTimer::GetDeltaElapsed() {
return end - start;
}
-GPUTiming::GPUTiming() : cpu_time_for_testing_() {
+GPUTimer::GPUTimer(scoped_refptr<GPUTimingClient> gpu_timing_client)
+ : gpu_timing_client_(gpu_timing_client) {
+ DCHECK(gpu_timing_client_);
+ memset(queries_, 0, sizeof(queries_));
+ glGenQueriesARB(2, queries_);
}
-GPUTiming::~GPUTiming() {
+GPUTimingClient::GPUTimingClient(GPUTiming* gpu_timing)
+ : gpu_timing_(gpu_timing) {
+ if (gpu_timing) {
+ timer_type_ = gpu_timing->GetTimerType();
+ }
}
-bool GPUTiming::Initialize(gfx::GLContext* gl_context) {
- DCHECK(gl_context);
- DCHECK_EQ(kTimerTypeInvalid, timer_type_);
-
- const gfx::GLVersionInfo* version_info = gl_context->GetVersionInfo();
- DCHECK(version_info);
- if (version_info->is_es3 && // glGetInteger64v is supported under ES3.
- gfx::g_driver_gl.ext.b_GL_EXT_disjoint_timer_query) {
- timer_type_ = kTimerTypeDisjoint;
- return true;
- } else if (gfx::g_driver_gl.ext.b_GL_ARB_timer_query) {
- timer_type_ = kTimerTypeARB;
- return true;
- }
- return false;
+scoped_ptr<GPUTimer> GPUTimingClient::CreateGPUTimer() {
+ return make_scoped_ptr(new GPUTimer(this));
}
-bool GPUTiming::IsAvailable() {
- return timer_type_ != kTimerTypeInvalid;
+bool GPUTimingClient::IsAvailable() {
+ return timer_type_ != GPUTiming::kTimerTypeInvalid;
}
-const char* GPUTiming::GetTimerTypeName() const {
+const char* GPUTimingClient::GetTimerTypeName() const {
switch (timer_type_) {
- case kTimerTypeDisjoint:
+ case GPUTiming::kTimerTypeDisjoint:
return "GL_EXT_disjoint_timer_query";
- case kTimerTypeARB:
+ case GPUTiming::kTimerTypeARB:
return "GL_ARB_timer_query";
default:
return "Unknown";
}
}
-bool GPUTiming::CheckAndResetTimerErrors() {
- if (timer_type_ == kTimerTypeDisjoint) {
+bool GPUTimingClient::CheckAndResetTimerErrors() {
+ if (timer_type_ == GPUTiming::kTimerTypeDisjoint) {
GLint disjoint_value = 0;
glGetIntegerv(GL_GPU_DISJOINT_EXT, &disjoint_value);
return disjoint_value != 0;
@@ -111,7 +119,7 @@ bool GPUTiming::CheckAndResetTimerErrors() {
}
}
-int64 GPUTiming::CalculateTimerOffset() {
+int64 GPUTimingClient::CalculateTimerOffset() {
if (!offset_valid_) {
GLint64 gl_now = 0;
glGetInteger64v(GL_TIMESTAMP, &gl_now);
@@ -120,27 +128,21 @@ int64 GPUTiming::CalculateTimerOffset() {
? base::TimeTicks::NowFromSystemTraceTime().ToInternalValue()
: cpu_time_for_testing_.Run();
offset_ = now - gl_now / base::Time::kNanosecondsPerMicrosecond;
- offset_valid_ = timer_type_ == kTimerTypeARB;
+ offset_valid_ = timer_type_ == GPUTiming::kTimerTypeARB;
}
return offset_;
}
-void GPUTiming::InvalidateTimerOffset() {
+void GPUTimingClient::InvalidateTimerOffset() {
offset_valid_ = false;
}
-void GPUTiming::SetCpuTimeForTesting(
+void GPUTimingClient::SetCpuTimeForTesting(
const base::Callback<int64(void)>& cpu_time) {
cpu_time_for_testing_ = cpu_time;
}
-void GPUTiming::SetOffsetForTesting(int64 offset, bool cache_it) {
- offset_ = offset;
- offset_valid_ = cache_it;
-}
-
-void GPUTiming::SetTimerTypeForTesting(TimerType type) {
- timer_type_ = type;
+GPUTimingClient::~GPUTimingClient() {
}
-} // namespace gpu
+} // namespace gfx
diff --git a/ui/gl/gpu_timing.h b/ui/gl/gpu_timing.h
new file mode 100644
index 0000000..9702fe1
--- /dev/null
+++ b/ui/gl/gpu_timing.h
@@ -0,0 +1,136 @@
+// 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.
+
+#ifndef GPU_COMMAND_BUFFER_SERVICE_GPU_TIMING_H_
+#define GPU_COMMAND_BUFFER_SERVICE_GPU_TIMING_H_
+
+#include "base/callback.h"
+#include "base/memory/scoped_ptr.h"
+#include "ui/gl/gl_export.h"
+
+// The gpu_timing classes handles the abstraction of GL GPU Timing extensions
+// into a common set of functions. Currently the different timer extensions
+// that are supported are ARB_timer_query and EXT_disjoint_timer_query.
+//
+// Explanation of Classes:
+// GPUTiming - GPU Timing is a private class which is only owned by the
+// underlying GLContextReal class. This class handles any GL Context level
+// states which may need to be redistributed to users of GPUTiming. For
+// example, there exists only a single disjoint flag for each real GL
+// Context. Once the disjoint flag is checked, internally it is reset to
+// false. In order to support multiple virtual contexts each checking the
+// disjoint flag seperately, GPUTiming is in charge of checking the
+// disjoint flag and broadcasting out the disjoint state to all the
+// various users of GPUTiming (GPUTimingClient below).
+// GPUTimingClient - The GLContextReal holds the GPUTiming class and is the
+// factory that creates GPUTimingClient objects. If a user would like to
+// obtain various GPU times they would access CreateGPUTimingClient() from
+// their GLContext and use the returned object for their timing calls.
+// Each virtual context as well as any other classes which need GPU times
+// will hold one of these. When they want to time a GPU trace they will
+// create GPUTimer objects.
+// GPUTimer - Once a user decides to trace something, the user creates a new
+// GPUTimer object from a GPUTimingClient and issue Start() and Stop() calls
+// around various GL Calls. Once IsAvailable() returns true, the GPU times
+// will be available through the various time stamp related functions.
+// The constructor and destructor of this object handles the actual
+// creation and deletion of the GL Queries within GL.
+
+namespace gfx {
+
+class GLContextReal;
+class GPUTimingClient;
+
+class GPUTiming {
+ public:
+ enum TimerType {
+ kTimerTypeInvalid = -1,
+
+ kTimerTypeARB, // ARB_timer_query
+ kTimerTypeDisjoint // EXT_disjoint_timer_query
+ };
+
+ TimerType GetTimerType() const { return timer_type_; }
+
+ private:
+ friend struct base::DefaultDeleter<GPUTiming>;
+ friend class GLContextReal;
+ explicit GPUTiming(GLContextReal* context);
+ ~GPUTiming();
+
+ scoped_refptr<GPUTimingClient> CreateGPUTimingClient();
+
+ TimerType timer_type_ = kTimerTypeInvalid;
+ DISALLOW_COPY_AND_ASSIGN(GPUTiming);
+};
+
+// Class to compute the amount of time it takes to fully
+// complete a set of GL commands
+class GL_EXPORT GPUTimer {
+ public:
+ ~GPUTimer();
+
+ void Start();
+ void End();
+ bool IsAvailable();
+
+ void GetStartEndTimestamps(int64* start, int64* end);
+ int64 GetDeltaElapsed();
+
+ private:
+ friend class GPUTimingClient;
+
+ explicit GPUTimer(scoped_refptr<GPUTimingClient> gpu_timing_client);
+
+ unsigned int queries_[2];
+ int64 offset_ = 0;
+ bool end_requested_ = false;
+ scoped_refptr<GPUTimingClient> gpu_timing_client_;
+
+ DISALLOW_COPY_AND_ASSIGN(GPUTimer);
+};
+
+// GPUTimingClient contains all the gl timing logic that is not specific
+// to a single GPUTimer.
+class GL_EXPORT GPUTimingClient
+ : public base::RefCounted<GPUTimingClient> {
+ public:
+ explicit GPUTimingClient(GPUTiming* gpu_timing = nullptr);
+
+ scoped_ptr<GPUTimer> CreateGPUTimer();
+ bool IsAvailable();
+ const char* GetTimerTypeName() const;
+
+ // CheckAndResetTimerErrors has to be called before reading timestamps
+ // from GPUTimers instances and after making sure all the timers
+ // were available.
+ // If the returned value is false, all the previous timers should be
+ // discarded.
+ bool CheckAndResetTimerErrors();
+
+ // Returns the offset between the current gpu time and the cpu time.
+ int64 CalculateTimerOffset();
+ void InvalidateTimerOffset();
+
+ void SetCpuTimeForTesting(const base::Callback<int64(void)>& cpu_time);
+
+ private:
+ friend class base::RefCounted<GPUTimingClient>;
+ friend class GPUTimer;
+ friend class GPUTiming;
+
+ virtual ~GPUTimingClient();
+
+ GPUTiming* gpu_timing_;
+ GPUTiming::TimerType timer_type_ = GPUTiming::kTimerTypeInvalid;
+ int64 offset_ = 0; // offset cache when timer_type_ == kTimerTypeARB
+ bool offset_valid_ = false;
+ base::Callback<int64(void)> cpu_time_for_testing_;
+
+ DISALLOW_COPY_AND_ASSIGN(GPUTimingClient);
+};
+
+} // namespace gfx
+
+#endif // GPU_COMMAND_BUFFER_SERVICE_GPU_TIMING_H_