Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(332)

Side by Side Diff: gpu/command_buffer/service/gpu_timing.cc

Issue 904743002: gpu: Extract the gpu timing code from gpu_tracer. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix cl.exe warning: 'const unsigned char' : forcing value to bool 'true' or 'false' Created 5 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright (c) 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "gpu/command_buffer/service/gpu_timing.h"
6
7 #include "base/time/time.h"
8 #include "ui/gl/gl_context.h"
9 #include "ui/gl/gl_version_info.h"
10
11 namespace gpu {
12
13 GPUTimer::GPUTimer(GPUTiming* gpu_timing) : gpu_timing_(gpu_timing) {
14 DCHECK(gpu_timing_);
15 memset(queries_, 0, sizeof(queries_));
16 glGenQueriesARB(2, queries_);
17 }
18
19 GPUTimer::~GPUTimer() {
20 glDeleteQueriesARB(2, queries_);
21 }
22
23 void GPUTimer::Start() {
24 // GL_TIMESTAMP and GL_TIMESTAMP_EXT both have the same value.
25 offset_ = gpu_timing_->CalculateTimerOffset();
26 glQueryCounter(queries_[0], GL_TIMESTAMP);
27 }
28
29 void GPUTimer::End() {
30 end_requested_ = true;
31 glQueryCounter(queries_[1], GL_TIMESTAMP);
32 }
33
34 bool GPUTimer::IsAvailable() {
35 if (!gpu_timing_->IsAvailable() || !end_requested_) {
36 return false;
37 }
38 GLint done = 0;
39 glGetQueryObjectivARB(queries_[1], GL_QUERY_RESULT_AVAILABLE, &done);
40 return done != 0;
41 }
42
43 void GPUTimer::GetStartEndTimestamps(int64* start, int64* end) {
44 DCHECK(start && end);
45 DCHECK(IsAvailable());
46 GLuint64 begin_stamp = 0;
47 GLuint64 end_stamp = 0;
48 // TODO(dsinclair): It's possible for the timer to wrap during the start/end.
49 // We need to detect if the end is less then the start and correct for the
50 // wrapping.
51 glGetQueryObjectui64v(queries_[0], GL_QUERY_RESULT, &begin_stamp);
52 *start = begin_stamp / base::Time::kNanosecondsPerMicrosecond + offset_;
53 glGetQueryObjectui64v(queries_[1], GL_QUERY_RESULT, &end_stamp);
54 *end = end_stamp / base::Time::kNanosecondsPerMicrosecond + offset_;
55 }
56
57 int64 GPUTimer::GetDeltaElapsed() {
58 int64 start = 0;
59 int64 end = 0;
60 GetStartEndTimestamps(&start, &end);
61 return end - start;
62 }
63
64 GPUTiming::GPUTiming() : cpu_time_for_testing_() {
65 }
66
67 GPUTiming::~GPUTiming() {
68 }
69
70 bool GPUTiming::Initialize(gfx::GLContext* gl_context) {
71 DCHECK(gl_context);
72 DCHECK_EQ(kTimerTypeInvalid, timer_type_);
73
74 const gfx::GLVersionInfo* version_info = gl_context->GetVersionInfo();
75 DCHECK(version_info);
76 if (version_info->is_es3 && // glGetInteger64v is supported under ES3.
77 gfx::g_driver_gl.ext.b_GL_EXT_disjoint_timer_query) {
78 timer_type_ = kTimerTypeDisjoint;
79 CheckAndResetTimerErrors();
David Yen 2015/02/06 22:47:01 The ResetTimerErrors() needs to be called everytim
Daniele Castagna 2015/02/10 04:49:33 Done.
80 return true;
81 } else if (gfx::g_driver_gl.ext.b_GL_ARB_timer_query) {
82 timer_type_ = kTimerTypeARB;
83 offset_ = CalculateTimerOffset();
David Yen 2015/02/06 22:47:01 I think we don't need to call CalculateTimerOffset
Daniele Castagna 2015/02/10 04:49:33 Done.
84 return true;
85 }
86 return false;
87 }
88
89 bool GPUTiming::IsAvailable() {
90 return timer_type_ != kTimerTypeInvalid;
91 }
92
93 const char* GPUTiming::GetTimerTypeName() const {
94 switch (timer_type_) {
95 case kTimerTypeDisjoint:
96 return "GL_EXT_disjoint_timer_query";
97 case kTimerTypeARB:
98 return "GL_ARB_timer_query";
99 default:
100 return "Unknown";
101 }
102 }
103
104 bool GPUTiming::CheckAndResetTimerErrors() {
105 if (timer_type_ == kTimerTypeDisjoint) {
106 DCHECK_EQ(kTimerTypeDisjoint, timer_type_);
David Yen 2015/02/06 22:47:01 This DCHECK seems unnecessary, was it from old cod
Daniele Castagna 2015/02/10 04:49:32 Done.
107 GLint disjoint_value = 0;
108 glGetIntegerv(GL_GPU_DISJOINT_EXT, &disjoint_value);
109 return disjoint_value != 0;
110 } else {
111 return false;
112 }
113 }
114
115 int64 GPUTiming::CalculateTimerOffset() {
116 if (!offset_valid_) {
117 GLint64 gl_now = 0;
118 glGetInteger64v(GL_TIMESTAMP, &gl_now);
119 int64 now =
120 cpu_time_for_testing_.is_null()
121 ? base::TimeTicks::NowFromSystemTraceTime().ToInternalValue()
122 : cpu_time_for_testing_.Run();
123 offset_ = now - gl_now / base::Time::kNanosecondsPerMicrosecond;
124 offset_valid_ = timer_type_ == kTimerTypeARB;
125 }
126 return offset_;
127 }
128
129 void GPUTiming::InvalidateTimerOffset() {
130 offset_valid_ = false;
131 }
132
133 void GPUTiming::SetCpuTimeForTesting(
134 const base::Callback<int64(void)>& cpu_time) {
135 cpu_time_for_testing_ = cpu_time;
136 }
137
138 void GPUTiming::SetOffsetForTesting(int64 offset, bool cache_it) {
139 offset_ = offset;
140 offset_valid_ = cache_it;
141 }
142
143 void GPUTiming::SetTimerTypeForTesting(TimerType type) {
144 timer_type_ = type;
145 }
146
147 } // namespace gpu
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698