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

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

Powered by Google App Engine
This is Rietveld 408576698