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

Side by Side Diff: cc/trees/single_thread_proxy.cc

Issue 134623005: Make SingleThreadProxy a SchedulerClient (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Add scoped_abort_remaining_swap_promises.h Created 6 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 | Annotate | Revision Log
« no previous file with comments | « cc/trees/single_thread_proxy.h ('k') | cc/trees/thread_proxy.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 2011 The Chromium Authors. All rights reserved. 1 // Copyright 2011 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/trees/single_thread_proxy.h" 5 #include "cc/trees/single_thread_proxy.h"
6 6
7 #include "base/auto_reset.h" 7 #include "base/auto_reset.h"
8 #include "base/debug/trace_event.h" 8 #include "base/debug/trace_event.h"
9 #include "cc/debug/benchmark_instrumentation.h" 9 #include "cc/debug/benchmark_instrumentation.h"
10 #include "cc/output/context_provider.h" 10 #include "cc/output/context_provider.h"
11 #include "cc/output/output_surface.h" 11 #include "cc/output/output_surface.h"
12 #include "cc/quads/draw_quad.h" 12 #include "cc/quads/draw_quad.h"
13 #include "cc/resources/prioritized_resource_manager.h" 13 #include "cc/resources/prioritized_resource_manager.h"
14 #include "cc/resources/resource_update_controller.h" 14 #include "cc/resources/resource_update_controller.h"
15 #include "cc/trees/blocking_task_runner.h" 15 #include "cc/trees/blocking_task_runner.h"
16 #include "cc/trees/layer_tree_host.h" 16 #include "cc/trees/layer_tree_host.h"
17 #include "cc/trees/layer_tree_host_single_thread_client.h" 17 #include "cc/trees/layer_tree_host_single_thread_client.h"
18 #include "cc/trees/layer_tree_impl.h" 18 #include "cc/trees/layer_tree_impl.h"
19 #include "cc/trees/scoped_abort_remaining_swap_promises.h"
19 #include "ui/gfx/frame_time.h" 20 #include "ui/gfx/frame_time.h"
20 21
21 namespace cc { 22 namespace cc {
22 23
23 scoped_ptr<Proxy> SingleThreadProxy::Create( 24 scoped_ptr<Proxy> SingleThreadProxy::Create(
24 LayerTreeHost* layer_tree_host, 25 LayerTreeHost* layer_tree_host,
25 LayerTreeHostSingleThreadClient* client, 26 LayerTreeHostSingleThreadClient* client,
26 scoped_refptr<base::SingleThreadTaskRunner> main_task_runner) { 27 scoped_refptr<base::SingleThreadTaskRunner> main_task_runner) {
27 return make_scoped_ptr( 28 return make_scoped_ptr(
28 new SingleThreadProxy(layer_tree_host, client, main_task_runner)) 29 new SingleThreadProxy(layer_tree_host, client, main_task_runner))
29 .PassAs<Proxy>(); 30 .PassAs<Proxy>();
30 } 31 }
31 32
32 SingleThreadProxy::SingleThreadProxy( 33 SingleThreadProxy::SingleThreadProxy(
33 LayerTreeHost* layer_tree_host, 34 LayerTreeHost* layer_tree_host,
34 LayerTreeHostSingleThreadClient* client, 35 LayerTreeHostSingleThreadClient* client,
35 scoped_refptr<base::SingleThreadTaskRunner> main_task_runner) 36 scoped_refptr<base::SingleThreadTaskRunner> main_task_runner)
36 : Proxy(main_task_runner, NULL), 37 : Proxy(main_task_runner, NULL),
37 layer_tree_host_(layer_tree_host), 38 layer_tree_host_(layer_tree_host),
38 client_(client), 39 client_(client),
40 timing_history_(layer_tree_host->rendering_stats_instrumentation()),
39 next_frame_is_newly_committed_frame_(false), 41 next_frame_is_newly_committed_frame_(false),
40 inside_draw_(false) { 42 inside_draw_(false),
43 defer_commits_(false),
44 commit_was_deferred_(false),
45 commit_requested_(false),
46 weak_factory_(this) {
41 TRACE_EVENT0("cc", "SingleThreadProxy::SingleThreadProxy"); 47 TRACE_EVENT0("cc", "SingleThreadProxy::SingleThreadProxy");
42 DCHECK(Proxy::IsMainThread()); 48 DCHECK(Proxy::IsMainThread());
43 DCHECK(layer_tree_host); 49 DCHECK(layer_tree_host);
44 50
45 // Impl-side painting not supported without threaded compositing. 51 // Impl-side painting not supported without threaded compositing.
46 CHECK(!layer_tree_host->settings().impl_side_painting) 52 CHECK(!layer_tree_host->settings().impl_side_painting)
47 << "Threaded compositing must be enabled to use impl-side painting."; 53 << "Threaded compositing must be enabled to use impl-side painting.";
48 } 54 }
49 55
50 void SingleThreadProxy::Start() { 56 void SingleThreadProxy::Start() {
(...skipping 19 matching lines...) Expand all
70 76
71 bool SingleThreadProxy::IsStarted() const { 77 bool SingleThreadProxy::IsStarted() const {
72 DCHECK(Proxy::IsMainThread()); 78 DCHECK(Proxy::IsMainThread());
73 return layer_tree_host_impl_; 79 return layer_tree_host_impl_;
74 } 80 }
75 81
76 void SingleThreadProxy::SetLayerTreeHostClientReady() { 82 void SingleThreadProxy::SetLayerTreeHostClientReady() {
77 TRACE_EVENT0("cc", "SingleThreadProxy::SetLayerTreeHostClientReady"); 83 TRACE_EVENT0("cc", "SingleThreadProxy::SetLayerTreeHostClientReady");
78 // Scheduling is controlled by the embedder in the single thread case, so 84 // Scheduling is controlled by the embedder in the single thread case, so
79 // nothing to do. 85 // nothing to do.
86 DCHECK(Proxy::IsMainThread());
87 DebugScopedSetImplThread impl(this);
88 if (layer_tree_host_->settings().single_thread_proxy_scheduler &&
89 !scheduler_on_impl_thread_) {
90 SchedulerSettings scheduler_settings(layer_tree_host_->settings());
91 scheduler_on_impl_thread_ = Scheduler::Create(this,
92 scheduler_settings,
93 layer_tree_host_->id(),
94 MainThreadTaskRunner());
95 scheduler_on_impl_thread_->SetCanStart();
96 scheduler_on_impl_thread_->SetVisible(layer_tree_host_impl_->visible());
97 }
80 } 98 }
81 99
82 void SingleThreadProxy::SetVisible(bool visible) { 100 void SingleThreadProxy::SetVisible(bool visible) {
83 TRACE_EVENT0("cc", "SingleThreadProxy::SetVisible"); 101 TRACE_EVENT0("cc", "SingleThreadProxy::SetVisible");
84 DebugScopedSetImplThread impl(this); 102 DebugScopedSetImplThread impl(this);
85 layer_tree_host_impl_->SetVisible(visible); 103 layer_tree_host_impl_->SetVisible(visible);
86 104 if (scheduler_on_impl_thread_)
105 scheduler_on_impl_thread_->SetVisible(layer_tree_host_impl_->visible());
87 // Changing visibility could change ShouldComposite(). 106 // Changing visibility could change ShouldComposite().
88 UpdateBackgroundAnimateTicking(); 107 UpdateBackgroundAnimateTicking();
89 } 108 }
90 109
91 void SingleThreadProxy::CreateAndInitializeOutputSurface() { 110 void SingleThreadProxy::CreateAndInitializeOutputSurface() {
92 TRACE_EVENT0( 111 TRACE_EVENT0(
93 "cc", "SingleThreadProxy::CreateAndInitializeOutputSurface"); 112 "cc", "SingleThreadProxy::CreateAndInitializeOutputSurface");
94 DCHECK(Proxy::IsMainThread()); 113 DCHECK(Proxy::IsMainThread());
95 DCHECK(layer_tree_host_->output_surface_lost()); 114 DCHECK(layer_tree_host_->output_surface_lost());
96 115
97 scoped_ptr<OutputSurface> output_surface = 116 scoped_ptr<OutputSurface> output_surface =
98 layer_tree_host_->CreateOutputSurface(); 117 layer_tree_host_->CreateOutputSurface();
99 118
100 renderer_capabilities_for_main_thread_ = RendererCapabilities(); 119 renderer_capabilities_for_main_thread_ = RendererCapabilities();
101 120
102 bool success = !!output_surface; 121 bool success = !!output_surface;
103 if (success) { 122 if (success) {
104 DebugScopedSetMainThreadBlocked main_thread_blocked(this); 123 DebugScopedSetMainThreadBlocked main_thread_blocked(this);
105 DebugScopedSetImplThread impl(this); 124 DebugScopedSetImplThread impl(this);
106 layer_tree_host_->DeleteContentsTexturesOnImplThread( 125 layer_tree_host_->DeleteContentsTexturesOnImplThread(
107 layer_tree_host_impl_->resource_provider()); 126 layer_tree_host_impl_->resource_provider());
108 success = layer_tree_host_impl_->InitializeRenderer(output_surface.Pass()); 127 success = layer_tree_host_impl_->InitializeRenderer(output_surface.Pass());
109 } 128 }
110 129
111 layer_tree_host_->OnCreateAndInitializeOutputSurfaceAttempted(success); 130 layer_tree_host_->OnCreateAndInitializeOutputSurfaceAttempted(success);
112 131
113 if (!success) { 132 if (success) {
114 // Force another recreation attempt to happen by requesting another commit. 133 if (scheduler_on_impl_thread_)
115 SetNeedsCommit(); 134 scheduler_on_impl_thread_->DidCreateAndInitializeOutputSurface();
135 } else if (Proxy::MainThreadTaskRunner()) {
136 MainThreadTaskRunner()->PostTask(
137 FROM_HERE,
138 base::Bind(&SingleThreadProxy::CreateAndInitializeOutputSurface,
139 weak_factory_.GetWeakPtr()));
116 } 140 }
117 } 141 }
118 142
119 const RendererCapabilities& SingleThreadProxy::GetRendererCapabilities() const { 143 const RendererCapabilities& SingleThreadProxy::GetRendererCapabilities() const {
120 DCHECK(Proxy::IsMainThread()); 144 DCHECK(Proxy::IsMainThread());
121 DCHECK(!layer_tree_host_->output_surface_lost()); 145 DCHECK(!layer_tree_host_->output_surface_lost());
122 return renderer_capabilities_for_main_thread_; 146 return renderer_capabilities_for_main_thread_;
123 } 147 }
124 148
125 void SingleThreadProxy::SetNeedsAnimate() { 149 void SingleThreadProxy::SetNeedsAnimate() {
126 TRACE_EVENT0("cc", "SingleThreadProxy::SetNeedsAnimate"); 150 TRACE_EVENT0("cc", "SingleThreadProxy::SetNeedsAnimate");
127 DCHECK(Proxy::IsMainThread()); 151 DCHECK(Proxy::IsMainThread());
128 client_->ScheduleAnimation(); 152 client_->ScheduleAnimation();
153 SetNeedsCommit();
129 } 154 }
130 155
131 void SingleThreadProxy::SetNeedsUpdateLayers() { 156 void SingleThreadProxy::SetNeedsUpdateLayers() {
132 TRACE_EVENT0("cc", "SingleThreadProxy::SetNeedsUpdateLayers"); 157 TRACE_EVENT0("cc", "SingleThreadProxy::SetNeedsUpdateLayers");
133 DCHECK(Proxy::IsMainThread()); 158 DCHECK(Proxy::IsMainThread());
134 client_->ScheduleComposite(); 159 SetNeedsCommit();
135 } 160 }
136 161
137 void SingleThreadProxy::DoCommit(scoped_ptr<ResourceUpdateQueue> queue) { 162 void SingleThreadProxy::DoCommit(const BeginFrameArgs& begin_frame_args) {
138 TRACE_EVENT0("cc", "SingleThreadProxy::DoCommit"); 163 TRACE_EVENT0("cc", "SingleThreadProxy::DoCommit");
139 DCHECK(Proxy::IsMainThread()); 164 DCHECK(Proxy::IsMainThread());
165 layer_tree_host_->WillBeginMainFrame();
166 layer_tree_host_->BeginMainFrame(begin_frame_args);
167 layer_tree_host_->AnimateLayers(begin_frame_args.frame_time);
168 layer_tree_host_->Layout();
169 commit_requested_ = false;
170
171 if (PrioritizedResourceManager* contents_texture_manager =
172 layer_tree_host_->contents_texture_manager()) {
173 contents_texture_manager->UnlinkAndClearEvictedBackings();
174 contents_texture_manager->SetMaxMemoryLimitBytes(
175 layer_tree_host_impl_->memory_allocation_limit_bytes());
176 contents_texture_manager->SetExternalPriorityCutoff(
177 layer_tree_host_impl_->memory_allocation_priority_cutoff());
178 }
179
180 scoped_ptr<ResourceUpdateQueue> queue =
181 make_scoped_ptr(new ResourceUpdateQueue);
182
183 layer_tree_host_->UpdateLayers(queue.get());
184
185 layer_tree_host_->WillCommit();
186
140 // Commit immediately. 187 // Commit immediately.
141 { 188 {
142 DebugScopedSetMainThreadBlocked main_thread_blocked(this); 189 DebugScopedSetMainThreadBlocked main_thread_blocked(this);
143 DebugScopedSetImplThread impl(this); 190 DebugScopedSetImplThread impl(this);
144 191
145 // This CapturePostTasks should be destroyed before CommitComplete() is 192 // This CapturePostTasks should be destroyed before CommitComplete() is
146 // called since that goes out to the embedder, and we want the embedder 193 // called since that goes out to the embedder, and we want the embedder
147 // to receive its callbacks before that. 194 // to receive its callbacks before that.
148 BlockingTaskRunner::CapturePostTasks blocked; 195 BlockingTaskRunner::CapturePostTasks blocked;
149 196
150 layer_tree_host_impl_->BeginCommit(); 197 layer_tree_host_impl_->BeginCommit();
151 198
152 if (PrioritizedResourceManager* contents_texture_manager = 199 if (PrioritizedResourceManager* contents_texture_manager =
153 layer_tree_host_->contents_texture_manager()) { 200 layer_tree_host_->contents_texture_manager()) {
154 contents_texture_manager->PushTexturePrioritiesToBackings(); 201 contents_texture_manager->PushTexturePrioritiesToBackings();
155 } 202 }
156 layer_tree_host_->BeginCommitOnImplThread(layer_tree_host_impl_.get()); 203 layer_tree_host_->BeginCommitOnImplThread(layer_tree_host_impl_.get());
157 204
158 scoped_ptr<ResourceUpdateController> update_controller = 205 scoped_ptr<ResourceUpdateController> update_controller =
159 ResourceUpdateController::Create( 206 ResourceUpdateController::Create(
160 NULL, 207 NULL,
161 Proxy::MainThreadTaskRunner(), 208 MainThreadTaskRunner(),
162 queue.Pass(), 209 queue.Pass(),
163 layer_tree_host_impl_->resource_provider()); 210 layer_tree_host_impl_->resource_provider());
164 update_controller->Finalize(); 211 update_controller->Finalize();
165 212
166 if (layer_tree_host_impl_->EvictedUIResourcesExist()) 213 if (layer_tree_host_impl_->EvictedUIResourcesExist())
167 layer_tree_host_->RecreateUIResources(); 214 layer_tree_host_->RecreateUIResources();
168 215
169 layer_tree_host_->FinishCommitOnImplThread(layer_tree_host_impl_.get()); 216 layer_tree_host_->FinishCommitOnImplThread(layer_tree_host_impl_.get());
170 217
171 layer_tree_host_impl_->CommitComplete(); 218 layer_tree_host_impl_->CommitComplete();
172 219
220 UpdateBackgroundAnimateTicking();
221
173 #if DCHECK_IS_ON 222 #if DCHECK_IS_ON
174 // In the single-threaded case, the scale and scroll deltas should never be 223 // In the single-threaded case, the scale and scroll deltas should never be
175 // touched on the impl layer tree. 224 // touched on the impl layer tree.
176 scoped_ptr<ScrollAndScaleSet> scroll_info = 225 scoped_ptr<ScrollAndScaleSet> scroll_info =
177 layer_tree_host_impl_->ProcessScrollDeltas(); 226 layer_tree_host_impl_->ProcessScrollDeltas();
178 DCHECK(!scroll_info->scrolls.size()); 227 DCHECK(!scroll_info->scrolls.size());
179 DCHECK_EQ(1.f, scroll_info->page_scale_delta); 228 DCHECK_EQ(1.f, scroll_info->page_scale_delta);
180 #endif 229 #endif
181 230
182 RenderingStatsInstrumentation* stats_instrumentation = 231 RenderingStatsInstrumentation* stats_instrumentation =
183 layer_tree_host_->rendering_stats_instrumentation(); 232 layer_tree_host_->rendering_stats_instrumentation();
184 benchmark_instrumentation::IssueMainThreadRenderingStatsEvent( 233 benchmark_instrumentation::IssueMainThreadRenderingStatsEvent(
185 stats_instrumentation->main_thread_rendering_stats()); 234 stats_instrumentation->main_thread_rendering_stats());
186 stats_instrumentation->AccumulateAndClearMainThreadStats(); 235 stats_instrumentation->AccumulateAndClearMainThreadStats();
187 } 236 }
188 layer_tree_host_->CommitComplete(); 237 layer_tree_host_->CommitComplete();
238 layer_tree_host_->DidBeginMainFrame();
239 timing_history_.DidCommit();
240
189 next_frame_is_newly_committed_frame_ = true; 241 next_frame_is_newly_committed_frame_ = true;
190 } 242 }
191 243
192 void SingleThreadProxy::SetNeedsCommit() { 244 void SingleThreadProxy::SetNeedsCommit() {
193 DCHECK(Proxy::IsMainThread()); 245 DCHECK(Proxy::IsMainThread());
246 DebugScopedSetImplThread impl(this);
194 client_->ScheduleComposite(); 247 client_->ScheduleComposite();
248 if (scheduler_on_impl_thread_)
249 scheduler_on_impl_thread_->SetNeedsCommit();
250 commit_requested_ = true;
195 } 251 }
196 252
197 void SingleThreadProxy::SetNeedsRedraw(const gfx::Rect& damage_rect) { 253 void SingleThreadProxy::SetNeedsRedraw(const gfx::Rect& damage_rect) {
198 TRACE_EVENT0("cc", "SingleThreadProxy::SetNeedsRedraw"); 254 TRACE_EVENT0("cc", "SingleThreadProxy::SetNeedsRedraw");
255 DCHECK(Proxy::IsMainThread());
256 DebugScopedSetImplThread impl(this);
257 client_->ScheduleComposite();
199 SetNeedsRedrawRectOnImplThread(damage_rect); 258 SetNeedsRedrawRectOnImplThread(damage_rect);
200 client_->ScheduleComposite();
201 } 259 }
202 260
203 void SingleThreadProxy::SetNextCommitWaitsForActivation() { 261 void SingleThreadProxy::SetNextCommitWaitsForActivation() {
204 // There is no activation here other than commit. So do nothing. 262 // There is no activation here other than commit. So do nothing.
263 DCHECK(Proxy::IsMainThread());
205 } 264 }
206 265
207 void SingleThreadProxy::SetDeferCommits(bool defer_commits) { 266 void SingleThreadProxy::SetDeferCommits(bool defer_commits) {
267 DCHECK(Proxy::IsMainThread());
268 // Deferring commits only makes sense if there's a scheduler.
269 if (!scheduler_on_impl_thread_)
270 return;
271 if (defer_commits_ == defer_commits)
272 return;
273
274 if (defer_commits)
275 TRACE_EVENT_ASYNC_BEGIN0("cc", "SingleThreadProxy::SetDeferCommits", this);
276 else
277 TRACE_EVENT_ASYNC_END0("cc", "SingleThreadProxy::SetDeferCommits", this);
278
279 defer_commits_ = defer_commits;
280 if (!defer_commits_ && commit_was_deferred_) {
281 commit_was_deferred_ = false;
282 BeginMainFrame();
283 }
208 } 284 }
209 285
210 bool SingleThreadProxy::CommitRequested() const { 286 bool SingleThreadProxy::CommitRequested() const {
211 return false; 287 DCHECK(Proxy::IsMainThread());
288 return commit_requested_;
212 } 289 }
213 290
214 bool SingleThreadProxy::BeginMainFrameRequested() const { 291 bool SingleThreadProxy::BeginMainFrameRequested() const {
215 return false; 292 DCHECK(Proxy::IsMainThread());
293 // If there is no scheduler, then there can be no pending begin frame,
294 // as all frames are all manually initiated by the embedder of cc.
295 if (!scheduler_on_impl_thread_)
296 return false;
297 return commit_requested_;
216 } 298 }
217 299
218 size_t SingleThreadProxy::MaxPartialTextureUpdates() const { 300 size_t SingleThreadProxy::MaxPartialTextureUpdates() const {
219 return std::numeric_limits<size_t>::max(); 301 return std::numeric_limits<size_t>::max();
220 } 302 }
221 303
222 void SingleThreadProxy::Stop() { 304 void SingleThreadProxy::Stop() {
223 TRACE_EVENT0("cc", "SingleThreadProxy::stop"); 305 TRACE_EVENT0("cc", "SingleThreadProxy::stop");
224 DCHECK(Proxy::IsMainThread()); 306 DCHECK(Proxy::IsMainThread());
225 { 307 {
226 DebugScopedSetMainThreadBlocked main_thread_blocked(this); 308 DebugScopedSetMainThreadBlocked main_thread_blocked(this);
227 DebugScopedSetImplThread impl(this); 309 DebugScopedSetImplThread impl(this);
228 310
229 BlockingTaskRunner::CapturePostTasks blocked; 311 BlockingTaskRunner::CapturePostTasks blocked;
230 layer_tree_host_->DeleteContentsTexturesOnImplThread( 312 layer_tree_host_->DeleteContentsTexturesOnImplThread(
231 layer_tree_host_impl_->resource_provider()); 313 layer_tree_host_impl_->resource_provider());
314 scheduler_on_impl_thread_.reset();
232 layer_tree_host_impl_.reset(); 315 layer_tree_host_impl_.reset();
233 } 316 }
234 layer_tree_host_ = NULL; 317 layer_tree_host_ = NULL;
235 } 318 }
236 319
237 void SingleThreadProxy::OnCanDrawStateChanged(bool can_draw) { 320 void SingleThreadProxy::OnCanDrawStateChanged(bool can_draw) {
238 TRACE_EVENT1( 321 TRACE_EVENT1(
239 "cc", "SingleThreadProxy::OnCanDrawStateChanged", "can_draw", can_draw); 322 "cc", "SingleThreadProxy::OnCanDrawStateChanged", "can_draw", can_draw);
240 DCHECK(Proxy::IsImplThread()); 323 DCHECK(Proxy::IsImplThread());
241 UpdateBackgroundAnimateTicking(); 324 UpdateBackgroundAnimateTicking();
325 if (scheduler_on_impl_thread_)
326 scheduler_on_impl_thread_->SetCanDraw(can_draw);
242 } 327 }
243 328
244 void SingleThreadProxy::NotifyReadyToActivate() { 329 void SingleThreadProxy::NotifyReadyToActivate() {
245 // Thread-only feature. 330 // Impl-side painting only.
246 NOTREACHED(); 331 NOTREACHED();
247 } 332 }
248 333
249 void SingleThreadProxy::SetNeedsRedrawOnImplThread() { 334 void SingleThreadProxy::SetNeedsRedrawOnImplThread() {
250 client_->ScheduleComposite(); 335 client_->ScheduleComposite();
336 if (scheduler_on_impl_thread_)
337 scheduler_on_impl_thread_->SetNeedsRedraw();
251 } 338 }
252 339
253 void SingleThreadProxy::SetNeedsAnimateOnImplThread() { 340 void SingleThreadProxy::SetNeedsAnimateOnImplThread() {
254 SetNeedsRedrawOnImplThread(); 341 SetNeedsRedrawOnImplThread();
255 } 342 }
256 343
257 void SingleThreadProxy::SetNeedsManageTilesOnImplThread() { 344 void SingleThreadProxy::SetNeedsManageTilesOnImplThread() {
258 // Thread-only/Impl-side-painting-only feature. 345 // Impl-side painting only.
259 NOTREACHED(); 346 NOTREACHED();
260 } 347 }
261 348
262 void SingleThreadProxy::SetNeedsRedrawRectOnImplThread( 349 void SingleThreadProxy::SetNeedsRedrawRectOnImplThread(
263 const gfx::Rect& damage_rect) { 350 const gfx::Rect& damage_rect) {
264 // TODO(brianderson): Once we move render_widget scheduling into this class,
265 // we can treat redraw requests more efficiently than CommitAndRedraw
266 // requests.
267 layer_tree_host_impl_->SetViewportDamage(damage_rect); 351 layer_tree_host_impl_->SetViewportDamage(damage_rect);
268 SetNeedsCommit(); 352 SetNeedsRedrawOnImplThread();
269 } 353 }
270 354
271 void SingleThreadProxy::DidInitializeVisibleTileOnImplThread() { 355 void SingleThreadProxy::DidInitializeVisibleTileOnImplThread() {
272 // Impl-side painting only. 356 // Impl-side painting only.
273 NOTREACHED(); 357 NOTREACHED();
274 } 358 }
275 359
276 void SingleThreadProxy::SetNeedsCommitOnImplThread() { 360 void SingleThreadProxy::SetNeedsCommitOnImplThread() {
277 client_->ScheduleComposite(); 361 client_->ScheduleComposite();
362 if (scheduler_on_impl_thread_)
363 scheduler_on_impl_thread_->SetNeedsCommit();
278 } 364 }
279 365
280 void SingleThreadProxy::PostAnimationEventsToMainThreadOnImplThread( 366 void SingleThreadProxy::PostAnimationEventsToMainThreadOnImplThread(
281 scoped_ptr<AnimationEventsVector> events) { 367 scoped_ptr<AnimationEventsVector> events) {
282 TRACE_EVENT0( 368 TRACE_EVENT0(
283 "cc", "SingleThreadProxy::PostAnimationEventsToMainThreadOnImplThread"); 369 "cc", "SingleThreadProxy::PostAnimationEventsToMainThreadOnImplThread");
284 DCHECK(Proxy::IsImplThread()); 370 DCHECK(Proxy::IsImplThread());
285 DebugScopedSetMainThread main(this); 371 DebugScopedSetMainThread main(this);
286 layer_tree_host_->SetAnimationEvents(events.Pass()); 372 layer_tree_host_->SetAnimationEvents(events.Pass());
287 } 373 }
(...skipping 16 matching lines...) Expand all
304 } 390 }
305 391
306 bool SingleThreadProxy::IsInsideDraw() { return inside_draw_; } 392 bool SingleThreadProxy::IsInsideDraw() { return inside_draw_; }
307 393
308 void SingleThreadProxy::UpdateRendererCapabilitiesOnImplThread() { 394 void SingleThreadProxy::UpdateRendererCapabilitiesOnImplThread() {
309 DCHECK(IsImplThread()); 395 DCHECK(IsImplThread());
310 renderer_capabilities_for_main_thread_ = 396 renderer_capabilities_for_main_thread_ =
311 layer_tree_host_impl_->GetRendererCapabilities().MainThreadCapabilities(); 397 layer_tree_host_impl_->GetRendererCapabilities().MainThreadCapabilities();
312 } 398 }
313 399
400 void SingleThreadProxy::DidManageTiles() {
401 // Impl-side painting only.
402 NOTREACHED();
403 }
404
314 void SingleThreadProxy::DidLoseOutputSurfaceOnImplThread() { 405 void SingleThreadProxy::DidLoseOutputSurfaceOnImplThread() {
315 TRACE_EVENT0("cc", "SingleThreadProxy::DidLoseOutputSurfaceOnImplThread"); 406 TRACE_EVENT0("cc", "SingleThreadProxy::DidLoseOutputSurfaceOnImplThread");
316 // Cause a commit so we can notice the lost context. 407 {
317 SetNeedsCommitOnImplThread(); 408 DebugScopedSetMainThread main(this);
409 // This must happen before we notify the scheduler as it may try to recreate
410 // the output surface if already in BEGIN_IMPL_FRAME_STATE_IDLE.
411 layer_tree_host_->DidLoseOutputSurface();
412 }
318 client_->DidAbortSwapBuffers(); 413 client_->DidAbortSwapBuffers();
414 if (scheduler_on_impl_thread_)
415 scheduler_on_impl_thread_->DidLoseOutputSurface();
319 } 416 }
320 417
321 void SingleThreadProxy::DidSwapBuffersOnImplThread() { 418 void SingleThreadProxy::DidSwapBuffersOnImplThread() {
419 TRACE_EVENT0("cc", "SingleThreadProxy::DidSwapBuffersOnImplThread");
420 if (scheduler_on_impl_thread_)
421 scheduler_on_impl_thread_->DidSwapBuffers();
322 client_->DidPostSwapBuffers(); 422 client_->DidPostSwapBuffers();
323 } 423 }
324 424
325 void SingleThreadProxy::DidSwapBuffersCompleteOnImplThread() { 425 void SingleThreadProxy::DidSwapBuffersCompleteOnImplThread() {
326 TRACE_EVENT0("cc", "SingleThreadProxy::DidSwapBuffersCompleteOnImplThread"); 426 TRACE_EVENT0("cc", "SingleThreadProxy::DidSwapBuffersCompleteOnImplThread");
327 client_->DidCompleteSwapBuffers(); 427 if (scheduler_on_impl_thread_)
428 scheduler_on_impl_thread_->DidSwapBuffersComplete();
429 layer_tree_host_->DidCompleteSwapBuffers();
328 } 430 }
329 431
330 // Called by the legacy scheduling path (e.g. where render_widget does the 432 void SingleThreadProxy::BeginFrame(const BeginFrameArgs& args) {
331 // scheduling) 433 TRACE_EVENT0("cc", "SingleThreadProxy::BeginFrame");
434 if (scheduler_on_impl_thread_)
435 scheduler_on_impl_thread_->BeginImplFrame(args);
436 }
437
332 void SingleThreadProxy::CompositeImmediately(base::TimeTicks frame_begin_time) { 438 void SingleThreadProxy::CompositeImmediately(base::TimeTicks frame_begin_time) {
333 TRACE_EVENT0("cc", "SingleThreadProxy::CompositeImmediately"); 439 TRACE_EVENT0("cc", "SingleThreadProxy::CompositeImmediately");
334 DCHECK(Proxy::IsMainThread()); 440 DCHECK(Proxy::IsMainThread());
335 DCHECK(!layer_tree_host_->output_surface_lost()); 441 DCHECK(!layer_tree_host_->output_surface_lost());
336 442
337 layer_tree_host_->AnimateLayers(frame_begin_time); 443 BeginFrameArgs begin_frame_args = BeginFrameArgs::Create(
338 444 frame_begin_time, base::TimeTicks(), BeginFrameArgs::DefaultInterval());
339 if (PrioritizedResourceManager* contents_texture_manager = 445 DoCommit(begin_frame_args);
340 layer_tree_host_->contents_texture_manager()) {
341 contents_texture_manager->UnlinkAndClearEvictedBackings();
342 contents_texture_manager->SetMaxMemoryLimitBytes(
343 layer_tree_host_impl_->memory_allocation_limit_bytes());
344 contents_texture_manager->SetExternalPriorityCutoff(
345 layer_tree_host_impl_->memory_allocation_priority_cutoff());
346 }
347
348 scoped_ptr<ResourceUpdateQueue> queue =
349 make_scoped_ptr(new ResourceUpdateQueue);
350 layer_tree_host_->UpdateLayers(queue.get());
351 layer_tree_host_->WillCommit();
352 DoCommit(queue.Pass());
353 layer_tree_host_->DidBeginMainFrame();
354 446
355 LayerTreeHostImpl::FrameData frame; 447 LayerTreeHostImpl::FrameData frame;
356 if (DoComposite(frame_begin_time, &frame)) { 448 DoComposite(frame_begin_time, &frame);
357 {
358 DebugScopedSetMainThreadBlocked main_thread_blocked(this);
359 DebugScopedSetImplThread impl(this);
360
361 // This CapturePostTasks should be destroyed before
362 // DidCommitAndDrawFrame() is called since that goes out to the embedder,
363 // and we want the embedder to receive its callbacks before that.
364 // NOTE: This maintains consistent ordering with the ThreadProxy since
365 // the DidCommitAndDrawFrame() must be post-tasked from the impl thread
366 // there as the main thread is not blocked, so any posted tasks inside
367 // the swap buffers will execute first.
368 BlockingTaskRunner::CapturePostTasks blocked;
369
370 layer_tree_host_impl_->SwapBuffers(frame);
371 }
372 DidSwapFrame();
373 }
374 } 449 }
375 450
376 void SingleThreadProxy::AsValueInto(base::debug::TracedValue* state) const { 451 void SingleThreadProxy::AsValueInto(base::debug::TracedValue* state) const {
377 // The following line casts away const modifiers because it is just 452 // The following line casts away const modifiers because it is just
378 // setting debug state. We still want the AsValue() function and its 453 // setting debug state. We still want the AsValue() function and its
379 // call chain to be const throughout. 454 // call chain to be const throughout.
380 DebugScopedSetImplThread impl(const_cast<SingleThreadProxy*>(this)); 455 DebugScopedSetImplThread impl(const_cast<SingleThreadProxy*>(this));
381 456
382 state->BeginDictionary("layer_tree_host_impl"); 457 state->BeginDictionary("layer_tree_host_impl");
383 layer_tree_host_impl_->AsValueInto(state); 458 layer_tree_host_impl_->AsValueInto(state);
(...skipping 19 matching lines...) Expand all
403 return layer_tree_host_impl_->visible() && 478 return layer_tree_host_impl_->visible() &&
404 layer_tree_host_impl_->CanDraw(); 479 layer_tree_host_impl_->CanDraw();
405 } 480 }
406 481
407 void SingleThreadProxy::UpdateBackgroundAnimateTicking() { 482 void SingleThreadProxy::UpdateBackgroundAnimateTicking() {
408 DCHECK(Proxy::IsImplThread()); 483 DCHECK(Proxy::IsImplThread());
409 layer_tree_host_impl_->UpdateBackgroundAnimateTicking( 484 layer_tree_host_impl_->UpdateBackgroundAnimateTicking(
410 !ShouldComposite() && layer_tree_host_impl_->active_tree()->root_layer()); 485 !ShouldComposite() && layer_tree_host_impl_->active_tree()->root_layer());
411 } 486 }
412 487
413 bool SingleThreadProxy::DoComposite(base::TimeTicks frame_begin_time, 488 DrawResult SingleThreadProxy::DoComposite(base::TimeTicks frame_begin_time,
414 LayerTreeHostImpl::FrameData* frame) { 489 LayerTreeHostImpl::FrameData* frame) {
415 TRACE_EVENT0("cc", "SingleThreadProxy::DoComposite"); 490 TRACE_EVENT0("cc", "SingleThreadProxy::DoComposite");
416 DCHECK(!layer_tree_host_->output_surface_lost()); 491 DCHECK(!layer_tree_host_->output_surface_lost());
417 492
418 bool lost_output_surface = false;
419 { 493 {
420 DebugScopedSetImplThread impl(this); 494 DebugScopedSetImplThread impl(this);
421 base::AutoReset<bool> mark_inside(&inside_draw_, true); 495 base::AutoReset<bool> mark_inside(&inside_draw_, true);
422 496
423 // We guard PrepareToDraw() with CanDraw() because it always returns a valid 497 // We guard PrepareToDraw() with CanDraw() because it always returns a valid
424 // frame, so can only be used when such a frame is possible. Since 498 // frame, so can only be used when such a frame is possible. Since
425 // DrawLayers() depends on the result of PrepareToDraw(), it is guarded on 499 // DrawLayers() depends on the result of PrepareToDraw(), it is guarded on
426 // CanDraw() as well. 500 // CanDraw() as well.
427 if (!ShouldComposite()) { 501 if (!ShouldComposite()) {
428 UpdateBackgroundAnimateTicking(); 502 UpdateBackgroundAnimateTicking();
429 return false; 503 return DRAW_ABORTED_CANT_DRAW;
430 } 504 }
431 505
506 timing_history_.DidStartDrawing();
507
432 layer_tree_host_impl_->Animate( 508 layer_tree_host_impl_->Animate(
433 layer_tree_host_impl_->CurrentBeginFrameArgs().frame_time); 509 layer_tree_host_impl_->CurrentBeginFrameArgs().frame_time);
434 UpdateBackgroundAnimateTicking(); 510 UpdateBackgroundAnimateTicking();
435 511
436 if (!layer_tree_host_impl_->IsContextLost()) { 512 if (!layer_tree_host_impl_->IsContextLost()) {
437 layer_tree_host_impl_->PrepareToDraw(frame); 513 layer_tree_host_impl_->PrepareToDraw(frame);
438 layer_tree_host_impl_->DrawLayers(frame, frame_begin_time); 514 layer_tree_host_impl_->DrawLayers(frame, frame_begin_time);
439 layer_tree_host_impl_->DidDrawAllLayers(*frame); 515 layer_tree_host_impl_->DidDrawAllLayers(*frame);
440 } 516 }
441 lost_output_surface = layer_tree_host_impl_->IsContextLost();
442 517
443 bool start_ready_animations = true; 518 bool start_ready_animations = true;
444 layer_tree_host_impl_->UpdateAnimationState(start_ready_animations); 519 layer_tree_host_impl_->UpdateAnimationState(start_ready_animations);
445 520
446 layer_tree_host_impl_->ResetCurrentBeginFrameArgsForNextFrame(); 521 layer_tree_host_impl_->ResetCurrentBeginFrameArgsForNextFrame();
522
523 timing_history_.DidFinishDrawing();
447 } 524 }
448 525
449 if (lost_output_surface) { 526 {
450 layer_tree_host_->DidLoseOutputSurface(); 527 DebugScopedSetImplThread impl(this);
451 return false; 528
529 if (layer_tree_host_impl_->IsContextLost()) {
530 DidLoseOutputSurfaceOnImplThread();
531 } else {
532 // This CapturePostTasks should be destroyed before
533 // DidCommitAndDrawFrame() is called since that goes out to the
534 // embedder,
535 // and we want the embedder to receive its callbacks before that.
536 // NOTE: This maintains consistent ordering with the ThreadProxy since
537 // the DidCommitAndDrawFrame() must be post-tasked from the impl thread
538 // there as the main thread is not blocked, so any posted tasks inside
539 // the swap buffers will execute first.
540 DebugScopedSetMainThreadBlocked main_thread_blocked(this);
541
542 BlockingTaskRunner::CapturePostTasks blocked;
543 layer_tree_host_impl_->SwapBuffers(*frame);
544 }
452 } 545 }
546 DidCommitAndDrawFrame();
453 547
454 return true; 548 return DRAW_SUCCESS;
455 } 549 }
456 550
457 void SingleThreadProxy::DidSwapFrame() { 551 void SingleThreadProxy::DidCommitAndDrawFrame() {
458 if (next_frame_is_newly_committed_frame_) { 552 if (next_frame_is_newly_committed_frame_) {
553 DebugScopedSetMainThread main(this);
459 next_frame_is_newly_committed_frame_ = false; 554 next_frame_is_newly_committed_frame_ = false;
460 layer_tree_host_->DidCommitAndDrawFrame(); 555 layer_tree_host_->DidCommitAndDrawFrame();
461 } 556 }
462 } 557 }
463 558
464 bool SingleThreadProxy::MainFrameWillHappenForTesting() { 559 bool SingleThreadProxy::MainFrameWillHappenForTesting() {
465 return false; 560 return false;
466 } 561 }
467 562
563 void SingleThreadProxy::SetNeedsBeginFrame(bool enable) {
564 layer_tree_host_impl_->SetNeedsBeginFrame(enable);
565 }
566
567 void SingleThreadProxy::WillBeginImplFrame(const BeginFrameArgs& args) {
568 layer_tree_host_impl_->WillBeginImplFrame(args);
569 }
570
571 void SingleThreadProxy::ScheduledActionSendBeginMainFrame() {
572 TRACE_EVENT0("cc", "SingleThreadProxy::ScheduledActionSendBeginMainFrame");
573 // Although this proxy is single-threaded, it's problematic to synchronously
574 // have BeginMainFrame happen after ScheduledActionSendBeginMainFrame. This
575 // could cause a commit to occur in between a series of SetNeedsCommit calls
576 // (i.e. property modifications) causing some to fall on one frame and some to
577 // fall on the next. Doing it asynchronously instead matches the semantics of
578 // ThreadProxy::SetNeedsCommit where SetNeedsCommit will not cause a
579 // synchronous commit.
580 MainThreadTaskRunner()->PostTask(
581 FROM_HERE,
582 base::Bind(&SingleThreadProxy::BeginMainFrame,
583 weak_factory_.GetWeakPtr()));
584 }
585
586 void SingleThreadProxy::BeginMainFrame() {
587 if (defer_commits_) {
588 DCHECK(!commit_was_deferred_);
589 commit_was_deferred_ = true;
590 layer_tree_host_->DidDeferCommit();
591 return;
592 }
593
594 // This checker assumes NotifyReadyToCommit below causes a synchronous commit.
595 ScopedAbortRemainingSwapPromises swap_promise_checker(layer_tree_host_);
596
597 if (!layer_tree_host_->visible()) {
598 TRACE_EVENT_INSTANT0("cc", "EarlyOut_NotVisible", TRACE_EVENT_SCOPE_THREAD);
599 BeginMainFrameAbortedOnImplThread();
600 return;
601 }
602
603 if (layer_tree_host_->output_surface_lost()) {
604 TRACE_EVENT_INSTANT0(
605 "cc", "EarlyOut_OutputSurfaceLost", TRACE_EVENT_SCOPE_THREAD);
606 BeginMainFrameAbortedOnImplThread();
607 return;
608 }
609
610 timing_history_.DidBeginMainFrame();
611
612 DCHECK(scheduler_on_impl_thread_);
613 scheduler_on_impl_thread_->NotifyBeginMainFrameStarted();
614 scheduler_on_impl_thread_->NotifyReadyToCommit();
615 }
616
617 void SingleThreadProxy::BeginMainFrameAbortedOnImplThread() {
618 DebugScopedSetImplThread impl(this);
619 DCHECK(scheduler_on_impl_thread_->CommitPending());
620 DCHECK(!layer_tree_host_impl_->pending_tree());
621
622 // TODO(enne): SingleThreadProxy does not support cancelling commits yet so
623 // did_handle is always false.
624 bool did_handle = false;
625 layer_tree_host_impl_->BeginMainFrameAborted(did_handle);
626 scheduler_on_impl_thread_->BeginMainFrameAborted(did_handle);
627 }
628
629 DrawResult SingleThreadProxy::ScheduledActionDrawAndSwapIfPossible() {
630 DebugScopedSetImplThread impl(this);
631 if (layer_tree_host_impl_->IsContextLost()) {
632 DidCommitAndDrawFrame();
633 return DRAW_SUCCESS;
634 }
635
636 LayerTreeHostImpl::FrameData frame;
637 return DoComposite(layer_tree_host_impl_->CurrentBeginFrameArgs().frame_time,
638 &frame);
639 }
640
641 DrawResult SingleThreadProxy::ScheduledActionDrawAndSwapForced() {
642 NOTREACHED();
643 return INVALID_RESULT;
644 }
645
646 void SingleThreadProxy::ScheduledActionCommit() {
647 DebugScopedSetMainThread main(this);
648 DoCommit(layer_tree_host_impl_->CurrentBeginFrameArgs());
649 }
650
651 void SingleThreadProxy::ScheduledActionAnimate() {
652 TRACE_EVENT0("cc", "ScheduledActionAnimate");
653 layer_tree_host_impl_->Animate(
654 layer_tree_host_impl_->CurrentBeginFrameArgs().frame_time);
655 }
656
657 void SingleThreadProxy::ScheduledActionUpdateVisibleTiles() {
658 // Impl-side painting only.
659 NOTREACHED();
660 }
661
662 void SingleThreadProxy::ScheduledActionActivateSyncTree() {
663 }
664
665 void SingleThreadProxy::ScheduledActionBeginOutputSurfaceCreation() {
666 DebugScopedSetMainThread main(this);
667 DCHECK(scheduler_on_impl_thread_);
668 // If possible, create the output surface in a post task. Synchronously
669 // creating the output surface makes tests more awkward since this differs
670 // from the ThreadProxy behavior. However, sometimes there is no
671 // task runner.
672 if (Proxy::MainThreadTaskRunner()) {
673 MainThreadTaskRunner()->PostTask(
674 FROM_HERE,
675 base::Bind(&SingleThreadProxy::CreateAndInitializeOutputSurface,
676 weak_factory_.GetWeakPtr()));
677 } else {
678 CreateAndInitializeOutputSurface();
679 }
680 }
681
682 void SingleThreadProxy::ScheduledActionManageTiles() {
683 // Impl-side painting only.
684 NOTREACHED();
685 }
686
687 void SingleThreadProxy::DidAnticipatedDrawTimeChange(base::TimeTicks time) {
688 }
689
690 base::TimeDelta SingleThreadProxy::DrawDurationEstimate() {
691 return timing_history_.DrawDurationEstimate();
692 }
693
694 base::TimeDelta SingleThreadProxy::BeginMainFrameToCommitDurationEstimate() {
695 return timing_history_.BeginMainFrameToCommitDurationEstimate();
696 }
697
698 base::TimeDelta SingleThreadProxy::CommitToActivateDurationEstimate() {
699 return timing_history_.CommitToActivateDurationEstimate();
700 }
701
702 void SingleThreadProxy::DidBeginImplFrameDeadline() {
703 layer_tree_host_impl_->ResetCurrentBeginFrameArgsForNextFrame();
704 }
705
468 } // namespace cc 706 } // namespace cc
OLDNEW
« no previous file with comments | « cc/trees/single_thread_proxy.h ('k') | cc/trees/thread_proxy.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698