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

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

Issue 199523002: cc: Throttle swaps in Scheduler instead of OutputSurface (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: WIP: pulling FRC out of OS Created 6 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
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 28 matching lines...) Expand all
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 : context_provider_(context_provider),
48 device_scale_factor_(-1), 48 device_scale_factor_(-1),
49 max_frames_pending_(0), 49 begin_impl_frame_interval_(BeginFrameArgs::DefaultInterval()),
50 pending_swap_buffers_(0), 50 throttle_frame_production_(true),
51 needs_begin_impl_frame_(false), 51 needs_begin_impl_frame_(false),
52 client_ready_for_begin_impl_frame_(true), 52 client_ready_for_begin_impl_frame_(true),
53 client_(NULL), 53 client_(NULL),
54 is_lost_(false),
54 check_for_retroactive_begin_impl_frame_pending_(false), 55 check_for_retroactive_begin_impl_frame_pending_(false),
55 external_stencil_test_enabled_(false), 56 external_stencil_test_enabled_(false),
56 weak_ptr_factory_(this), 57 weak_ptr_factory_(this),
57 gpu_latency_history_(kGpuLatencyHistorySize) {} 58 gpu_latency_history_(kGpuLatencyHistorySize) {}
58 59
59 OutputSurface::OutputSurface(scoped_ptr<SoftwareOutputDevice> software_device) 60 OutputSurface::OutputSurface(scoped_ptr<SoftwareOutputDevice> software_device)
60 : software_device_(software_device.Pass()), 61 : software_device_(software_device.Pass()),
61 device_scale_factor_(-1), 62 device_scale_factor_(-1),
62 max_frames_pending_(0), 63 begin_impl_frame_interval_(BeginFrameArgs::DefaultInterval()),
63 pending_swap_buffers_(0), 64 throttle_frame_production_(true),
64 needs_begin_impl_frame_(false), 65 needs_begin_impl_frame_(false),
65 client_ready_for_begin_impl_frame_(true), 66 client_ready_for_begin_impl_frame_(true),
66 client_(NULL), 67 client_(NULL),
68 is_lost_(false),
67 check_for_retroactive_begin_impl_frame_pending_(false), 69 check_for_retroactive_begin_impl_frame_pending_(false),
68 external_stencil_test_enabled_(false), 70 external_stencil_test_enabled_(false),
69 weak_ptr_factory_(this), 71 weak_ptr_factory_(this),
70 gpu_latency_history_(kGpuLatencyHistorySize) {} 72 gpu_latency_history_(kGpuLatencyHistorySize) {}
71 73
72 OutputSurface::OutputSurface(scoped_refptr<ContextProvider> context_provider, 74 OutputSurface::OutputSurface(scoped_refptr<ContextProvider> context_provider,
73 scoped_ptr<SoftwareOutputDevice> software_device) 75 scoped_ptr<SoftwareOutputDevice> software_device)
74 : context_provider_(context_provider), 76 : context_provider_(context_provider),
75 software_device_(software_device.Pass()), 77 software_device_(software_device.Pass()),
76 device_scale_factor_(-1), 78 device_scale_factor_(-1),
77 max_frames_pending_(0), 79 begin_impl_frame_interval_(BeginFrameArgs::DefaultInterval()),
78 pending_swap_buffers_(0), 80 throttle_frame_production_(true),
79 needs_begin_impl_frame_(false), 81 needs_begin_impl_frame_(false),
80 client_ready_for_begin_impl_frame_(true), 82 client_ready_for_begin_impl_frame_(true),
81 client_(NULL), 83 client_(NULL),
84 is_lost_(false),
82 check_for_retroactive_begin_impl_frame_pending_(false), 85 check_for_retroactive_begin_impl_frame_pending_(false),
83 external_stencil_test_enabled_(false), 86 external_stencil_test_enabled_(false),
84 weak_ptr_factory_(this), 87 weak_ptr_factory_(this),
85 gpu_latency_history_(kGpuLatencyHistorySize) {} 88 gpu_latency_history_(kGpuLatencyHistorySize) {}
86 89
87 void OutputSurface::InitializeBeginImplFrameEmulation( 90 void OutputSurface::SetThrottleFrameProduction(bool enable) {
88 base::SingleThreadTaskRunner* task_runner, 91 throttle_frame_production_ = enable;
89 bool throttle_frame_production,
90 base::TimeDelta interval) {
91 if (throttle_frame_production) {
92 scoped_refptr<DelayBasedTimeSource> time_source;
93 if (gfx::FrameTime::TimestampsAreHighRes())
94 time_source = DelayBasedTimeSourceHighRes::Create(interval, task_runner);
95 else
96 time_source = DelayBasedTimeSource::Create(interval, task_runner);
97 frame_rate_controller_.reset(new FrameRateController(time_source));
98 } else {
99 frame_rate_controller_.reset(new FrameRateController(task_runner));
100 }
101
102 frame_rate_controller_->SetClient(this);
103 frame_rate_controller_->SetMaxSwapsPending(max_frames_pending_);
104 frame_rate_controller_->SetDeadlineAdjustment(
105 capabilities_.adjust_deadline_for_parent ?
106 BeginFrameArgs::DefaultDeadlineAdjustment() : base::TimeDelta());
107
108 // The new frame rate controller will consume the swap acks of the old
109 // frame rate controller, so we set that expectation up here.
110 for (int i = 0; i < pending_swap_buffers_; i++)
111 frame_rate_controller_->DidSwapBuffers();
112 }
113
114 void OutputSurface::SetMaxFramesPending(int max_frames_pending) {
115 if (frame_rate_controller_)
116 frame_rate_controller_->SetMaxSwapsPending(max_frames_pending);
117 max_frames_pending_ = max_frames_pending;
118 } 92 }
119 93
120 void OutputSurface::CommitVSyncParameters(base::TimeTicks timebase, 94 void OutputSurface::CommitVSyncParameters(base::TimeTicks timebase,
121 base::TimeDelta interval) { 95 base::TimeDelta interval) {
122 TRACE_EVENT2("cc", 96 TRACE_EVENT2("cc",
123 "OutputSurface::CommitVSyncParameters", 97 "OutputSurface::CommitVSyncParameters",
124 "timebase", 98 "timebase",
125 (timebase - base::TimeTicks()).InSecondsF(), 99 (timebase - base::TimeTicks()).InSecondsF(),
126 "interval", 100 "interval",
127 interval.InSecondsF()); 101 interval.InSecondsF());
128 if (frame_rate_controller_) 102 begin_impl_frame_interval_ = interval;
129 frame_rate_controller_->SetTimebaseAndInterval(timebase, interval); 103 client_->CommitVSyncParameters(timebase, interval);
130 }
131
132 void OutputSurface::FrameRateControllerTick(bool throttled,
133 const BeginFrameArgs& args) {
134 DCHECK(frame_rate_controller_);
135 if (throttled)
136 skipped_begin_impl_frame_args_ = args;
137 else
138 BeginImplFrame(args);
139 } 104 }
140 105
141 // Forwarded to OutputSurfaceClient 106 // Forwarded to OutputSurfaceClient
142 void OutputSurface::SetNeedsRedrawRect(const gfx::Rect& damage_rect) { 107 void OutputSurface::SetNeedsRedrawRect(const gfx::Rect& damage_rect) {
143 TRACE_EVENT0("cc", "OutputSurface::SetNeedsRedrawRect"); 108 TRACE_EVENT0("cc", "OutputSurface::SetNeedsRedrawRect");
144 client_->SetNeedsRedrawRect(damage_rect); 109 client_->SetNeedsRedrawRect(damage_rect);
145 } 110 }
146 111
147 void OutputSurface::SetNeedsBeginImplFrame(bool enable) { 112 void OutputSurface::SetNeedsBeginImplFrame(bool enable) {
148 TRACE_EVENT1("cc", "OutputSurface::SetNeedsBeginImplFrame", "enable", enable); 113 TRACE_EVENT1("cc", "OutputSurface::SetNeedsBeginImplFrame", "enable", enable);
149 needs_begin_impl_frame_ = enable; 114 needs_begin_impl_frame_ = enable;
150 client_ready_for_begin_impl_frame_ = true; 115 client_ready_for_begin_impl_frame_ = true;
151 if (frame_rate_controller_) { 116 if (!throttle_frame_production_) {
152 BeginFrameArgs skipped = frame_rate_controller_->SetActive(enable); 117 if (enable) {
153 if (skipped.IsValid()) 118 base::TimeTicks frame_time = gfx::FrameTime::Now();
154 skipped_begin_impl_frame_args_ = skipped; 119 base::TimeTicks deadline = frame_time + begin_impl_frame_interval_;
120 skipped_begin_impl_frame_args_ = BeginFrameArgs::Create(
121 frame_time, deadline, begin_impl_frame_interval_);
122 }
155 } 123 }
124
156 if (needs_begin_impl_frame_) 125 if (needs_begin_impl_frame_)
157 PostCheckForRetroactiveBeginImplFrame(); 126 PostCheckForRetroactiveBeginImplFrame();
158 } 127 }
159 128
160 void OutputSurface::BeginImplFrame(const BeginFrameArgs& args) { 129 void OutputSurface::BeginImplFrame(const BeginFrameArgs& args) {
161 TRACE_EVENT2("cc", "OutputSurface::BeginImplFrame", 130 TRACE_EVENT1("cc",
131 "OutputSurface::BeginImplFrame",
162 "client_ready_for_begin_impl_frame_", 132 "client_ready_for_begin_impl_frame_",
163 client_ready_for_begin_impl_frame_, 133 client_ready_for_begin_impl_frame_);
164 "pending_swap_buffers_", pending_swap_buffers_); 134 if (!needs_begin_impl_frame_ || !client_ready_for_begin_impl_frame_) {
165 if (!needs_begin_impl_frame_ || !client_ready_for_begin_impl_frame_ ||
166 (pending_swap_buffers_ >= max_frames_pending_ &&
167 max_frames_pending_ > 0)) {
168 skipped_begin_impl_frame_args_ = args; 135 skipped_begin_impl_frame_args_ = args;
169 } else { 136 } else {
170 client_ready_for_begin_impl_frame_ = false; 137 client_ready_for_begin_impl_frame_ = false;
171 client_->BeginImplFrame(args); 138 client_->BeginImplFrame(args);
172 // args might be an alias for skipped_begin_impl_frame_args_. 139 // args might be an alias for skipped_begin_impl_frame_args_.
173 // Do not reset it before calling BeginImplFrame! 140 // Do not reset it before calling BeginImplFrame!
174 skipped_begin_impl_frame_args_ = BeginFrameArgs(); 141 skipped_begin_impl_frame_args_ = BeginFrameArgs();
175 } 142 }
176 } 143 }
177 144
(...skipping 15 matching lines...) Expand all
193 base::MessageLoop::current()->PostTask( 160 base::MessageLoop::current()->PostTask(
194 FROM_HERE, 161 FROM_HERE,
195 base::Bind(&OutputSurface::CheckForRetroactiveBeginImplFrame, 162 base::Bind(&OutputSurface::CheckForRetroactiveBeginImplFrame,
196 weak_ptr_factory_.GetWeakPtr())); 163 weak_ptr_factory_.GetWeakPtr()));
197 check_for_retroactive_begin_impl_frame_pending_ = true; 164 check_for_retroactive_begin_impl_frame_pending_ = true;
198 } 165 }
199 166
200 void OutputSurface::CheckForRetroactiveBeginImplFrame() { 167 void OutputSurface::CheckForRetroactiveBeginImplFrame() {
201 TRACE_EVENT0("cc", "OutputSurface::CheckForRetroactiveBeginImplFrame"); 168 TRACE_EVENT0("cc", "OutputSurface::CheckForRetroactiveBeginImplFrame");
202 check_for_retroactive_begin_impl_frame_pending_ = false; 169 check_for_retroactive_begin_impl_frame_pending_ = false;
203 if (gfx::FrameTime::Now() < RetroactiveBeginImplFrameDeadline()) 170 if (!throttle_frame_production_ ||
171 gfx::FrameTime::Now() < RetroactiveBeginImplFrameDeadline())
204 BeginImplFrame(skipped_begin_impl_frame_args_); 172 BeginImplFrame(skipped_begin_impl_frame_args_);
205 } 173 }
206 174
207 void OutputSurface::DidSwapBuffers() { 175 void OutputSurface::DidSwapBuffers() {
208 pending_swap_buffers_++; 176 if (is_lost_)
209 TRACE_EVENT1("cc", "OutputSurface::DidSwapBuffers", 177 return;
210 "pending_swap_buffers_", pending_swap_buffers_); 178 TRACE_EVENT0("cc", "OutputSurface::DidSwapBuffers");
211 client_->DidSwapBuffers(); 179 client_->DidSwapBuffers();
212 if (frame_rate_controller_)
213 frame_rate_controller_->DidSwapBuffers();
214 PostCheckForRetroactiveBeginImplFrame();
215 } 180 }
216 181
217 void OutputSurface::OnSwapBuffersComplete() { 182 void OutputSurface::OnSwapBuffersComplete() {
218 pending_swap_buffers_--; 183 if (is_lost_)
219 TRACE_EVENT1("cc", "OutputSurface::OnSwapBuffersComplete", 184 return;
220 "pending_swap_buffers_", pending_swap_buffers_); 185 TRACE_EVENT0("cc", "OutputSurface::OnSwapBuffersComplete");
221 client_->OnSwapBuffersComplete(); 186 client_->OnSwapBuffersComplete();
222 if (frame_rate_controller_)
223 frame_rate_controller_->DidSwapBuffersComplete();
224 PostCheckForRetroactiveBeginImplFrame();
225 } 187 }
226 188
227 void OutputSurface::ReclaimResources(const CompositorFrameAck* ack) { 189 void OutputSurface::ReclaimResources(const CompositorFrameAck* ack) {
228 client_->ReclaimResources(ack); 190 client_->ReclaimResources(ack);
229 } 191 }
230 192
231 void OutputSurface::DidLoseOutputSurface() { 193 void OutputSurface::DidLoseOutputSurface() {
232 TRACE_EVENT0("cc", "OutputSurface::DidLoseOutputSurface"); 194 TRACE_EVENT0("cc", "OutputSurface::DidLoseOutputSurface");
233 client_ready_for_begin_impl_frame_ = true; 195 client_ready_for_begin_impl_frame_ = true;
234 pending_swap_buffers_ = 0;
235 skipped_begin_impl_frame_args_ = BeginFrameArgs(); 196 skipped_begin_impl_frame_args_ = BeginFrameArgs();
236 if (frame_rate_controller_)
237 frame_rate_controller_->SetActive(false);
238 pending_gpu_latency_query_ids_.clear(); 197 pending_gpu_latency_query_ids_.clear();
239 available_gpu_latency_query_ids_.clear(); 198 available_gpu_latency_query_ids_.clear();
240 client_->DidLoseOutputSurface(); 199 client_->DidLoseOutputSurface();
200 is_lost_ = true;
241 } 201 }
242 202
243 void OutputSurface::SetExternalStencilTest(bool enabled) { 203 void OutputSurface::SetExternalStencilTest(bool enabled) {
244 external_stencil_test_enabled_ = enabled; 204 external_stencil_test_enabled_ = enabled;
245 } 205 }
246 206
247 void OutputSurface::SetExternalDrawConstraints(const gfx::Transform& transform, 207 void OutputSurface::SetExternalDrawConstraints(const gfx::Transform& transform,
248 const gfx::Rect& viewport, 208 const gfx::Rect& viewport,
249 const gfx::Rect& clip, 209 const gfx::Rect& clip,
250 bool valid_for_tile_management) { 210 bool valid_for_tile_management) {
251 client_->SetExternalDrawConstraints( 211 client_->SetExternalDrawConstraints(
252 transform, viewport, clip, valid_for_tile_management); 212 transform, viewport, clip, valid_for_tile_management);
253 } 213 }
254 214
255 OutputSurface::~OutputSurface() { 215 OutputSurface::~OutputSurface() {
256 if (frame_rate_controller_)
257 frame_rate_controller_->SetActive(false);
258 ResetContext3d(); 216 ResetContext3d();
259 } 217 }
260 218
261 bool OutputSurface::HasExternalStencilTest() const { 219 bool OutputSurface::HasExternalStencilTest() const {
262 return external_stencil_test_enabled_; 220 return external_stencil_test_enabled_;
263 } 221 }
264 222
265 bool OutputSurface::ForcedDrawToSoftwareDevice() const { return false; } 223 bool OutputSurface::ForcedDrawToSoftwareDevice() const { return false; }
266 224
267 bool OutputSurface::BindToClient(OutputSurfaceClient* client) { 225 bool OutputSurface::BindToClient(OutputSurfaceClient* client) {
(...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after
486 TRACE_EVENT1("cc", "OutputSurface::SetMemoryPolicy", 444 TRACE_EVENT1("cc", "OutputSurface::SetMemoryPolicy",
487 "bytes_limit_when_visible", policy.bytes_limit_when_visible); 445 "bytes_limit_when_visible", policy.bytes_limit_when_visible);
488 // Just ignore the memory manager when it says to set the limit to zero 446 // Just ignore the memory manager when it says to set the limit to zero
489 // bytes. This will happen when the memory manager thinks that the renderer 447 // bytes. This will happen when the memory manager thinks that the renderer
490 // is not visible (which the renderer knows better). 448 // is not visible (which the renderer knows better).
491 if (policy.bytes_limit_when_visible) 449 if (policy.bytes_limit_when_visible)
492 client_->SetMemoryPolicy(policy); 450 client_->SetMemoryPolicy(policy);
493 } 451 }
494 452
495 } // namespace cc 453 } // namespace cc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698