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

Side by Side Diff: ui/gl/gpu_timing.cc

Issue 937263006: Refactored GLContext to own GPUTiming which spawn GPUTimingClients. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Added GPUTiming descriptions for all 3 classes, refptr in GPUTimer Created 5 years, 9 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
« no previous file with comments | « ui/gl/gpu_timing.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2015 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "gpu/command_buffer/service/gpu_timing.h" 5 #include "ui/gl/gpu_timing.h"
6 6
7 #include "base/time/time.h" 7 #include "base/time/time.h"
8 #include "ui/gl/gl_bindings.h" 8 #include "ui/gl/gl_bindings.h"
9 #include "ui/gl/gl_context.h" 9 #include "ui/gl/gl_context.h"
10 #include "ui/gl/gl_version_info.h" 10 #include "ui/gl/gl_version_info.h"
11 11
12 namespace gpu { 12 namespace gfx {
13 13
14 GPUTimer::GPUTimer(GPUTiming* gpu_timing) : gpu_timing_(gpu_timing) { 14 GPUTiming::GPUTiming(GLContextReal* context) {
15 DCHECK(gpu_timing_); 15 DCHECK(context);
16 memset(queries_, 0, sizeof(queries_)); 16 const GLVersionInfo* version_info = context->GetVersionInfo();
17 glGenQueriesARB(2, queries_); 17 DCHECK(version_info);
18 if (version_info->is_es3 && // glGetInteger64v is supported under ES3.
19 context->HasExtension("GL_EXT_disjoint_timer_query")) {
20 timer_type_ = kTimerTypeDisjoint;
21 } else if (context->HasExtension("GL_ARB_timer_query")) {
22 timer_type_ = kTimerTypeARB;
23 }
24 }
25
26 GPUTiming::~GPUTiming() {
27 }
28
29 scoped_refptr<GPUTimingClient> GPUTiming::CreateGPUTimingClient() {
30 return new GPUTimingClient(this);
18 } 31 }
19 32
20 GPUTimer::~GPUTimer() { 33 GPUTimer::~GPUTimer() {
21 glDeleteQueriesARB(2, queries_); 34 glDeleteQueriesARB(2, queries_);
22 } 35 }
23 36
24 void GPUTimer::Start() { 37 void GPUTimer::Start() {
25 // GL_TIMESTAMP and GL_TIMESTAMP_EXT both have the same value. 38 // GL_TIMESTAMP and GL_TIMESTAMP_EXT both have the same value.
26 glQueryCounter(queries_[0], GL_TIMESTAMP); 39 glQueryCounter(queries_[0], GL_TIMESTAMP);
27 } 40 }
28 41
29 void GPUTimer::End() { 42 void GPUTimer::End() {
30 end_requested_ = true; 43 end_requested_ = true;
31 offset_ = gpu_timing_->CalculateTimerOffset(); 44 offset_ = gpu_timing_client_->CalculateTimerOffset();
32 glQueryCounter(queries_[1], GL_TIMESTAMP); 45 glQueryCounter(queries_[1], GL_TIMESTAMP);
33 } 46 }
34 47
35 bool GPUTimer::IsAvailable() { 48 bool GPUTimer::IsAvailable() {
36 if (!gpu_timing_->IsAvailable() || !end_requested_) { 49 if (!gpu_timing_client_->IsAvailable() || !end_requested_) {
37 return false; 50 return false;
38 } 51 }
39 GLint done = 0; 52 GLint done = 0;
40 glGetQueryObjectivARB(queries_[1], GL_QUERY_RESULT_AVAILABLE, &done); 53 glGetQueryObjectivARB(queries_[1], GL_QUERY_RESULT_AVAILABLE, &done);
41 return done != 0; 54 return done != 0;
42 } 55 }
43 56
44 void GPUTimer::GetStartEndTimestamps(int64* start, int64* end) { 57 void GPUTimer::GetStartEndTimestamps(int64* start, int64* end) {
45 DCHECK(start && end); 58 DCHECK(start && end);
46 DCHECK(IsAvailable()); 59 DCHECK(IsAvailable());
47 GLuint64 begin_stamp = 0; 60 GLuint64 begin_stamp = 0;
48 GLuint64 end_stamp = 0; 61 GLuint64 end_stamp = 0;
49 // TODO(dsinclair): It's possible for the timer to wrap during the start/end. 62 // TODO(dsinclair): It's possible for the timer to wrap during the start/end.
50 // We need to detect if the end is less then the start and correct for the 63 // We need to detect if the end is less then the start and correct for the
51 // wrapping. 64 // wrapping.
52 glGetQueryObjectui64v(queries_[0], GL_QUERY_RESULT, &begin_stamp); 65 glGetQueryObjectui64v(queries_[0], GL_QUERY_RESULT, &begin_stamp);
53 glGetQueryObjectui64v(queries_[1], GL_QUERY_RESULT, &end_stamp); 66 glGetQueryObjectui64v(queries_[1], GL_QUERY_RESULT, &end_stamp);
54 67
55 *start = (begin_stamp / base::Time::kNanosecondsPerMicrosecond) + offset_; 68 *start = (begin_stamp / base::Time::kNanosecondsPerMicrosecond) + offset_;
56 *end = (end_stamp / base::Time::kNanosecondsPerMicrosecond) + offset_; 69 *end = (end_stamp / base::Time::kNanosecondsPerMicrosecond) + offset_;
57 } 70 }
58 71
59 int64 GPUTimer::GetDeltaElapsed() { 72 int64 GPUTimer::GetDeltaElapsed() {
60 int64 start = 0; 73 int64 start = 0;
61 int64 end = 0; 74 int64 end = 0;
62 GetStartEndTimestamps(&start, &end); 75 GetStartEndTimestamps(&start, &end);
63 return end - start; 76 return end - start;
64 } 77 }
65 78
66 GPUTiming::GPUTiming() : cpu_time_for_testing_() { 79 GPUTimer::GPUTimer(scoped_refptr<GPUTimingClient> gpu_timing_client)
80 : gpu_timing_client_(gpu_timing_client) {
81 DCHECK(gpu_timing_client_);
82 memset(queries_, 0, sizeof(queries_));
83 glGenQueriesARB(2, queries_);
67 } 84 }
68 85
69 GPUTiming::~GPUTiming() { 86 GPUTimingClient::GPUTimingClient(GPUTiming* gpu_timing)
87 : gpu_timing_(gpu_timing) {
88 if (gpu_timing) {
89 timer_type_ = gpu_timing->GetTimerType();
90 }
70 } 91 }
71 92
72 bool GPUTiming::Initialize(gfx::GLContext* gl_context) { 93 scoped_ptr<GPUTimer> GPUTimingClient::CreateGPUTimer() {
73 DCHECK(gl_context); 94 return make_scoped_ptr(new GPUTimer(this));
74 DCHECK_EQ(kTimerTypeInvalid, timer_type_);
75
76 const gfx::GLVersionInfo* version_info = gl_context->GetVersionInfo();
77 DCHECK(version_info);
78 if (version_info->is_es3 && // glGetInteger64v is supported under ES3.
79 gfx::g_driver_gl.ext.b_GL_EXT_disjoint_timer_query) {
80 timer_type_ = kTimerTypeDisjoint;
81 return true;
82 } else if (gfx::g_driver_gl.ext.b_GL_ARB_timer_query) {
83 timer_type_ = kTimerTypeARB;
84 return true;
85 }
86 return false;
87 } 95 }
88 96
89 bool GPUTiming::IsAvailable() { 97 bool GPUTimingClient::IsAvailable() {
90 return timer_type_ != kTimerTypeInvalid; 98 return timer_type_ != GPUTiming::kTimerTypeInvalid;
91 } 99 }
92 100
93 const char* GPUTiming::GetTimerTypeName() const { 101 const char* GPUTimingClient::GetTimerTypeName() const {
94 switch (timer_type_) { 102 switch (timer_type_) {
95 case kTimerTypeDisjoint: 103 case GPUTiming::kTimerTypeDisjoint:
96 return "GL_EXT_disjoint_timer_query"; 104 return "GL_EXT_disjoint_timer_query";
97 case kTimerTypeARB: 105 case GPUTiming::kTimerTypeARB:
98 return "GL_ARB_timer_query"; 106 return "GL_ARB_timer_query";
99 default: 107 default:
100 return "Unknown"; 108 return "Unknown";
101 } 109 }
102 } 110 }
103 111
104 bool GPUTiming::CheckAndResetTimerErrors() { 112 bool GPUTimingClient::CheckAndResetTimerErrors() {
105 if (timer_type_ == kTimerTypeDisjoint) { 113 if (timer_type_ == GPUTiming::kTimerTypeDisjoint) {
106 GLint disjoint_value = 0; 114 GLint disjoint_value = 0;
107 glGetIntegerv(GL_GPU_DISJOINT_EXT, &disjoint_value); 115 glGetIntegerv(GL_GPU_DISJOINT_EXT, &disjoint_value);
108 return disjoint_value != 0; 116 return disjoint_value != 0;
109 } else { 117 } else {
110 return false; 118 return false;
111 } 119 }
112 } 120 }
113 121
114 int64 GPUTiming::CalculateTimerOffset() { 122 int64 GPUTimingClient::CalculateTimerOffset() {
115 if (!offset_valid_) { 123 if (!offset_valid_) {
116 GLint64 gl_now = 0; 124 GLint64 gl_now = 0;
117 glGetInteger64v(GL_TIMESTAMP, &gl_now); 125 glGetInteger64v(GL_TIMESTAMP, &gl_now);
118 int64 now = 126 int64 now =
119 cpu_time_for_testing_.is_null() 127 cpu_time_for_testing_.is_null()
120 ? base::TimeTicks::NowFromSystemTraceTime().ToInternalValue() 128 ? base::TimeTicks::NowFromSystemTraceTime().ToInternalValue()
121 : cpu_time_for_testing_.Run(); 129 : cpu_time_for_testing_.Run();
122 offset_ = now - gl_now / base::Time::kNanosecondsPerMicrosecond; 130 offset_ = now - gl_now / base::Time::kNanosecondsPerMicrosecond;
123 offset_valid_ = timer_type_ == kTimerTypeARB; 131 offset_valid_ = timer_type_ == GPUTiming::kTimerTypeARB;
124 } 132 }
125 return offset_; 133 return offset_;
126 } 134 }
127 135
128 void GPUTiming::InvalidateTimerOffset() { 136 void GPUTimingClient::InvalidateTimerOffset() {
129 offset_valid_ = false; 137 offset_valid_ = false;
130 } 138 }
131 139
132 void GPUTiming::SetCpuTimeForTesting( 140 void GPUTimingClient::SetCpuTimeForTesting(
133 const base::Callback<int64(void)>& cpu_time) { 141 const base::Callback<int64(void)>& cpu_time) {
134 cpu_time_for_testing_ = cpu_time; 142 cpu_time_for_testing_ = cpu_time;
135 } 143 }
136 144
137 void GPUTiming::SetOffsetForTesting(int64 offset, bool cache_it) { 145 GPUTimingClient::~GPUTimingClient() {
138 offset_ = offset;
139 offset_valid_ = cache_it;
140 } 146 }
141 147
142 void GPUTiming::SetTimerTypeForTesting(TimerType type) { 148 } // namespace gfx
143 timer_type_ = type;
144 }
145
146 } // namespace gpu
OLDNEW
« no previous file with comments | « ui/gl/gpu_timing.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698