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

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; add comment about race 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
« no previous file with comments | « cc/output/output_surface.h ('k') | cc/output/output_surface_client.h » ('j') | 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) 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 context_provider_(context_provider),
48 device_scale_factor_(-1), 49 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 check_for_retroactive_begin_frame_pending_(false),
55 external_stencil_test_enabled_(false), 50 external_stencil_test_enabled_(false),
56 weak_ptr_factory_(this), 51 weak_ptr_factory_(this),
57 gpu_latency_history_(kGpuLatencyHistorySize) {} 52 gpu_latency_history_(kGpuLatencyHistorySize) {
53 }
58 54
59 OutputSurface::OutputSurface(scoped_ptr<SoftwareOutputDevice> software_device) 55 OutputSurface::OutputSurface(scoped_ptr<SoftwareOutputDevice> software_device)
60 : software_device_(software_device.Pass()), 56 : client_(NULL),
57 software_device_(software_device.Pass()),
61 device_scale_factor_(-1), 58 device_scale_factor_(-1),
62 begin_frame_interval_(BeginFrameArgs::DefaultInterval()),
63 throttle_frame_production_(true),
64 needs_begin_frame_(false),
65 client_ready_for_begin_frame_(true),
66 client_(NULL),
67 check_for_retroactive_begin_frame_pending_(false),
68 external_stencil_test_enabled_(false), 59 external_stencil_test_enabled_(false),
69 weak_ptr_factory_(this), 60 weak_ptr_factory_(this),
70 gpu_latency_history_(kGpuLatencyHistorySize) {} 61 gpu_latency_history_(kGpuLatencyHistorySize) {
62 }
71 63
72 OutputSurface::OutputSurface(scoped_refptr<ContextProvider> context_provider, 64 OutputSurface::OutputSurface(scoped_refptr<ContextProvider> context_provider,
73 scoped_ptr<SoftwareOutputDevice> software_device) 65 scoped_ptr<SoftwareOutputDevice> software_device)
74 : context_provider_(context_provider), 66 : client_(NULL),
67 context_provider_(context_provider),
75 software_device_(software_device.Pass()), 68 software_device_(software_device.Pass()),
76 device_scale_factor_(-1), 69 device_scale_factor_(-1),
77 begin_frame_interval_(BeginFrameArgs::DefaultInterval()),
78 throttle_frame_production_(true),
79 needs_begin_frame_(false),
80 client_ready_for_begin_frame_(true),
81 client_(NULL),
82 check_for_retroactive_begin_frame_pending_(false),
83 external_stencil_test_enabled_(false), 70 external_stencil_test_enabled_(false),
84 weak_ptr_factory_(this), 71 weak_ptr_factory_(this),
85 gpu_latency_history_(kGpuLatencyHistorySize) {} 72 gpu_latency_history_(kGpuLatencyHistorySize) {
86
87 void OutputSurface::SetThrottleFrameProduction(bool enable) {
88 DCHECK(!frame_rate_controller_);
89 throttle_frame_production_ = enable;
90 }
91
92 void OutputSurface::InitializeBeginFrameEmulation(
93 base::SingleThreadTaskRunner* task_runner,
94 base::TimeDelta interval) {
95 DCHECK(throttle_frame_production_);
96 scoped_refptr<DelayBasedTimeSource> time_source;
97 if (gfx::FrameTime::TimestampsAreHighRes())
98 time_source = DelayBasedTimeSourceHighRes::Create(interval, task_runner);
99 else
100 time_source = DelayBasedTimeSource::Create(interval, task_runner);
101 frame_rate_controller_.reset(new FrameRateController(time_source));
102
103 frame_rate_controller_->SetClient(this);
104 frame_rate_controller_->SetDeadlineAdjustment(
105 capabilities_.adjust_deadline_for_parent ?
106 BeginFrameArgs::DefaultDeadlineAdjustment() : base::TimeDelta());
107 } 73 }
108 74
109 void OutputSurface::CommitVSyncParameters(base::TimeTicks timebase, 75 void OutputSurface::CommitVSyncParameters(base::TimeTicks timebase,
110 base::TimeDelta interval) { 76 base::TimeDelta interval) {
111 TRACE_EVENT2("cc", 77 TRACE_EVENT2("cc",
112 "OutputSurface::CommitVSyncParameters", 78 "OutputSurface::CommitVSyncParameters",
113 "timebase", 79 "timebase",
114 (timebase - base::TimeTicks()).InSecondsF(), 80 (timebase - base::TimeTicks()).InSecondsF(),
115 "interval", 81 "interval",
116 interval.InSecondsF()); 82 interval.InSecondsF());
117 begin_frame_interval_ = interval; 83 client_->CommitVSyncParameters(timebase, interval);
118 if (frame_rate_controller_)
119 frame_rate_controller_->SetTimebaseAndInterval(timebase, interval);
120 }
121
122 void OutputSurface::FrameRateControllerTick(const BeginFrameArgs& args) {
123 DCHECK(frame_rate_controller_);
124 BeginFrame(args);
125 } 84 }
126 85
127 // Forwarded to OutputSurfaceClient 86 // Forwarded to OutputSurfaceClient
128 void OutputSurface::SetNeedsRedrawRect(const gfx::Rect& damage_rect) { 87 void OutputSurface::SetNeedsRedrawRect(const gfx::Rect& damage_rect) {
129 TRACE_EVENT0("cc", "OutputSurface::SetNeedsRedrawRect"); 88 TRACE_EVENT0("cc", "OutputSurface::SetNeedsRedrawRect");
130 client_->SetNeedsRedrawRect(damage_rect); 89 client_->SetNeedsRedrawRect(damage_rect);
131 } 90 }
132 91
133 void OutputSurface::SetNeedsBeginFrame(bool enable) {
134 TRACE_EVENT1("cc", "OutputSurface::SetNeedsBeginFrame", "enable", enable);
135 needs_begin_frame_ = enable;
136 client_ready_for_begin_frame_ = true;
137 if (!throttle_frame_production_) {
138 if (enable) {
139 base::TimeTicks frame_time = gfx::FrameTime::Now();
140 base::TimeTicks deadline = frame_time + begin_frame_interval_;
141 skipped_begin_frame_args_ =
142 BeginFrameArgs::Create(frame_time, deadline, begin_frame_interval_);
143 }
144 } else if (frame_rate_controller_) {
145 BeginFrameArgs skipped = frame_rate_controller_->SetActive(enable);
146 if (skipped.IsValid())
147 skipped_begin_frame_args_ = skipped;
148 }
149
150 if (needs_begin_frame_)
151 PostCheckForRetroactiveBeginFrame();
152 }
153
154 void OutputSurface::BeginFrame(const BeginFrameArgs& args) {
155 TRACE_EVENT1("cc",
156 "OutputSurface::BeginFrame",
157 "client_ready_for_begin_frame_",
158 client_ready_for_begin_frame_);
159 if (!needs_begin_frame_ || !client_ready_for_begin_frame_) {
160 skipped_begin_frame_args_ = args;
161 } else {
162 client_ready_for_begin_frame_ = false;
163 client_->BeginFrame(args);
164 // args might be an alias for skipped_begin_frame_args_.
165 // Do not reset it before calling BeginFrame!
166 skipped_begin_frame_args_ = BeginFrameArgs();
167 }
168 }
169
170 base::TimeTicks OutputSurface::RetroactiveBeginFrameDeadline() {
171 // TODO(brianderson): Remove the alternative deadline once we have better
172 // deadline estimations.
173 base::TimeTicks alternative_deadline =
174 skipped_begin_frame_args_.frame_time +
175 BeginFrameArgs::DefaultRetroactiveBeginFramePeriod();
176 return std::max(skipped_begin_frame_args_.deadline, alternative_deadline);
177 }
178
179 void OutputSurface::PostCheckForRetroactiveBeginFrame() {
180 if (!skipped_begin_frame_args_.IsValid() ||
181 check_for_retroactive_begin_frame_pending_)
182 return;
183
184 base::MessageLoop::current()->PostTask(
185 FROM_HERE,
186 base::Bind(&OutputSurface::CheckForRetroactiveBeginFrame,
187 weak_ptr_factory_.GetWeakPtr()));
188 check_for_retroactive_begin_frame_pending_ = true;
189 }
190
191 void OutputSurface::CheckForRetroactiveBeginFrame() {
192 TRACE_EVENT0("cc", "OutputSurface::CheckForRetroactiveBeginFrame");
193 check_for_retroactive_begin_frame_pending_ = false;
194 if (!throttle_frame_production_ ||
195 gfx::FrameTime::Now() < RetroactiveBeginFrameDeadline())
196 BeginFrame(skipped_begin_frame_args_);
197 }
198
199 void OutputSurface::DidSwapBuffers() {
200 TRACE_EVENT0("cc", "OutputSurface::DidSwapBuffers");
201 client_->DidSwapBuffers();
202 }
203
204 void OutputSurface::OnSwapBuffersComplete() {
205 TRACE_EVENT0("cc", "OutputSurface::OnSwapBuffersComplete");
206 client_->DidSwapBuffersComplete();
207 }
208
209 void OutputSurface::ReclaimResources(const CompositorFrameAck* ack) { 92 void OutputSurface::ReclaimResources(const CompositorFrameAck* ack) {
210 client_->ReclaimResources(ack); 93 client_->ReclaimResources(ack);
211 } 94 }
212 95
213 void OutputSurface::DidLoseOutputSurface() { 96 void OutputSurface::DidLoseOutputSurface() {
214 TRACE_EVENT0("cc", "OutputSurface::DidLoseOutputSurface"); 97 TRACE_EVENT0("cc", "OutputSurface::DidLoseOutputSurface");
215 client_ready_for_begin_frame_ = true;
216 skipped_begin_frame_args_ = BeginFrameArgs();
217 if (frame_rate_controller_)
218 frame_rate_controller_->SetActive(false);
219 pending_gpu_latency_query_ids_.clear(); 98 pending_gpu_latency_query_ids_.clear();
220 available_gpu_latency_query_ids_.clear(); 99 available_gpu_latency_query_ids_.clear();
221 client_->DidLoseOutputSurface(); 100 client_->DidLoseOutputSurface();
222 } 101 }
223 102
224 void OutputSurface::SetExternalStencilTest(bool enabled) { 103 void OutputSurface::SetExternalStencilTest(bool enabled) {
225 external_stencil_test_enabled_ = enabled; 104 external_stencil_test_enabled_ = enabled;
226 } 105 }
227 106
228 void OutputSurface::SetExternalDrawConstraints(const gfx::Transform& transform, 107 void OutputSurface::SetExternalDrawConstraints(const gfx::Transform& transform,
229 const gfx::Rect& viewport, 108 const gfx::Rect& viewport,
230 const gfx::Rect& clip, 109 const gfx::Rect& clip,
231 bool valid_for_tile_management) { 110 bool valid_for_tile_management) {
232 client_->SetExternalDrawConstraints( 111 client_->SetExternalDrawConstraints(
233 transform, viewport, clip, valid_for_tile_management); 112 transform, viewport, clip, valid_for_tile_management);
234 } 113 }
235 114
236 OutputSurface::~OutputSurface() { 115 OutputSurface::~OutputSurface() {
237 if (frame_rate_controller_)
238 frame_rate_controller_->SetActive(false);
239 ResetContext3d(); 116 ResetContext3d();
240 } 117 }
241 118
242 bool OutputSurface::HasExternalStencilTest() const { 119 bool OutputSurface::HasExternalStencilTest() const {
243 return external_stencil_test_enabled_; 120 return external_stencil_test_enabled_;
244 } 121 }
245 122
246 bool OutputSurface::ForcedDrawToSoftwareDevice() const { return false; } 123 bool OutputSurface::ForcedDrawToSoftwareDevice() const { return false; }
247 124
248 bool OutputSurface::BindToClient(OutputSurfaceClient* client) { 125 bool OutputSurface::BindToClient(OutputSurfaceClient* client) {
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
357 } 234 }
358 235
359 void OutputSurface::BindFramebuffer() { 236 void OutputSurface::BindFramebuffer() {
360 DCHECK(context_provider_); 237 DCHECK(context_provider_);
361 context_provider_->ContextGL()->BindFramebuffer(GL_FRAMEBUFFER, 0); 238 context_provider_->ContextGL()->BindFramebuffer(GL_FRAMEBUFFER, 0);
362 } 239 }
363 240
364 void OutputSurface::SwapBuffers(CompositorFrame* frame) { 241 void OutputSurface::SwapBuffers(CompositorFrame* frame) {
365 if (frame->software_frame_data) { 242 if (frame->software_frame_data) {
366 PostSwapBuffersComplete(); 243 PostSwapBuffersComplete();
367 DidSwapBuffers(); 244 client_->DidSwapBuffers();
368 return; 245 return;
369 } 246 }
370 247
371 DCHECK(context_provider_); 248 DCHECK(context_provider_);
372 DCHECK(frame->gl_frame_data); 249 DCHECK(frame->gl_frame_data);
373 250
374 UpdateAndMeasureGpuLatency(); 251 UpdateAndMeasureGpuLatency();
375 if (frame->gl_frame_data->sub_buffer_rect == 252 if (frame->gl_frame_data->sub_buffer_rect ==
376 gfx::Rect(frame->gl_frame_data->size)) { 253 gfx::Rect(frame->gl_frame_data->size)) {
377 context_provider_->ContextSupport()->Swap(); 254 context_provider_->ContextSupport()->Swap();
378 } else { 255 } else {
379 context_provider_->ContextSupport()->PartialSwapBuffers( 256 context_provider_->ContextSupport()->PartialSwapBuffers(
380 frame->gl_frame_data->sub_buffer_rect); 257 frame->gl_frame_data->sub_buffer_rect);
381 } 258 }
382 259
383 DidSwapBuffers(); 260 client_->DidSwapBuffers();
384 } 261 }
385 262
386 base::TimeDelta OutputSurface::GpuLatencyEstimate() { 263 base::TimeDelta OutputSurface::GpuLatencyEstimate() {
387 if (context_provider_ && !capabilities_.adjust_deadline_for_parent) 264 if (context_provider_ && !capabilities_.adjust_deadline_for_parent)
388 return gpu_latency_history_.Percentile(kGpuLatencyEstimationPercentile); 265 return gpu_latency_history_.Percentile(kGpuLatencyEstimationPercentile);
389 else 266 else
390 return base::TimeDelta(); 267 return base::TimeDelta();
391 } 268 }
392 269
393 void OutputSurface::UpdateAndMeasureGpuLatency() { 270 void OutputSurface::UpdateAndMeasureGpuLatency() {
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
456 #endif 333 #endif
457 } 334 }
458 335
459 void OutputSurface::PostSwapBuffersComplete() { 336 void OutputSurface::PostSwapBuffersComplete() {
460 base::MessageLoop::current()->PostTask( 337 base::MessageLoop::current()->PostTask(
461 FROM_HERE, 338 FROM_HERE,
462 base::Bind(&OutputSurface::OnSwapBuffersComplete, 339 base::Bind(&OutputSurface::OnSwapBuffersComplete,
463 weak_ptr_factory_.GetWeakPtr())); 340 weak_ptr_factory_.GetWeakPtr()));
464 } 341 }
465 342
343 // We don't post tasks bound to the client directly since they might run
344 // after the OutputSurface has been destroyed.
345 void OutputSurface::OnSwapBuffersComplete() {
346 client_->DidSwapBuffersComplete();
347 }
348
466 void OutputSurface::SetMemoryPolicy(const ManagedMemoryPolicy& policy) { 349 void OutputSurface::SetMemoryPolicy(const ManagedMemoryPolicy& policy) {
467 TRACE_EVENT1("cc", "OutputSurface::SetMemoryPolicy", 350 TRACE_EVENT1("cc", "OutputSurface::SetMemoryPolicy",
468 "bytes_limit_when_visible", policy.bytes_limit_when_visible); 351 "bytes_limit_when_visible", policy.bytes_limit_when_visible);
469 // Just ignore the memory manager when it says to set the limit to zero 352 // Just ignore the memory manager when it says to set the limit to zero
470 // bytes. This will happen when the memory manager thinks that the renderer 353 // bytes. This will happen when the memory manager thinks that the renderer
471 // is not visible (which the renderer knows better). 354 // is not visible (which the renderer knows better).
472 if (policy.bytes_limit_when_visible) 355 if (policy.bytes_limit_when_visible)
473 client_->SetMemoryPolicy(policy); 356 client_->SetMemoryPolicy(policy);
474 } 357 }
475 358
476 } // namespace cc 359 } // namespace cc
OLDNEW
« no previous file with comments | « cc/output/output_surface.h ('k') | cc/output/output_surface_client.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698