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

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: Merged with latest 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
« ui/gl/gpu_timing.h ('K') | « 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 gpu {
13 13
14 GPUTimer::GPUTimer(GPUTiming* gpu_timing) : gpu_timing_(gpu_timing) { 14 GPUTiming::GPUTiming(gfx::GLContext* context) {
15 DCHECK(gpu_timing_); 15 Initialize(context);
16 memset(queries_, 0, sizeof(queries_)); 16 }
17 glGenQueriesARB(2, queries_); 17
18 GPUTiming::~GPUTiming() {
19 }
20
21 void GPUTiming::Initialize(gfx::GLContext* context) {
22 timer_type_ = kTimerTypeInvalid;
23 if (context) {
24 const gfx::GLVersionInfo* version_info = context->GetVersionInfo();
25 DCHECK(version_info);
26 if (version_info->is_es3 && // glGetInteger64v is supported under ES3.
27 context->HasExtension("GL_EXT_disjoint_timer_query")) {
28 timer_type_ = kTimerTypeDisjoint;
29 } else if (context->HasExtension("GL_ARB_timer_query")) {
30 timer_type_ = kTimerTypeARB;
31 }
32 }
33 }
34
35 scoped_refptr<GPUTimingClient> GPUTiming::CreateGPUTimingClient() {
36 return new GPUTimingClient(this);
18 } 37 }
19 38
20 GPUTimer::~GPUTimer() { 39 GPUTimer::~GPUTimer() {
21 glDeleteQueriesARB(2, queries_); 40 glDeleteQueriesARB(2, queries_);
22 } 41 }
23 42
24 void GPUTimer::Start() { 43 void GPUTimer::Start() {
25 // GL_TIMESTAMP and GL_TIMESTAMP_EXT both have the same value. 44 // GL_TIMESTAMP and GL_TIMESTAMP_EXT both have the same value.
26 glQueryCounter(queries_[0], GL_TIMESTAMP); 45 glQueryCounter(queries_[0], GL_TIMESTAMP);
27 } 46 }
28 47
29 void GPUTimer::End() { 48 void GPUTimer::End() {
30 end_requested_ = true; 49 end_requested_ = true;
31 offset_ = gpu_timing_->CalculateTimerOffset(); 50 offset_ = gpu_timing_client_->CalculateTimerOffset();
32 glQueryCounter(queries_[1], GL_TIMESTAMP); 51 glQueryCounter(queries_[1], GL_TIMESTAMP);
33 } 52 }
34 53
35 bool GPUTimer::IsAvailable() { 54 bool GPUTimer::IsAvailable() {
36 if (!gpu_timing_->IsAvailable() || !end_requested_) { 55 if (!gpu_timing_client_->IsAvailable() || !end_requested_) {
37 return false; 56 return false;
38 } 57 }
39 GLint done = 0; 58 GLint done = 0;
40 glGetQueryObjectivARB(queries_[1], GL_QUERY_RESULT_AVAILABLE, &done); 59 glGetQueryObjectivARB(queries_[1], GL_QUERY_RESULT_AVAILABLE, &done);
41 return done != 0; 60 return done != 0;
42 } 61 }
43 62
44 void GPUTimer::GetStartEndTimestamps(int64* start, int64* end) { 63 void GPUTimer::GetStartEndTimestamps(int64* start, int64* end) {
45 DCHECK(start && end); 64 DCHECK(start && end);
46 DCHECK(IsAvailable()); 65 DCHECK(IsAvailable());
47 GLuint64 begin_stamp = 0; 66 GLuint64 begin_stamp = 0;
48 GLuint64 end_stamp = 0; 67 GLuint64 end_stamp = 0;
49 // TODO(dsinclair): It's possible for the timer to wrap during the start/end. 68 // 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 69 // We need to detect if the end is less then the start and correct for the
51 // wrapping. 70 // wrapping.
52 glGetQueryObjectui64v(queries_[0], GL_QUERY_RESULT, &begin_stamp); 71 glGetQueryObjectui64v(queries_[0], GL_QUERY_RESULT, &begin_stamp);
53 glGetQueryObjectui64v(queries_[1], GL_QUERY_RESULT, &end_stamp); 72 glGetQueryObjectui64v(queries_[1], GL_QUERY_RESULT, &end_stamp);
54 73
55 *start = (begin_stamp / base::Time::kNanosecondsPerMicrosecond) + offset_; 74 *start = (begin_stamp / base::Time::kNanosecondsPerMicrosecond) + offset_;
56 *end = (end_stamp / base::Time::kNanosecondsPerMicrosecond) + offset_; 75 *end = (end_stamp / base::Time::kNanosecondsPerMicrosecond) + offset_;
57 } 76 }
58 77
59 int64 GPUTimer::GetDeltaElapsed() { 78 int64 GPUTimer::GetDeltaElapsed() {
60 int64 start = 0; 79 int64 start = 0;
61 int64 end = 0; 80 int64 end = 0;
62 GetStartEndTimestamps(&start, &end); 81 GetStartEndTimestamps(&start, &end);
63 return end - start; 82 return end - start;
64 } 83 }
65 84
66 GPUTiming::GPUTiming() : cpu_time_for_testing_() { 85 GPUTimer::GPUTimer(GPUTimingClient* gpu_timing_client)
86 : gpu_timing_client_(gpu_timing_client) {
87 DCHECK(gpu_timing_client_);
88 memset(queries_, 0, sizeof(queries_));
89 glGenQueriesARB(2, queries_);
67 } 90 }
68 91
69 GPUTiming::~GPUTiming() { 92 GPUTimingClient::GPUTimingClient(GPUTiming* gpu_timing)
93 : gpu_timing_(gpu_timing) {
94 if (gpu_timing) {
95 timer_type_ = gpu_timing->GetTimerType();
96 }
70 } 97 }
71 98
72 bool GPUTiming::Initialize(gfx::GLContext* gl_context) { 99 scoped_ptr<GPUTimer> GPUTimingClient::CreateGPUTimer() {
73 DCHECK(gl_context); 100 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 } 101 }
88 102
89 bool GPUTiming::IsAvailable() { 103 bool GPUTimingClient::IsAvailable() {
90 return timer_type_ != kTimerTypeInvalid; 104 return timer_type_ != GPUTiming::kTimerTypeInvalid;
91 } 105 }
92 106
93 const char* GPUTiming::GetTimerTypeName() const { 107 const char* GPUTimingClient::GetTimerTypeName() const {
94 switch (timer_type_) { 108 switch (timer_type_) {
95 case kTimerTypeDisjoint: 109 case GPUTiming::kTimerTypeDisjoint:
96 return "GL_EXT_disjoint_timer_query"; 110 return "GL_EXT_disjoint_timer_query";
97 case kTimerTypeARB: 111 case GPUTiming::kTimerTypeARB:
98 return "GL_ARB_timer_query"; 112 return "GL_ARB_timer_query";
99 default: 113 default:
100 return "Unknown"; 114 return "Unknown";
101 } 115 }
102 } 116 }
103 117
104 bool GPUTiming::CheckAndResetTimerErrors() { 118 bool GPUTimingClient::CheckAndResetTimerErrors() {
105 if (timer_type_ == kTimerTypeDisjoint) { 119 if (timer_type_ == GPUTiming::kTimerTypeDisjoint) {
106 GLint disjoint_value = 0; 120 GLint disjoint_value = 0;
107 glGetIntegerv(GL_GPU_DISJOINT_EXT, &disjoint_value); 121 glGetIntegerv(GL_GPU_DISJOINT_EXT, &disjoint_value);
108 return disjoint_value != 0; 122 return disjoint_value != 0;
109 } else { 123 } else {
110 return false; 124 return false;
111 } 125 }
112 } 126 }
113 127
114 int64 GPUTiming::CalculateTimerOffset() { 128 int64 GPUTimingClient::CalculateTimerOffset() {
115 if (!offset_valid_) { 129 if (!offset_valid_) {
116 GLint64 gl_now = 0; 130 GLint64 gl_now = 0;
117 glGetInteger64v(GL_TIMESTAMP, &gl_now); 131 glGetInteger64v(GL_TIMESTAMP, &gl_now);
118 int64 now = 132 int64 now =
119 cpu_time_for_testing_.is_null() 133 cpu_time_for_testing_.is_null()
120 ? base::TimeTicks::NowFromSystemTraceTime().ToInternalValue() 134 ? base::TimeTicks::NowFromSystemTraceTime().ToInternalValue()
121 : cpu_time_for_testing_.Run(); 135 : cpu_time_for_testing_.Run();
122 offset_ = now - gl_now / base::Time::kNanosecondsPerMicrosecond; 136 offset_ = now - gl_now / base::Time::kNanosecondsPerMicrosecond;
123 offset_valid_ = timer_type_ == kTimerTypeARB; 137 offset_valid_ = timer_type_ == GPUTiming::kTimerTypeARB;
124 } 138 }
125 return offset_; 139 return offset_;
126 } 140 }
127 141
128 void GPUTiming::InvalidateTimerOffset() { 142 void GPUTimingClient::InvalidateTimerOffset() {
129 offset_valid_ = false; 143 offset_valid_ = false;
130 } 144 }
131 145
132 void GPUTiming::SetCpuTimeForTesting( 146 void GPUTimingClient::SetCpuTimeForTesting(
133 const base::Callback<int64(void)>& cpu_time) { 147 const base::Callback<int64(void)>& cpu_time) {
134 cpu_time_for_testing_ = cpu_time; 148 cpu_time_for_testing_ = cpu_time;
135 } 149 }
136 150
137 void GPUTiming::SetOffsetForTesting(int64 offset, bool cache_it) { 151 GPUTimingClient::~GPUTimingClient() {
138 offset_ = offset;
139 offset_valid_ = cache_it;
140 }
141
142 void GPUTiming::SetTimerTypeForTesting(TimerType type) {
143 timer_type_ = type;
144 } 152 }
145 153
146 } // namespace gpu 154 } // namespace gpu
OLDNEW
« ui/gl/gpu_timing.h ('K') | « ui/gl/gpu_timing.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698