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

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: 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
90 void OutputSurface::SetThrottleFrameProduction(bool enable) {
91 DCHECK(!frame_rate_controller_);
92 throttle_frame_production_ = enable;
93 }
94
87 void OutputSurface::InitializeBeginImplFrameEmulation( 95 void OutputSurface::InitializeBeginImplFrameEmulation(
88 base::SingleThreadTaskRunner* task_runner, 96 base::SingleThreadTaskRunner* task_runner,
89 bool throttle_frame_production,
90 base::TimeDelta interval) { 97 base::TimeDelta interval) {
91 if (throttle_frame_production) { 98 DCHECK(throttle_frame_production_);
92 scoped_refptr<DelayBasedTimeSource> time_source; 99 scoped_refptr<DelayBasedTimeSource> time_source;
93 if (gfx::FrameTime::TimestampsAreHighRes()) 100 if (gfx::FrameTime::TimestampsAreHighRes())
94 time_source = DelayBasedTimeSourceHighRes::Create(interval, task_runner); 101 time_source = DelayBasedTimeSourceHighRes::Create(interval, task_runner);
95 else 102 else
96 time_source = DelayBasedTimeSource::Create(interval, task_runner); 103 time_source = DelayBasedTimeSource::Create(interval, task_runner);
97 frame_rate_controller_.reset(new FrameRateController(time_source)); 104 frame_rate_controller_.reset(new FrameRateController(time_source));
98 } else {
99 frame_rate_controller_.reset(new FrameRateController(task_runner));
100 }
101 105
102 frame_rate_controller_->SetClient(this); 106 frame_rate_controller_->SetClient(this);
103 frame_rate_controller_->SetMaxSwapsPending(max_frames_pending_);
104 frame_rate_controller_->SetDeadlineAdjustment( 107 frame_rate_controller_->SetDeadlineAdjustment(
105 capabilities_.adjust_deadline_for_parent ? 108 capabilities_.adjust_deadline_for_parent ?
106 BeginFrameArgs::DefaultDeadlineAdjustment() : base::TimeDelta()); 109 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 } 110 }
119 111
120 void OutputSurface::CommitVSyncParameters(base::TimeTicks timebase, 112 void OutputSurface::CommitVSyncParameters(base::TimeTicks timebase,
121 base::TimeDelta interval) { 113 base::TimeDelta interval) {
122 TRACE_EVENT2("cc", 114 TRACE_EVENT2("cc",
123 "OutputSurface::CommitVSyncParameters", 115 "OutputSurface::CommitVSyncParameters",
124 "timebase", 116 "timebase",
125 (timebase - base::TimeTicks()).InSecondsF(), 117 (timebase - base::TimeTicks()).InSecondsF(),
126 "interval", 118 "interval",
127 interval.InSecondsF()); 119 interval.InSecondsF());
120 begin_impl_frame_interval_ = interval;
128 if (frame_rate_controller_) 121 if (frame_rate_controller_)
129 frame_rate_controller_->SetTimebaseAndInterval(timebase, interval); 122 frame_rate_controller_->SetTimebaseAndInterval(timebase, interval);
130 } 123 }
131 124
132 void OutputSurface::FrameRateControllerTick(bool throttled, 125 void OutputSurface::FrameRateControllerTick(const BeginFrameArgs& args) {
133 const BeginFrameArgs& args) {
134 DCHECK(frame_rate_controller_); 126 DCHECK(frame_rate_controller_);
135 if (throttled) 127 BeginImplFrame(args);
136 skipped_begin_impl_frame_args_ = args;
137 else
138 BeginImplFrame(args);
139 } 128 }
140 129
141 // Forwarded to OutputSurfaceClient 130 // Forwarded to OutputSurfaceClient
142 void OutputSurface::SetNeedsRedrawRect(const gfx::Rect& damage_rect) { 131 void OutputSurface::SetNeedsRedrawRect(const gfx::Rect& damage_rect) {
143 TRACE_EVENT0("cc", "OutputSurface::SetNeedsRedrawRect"); 132 TRACE_EVENT0("cc", "OutputSurface::SetNeedsRedrawRect");
144 client_->SetNeedsRedrawRect(damage_rect); 133 client_->SetNeedsRedrawRect(damage_rect);
145 } 134 }
146 135
147 void OutputSurface::SetNeedsBeginImplFrame(bool enable) { 136 void OutputSurface::SetNeedsBeginImplFrame(bool enable) {
148 TRACE_EVENT1("cc", "OutputSurface::SetNeedsBeginImplFrame", "enable", enable); 137 TRACE_EVENT1("cc", "OutputSurface::SetNeedsBeginImplFrame", "enable", enable);
149 needs_begin_impl_frame_ = enable; 138 needs_begin_impl_frame_ = enable;
150 client_ready_for_begin_impl_frame_ = true; 139 client_ready_for_begin_impl_frame_ = true;
151 if (frame_rate_controller_) { 140 if (!throttle_frame_production_) {
141 if (enable) {
142 base::TimeTicks frame_time = gfx::FrameTime::Now();
143 base::TimeTicks deadline = frame_time + begin_impl_frame_interval_;
144 skipped_begin_impl_frame_args_ = BeginFrameArgs::Create(
145 frame_time, deadline, begin_impl_frame_interval_);
146 }
147 } else if (frame_rate_controller_) {
152 BeginFrameArgs skipped = frame_rate_controller_->SetActive(enable); 148 BeginFrameArgs skipped = frame_rate_controller_->SetActive(enable);
153 if (skipped.IsValid()) 149 if (skipped.IsValid())
154 skipped_begin_impl_frame_args_ = skipped; 150 skipped_begin_impl_frame_args_ = skipped;
155 } 151 }
152
156 if (needs_begin_impl_frame_) 153 if (needs_begin_impl_frame_)
157 PostCheckForRetroactiveBeginImplFrame(); 154 PostCheckForRetroactiveBeginImplFrame();
158 } 155 }
159 156
160 void OutputSurface::BeginImplFrame(const BeginFrameArgs& args) { 157 void OutputSurface::BeginImplFrame(const BeginFrameArgs& args) {
161 TRACE_EVENT2("cc", "OutputSurface::BeginImplFrame", 158 TRACE_EVENT1("cc",
159 "OutputSurface::BeginImplFrame",
162 "client_ready_for_begin_impl_frame_", 160 "client_ready_for_begin_impl_frame_",
163 client_ready_for_begin_impl_frame_, 161 client_ready_for_begin_impl_frame_);
164 "pending_swap_buffers_", pending_swap_buffers_); 162 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; 163 skipped_begin_impl_frame_args_ = args;
169 } else { 164 } else {
170 client_ready_for_begin_impl_frame_ = false; 165 client_ready_for_begin_impl_frame_ = false;
171 client_->BeginImplFrame(args); 166 client_->BeginImplFrame(args);
172 // args might be an alias for skipped_begin_impl_frame_args_. 167 // args might be an alias for skipped_begin_impl_frame_args_.
173 // Do not reset it before calling BeginImplFrame! 168 // Do not reset it before calling BeginImplFrame!
174 skipped_begin_impl_frame_args_ = BeginFrameArgs(); 169 skipped_begin_impl_frame_args_ = BeginFrameArgs();
175 } 170 }
176 } 171 }
177 172
(...skipping 15 matching lines...) Expand all
193 base::MessageLoop::current()->PostTask( 188 base::MessageLoop::current()->PostTask(
194 FROM_HERE, 189 FROM_HERE,
195 base::Bind(&OutputSurface::CheckForRetroactiveBeginImplFrame, 190 base::Bind(&OutputSurface::CheckForRetroactiveBeginImplFrame,
196 weak_ptr_factory_.GetWeakPtr())); 191 weak_ptr_factory_.GetWeakPtr()));
197 check_for_retroactive_begin_impl_frame_pending_ = true; 192 check_for_retroactive_begin_impl_frame_pending_ = true;
198 } 193 }
199 194
200 void OutputSurface::CheckForRetroactiveBeginImplFrame() { 195 void OutputSurface::CheckForRetroactiveBeginImplFrame() {
201 TRACE_EVENT0("cc", "OutputSurface::CheckForRetroactiveBeginImplFrame"); 196 TRACE_EVENT0("cc", "OutputSurface::CheckForRetroactiveBeginImplFrame");
202 check_for_retroactive_begin_impl_frame_pending_ = false; 197 check_for_retroactive_begin_impl_frame_pending_ = false;
203 if (gfx::FrameTime::Now() < RetroactiveBeginImplFrameDeadline()) 198 if (!throttle_frame_production_ ||
199 gfx::FrameTime::Now() < RetroactiveBeginImplFrameDeadline())
204 BeginImplFrame(skipped_begin_impl_frame_args_); 200 BeginImplFrame(skipped_begin_impl_frame_args_);
205 } 201 }
206 202
207 void OutputSurface::DidSwapBuffers() { 203 void OutputSurface::DidSwapBuffers() {
208 pending_swap_buffers_++; 204 if (is_lost_)
209 TRACE_EVENT1("cc", "OutputSurface::DidSwapBuffers", 205 return;
210 "pending_swap_buffers_", pending_swap_buffers_); 206 TRACE_EVENT0("cc", "OutputSurface::DidSwapBuffers");
211 client_->DidSwapBuffers(); 207 client_->DidSwapBuffers();
212 if (frame_rate_controller_)
213 frame_rate_controller_->DidSwapBuffers();
214 PostCheckForRetroactiveBeginImplFrame();
215 } 208 }
216 209
217 void OutputSurface::OnSwapBuffersComplete() { 210 void OutputSurface::OnSwapBuffersComplete() {
218 pending_swap_buffers_--; 211 if (is_lost_)
219 TRACE_EVENT1("cc", "OutputSurface::OnSwapBuffersComplete", 212 return;
220 "pending_swap_buffers_", pending_swap_buffers_); 213 TRACE_EVENT0("cc", "OutputSurface::OnSwapBuffersComplete");
221 client_->OnSwapBuffersComplete(); 214 client_->OnSwapBuffersComplete();
222 if (frame_rate_controller_)
223 frame_rate_controller_->DidSwapBuffersComplete();
224 PostCheckForRetroactiveBeginImplFrame();
225 } 215 }
226 216
227 void OutputSurface::ReclaimResources(const CompositorFrameAck* ack) { 217 void OutputSurface::ReclaimResources(const CompositorFrameAck* ack) {
228 client_->ReclaimResources(ack); 218 client_->ReclaimResources(ack);
229 } 219 }
230 220
231 void OutputSurface::DidLoseOutputSurface() { 221 void OutputSurface::DidLoseOutputSurface() {
232 TRACE_EVENT0("cc", "OutputSurface::DidLoseOutputSurface"); 222 TRACE_EVENT0("cc", "OutputSurface::DidLoseOutputSurface");
233 client_ready_for_begin_impl_frame_ = true; 223 client_ready_for_begin_impl_frame_ = true;
234 pending_swap_buffers_ = 0;
235 skipped_begin_impl_frame_args_ = BeginFrameArgs(); 224 skipped_begin_impl_frame_args_ = BeginFrameArgs();
236 if (frame_rate_controller_) 225 if (frame_rate_controller_)
237 frame_rate_controller_->SetActive(false); 226 frame_rate_controller_->SetActive(false);
238 pending_gpu_latency_query_ids_.clear(); 227 pending_gpu_latency_query_ids_.clear();
239 available_gpu_latency_query_ids_.clear(); 228 available_gpu_latency_query_ids_.clear();
240 client_->DidLoseOutputSurface(); 229 client_->DidLoseOutputSurface();
230 is_lost_ = true;
241 } 231 }
242 232
243 void OutputSurface::SetExternalStencilTest(bool enabled) { 233 void OutputSurface::SetExternalStencilTest(bool enabled) {
244 external_stencil_test_enabled_ = enabled; 234 external_stencil_test_enabled_ = enabled;
245 } 235 }
246 236
247 void OutputSurface::SetExternalDrawConstraints(const gfx::Transform& transform, 237 void OutputSurface::SetExternalDrawConstraints(const gfx::Transform& transform,
248 const gfx::Rect& viewport, 238 const gfx::Rect& viewport,
249 const gfx::Rect& clip, 239 const gfx::Rect& clip,
250 bool valid_for_tile_management) { 240 bool valid_for_tile_management) {
(...skipping 235 matching lines...) Expand 10 before | Expand all | Expand 10 after
486 TRACE_EVENT1("cc", "OutputSurface::SetMemoryPolicy", 476 TRACE_EVENT1("cc", "OutputSurface::SetMemoryPolicy",
487 "bytes_limit_when_visible", policy.bytes_limit_when_visible); 477 "bytes_limit_when_visible", policy.bytes_limit_when_visible);
488 // Just ignore the memory manager when it says to set the limit to zero 478 // 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 479 // bytes. This will happen when the memory manager thinks that the renderer
490 // is not visible (which the renderer knows better). 480 // is not visible (which the renderer knows better).
491 if (policy.bytes_limit_when_visible) 481 if (policy.bytes_limit_when_visible)
492 client_->SetMemoryPolicy(policy); 482 client_->SetMemoryPolicy(policy);
493 } 483 }
494 484
495 } // namespace cc 485 } // namespace cc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698