OLD | NEW |
---|---|
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 "gpu/command_buffer/service/gpu_timing.h" |
6 | 6 |
7 #include "base/time/time.h" | 7 #include "base/time/time.h" |
8 #include "ui/gl/gl_context.h" | 8 #include "ui/gl/gl_context.h" |
9 #include "ui/gl/gl_version_info.h" | 9 #include "ui/gl/gl_version_info.h" |
10 | 10 |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
55 *end = (end_stamp / base::Time::kNanosecondsPerMicrosecond) + offset_; | 55 *end = (end_stamp / base::Time::kNanosecondsPerMicrosecond) + offset_; |
56 } | 56 } |
57 | 57 |
58 int64 GPUTimer::GetDeltaElapsed() { | 58 int64 GPUTimer::GetDeltaElapsed() { |
59 int64 start = 0; | 59 int64 start = 0; |
60 int64 end = 0; | 60 int64 end = 0; |
61 GetStartEndTimestamps(&start, &end); | 61 GetStartEndTimestamps(&start, &end); |
62 return end - start; | 62 return end - start; |
63 } | 63 } |
64 | 64 |
65 DisjointContext::DisjointContext(GPUTiming* gpu_timing, bool disjoint_value) | |
66 : gpu_timing_(gpu_timing), | |
Daniele Castagna
2015/02/19 18:15:32
Can gpu_timing be null?
I'd add a DCHECK.
David Yen
2015/02/19 19:00:47
Done.
| |
67 disjoint_value_(disjoint_value) { | |
68 } | |
69 | |
70 bool DisjointContext::CheckAndResetTimerErrors() { | |
71 if (gpu_timing_) { | |
Daniele Castagna
2015/02/20 01:38:18
Should we make sure that gpu_timing_ is set here?
| |
72 gpu_timing_->UpdateDisjointContexts(); | |
73 } | |
74 bool previous_disjoint_value = disjoint_value_; | |
75 disjoint_value_ = false; | |
76 return previous_disjoint_value; | |
77 } | |
78 | |
79 void DisjointContext::ResetParentGPUTiming() { | |
80 gpu_timing_ = NULL; | |
81 } | |
82 | |
83 void DisjointContext::SetDisjoint() { | |
84 disjoint_value_ = true; | |
85 } | |
86 | |
87 DisjointContext::~DisjointContext() { | |
88 if (gpu_timing_) { | |
89 gpu_timing_->RemoveDisjointContext(this); | |
90 } | |
91 } | |
92 | |
65 GPUTiming::GPUTiming() : cpu_time_for_testing_() { | 93 GPUTiming::GPUTiming() : cpu_time_for_testing_() { |
66 } | 94 } |
67 | 95 |
68 GPUTiming::~GPUTiming() { | 96 GPUTiming::~GPUTiming() { |
97 // Notify any disjoint contexts that the parent no longer exists. | |
98 for (DisjointContext* context_iter : disjoint_contexts_) { | |
Daniele Castagna
2015/02/19 18:15:32
Do we really need to handle the case where GPUTimi
David Yen
2015/02/19 19:00:47
Unfortunately I think this is necessary because GP
Daniele Castagna
2015/02/19 20:55:52
Isn't the lifetime of those objects completely con
David Yen
2015/02/19 22:48:03
I've added a test for this.
I'm not referring to
Daniele Castagna
2015/02/20 01:38:18
Sorry if I insist on this, but I still stand with
David Yen
2015/02/20 02:02:57
We are going to use those objects in that way in g
| |
99 context_iter->ResetParentGPUTiming(); | |
100 } | |
69 } | 101 } |
70 | 102 |
71 bool GPUTiming::Initialize(gfx::GLContext* gl_context) { | 103 bool GPUTiming::Initialize(gfx::GLContext* gl_context) { |
72 DCHECK(gl_context); | 104 DCHECK(gl_context); |
73 DCHECK_EQ(kTimerTypeInvalid, timer_type_); | 105 DCHECK_EQ(kTimerTypeInvalid, timer_type_); |
74 | 106 |
75 const gfx::GLVersionInfo* version_info = gl_context->GetVersionInfo(); | 107 const gfx::GLVersionInfo* version_info = gl_context->GetVersionInfo(); |
76 DCHECK(version_info); | 108 DCHECK(version_info); |
77 if (version_info->is_es3 && // glGetInteger64v is supported under ES3. | 109 if (version_info->is_es3 && // glGetInteger64v is supported under ES3. |
78 gfx::g_driver_gl.ext.b_GL_EXT_disjoint_timer_query) { | 110 gfx::g_driver_gl.ext.b_GL_EXT_disjoint_timer_query) { |
79 timer_type_ = kTimerTypeDisjoint; | 111 timer_type_ = kTimerTypeDisjoint; |
80 return true; | 112 return true; |
81 } else if (gfx::g_driver_gl.ext.b_GL_ARB_timer_query) { | 113 } else if (gfx::g_driver_gl.ext.b_GL_ARB_timer_query) { |
82 timer_type_ = kTimerTypeARB; | 114 timer_type_ = kTimerTypeARB; |
83 return true; | 115 return true; |
84 } | 116 } |
85 return false; | 117 return false; |
86 } | 118 } |
87 | 119 |
88 bool GPUTiming::IsAvailable() { | 120 bool GPUTiming::IsAvailable() { |
89 return timer_type_ != kTimerTypeInvalid; | 121 return timer_type_ != kTimerTypeInvalid; |
90 } | 122 } |
91 | 123 |
124 scoped_refptr<DisjointContext> GPUTiming::CreateDisjointContext() { | |
125 disjoint_contexts_.push_back(new DisjointContext(this, disjoint_occurred_)); | |
126 return disjoint_contexts_.back(); | |
127 } | |
128 | |
92 const char* GPUTiming::GetTimerTypeName() const { | 129 const char* GPUTiming::GetTimerTypeName() const { |
93 switch (timer_type_) { | 130 switch (timer_type_) { |
94 case kTimerTypeDisjoint: | 131 case kTimerTypeDisjoint: |
95 return "GL_EXT_disjoint_timer_query"; | 132 return "GL_EXT_disjoint_timer_query"; |
96 case kTimerTypeARB: | 133 case kTimerTypeARB: |
97 return "GL_ARB_timer_query"; | 134 return "GL_ARB_timer_query"; |
98 default: | 135 default: |
99 return "Unknown"; | 136 return "Unknown"; |
100 } | 137 } |
101 } | 138 } |
102 | 139 |
103 bool GPUTiming::CheckAndResetTimerErrors() { | |
104 if (timer_type_ == kTimerTypeDisjoint) { | |
105 GLint disjoint_value = 0; | |
106 glGetIntegerv(GL_GPU_DISJOINT_EXT, &disjoint_value); | |
107 return disjoint_value != 0; | |
108 } else { | |
109 return false; | |
110 } | |
111 } | |
112 | |
113 int64 GPUTiming::CalculateTimerOffset() { | 140 int64 GPUTiming::CalculateTimerOffset() { |
114 if (!offset_valid_) { | 141 if (!offset_valid_) { |
115 GLint64 gl_now = 0; | 142 GLint64 gl_now = 0; |
116 glGetInteger64v(GL_TIMESTAMP, &gl_now); | 143 glGetInteger64v(GL_TIMESTAMP, &gl_now); |
117 int64 now = | 144 int64 now = |
118 cpu_time_for_testing_.is_null() | 145 cpu_time_for_testing_.is_null() |
119 ? base::TimeTicks::NowFromSystemTraceTime().ToInternalValue() | 146 ? base::TimeTicks::NowFromSystemTraceTime().ToInternalValue() |
120 : cpu_time_for_testing_.Run(); | 147 : cpu_time_for_testing_.Run(); |
121 offset_ = now - gl_now / base::Time::kNanosecondsPerMicrosecond; | 148 offset_ = now - gl_now / base::Time::kNanosecondsPerMicrosecond; |
122 offset_valid_ = timer_type_ == kTimerTypeARB; | 149 offset_valid_ = timer_type_ == kTimerTypeARB; |
(...skipping 12 matching lines...) Expand all Loading... | |
135 | 162 |
136 void GPUTiming::SetOffsetForTesting(int64 offset, bool cache_it) { | 163 void GPUTiming::SetOffsetForTesting(int64 offset, bool cache_it) { |
137 offset_ = offset; | 164 offset_ = offset; |
138 offset_valid_ = cache_it; | 165 offset_valid_ = cache_it; |
139 } | 166 } |
140 | 167 |
141 void GPUTiming::SetTimerTypeForTesting(TimerType type) { | 168 void GPUTiming::SetTimerTypeForTesting(TimerType type) { |
142 timer_type_ = type; | 169 timer_type_ = type; |
143 } | 170 } |
144 | 171 |
172 void GPUTiming::UpdateDisjointContexts() { | |
173 if (timer_type_ == kTimerTypeDisjoint) { | |
174 GLint disjoint_value = 0; | |
175 glGetIntegerv(GL_GPU_DISJOINT_EXT, &disjoint_value); | |
176 if (disjoint_value != 0) { | |
Daniele Castagna
2015/02/19 18:15:32
I personally like being explicit with != 0, but in
David Yen
2015/02/19 19:00:47
I just moved this code from the previous version l
Daniele Castagna
2015/02/19 20:55:53
It was just FYI, I didn't necessarily expect any a
| |
177 disjoint_occurred_ = true; | |
178 for (DisjointContext* context_iter : disjoint_contexts_) { | |
Daniele Castagna
2015/02/19 18:15:32
nit: "context_iter" is not an iterator, I'd rename
David Yen
2015/02/19 19:00:47
Done.
| |
179 context_iter->SetDisjoint(); | |
180 } | |
181 } | |
182 } | |
183 } | |
184 | |
185 void GPUTiming::RemoveDisjointContext(DisjointContext* context) { | |
186 bool item_found = false; | |
Daniele Castagna
2015/02/19 18:15:32
Assuming we can use algorithms from stl in Chromiu
David Yen
2015/02/19 19:00:47
I was trying to avoid shifting memory because this
Daniele Castagna
2015/02/19 20:55:53
If you want to avoid shifting a few pointers, what
David Yen
2015/02/19 22:48:03
Done.
| |
187 auto last_item = disjoint_contexts_.end() - 1; | |
188 for (auto context_iter = disjoint_contexts_.begin(); | |
189 context_iter != disjoint_contexts_.end(); | |
190 ++context_iter) { | |
191 if (*context_iter == context) { | |
192 item_found = true; | |
193 if (context_iter != last_item) { | |
194 std::iter_swap(context_iter, last_item); | |
195 } | |
196 } | |
197 } | |
198 DCHECK(item_found); | |
199 disjoint_contexts_.resize(disjoint_contexts_.size()-1); | |
200 } | |
201 | |
145 } // namespace gpu | 202 } // namespace gpu |
OLD | NEW |