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

Side by Side Diff: cc/output/output_surface.cc

Issue 221833009: cc: Move scheduling logic out of OutputSurface (Closed) Base URL: http://git.chromium.org/chromium/src.git@swapAck2Sched11
Patch Set: rebase; fix tests Created 6 years, 8 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
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2013 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 "cc/output/output_surface.h" 5 #include "cc/output/output_surface.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <set> 8 #include <set>
9 #include <string> 9 #include <string>
10 #include <vector> 10 #include <vector>
(...skipping 26 matching lines...) Expand all
37 namespace { 37 namespace {
38 38
39 const size_t kGpuLatencyHistorySize = 60; 39 const size_t kGpuLatencyHistorySize = 60;
40 const double kGpuLatencyEstimationPercentile = 100.0; 40 const double kGpuLatencyEstimationPercentile = 100.0;
41 41
42 } 42 }
43 43
44 namespace cc { 44 namespace cc {
45 45
46 OutputSurface::OutputSurface(scoped_refptr<ContextProvider> context_provider) 46 OutputSurface::OutputSurface(scoped_refptr<ContextProvider> context_provider)
47 : context_provider_(context_provider), 47 : client_(NULL),
48 is_lost_(false),
49 context_provider_(context_provider),
48 device_scale_factor_(-1), 50 device_scale_factor_(-1),
49 begin_frame_interval_(BeginFrameArgs::DefaultInterval()),
50 throttle_frame_production_(true),
51 needs_begin_frame_(false),
52 client_ready_for_begin_frame_(true),
53 client_(NULL),
54 is_lost_(false),
55 check_for_retroactive_begin_frame_pending_(false),
56 external_stencil_test_enabled_(false), 51 external_stencil_test_enabled_(false),
57 weak_ptr_factory_(this), 52 weak_ptr_factory_(this),
58 gpu_latency_history_(kGpuLatencyHistorySize) {} 53 gpu_latency_history_(kGpuLatencyHistorySize) {}
59 54
60 OutputSurface::OutputSurface(scoped_ptr<SoftwareOutputDevice> software_device) 55 OutputSurface::OutputSurface(scoped_ptr<SoftwareOutputDevice> software_device)
61 : software_device_(software_device.Pass()), 56 : client_(NULL),
57 is_lost_(false),
58 software_device_(software_device.Pass()),
62 device_scale_factor_(-1), 59 device_scale_factor_(-1),
63 begin_frame_interval_(BeginFrameArgs::DefaultInterval()),
64 throttle_frame_production_(true),
65 needs_begin_frame_(false),
66 client_ready_for_begin_frame_(true),
67 client_(NULL),
68 is_lost_(false),
69 check_for_retroactive_begin_frame_pending_(false),
70 external_stencil_test_enabled_(false), 60 external_stencil_test_enabled_(false),
71 weak_ptr_factory_(this), 61 weak_ptr_factory_(this),
72 gpu_latency_history_(kGpuLatencyHistorySize) {} 62 gpu_latency_history_(kGpuLatencyHistorySize) {}
73 63
74 OutputSurface::OutputSurface(scoped_refptr<ContextProvider> context_provider, 64 OutputSurface::OutputSurface(scoped_refptr<ContextProvider> context_provider,
75 scoped_ptr<SoftwareOutputDevice> software_device) 65 scoped_ptr<SoftwareOutputDevice> software_device)
76 : context_provider_(context_provider), 66 : client_(NULL),
67 is_lost_(false),
68 context_provider_(context_provider),
77 software_device_(software_device.Pass()), 69 software_device_(software_device.Pass()),
78 device_scale_factor_(-1), 70 device_scale_factor_(-1),
79 begin_frame_interval_(BeginFrameArgs::DefaultInterval()),
80 throttle_frame_production_(true),
81 needs_begin_frame_(false),
82 client_ready_for_begin_frame_(true),
83 client_(NULL),
84 is_lost_(false),
85 check_for_retroactive_begin_frame_pending_(false),
86 external_stencil_test_enabled_(false), 71 external_stencil_test_enabled_(false),
87 weak_ptr_factory_(this), 72 weak_ptr_factory_(this),
88 gpu_latency_history_(kGpuLatencyHistorySize) {} 73 gpu_latency_history_(kGpuLatencyHistorySize) {}
89 74
90 void OutputSurface::SetThrottleFrameProduction(bool enable) {
91 DCHECK(!frame_rate_controller_);
92 throttle_frame_production_ = enable;
93 }
94
95 void OutputSurface::InitializeBeginFrameEmulation(
96 base::SingleThreadTaskRunner* task_runner,
97 base::TimeDelta interval) {
98 DCHECK(throttle_frame_production_);
99 scoped_refptr<DelayBasedTimeSource> time_source;
100 if (gfx::FrameTime::TimestampsAreHighRes())
101 time_source = DelayBasedTimeSourceHighRes::Create(interval, task_runner);
102 else
103 time_source = DelayBasedTimeSource::Create(interval, task_runner);
104 frame_rate_controller_.reset(new FrameRateController(time_source));
105
106 frame_rate_controller_->SetClient(this);
107 frame_rate_controller_->SetDeadlineAdjustment(
108 capabilities_.adjust_deadline_for_parent ?
109 BeginFrameArgs::DefaultDeadlineAdjustment() : base::TimeDelta());
110 }
111
112 void OutputSurface::CommitVSyncParameters(base::TimeTicks timebase, 75 void OutputSurface::CommitVSyncParameters(base::TimeTicks timebase,
113 base::TimeDelta interval) { 76 base::TimeDelta interval) {
114 TRACE_EVENT2("cc", 77 TRACE_EVENT2("cc",
115 "OutputSurface::CommitVSyncParameters", 78 "OutputSurface::CommitVSyncParameters",
116 "timebase", 79 "timebase",
117 (timebase - base::TimeTicks()).InSecondsF(), 80 (timebase - base::TimeTicks()).InSecondsF(),
118 "interval", 81 "interval",
119 interval.InSecondsF()); 82 interval.InSecondsF());
120 begin_frame_interval_ = interval; 83 client_->CommitVSyncParameters(timebase, interval);
121 if (frame_rate_controller_)
122 frame_rate_controller_->SetTimebaseAndInterval(timebase, interval);
123 }
124
125 void OutputSurface::FrameRateControllerTick(const BeginFrameArgs& args) {
126 DCHECK(frame_rate_controller_);
127 BeginFrame(args);
128 }
129
130 // Forwarded to OutputSurfaceClient
131 void OutputSurface::SetNeedsRedrawRect(const gfx::Rect& damage_rect) {
132 TRACE_EVENT0("cc", "OutputSurface::SetNeedsRedrawRect");
133 client_->SetNeedsRedrawRect(damage_rect);
134 }
135
136 void OutputSurface::SetNeedsBeginFrame(bool enable) {
137 TRACE_EVENT1("cc", "OutputSurface::SetNeedsBeginFrame", "enable", enable);
138 needs_begin_frame_ = enable;
139 client_ready_for_begin_frame_ = true;
140 if (!throttle_frame_production_) {
141 if (enable) {
142 base::TimeTicks frame_time = gfx::FrameTime::Now();
143 base::TimeTicks deadline = frame_time + begin_frame_interval_;
144 skipped_begin_frame_args_ =
145 BeginFrameArgs::Create(frame_time, deadline, begin_frame_interval_);
146 }
147 } else if (frame_rate_controller_) {
148 BeginFrameArgs skipped = frame_rate_controller_->SetActive(enable);
149 if (skipped.IsValid())
150 skipped_begin_frame_args_ = skipped;
151 }
152
153 if (needs_begin_frame_)
154 PostCheckForRetroactiveBeginFrame();
155 }
156
157 void OutputSurface::BeginFrame(const BeginFrameArgs& args) {
158 TRACE_EVENT1("cc",
159 "OutputSurface::BeginFrame",
160 "client_ready_for_begin_frame_",
161 client_ready_for_begin_frame_);
162 if (!needs_begin_frame_ || !client_ready_for_begin_frame_) {
163 skipped_begin_frame_args_ = args;
164 } else {
165 client_ready_for_begin_frame_ = false;
166 client_->BeginFrame(args);
167 // args might be an alias for skipped_begin_frame_args_.
168 // Do not reset it before calling BeginFrame!
169 skipped_begin_frame_args_ = BeginFrameArgs();
170 }
171 }
172
173 base::TimeTicks OutputSurface::RetroactiveBeginFrameDeadline() {
174 // TODO(brianderson): Remove the alternative deadline once we have better
175 // deadline estimations.
176 base::TimeTicks alternative_deadline =
177 skipped_begin_frame_args_.frame_time +
178 BeginFrameArgs::DefaultRetroactiveBeginFramePeriod();
179 return std::max(skipped_begin_frame_args_.deadline, alternative_deadline);
180 }
181
182 void OutputSurface::PostCheckForRetroactiveBeginFrame() {
183 if (!skipped_begin_frame_args_.IsValid() ||
184 check_for_retroactive_begin_frame_pending_)
185 return;
186
187 base::MessageLoop::current()->PostTask(
188 FROM_HERE,
189 base::Bind(&OutputSurface::CheckForRetroactiveBeginFrame,
190 weak_ptr_factory_.GetWeakPtr()));
191 check_for_retroactive_begin_frame_pending_ = true;
192 }
193
194 void OutputSurface::CheckForRetroactiveBeginFrame() {
195 TRACE_EVENT0("cc", "OutputSurface::CheckForRetroactiveBeginFrame");
196 check_for_retroactive_begin_frame_pending_ = false;
197 if (!throttle_frame_production_ ||
198 gfx::FrameTime::Now() < RetroactiveBeginFrameDeadline())
199 BeginFrame(skipped_begin_frame_args_);
200 }
201
202 void OutputSurface::DidSwapBuffers() {
203 if (is_lost_)
204 return;
205 TRACE_EVENT0("cc", "OutputSurface::DidSwapBuffers");
206 client_->DidSwapBuffers();
207 }
208
209 void OutputSurface::OnSwapBuffersComplete() {
210 if (is_lost_)
211 return;
212 TRACE_EVENT0("cc", "OutputSurface::OnSwapBuffersComplete");
213 client_->OnSwapBuffersComplete();
214 } 84 }
215 85
216 void OutputSurface::ReclaimResources(const CompositorFrameAck* ack) { 86 void OutputSurface::ReclaimResources(const CompositorFrameAck* ack) {
217 client_->ReclaimResources(ack); 87 client_->ReclaimResources(ack);
218 } 88 }
219 89
220 void OutputSurface::DidLoseOutputSurface() { 90 void OutputSurface::DidLoseOutputSurface() {
221 TRACE_EVENT0("cc", "OutputSurface::DidLoseOutputSurface"); 91 TRACE_EVENT0("cc", "OutputSurface::DidLoseOutputSurface");
222 client_ready_for_begin_frame_ = true; 92 is_lost_ = true;
223 skipped_begin_frame_args_ = BeginFrameArgs();
224 if (frame_rate_controller_)
225 frame_rate_controller_->SetActive(false);
226 pending_gpu_latency_query_ids_.clear(); 93 pending_gpu_latency_query_ids_.clear();
227 available_gpu_latency_query_ids_.clear(); 94 available_gpu_latency_query_ids_.clear();
228 client_->DidLoseOutputSurface(); 95 client_->DidLoseOutputSurface();
229 is_lost_ = true;
230 } 96 }
231 97
232 void OutputSurface::SetExternalStencilTest(bool enabled) { 98 void OutputSurface::SetExternalStencilTest(bool enabled) {
233 external_stencil_test_enabled_ = enabled; 99 external_stencil_test_enabled_ = enabled;
234 } 100 }
235 101
236 void OutputSurface::SetExternalDrawConstraints(const gfx::Transform& transform, 102 void OutputSurface::SetExternalDrawConstraints(const gfx::Transform& transform,
237 const gfx::Rect& viewport, 103 const gfx::Rect& viewport,
238 const gfx::Rect& clip, 104 const gfx::Rect& clip,
239 bool valid_for_tile_management) { 105 bool valid_for_tile_management) {
240 client_->SetExternalDrawConstraints( 106 client_->SetExternalDrawConstraints(
241 transform, viewport, clip, valid_for_tile_management); 107 transform, viewport, clip, valid_for_tile_management);
242 } 108 }
243 109
244 OutputSurface::~OutputSurface() { 110 OutputSurface::~OutputSurface() {
245 if (frame_rate_controller_)
246 frame_rate_controller_->SetActive(false);
247 ResetContext3d(); 111 ResetContext3d();
248 } 112 }
249 113
250 bool OutputSurface::HasExternalStencilTest() const { 114 bool OutputSurface::HasExternalStencilTest() const {
251 return external_stencil_test_enabled_; 115 return external_stencil_test_enabled_;
252 } 116 }
253 117
254 bool OutputSurface::ForcedDrawToSoftwareDevice() const { return false; } 118 bool OutputSurface::ForcedDrawToSoftwareDevice() const { return false; }
255 119
256 bool OutputSurface::BindToClient(OutputSurfaceClient* client) { 120 bool OutputSurface::BindToClient(OutputSurfaceClient* client) {
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after
366 } 230 }
367 231
368 void OutputSurface::BindFramebuffer() { 232 void OutputSurface::BindFramebuffer() {
369 DCHECK(context_provider_); 233 DCHECK(context_provider_);
370 context_provider_->ContextGL()->BindFramebuffer(GL_FRAMEBUFFER, 0); 234 context_provider_->ContextGL()->BindFramebuffer(GL_FRAMEBUFFER, 0);
371 } 235 }
372 236
373 void OutputSurface::SwapBuffers(CompositorFrame* frame) { 237 void OutputSurface::SwapBuffers(CompositorFrame* frame) {
374 if (frame->software_frame_data) { 238 if (frame->software_frame_data) {
375 PostSwapBuffersComplete(); 239 PostSwapBuffersComplete();
376 DidSwapBuffers(); 240 client_->DidSwapBuffers();
377 return; 241 return;
378 } 242 }
379 243
380 DCHECK(context_provider_); 244 DCHECK(context_provider_);
381 DCHECK(frame->gl_frame_data); 245 DCHECK(frame->gl_frame_data);
382 246
383 UpdateAndMeasureGpuLatency(); 247 UpdateAndMeasureGpuLatency();
384 if (frame->gl_frame_data->sub_buffer_rect == 248 if (frame->gl_frame_data->sub_buffer_rect ==
385 gfx::Rect(frame->gl_frame_data->size)) { 249 gfx::Rect(frame->gl_frame_data->size)) {
386 context_provider_->ContextSupport()->Swap(); 250 context_provider_->ContextSupport()->Swap();
387 } else { 251 } else {
388 context_provider_->ContextSupport()->PartialSwapBuffers( 252 context_provider_->ContextSupport()->PartialSwapBuffers(
389 frame->gl_frame_data->sub_buffer_rect); 253 frame->gl_frame_data->sub_buffer_rect);
390 } 254 }
391 255
392 DidSwapBuffers(); 256 client_->DidSwapBuffers();
Sami 2014/04/08 13:46:01 Should we guard against is_lost_?
brianderson 2014/04/09 02:52:05 Good idea. I will return early if is_lost_ here an
brianderson 2014/04/10 23:45:58 Done.
393 } 257 }
394 258
395 base::TimeDelta OutputSurface::GpuLatencyEstimate() { 259 base::TimeDelta OutputSurface::GpuLatencyEstimate() {
396 if (context_provider_ && !capabilities_.adjust_deadline_for_parent) 260 if (context_provider_ && !capabilities_.adjust_deadline_for_parent)
397 return gpu_latency_history_.Percentile(kGpuLatencyEstimationPercentile); 261 return gpu_latency_history_.Percentile(kGpuLatencyEstimationPercentile);
398 else 262 else
399 return base::TimeDelta(); 263 return base::TimeDelta();
400 } 264 }
401 265
402 void OutputSurface::UpdateAndMeasureGpuLatency() { 266 void OutputSurface::UpdateAndMeasureGpuLatency() {
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
465 #endif 329 #endif
466 } 330 }
467 331
468 void OutputSurface::PostSwapBuffersComplete() { 332 void OutputSurface::PostSwapBuffersComplete() {
469 base::MessageLoop::current()->PostTask( 333 base::MessageLoop::current()->PostTask(
470 FROM_HERE, 334 FROM_HERE,
471 base::Bind(&OutputSurface::OnSwapBuffersComplete, 335 base::Bind(&OutputSurface::OnSwapBuffersComplete,
472 weak_ptr_factory_.GetWeakPtr())); 336 weak_ptr_factory_.GetWeakPtr()));
473 } 337 }
474 338
339 void OutputSurface::OnSwapBuffersComplete() {
340 if (!is_lost_)
341 client_->OnSwapBuffersComplete();
342 }
343
475 void OutputSurface::SetMemoryPolicy(const ManagedMemoryPolicy& policy) { 344 void OutputSurface::SetMemoryPolicy(const ManagedMemoryPolicy& policy) {
476 TRACE_EVENT1("cc", "OutputSurface::SetMemoryPolicy", 345 TRACE_EVENT1("cc", "OutputSurface::SetMemoryPolicy",
477 "bytes_limit_when_visible", policy.bytes_limit_when_visible); 346 "bytes_limit_when_visible", policy.bytes_limit_when_visible);
478 // Just ignore the memory manager when it says to set the limit to zero 347 // Just ignore the memory manager when it says to set the limit to zero
479 // bytes. This will happen when the memory manager thinks that the renderer 348 // bytes. This will happen when the memory manager thinks that the renderer
480 // is not visible (which the renderer knows better). 349 // is not visible (which the renderer knows better).
481 if (policy.bytes_limit_when_visible) 350 if (policy.bytes_limit_when_visible)
482 client_->SetMemoryPolicy(policy); 351 client_->SetMemoryPolicy(policy);
483 } 352 }
484 353
485 } // namespace cc 354 } // namespace cc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698