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

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

Issue 22354007: cc: Add queue of BeginFrames to support long deadlines. (Closed) Base URL: http://git.chromium.org/chromium/src.git@deferredCommit
Patch Set: Created 7 years, 4 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/scheduler/frame_rate_controller.cc » ('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 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
94 : context3d_(context3d.Pass()), 94 : context3d_(context3d.Pass()),
95 has_gl_discard_backbuffer_(false), 95 has_gl_discard_backbuffer_(false),
96 has_swap_buffers_complete_callback_(false), 96 has_swap_buffers_complete_callback_(false),
97 device_scale_factor_(-1), 97 device_scale_factor_(-1),
98 weak_ptr_factory_(this), 98 weak_ptr_factory_(this),
99 max_frames_pending_(0), 99 max_frames_pending_(0),
100 pending_swap_buffers_(0), 100 pending_swap_buffers_(0),
101 needs_begin_frame_(false), 101 needs_begin_frame_(false),
102 begin_frame_pending_(false), 102 begin_frame_pending_(false),
103 client_(NULL), 103 client_(NULL),
104 consecutive_missed_deadlines_(0),
104 check_for_retroactive_begin_frame_pending_(false) { 105 check_for_retroactive_begin_frame_pending_(false) {
105 } 106 }
106 107
107 OutputSurface::OutputSurface( 108 OutputSurface::OutputSurface(
108 scoped_ptr<cc::SoftwareOutputDevice> software_device) 109 scoped_ptr<cc::SoftwareOutputDevice> software_device)
109 : software_device_(software_device.Pass()), 110 : software_device_(software_device.Pass()),
110 has_gl_discard_backbuffer_(false), 111 has_gl_discard_backbuffer_(false),
111 has_swap_buffers_complete_callback_(false), 112 has_swap_buffers_complete_callback_(false),
112 device_scale_factor_(-1), 113 device_scale_factor_(-1),
113 weak_ptr_factory_(this), 114 weak_ptr_factory_(this),
114 max_frames_pending_(0), 115 max_frames_pending_(0),
115 pending_swap_buffers_(0), 116 pending_swap_buffers_(0),
116 needs_begin_frame_(false), 117 needs_begin_frame_(false),
117 begin_frame_pending_(false), 118 begin_frame_pending_(false),
118 client_(NULL), 119 client_(NULL),
120 consecutive_missed_deadlines_(0),
119 check_for_retroactive_begin_frame_pending_(false) { 121 check_for_retroactive_begin_frame_pending_(false) {
120 } 122 }
121 123
122 OutputSurface::OutputSurface( 124 OutputSurface::OutputSurface(
123 scoped_ptr<WebKit::WebGraphicsContext3D> context3d, 125 scoped_ptr<WebKit::WebGraphicsContext3D> context3d,
124 scoped_ptr<cc::SoftwareOutputDevice> software_device) 126 scoped_ptr<cc::SoftwareOutputDevice> software_device)
125 : context3d_(context3d.Pass()), 127 : context3d_(context3d.Pass()),
126 software_device_(software_device.Pass()), 128 software_device_(software_device.Pass()),
127 has_gl_discard_backbuffer_(false), 129 has_gl_discard_backbuffer_(false),
128 has_swap_buffers_complete_callback_(false), 130 has_swap_buffers_complete_callback_(false),
129 device_scale_factor_(-1), 131 device_scale_factor_(-1),
130 weak_ptr_factory_(this), 132 weak_ptr_factory_(this),
131 max_frames_pending_(0), 133 max_frames_pending_(0),
132 pending_swap_buffers_(0), 134 pending_swap_buffers_(0),
133 needs_begin_frame_(false), 135 needs_begin_frame_(false),
134 begin_frame_pending_(false), 136 begin_frame_pending_(false),
135 client_(NULL), 137 client_(NULL),
138 consecutive_missed_deadlines_(0),
136 check_for_retroactive_begin_frame_pending_(false) { 139 check_for_retroactive_begin_frame_pending_(false) {
137 } 140 }
138 141
139 void OutputSurface::InitializeBeginFrameEmulation( 142 void OutputSurface::InitializeBeginFrameEmulation(
140 base::SingleThreadTaskRunner* task_runner, 143 base::SingleThreadTaskRunner* task_runner,
141 bool throttle_frame_production, 144 bool throttle_frame_production,
142 base::TimeDelta interval) { 145 base::TimeDelta interval) {
143 if (throttle_frame_production) { 146 if (throttle_frame_production) {
144 frame_rate_controller_.reset( 147 frame_rate_controller_.reset(
145 new FrameRateController( 148 new FrameRateController(
(...skipping 22 matching lines...) Expand all
168 171
169 void OutputSurface::OnVSyncParametersChanged(base::TimeTicks timebase, 172 void OutputSurface::OnVSyncParametersChanged(base::TimeTicks timebase,
170 base::TimeDelta interval) { 173 base::TimeDelta interval) {
171 TRACE_EVENT2("cc", "OutputSurface::OnVSyncParametersChanged", 174 TRACE_EVENT2("cc", "OutputSurface::OnVSyncParametersChanged",
172 "timebase", (timebase - base::TimeTicks()).InSecondsF(), 175 "timebase", (timebase - base::TimeTicks()).InSecondsF(),
173 "interval", interval.InSecondsF()); 176 "interval", interval.InSecondsF());
174 if (frame_rate_controller_) 177 if (frame_rate_controller_)
175 frame_rate_controller_->SetTimebaseAndInterval(timebase, interval); 178 frame_rate_controller_->SetTimebaseAndInterval(timebase, interval);
176 } 179 }
177 180
181 void OutputSurface::AddSkippedBeginFrame(const BeginFrameArgs& skipped) {
182 if (skipped.IsValid() &&
183 (skipped_begin_frame_args_.empty() ||
184 skipped.frame_time != skipped_begin_frame_args_.back().frame_time)) {
185 skipped_begin_frame_args_.push_back(skipped);
186 }
187 }
188
178 void OutputSurface::FrameRateControllerTick(bool throttled, 189 void OutputSurface::FrameRateControllerTick(bool throttled,
179 const BeginFrameArgs& args) { 190 const BeginFrameArgs& args) {
180 DCHECK(frame_rate_controller_); 191 DCHECK(frame_rate_controller_);
181 if (throttled) 192 if (throttled)
182 skipped_begin_frame_args_ = args; 193 AddSkippedBeginFrame(args);
183 else 194 else
184 BeginFrame(args); 195 BeginFrame(args);
185 } 196 }
186 197
187 // Forwarded to OutputSurfaceClient 198 // Forwarded to OutputSurfaceClient
188 void OutputSurface::SetNeedsRedrawRect(gfx::Rect damage_rect) { 199 void OutputSurface::SetNeedsRedrawRect(gfx::Rect damage_rect) {
189 TRACE_EVENT0("cc", "OutputSurface::SetNeedsRedrawRect"); 200 TRACE_EVENT0("cc", "OutputSurface::SetNeedsRedrawRect");
190 client_->SetNeedsRedrawRect(damage_rect); 201 client_->SetNeedsRedrawRect(damage_rect);
191 } 202 }
192 203
193 void OutputSurface::SetNeedsBeginFrame(bool enable) { 204 void OutputSurface::SetNeedsBeginFrame(bool enable) {
194 TRACE_EVENT1("cc", "OutputSurface::SetNeedsBeginFrame", "enable", enable); 205 TRACE_EVENT1("cc", "OutputSurface::SetNeedsBeginFrame", "enable", enable);
195 needs_begin_frame_ = enable; 206 needs_begin_frame_ = enable;
196 begin_frame_pending_ = false; 207 begin_frame_pending_ = false;
197 if (frame_rate_controller_) { 208 if (frame_rate_controller_) {
198 BeginFrameArgs skipped = frame_rate_controller_->SetActive(enable); 209 BeginFrameArgs skipped = frame_rate_controller_->SetActive(enable);
199 if (skipped.IsValid()) 210 AddSkippedBeginFrame(skipped);
200 skipped_begin_frame_args_ = skipped;
201 } 211 }
202 if (needs_begin_frame_) 212 if (needs_begin_frame_)
203 PostCheckForRetroactiveBeginFrame(); 213 PostCheckForRetroactiveBeginFrame();
204 } 214 }
205 215
206 void OutputSurface::BeginFrame(const BeginFrameArgs& args) { 216 void OutputSurface::BeginFrame(const BeginFrameArgs& args) {
207 TRACE_EVENT2("cc", "OutputSurface::BeginFrame", 217 TRACE_EVENT2("cc", "OutputSurface::BeginFrame",
208 "begin_frame_pending_", begin_frame_pending_, 218 "begin_frame_pending_", begin_frame_pending_,
209 "pending_swap_buffers_", pending_swap_buffers_); 219 "pending_swap_buffers_", pending_swap_buffers_);
210 if (!needs_begin_frame_ || begin_frame_pending_ || 220 if (!needs_begin_frame_ || begin_frame_pending_ ||
211 (pending_swap_buffers_ >= max_frames_pending_ && 221 (pending_swap_buffers_ >= max_frames_pending_ &&
212 max_frames_pending_ > 0)) { 222 max_frames_pending_ > 0)) {
213 skipped_begin_frame_args_ = args; 223 AddSkippedBeginFrame(args);
214 } else { 224 } else {
215 begin_frame_pending_ = true; 225 begin_frame_pending_ = true;
226 consecutive_missed_deadlines_ = 0;
216 client_->BeginFrame(args); 227 client_->BeginFrame(args);
217 // args might be an alias for skipped_begin_frame_args_.
218 // Do not reset it before calling BeginFrame!
219 skipped_begin_frame_args_ = BeginFrameArgs();
220 } 228 }
221 } 229 }
222 230
223 base::TimeTicks OutputSurface::RetroactiveBeginFrameDeadline() { 231 base::TimeTicks OutputSurface::RetroactiveBeginFrameDeadline() {
232 if (consecutive_missed_deadlines_) {
Sami 2013/08/13 16:44:08 I think the interaction between CheckForRetroactiv
233 return skipped_begin_frame_args_.front().frame_time +
234 skipped_begin_frame_args_.front().interval;
235 }
236
224 // TODO(brianderson): Remove the alternative deadline once we have better 237 // TODO(brianderson): Remove the alternative deadline once we have better
225 // deadline estimations. 238 // deadline estimations.
226 base::TimeTicks alternative_deadline = 239 base::TimeTicks alternative_deadline =
227 skipped_begin_frame_args_.frame_time + 240 skipped_begin_frame_args_.front().frame_time +
228 BeginFrameArgs::DefaultRetroactiveBeginFramePeriod(); 241 BeginFrameArgs::DefaultRetroactiveBeginFramePeriod();
229 return std::max(skipped_begin_frame_args_.deadline, alternative_deadline); 242 return std::max(skipped_begin_frame_args_.front().deadline,
243 alternative_deadline);
230 } 244 }
231 245
232 void OutputSurface::PostCheckForRetroactiveBeginFrame() { 246 void OutputSurface::PostCheckForRetroactiveBeginFrame() {
233 if (!skipped_begin_frame_args_.IsValid() || 247 if (skipped_begin_frame_args_.empty() ||
234 check_for_retroactive_begin_frame_pending_) 248 check_for_retroactive_begin_frame_pending_)
235 return; 249 return;
236 250
237 base::MessageLoop::current()->PostTask( 251 base::MessageLoop::current()->PostTask(
238 FROM_HERE, 252 FROM_HERE,
239 base::Bind(&OutputSurface::CheckForRetroactiveBeginFrame, 253 base::Bind(&OutputSurface::CheckForRetroactiveBeginFrame,
240 weak_ptr_factory_.GetWeakPtr())); 254 weak_ptr_factory_.GetWeakPtr()));
241 check_for_retroactive_begin_frame_pending_ = true; 255 check_for_retroactive_begin_frame_pending_ = true;
242 } 256 }
243 257
244 void OutputSurface::CheckForRetroactiveBeginFrame() { 258 void OutputSurface::CheckForRetroactiveBeginFrame() {
259 check_for_retroactive_begin_frame_pending_ = false;
260 if (skipped_begin_frame_args_.empty())
261 return;
262
245 TRACE_EVENT0("cc", "OutputSurface::CheckForRetroactiveBeginFrame"); 263 TRACE_EVENT0("cc", "OutputSurface::CheckForRetroactiveBeginFrame");
246 check_for_retroactive_begin_frame_pending_ = false; 264 base::TimeTicks now = base::TimeTicks::Now();
247 if (base::TimeTicks::Now() < RetroactiveBeginFrameDeadline()) 265 while (skipped_begin_frame_args_.size() > 1 &&
248 BeginFrame(skipped_begin_frame_args_); 266 now > skipped_begin_frame_args_.front().deadline) {
267 skipped_begin_frame_args_.pop_front();
268 consecutive_missed_deadlines_++;
269 }
270
271 if (now < RetroactiveBeginFrameDeadline())
272 BeginFrame(skipped_begin_frame_args_.front());
273 else
274 consecutive_missed_deadlines_++;
275
276 skipped_begin_frame_args_.pop_front();
249 } 277 }
250 278
251 void OutputSurface::DidSwapBuffers() { 279 void OutputSurface::DidSwapBuffers() {
252 begin_frame_pending_ = false; 280 begin_frame_pending_ = false;
253 pending_swap_buffers_++; 281 pending_swap_buffers_++;
254 TRACE_EVENT1("cc", "OutputSurface::DidSwapBuffers", 282 TRACE_EVENT1("cc", "OutputSurface::DidSwapBuffers",
255 "pending_swap_buffers_", pending_swap_buffers_); 283 "pending_swap_buffers_", pending_swap_buffers_);
256 if (frame_rate_controller_) 284 if (frame_rate_controller_)
257 frame_rate_controller_->DidSwapBuffers(); 285 frame_rate_controller_->DidSwapBuffers();
258 PostCheckForRetroactiveBeginFrame(); 286 PostCheckForRetroactiveBeginFrame();
(...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after
452 "discard_backbuffer", discard_backbuffer); 480 "discard_backbuffer", discard_backbuffer);
453 // Just ignore the memory manager when it says to set the limit to zero 481 // Just ignore the memory manager when it says to set the limit to zero
454 // bytes. This will happen when the memory manager thinks that the renderer 482 // bytes. This will happen when the memory manager thinks that the renderer
455 // is not visible (which the renderer knows better). 483 // is not visible (which the renderer knows better).
456 if (policy.bytes_limit_when_visible) 484 if (policy.bytes_limit_when_visible)
457 client_->SetMemoryPolicy(policy); 485 client_->SetMemoryPolicy(policy);
458 client_->SetDiscardBackBufferWhenNotVisible(discard_backbuffer); 486 client_->SetDiscardBackBufferWhenNotVisible(discard_backbuffer);
459 } 487 }
460 488
461 } // namespace cc 489 } // namespace cc
OLDNEW
« no previous file with comments | « cc/output/output_surface.h ('k') | cc/scheduler/frame_rate_controller.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698