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

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

Issue 1417053005: cc: Split ThreadProxy into ProxyMain and ProxyImpl (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Update ProxyImpl and ProxyMain class structure. Created 5 years 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
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "cc/trees/thread_proxy.h"
6
7 #include <algorithm>
8 #include <string>
9
10 #include "base/auto_reset.h"
11 #include "base/bind.h"
12 #include "base/trace_event/trace_event.h"
13 #include "base/trace_event/trace_event_argument.h"
14 #include "base/trace_event/trace_event_synthetic_delay.h"
15 #include "cc/debug/benchmark_instrumentation.h"
16 #include "cc/debug/devtools_instrumentation.h"
17 #include "cc/input/input_handler.h"
18 #include "cc/input/top_controls_manager.h"
19 #include "cc/output/context_provider.h"
20 #include "cc/output/output_surface.h"
21 #include "cc/output/swap_promise.h"
22 #include "cc/quads/draw_quad.h"
23 #include "cc/scheduler/commit_earlyout_reason.h"
24 #include "cc/scheduler/compositor_timing_history.h"
25 #include "cc/scheduler/scheduler.h"
26 #include "cc/trees/blocking_task_runner.h"
27 #include "cc/trees/layer_tree_host.h"
28 #include "cc/trees/layer_tree_impl.h"
29 #include "cc/trees/scoped_abort_remaining_swap_promises.h"
30 #include "gpu/command_buffer/client/gles2_interface.h"
31
32 namespace cc {
33
34 namespace {
35
36 // Measured in seconds.
37 const double kSmoothnessTakesPriorityExpirationDelay = 0.25;
38
39 unsigned int nextBeginFrameId = 0;
40
41 } // namespace
42
43 struct ThreadProxy::SchedulerStateRequest {
44 CompletionEvent completion;
45 scoped_ptr<base::Value> state;
46 };
47
48 scoped_ptr<Proxy> ThreadProxy::Create(
49 LayerTreeHost* layer_tree_host,
50 TaskRunnerProvider* task_runner_provider,
51 scoped_ptr<BeginFrameSource> external_begin_frame_source) {
52 return make_scoped_ptr(
53 new ThreadProxy(layer_tree_host, task_runner_provider,
54 std::move(external_begin_frame_source)));
55 }
56
57 ThreadProxy::ThreadProxy(
58 LayerTreeHost* layer_tree_host,
59 TaskRunnerProvider* task_runner_provider,
60 scoped_ptr<BeginFrameSource> external_begin_frame_source)
61 : task_runner_provider_(task_runner_provider),
62 main_thread_only_vars_unsafe_(this, layer_tree_host),
63 compositor_thread_vars_unsafe_(
64 this,
65 layer_tree_host->id(),
66 layer_tree_host->rendering_stats_instrumentation(),
67 std::move(external_begin_frame_source)) {
68 TRACE_EVENT0("cc", "ThreadProxy::ThreadProxy");
69 DCHECK(task_runner_provider_);
70 DCHECK(task_runner_provider_->IsMainThread());
71 DCHECK(this->main().layer_tree_host);
72 // TODO(khushalsagar): Move this to LayerTreeHost#InitializeThreaded once
73 // ThreadProxy is split. LayerTreeHost creates the channel and passes it to
74 // ProxyMain#SetChannel.
75 SetChannel(ThreadedChannel::Create(this, task_runner_provider_));
76 }
77
78 ThreadProxy::MainThreadOnly::MainThreadOnly(ThreadProxy* proxy,
79 LayerTreeHost* layer_tree_host)
80 : layer_tree_host_id(layer_tree_host->id()),
81 layer_tree_host(layer_tree_host),
82 max_requested_pipeline_stage(NO_PIPELINE_STAGE),
83 current_pipeline_stage(NO_PIPELINE_STAGE),
84 final_pipeline_stage(NO_PIPELINE_STAGE),
85 commit_waits_for_activation(false),
86 started(false),
87 prepare_tiles_pending(false),
88 defer_commits(false),
89 weak_factory(proxy) {}
90
91 ThreadProxy::MainThreadOnly::~MainThreadOnly() {}
92
93 ThreadProxy::BlockedMainCommitOnly::BlockedMainCommitOnly()
94 : layer_tree_host(nullptr) {}
95
96 ThreadProxy::BlockedMainCommitOnly::~BlockedMainCommitOnly() {}
97
98 ThreadProxy::CompositorThreadOnly::CompositorThreadOnly(
99 ThreadProxy* proxy,
100 int layer_tree_host_id,
101 RenderingStatsInstrumentation* rendering_stats_instrumentation,
102 scoped_ptr<BeginFrameSource> external_begin_frame_source)
103 : layer_tree_host_id(layer_tree_host_id),
104 next_commit_waits_for_activation(false),
105 commit_completion_event(nullptr),
106 next_frame_is_newly_committed_frame(false),
107 inside_draw(false),
108 input_throttled_until_commit(false),
109 smoothness_priority_expiration_notifier(
110 proxy->task_runner_provider()
111 ->ImplThreadTaskRunner(),
112 base::Bind(&ThreadProxy::RenewTreePriority, base::Unretained(proxy)),
113 base::TimeDelta::FromMilliseconds(
114 kSmoothnessTakesPriorityExpirationDelay * 1000)),
115 external_begin_frame_source(std::move(external_begin_frame_source)),
116 rendering_stats_instrumentation(rendering_stats_instrumentation),
117 weak_factory(proxy) {}
118
119 ThreadProxy::CompositorThreadOnly::~CompositorThreadOnly() {}
120
121 ThreadProxy::~ThreadProxy() {
122 TRACE_EVENT0("cc", "ThreadProxy::~ThreadProxy");
123 DCHECK(task_runner_provider_->IsMainThread());
124 DCHECK(!main().started);
125 }
126
127 void ThreadProxy::SetChannel(scoped_ptr<ThreadedChannel> threaded_channel) {
128 threaded_channel_ = std::move(threaded_channel);
129 main().channel_main = threaded_channel_.get();
130 }
131
132 void ThreadProxy::FinishAllRendering() {
133 DCHECK(task_runner_provider_->IsMainThread());
134 DCHECK(!main().defer_commits);
135
136 // Make sure all GL drawing is finished on the impl thread.
137 DebugScopedSetMainThreadBlocked main_thread_blocked(task_runner_provider_);
138 CompletionEvent completion;
139 main().channel_main->FinishAllRenderingOnImpl(&completion);
140 completion.Wait();
141 }
142
143 bool ThreadProxy::IsStarted() const {
144 DCHECK(task_runner_provider_->IsMainThread());
145 return main().started;
146 }
147
148 bool ThreadProxy::CommitToActiveTree() const {
149 // With ThreadProxy, we use a pending tree and activate it once it's ready to
150 // draw to allow input to modify the active tree and draw during raster.
151 return false;
152 }
153
154 void ThreadProxy::SetVisible(bool visible) {
155 TRACE_EVENT1("cc", "ThreadProxy::SetVisible", "visible", visible);
156 main().channel_main->SetVisibleOnImpl(visible);
157 }
158
159 void ThreadProxy::SetVisibleOnImpl(bool visible) {
160 TRACE_EVENT1("cc", "ThreadProxy::SetVisibleOnImplThread", "visible", visible);
161 impl().layer_tree_host_impl->SetVisible(visible);
162 impl().scheduler->SetVisible(visible);
163 }
164
165 void ThreadProxy::SetThrottleFrameProduction(bool throttle) {
166 TRACE_EVENT1("cc", "ThreadProxy::SetThrottleFrameProduction", "throttle",
167 throttle);
168 main().channel_main->SetThrottleFrameProductionOnImpl(throttle);
169 }
170
171 void ThreadProxy::SetThrottleFrameProductionOnImpl(bool throttle) {
172 TRACE_EVENT1("cc", "ThreadProxy::SetThrottleFrameProductionOnImplThread",
173 "throttle", throttle);
174 impl().scheduler->SetThrottleFrameProduction(throttle);
175 }
176
177 void ThreadProxy::DidLoseOutputSurface() {
178 TRACE_EVENT0("cc", "ThreadProxy::DidLoseOutputSurface");
179 DCHECK(task_runner_provider_->IsMainThread());
180 main().layer_tree_host->DidLoseOutputSurface();
181 }
182
183 void ThreadProxy::RequestNewOutputSurface() {
184 DCHECK(task_runner_provider_->IsMainThread());
185 main().layer_tree_host->RequestNewOutputSurface();
186 }
187
188 void ThreadProxy::SetOutputSurface(OutputSurface* output_surface) {
189 main().channel_main->InitializeOutputSurfaceOnImpl(output_surface);
190 }
191
192 void ThreadProxy::ReleaseOutputSurface() {
193 DCHECK(task_runner_provider_->IsMainThread());
194 DCHECK(main().layer_tree_host->output_surface_lost());
195
196 DebugScopedSetMainThreadBlocked main_thread_blocked(task_runner_provider_);
197 CompletionEvent completion;
198 main().channel_main->ReleaseOutputSurfaceOnImpl(&completion);
199 completion.Wait();
200 }
201
202 void ThreadProxy::DidInitializeOutputSurface(
203 bool success,
204 const RendererCapabilities& capabilities) {
205 TRACE_EVENT0("cc", "ThreadProxy::DidInitializeOutputSurface");
206 DCHECK(task_runner_provider_->IsMainThread());
207
208 if (!success) {
209 main().layer_tree_host->DidFailToInitializeOutputSurface();
210 return;
211 }
212 main().renderer_capabilities_main_thread_copy = capabilities;
213 main().layer_tree_host->DidInitializeOutputSurface();
214 }
215
216 void ThreadProxy::SetRendererCapabilitiesMainCopy(
217 const RendererCapabilities& capabilities) {
218 main().renderer_capabilities_main_thread_copy = capabilities;
219 }
220
221 bool ThreadProxy::SendCommitRequestToImplThreadIfNeeded(
222 CommitPipelineStage required_stage) {
223 DCHECK(task_runner_provider_->IsMainThread());
224 DCHECK_NE(NO_PIPELINE_STAGE, required_stage);
225 bool already_posted =
226 main().max_requested_pipeline_stage != NO_PIPELINE_STAGE;
227 main().max_requested_pipeline_stage =
228 std::max(main().max_requested_pipeline_stage, required_stage);
229 if (already_posted)
230 return false;
231 main().channel_main->SetNeedsCommitOnImpl();
232 return true;
233 }
234
235 void ThreadProxy::SetNeedsCommitOnImpl() {
236 SetNeedsCommitOnImplThread();
237 }
238
239 void ThreadProxy::DidCompletePageScaleAnimation() {
240 DCHECK(task_runner_provider_->IsMainThread());
241 main().layer_tree_host->DidCompletePageScaleAnimation();
242 }
243
244 const RendererCapabilities& ThreadProxy::GetRendererCapabilities() const {
245 DCHECK(task_runner_provider_->IsMainThread());
246 DCHECK(!main().layer_tree_host->output_surface_lost());
247 return main().renderer_capabilities_main_thread_copy;
248 }
249
250 void ThreadProxy::SetNeedsAnimate() {
251 DCHECK(task_runner_provider_->IsMainThread());
252 if (SendCommitRequestToImplThreadIfNeeded(ANIMATE_PIPELINE_STAGE)) {
253 TRACE_EVENT_INSTANT0("cc", "ThreadProxy::SetNeedsAnimate",
254 TRACE_EVENT_SCOPE_THREAD);
255 }
256 }
257
258 void ThreadProxy::SetNeedsUpdateLayers() {
259 DCHECK(task_runner_provider_->IsMainThread());
260 // If we are currently animating, make sure we also update the layers.
261 if (main().current_pipeline_stage == ANIMATE_PIPELINE_STAGE) {
262 main().final_pipeline_stage =
263 std::max(main().final_pipeline_stage, UPDATE_LAYERS_PIPELINE_STAGE);
264 return;
265 }
266 if (SendCommitRequestToImplThreadIfNeeded(UPDATE_LAYERS_PIPELINE_STAGE)) {
267 TRACE_EVENT_INSTANT0("cc", "ThreadProxy::SetNeedsUpdateLayers",
268 TRACE_EVENT_SCOPE_THREAD);
269 }
270 }
271
272 void ThreadProxy::SetNeedsCommit() {
273 DCHECK(task_runner_provider_->IsMainThread());
274 // If we are currently animating, make sure we don't skip the commit. Note
275 // that requesting a commit during the layer update stage means we need to
276 // schedule another full commit.
277 if (main().current_pipeline_stage == ANIMATE_PIPELINE_STAGE) {
278 main().final_pipeline_stage =
279 std::max(main().final_pipeline_stage, COMMIT_PIPELINE_STAGE);
280 return;
281 }
282 if (SendCommitRequestToImplThreadIfNeeded(COMMIT_PIPELINE_STAGE)) {
283 TRACE_EVENT_INSTANT0("cc", "ThreadProxy::SetNeedsCommit",
284 TRACE_EVENT_SCOPE_THREAD);
285 }
286 }
287
288 void ThreadProxy::UpdateRendererCapabilitiesOnImplThread() {
289 DCHECK(task_runner_provider_->IsImplThread());
290 impl().channel_impl->SetRendererCapabilitiesMainCopy(
291 impl()
292 .layer_tree_host_impl->GetRendererCapabilities()
293 .MainThreadCapabilities());
294 }
295
296 void ThreadProxy::DidLoseOutputSurfaceOnImplThread() {
297 TRACE_EVENT0("cc", "ThreadProxy::DidLoseOutputSurfaceOnImplThread");
298 DCHECK(task_runner_provider_->IsImplThread());
299 impl().channel_impl->DidLoseOutputSurface();
300 impl().scheduler->DidLoseOutputSurface();
301 }
302
303 void ThreadProxy::CommitVSyncParameters(base::TimeTicks timebase,
304 base::TimeDelta interval) {
305 impl().scheduler->CommitVSyncParameters(timebase, interval);
306 }
307
308 void ThreadProxy::SetEstimatedParentDrawTime(base::TimeDelta draw_time) {
309 impl().scheduler->SetEstimatedParentDrawTime(draw_time);
310 }
311
312 void ThreadProxy::DidSwapBuffersOnImplThread() {
313 impl().scheduler->DidSwapBuffers();
314 }
315
316 void ThreadProxy::DidSwapBuffersCompleteOnImplThread() {
317 TRACE_EVENT0("cc,benchmark",
318 "ThreadProxy::DidSwapBuffersCompleteOnImplThread");
319 DCHECK(task_runner_provider_->IsImplThread());
320 impl().scheduler->DidSwapBuffersComplete();
321 impl().channel_impl->DidCompleteSwapBuffers();
322 }
323
324 void ThreadProxy::WillBeginImplFrame(const BeginFrameArgs& args) {
325 impl().layer_tree_host_impl->WillBeginImplFrame(args);
326 if (impl().last_processed_begin_main_frame_args.IsValid()) {
327 // Last processed begin main frame args records the frame args that we sent
328 // to the main thread for the last frame that we've processed. If that is
329 // set, that means the current frame is one past the frame in which we've
330 // finished the processing.
331 impl().layer_tree_host_impl->RecordMainFrameTiming(
332 impl().last_processed_begin_main_frame_args, args);
333 impl().last_processed_begin_main_frame_args = BeginFrameArgs();
334 }
335 }
336
337 void ThreadProxy::OnResourcelessSoftareDrawStateChanged(
338 bool resourceless_draw) {
339 DCHECK(task_runner_provider_->IsImplThread());
340 impl().scheduler->SetResourcelessSoftareDraw(resourceless_draw);
341 }
342
343 void ThreadProxy::OnCanDrawStateChanged(bool can_draw) {
344 TRACE_EVENT1(
345 "cc", "ThreadProxy::OnCanDrawStateChanged", "can_draw", can_draw);
346 DCHECK(task_runner_provider_->IsImplThread());
347 impl().scheduler->SetCanDraw(can_draw);
348 }
349
350 void ThreadProxy::NotifyReadyToActivate() {
351 TRACE_EVENT0("cc", "ThreadProxy::NotifyReadyToActivate");
352 impl().scheduler->NotifyReadyToActivate();
353 }
354
355 void ThreadProxy::NotifyReadyToDraw() {
356 TRACE_EVENT0("cc", "ThreadProxy::NotifyReadyToDraw");
357 impl().scheduler->NotifyReadyToDraw();
358 }
359
360 void ThreadProxy::SetNeedsCommitOnImplThread() {
361 TRACE_EVENT0("cc", "ThreadProxy::SetNeedsCommitOnImplThread");
362 DCHECK(task_runner_provider_->IsImplThread());
363 impl().scheduler->SetNeedsBeginMainFrame();
364 }
365
366 void ThreadProxy::SetVideoNeedsBeginFrames(bool needs_begin_frames) {
367 TRACE_EVENT1("cc", "ThreadProxy::SetVideoNeedsBeginFrames",
368 "needs_begin_frames", needs_begin_frames);
369 DCHECK(task_runner_provider_->IsImplThread());
370 // In tests the layer tree is destroyed after the scheduler is.
371 if (impl().scheduler)
372 impl().scheduler->SetVideoNeedsBeginFrames(needs_begin_frames);
373 }
374
375 void ThreadProxy::PostAnimationEventsToMainThreadOnImplThread(
376 scoped_ptr<AnimationEventsVector> events) {
377 TRACE_EVENT0("cc",
378 "ThreadProxy::PostAnimationEventsToMainThreadOnImplThread");
379 DCHECK(task_runner_provider_->IsImplThread());
380 impl().channel_impl->SetAnimationEvents(std::move(events));
381 }
382
383 bool ThreadProxy::IsInsideDraw() { return impl().inside_draw; }
384
385 void ThreadProxy::SetNeedsRedraw(const gfx::Rect& damage_rect) {
386 TRACE_EVENT0("cc", "ThreadProxy::SetNeedsRedraw");
387 DCHECK(task_runner_provider_->IsMainThread());
388 main().channel_main->SetNeedsRedrawOnImpl(damage_rect);
389 }
390
391 void ThreadProxy::SetNeedsRedrawOnImpl(const gfx::Rect& damage_rect) {
392 DCHECK(task_runner_provider_->IsImplThread());
393 SetNeedsRedrawRectOnImplThread(damage_rect);
394 }
395
396 void ThreadProxy::SetNextCommitWaitsForActivation() {
397 DCHECK(task_runner_provider_->IsMainThread());
398 main().commit_waits_for_activation = true;
399 }
400
401 void ThreadProxy::SetDeferCommits(bool defer_commits) {
402 DCHECK(task_runner_provider_->IsMainThread());
403 if (main().defer_commits == defer_commits)
404 return;
405
406 main().defer_commits = defer_commits;
407 if (main().defer_commits)
408 TRACE_EVENT_ASYNC_BEGIN0("cc", "ThreadProxy::SetDeferCommits", this);
409 else
410 TRACE_EVENT_ASYNC_END0("cc", "ThreadProxy::SetDeferCommits", this);
411
412 main().channel_main->SetDeferCommitsOnImpl(defer_commits);
413 }
414
415 void ThreadProxy::SetDeferCommitsOnImpl(bool defer_commits) const {
416 DCHECK(task_runner_provider_->IsImplThread());
417 impl().scheduler->SetDeferCommits(defer_commits);
418 }
419
420 bool ThreadProxy::CommitRequested() const {
421 DCHECK(task_runner_provider_->IsMainThread());
422 // TODO(skyostil): Split this into something like CommitRequested() and
423 // CommitInProgress().
424 return main().current_pipeline_stage != NO_PIPELINE_STAGE ||
425 main().max_requested_pipeline_stage >= COMMIT_PIPELINE_STAGE;
426 }
427
428 bool ThreadProxy::BeginMainFrameRequested() const {
429 DCHECK(task_runner_provider_->IsMainThread());
430 return main().max_requested_pipeline_stage != NO_PIPELINE_STAGE;
431 }
432
433 void ThreadProxy::SetNeedsRedrawOnImplThread() {
434 TRACE_EVENT0("cc", "ThreadProxy::SetNeedsRedrawOnImplThread");
435 DCHECK(task_runner_provider_->IsImplThread());
436 impl().scheduler->SetNeedsRedraw();
437 }
438
439 void ThreadProxy::SetNeedsAnimateOnImplThread() {
440 TRACE_EVENT0("cc", "ThreadProxy::SetNeedsAnimateOnImplThread");
441 DCHECK(task_runner_provider_->IsImplThread());
442 impl().scheduler->SetNeedsAnimate();
443 }
444
445 void ThreadProxy::SetNeedsPrepareTilesOnImplThread() {
446 DCHECK(task_runner_provider_->IsImplThread());
447 impl().scheduler->SetNeedsPrepareTiles();
448 }
449
450 void ThreadProxy::SetNeedsRedrawRectOnImplThread(const gfx::Rect& damage_rect) {
451 DCHECK(task_runner_provider_->IsImplThread());
452 impl().layer_tree_host_impl->SetViewportDamage(damage_rect);
453 SetNeedsRedrawOnImplThread();
454 }
455
456 void ThreadProxy::MainThreadHasStoppedFlinging() {
457 DCHECK(task_runner_provider_->IsMainThread());
458 main().channel_main->MainThreadHasStoppedFlingingOnImpl();
459 }
460
461 void ThreadProxy::MainThreadHasStoppedFlingingOnImpl() {
462 DCHECK(task_runner_provider_->IsImplThread());
463 impl().layer_tree_host_impl->MainThreadHasStoppedFlinging();
464 }
465
466 void ThreadProxy::NotifyInputThrottledUntilCommit() {
467 DCHECK(task_runner_provider_->IsMainThread());
468 main().channel_main->SetInputThrottledUntilCommitOnImpl(true);
469 }
470
471 void ThreadProxy::SetInputThrottledUntilCommitOnImpl(bool is_throttled) {
472 DCHECK(task_runner_provider_->IsImplThread());
473 if (is_throttled == impl().input_throttled_until_commit)
474 return;
475 impl().input_throttled_until_commit = is_throttled;
476 RenewTreePriority();
477 }
478
479 ThreadProxy::MainThreadOnly& ThreadProxy::main() {
480 DCHECK(task_runner_provider_->IsMainThread());
481 return main_thread_only_vars_unsafe_;
482 }
483 const ThreadProxy::MainThreadOnly& ThreadProxy::main() const {
484 DCHECK(task_runner_provider_->IsMainThread());
485 return main_thread_only_vars_unsafe_;
486 }
487
488 ThreadProxy::BlockedMainCommitOnly& ThreadProxy::blocked_main_commit() {
489 DCHECK(impl().commit_completion_event);
490 DCHECK(task_runner_provider_->IsMainThreadBlocked());
491 return main_thread_blocked_commit_vars_unsafe_;
492 }
493
494 ThreadProxy::CompositorThreadOnly& ThreadProxy::impl() {
495 DCHECK(task_runner_provider_->IsImplThread());
496 return compositor_thread_vars_unsafe_;
497 }
498
499 const ThreadProxy::CompositorThreadOnly& ThreadProxy::impl() const {
500 DCHECK(task_runner_provider_->IsImplThread());
501 return compositor_thread_vars_unsafe_;
502 }
503
504 void ThreadProxy::Start() {
505 DCHECK(task_runner_provider_->IsMainThread());
506 DCHECK(task_runner_provider_->HasImplThread());
507
508 // Create LayerTreeHostImpl.
509 DebugScopedSetMainThreadBlocked main_thread_blocked(task_runner_provider_);
510 CompletionEvent completion;
511 main().channel_main->InitializeImplOnImpl(&completion,
512 main().layer_tree_host);
513 completion.Wait();
514
515 main_thread_weak_ptr_ = main().weak_factory.GetWeakPtr();
516
517 main().started = true;
518 }
519
520 void ThreadProxy::Stop() {
521 TRACE_EVENT0("cc", "ThreadProxy::Stop");
522 DCHECK(task_runner_provider_->IsMainThread());
523 DCHECK(main().started);
524
525 // Synchronously finishes pending GL operations and deletes the impl.
526 // The two steps are done as separate post tasks, so that tasks posted
527 // by the GL implementation due to the Finish can be executed by the
528 // renderer before shutting it down.
529 {
530 DebugScopedSetMainThreadBlocked main_thread_blocked(task_runner_provider_);
531 CompletionEvent completion;
532 main().channel_main->FinishGLOnImpl(&completion);
533 completion.Wait();
534 }
535 {
536 DebugScopedSetMainThreadBlocked main_thread_blocked(task_runner_provider_);
537
538 CompletionEvent completion;
539 main().channel_main->LayerTreeHostClosedOnImpl(&completion);
540 completion.Wait();
541 }
542
543 main().weak_factory.InvalidateWeakPtrs();
544 main().layer_tree_host = nullptr;
545 main().started = false;
546 }
547
548 bool ThreadProxy::SupportsImplScrolling() const {
549 return true;
550 }
551
552 void ThreadProxy::FinishAllRenderingOnImpl(CompletionEvent* completion) {
553 TRACE_EVENT0("cc", "ThreadProxy::FinishAllRenderingOnImplThread");
554 DCHECK(task_runner_provider_->IsImplThread());
555 impl().layer_tree_host_impl->FinishAllRendering();
556 completion->Signal();
557 }
558
559 void ThreadProxy::ScheduledActionSendBeginMainFrame(
560 const BeginFrameArgs& args) {
561 unsigned int begin_frame_id = nextBeginFrameId++;
562 benchmark_instrumentation::ScopedBeginFrameTask begin_frame_task(
563 benchmark_instrumentation::kSendBeginFrame, begin_frame_id);
564 scoped_ptr<BeginMainFrameAndCommitState> begin_main_frame_state(
565 new BeginMainFrameAndCommitState);
566 begin_main_frame_state->begin_frame_id = begin_frame_id;
567 begin_main_frame_state->begin_frame_args = args;
568 begin_main_frame_state->scroll_info =
569 impl().layer_tree_host_impl->ProcessScrollDeltas();
570 begin_main_frame_state->memory_allocation_limit_bytes =
571 impl().layer_tree_host_impl->memory_allocation_limit_bytes();
572 begin_main_frame_state->evicted_ui_resources =
573 impl().layer_tree_host_impl->EvictedUIResourcesExist();
574 // TODO(vmpstr): This needs to be fixed if
575 // main_frame_before_activation_enabled is set, since we might run this code
576 // twice before recording a duration. crbug.com/469824
577 impl().last_begin_main_frame_args = begin_main_frame_state->begin_frame_args;
578 impl().channel_impl->BeginMainFrame(std::move(begin_main_frame_state));
579 devtools_instrumentation::DidRequestMainThreadFrame(
580 impl().layer_tree_host_id);
581 }
582
583 void ThreadProxy::SendBeginMainFrameNotExpectedSoon() {
584 impl().channel_impl->BeginMainFrameNotExpectedSoon();
585 }
586
587 void ThreadProxy::BeginMainFrame(
588 scoped_ptr<BeginMainFrameAndCommitState> begin_main_frame_state) {
589 benchmark_instrumentation::ScopedBeginFrameTask begin_frame_task(
590 benchmark_instrumentation::kDoBeginFrame,
591 begin_main_frame_state->begin_frame_id);
592
593 base::TimeTicks begin_main_frame_start_time = base::TimeTicks::Now();
594
595 TRACE_EVENT_SYNTHETIC_DELAY_BEGIN("cc.BeginMainFrame");
596 DCHECK(task_runner_provider_->IsMainThread());
597 DCHECK_EQ(NO_PIPELINE_STAGE, main().current_pipeline_stage);
598
599 if (main().defer_commits) {
600 TRACE_EVENT_INSTANT0("cc", "EarlyOut_DeferCommit",
601 TRACE_EVENT_SCOPE_THREAD);
602 main().channel_main->BeginMainFrameAbortedOnImpl(
603 CommitEarlyOutReason::ABORTED_DEFERRED_COMMIT,
604 begin_main_frame_start_time);
605 return;
606 }
607
608 // If the commit finishes, LayerTreeHost will transfer its swap promises to
609 // LayerTreeImpl. The destructor of ScopedSwapPromiseChecker aborts the
610 // remaining swap promises.
611 ScopedAbortRemainingSwapPromises swap_promise_checker(main().layer_tree_host);
612
613 main().final_pipeline_stage = main().max_requested_pipeline_stage;
614 main().max_requested_pipeline_stage = NO_PIPELINE_STAGE;
615
616 if (!main().layer_tree_host->visible()) {
617 TRACE_EVENT_INSTANT0("cc", "EarlyOut_NotVisible", TRACE_EVENT_SCOPE_THREAD);
618 main().channel_main->BeginMainFrameAbortedOnImpl(
619 CommitEarlyOutReason::ABORTED_NOT_VISIBLE, begin_main_frame_start_time);
620 return;
621 }
622
623 if (main().layer_tree_host->output_surface_lost()) {
624 TRACE_EVENT_INSTANT0(
625 "cc", "EarlyOut_OutputSurfaceLost", TRACE_EVENT_SCOPE_THREAD);
626 main().channel_main->BeginMainFrameAbortedOnImpl(
627 CommitEarlyOutReason::ABORTED_OUTPUT_SURFACE_LOST,
628 begin_main_frame_start_time);
629 return;
630 }
631
632 main().current_pipeline_stage = ANIMATE_PIPELINE_STAGE;
633
634 main().layer_tree_host->ApplyScrollAndScale(
635 begin_main_frame_state->scroll_info.get());
636
637 main().layer_tree_host->WillBeginMainFrame();
638
639 main().layer_tree_host->BeginMainFrame(
640 begin_main_frame_state->begin_frame_args);
641 main().layer_tree_host->AnimateLayers(
642 begin_main_frame_state->begin_frame_args.frame_time);
643
644 // Recreate all UI resources if there were evicted UI resources when the impl
645 // thread initiated the commit.
646 if (begin_main_frame_state->evicted_ui_resources)
647 main().layer_tree_host->RecreateUIResources();
648
649 main().layer_tree_host->RequestMainFrameUpdate();
650 TRACE_EVENT_SYNTHETIC_DELAY_END("cc.BeginMainFrame");
651
652 bool can_cancel_this_commit =
653 main().final_pipeline_stage < COMMIT_PIPELINE_STAGE &&
654 !begin_main_frame_state->evicted_ui_resources;
655
656 main().current_pipeline_stage = UPDATE_LAYERS_PIPELINE_STAGE;
657 bool should_update_layers =
658 main().final_pipeline_stage >= UPDATE_LAYERS_PIPELINE_STAGE;
659 bool updated = should_update_layers && main().layer_tree_host->UpdateLayers();
660
661 main().layer_tree_host->WillCommit();
662 devtools_instrumentation::ScopedCommitTrace commit_task(
663 main().layer_tree_host->id());
664
665 main().current_pipeline_stage = COMMIT_PIPELINE_STAGE;
666 if (!updated && can_cancel_this_commit) {
667 TRACE_EVENT_INSTANT0("cc", "EarlyOut_NoUpdates", TRACE_EVENT_SCOPE_THREAD);
668 main().channel_main->BeginMainFrameAbortedOnImpl(
669 CommitEarlyOutReason::FINISHED_NO_UPDATES, begin_main_frame_start_time);
670
671 // Although the commit is internally aborted, this is because it has been
672 // detected to be a no-op. From the perspective of an embedder, this commit
673 // went through, and input should no longer be throttled, etc.
674 main().current_pipeline_stage = NO_PIPELINE_STAGE;
675 main().layer_tree_host->CommitComplete();
676 main().layer_tree_host->DidBeginMainFrame();
677 main().layer_tree_host->BreakSwapPromises(SwapPromise::COMMIT_NO_UPDATE);
678 return;
679 }
680
681 // Notify the impl thread that the main thread is ready to commit. This will
682 // begin the commit process, which is blocking from the main thread's
683 // point of view, but asynchronously performed on the impl thread,
684 // coordinated by the Scheduler.
685 {
686 TRACE_EVENT0("cc", "ThreadProxy::BeginMainFrame::commit");
687
688 DebugScopedSetMainThreadBlocked main_thread_blocked(task_runner_provider_);
689
690 // This CapturePostTasks should be destroyed before CommitComplete() is
691 // called since that goes out to the embedder, and we want the embedder
692 // to receive its callbacks before that.
693 BlockingTaskRunner::CapturePostTasks blocked(
694 task_runner_provider_->blocking_main_thread_task_runner());
695
696 CompletionEvent completion;
697 main().channel_main->StartCommitOnImpl(&completion, main().layer_tree_host,
698 begin_main_frame_start_time,
699 main().commit_waits_for_activation);
700 completion.Wait();
701 main().commit_waits_for_activation = false;
702 }
703
704 main().current_pipeline_stage = NO_PIPELINE_STAGE;
705 main().layer_tree_host->CommitComplete();
706 main().layer_tree_host->DidBeginMainFrame();
707 }
708
709 void ThreadProxy::BeginMainFrameNotExpectedSoon() {
710 TRACE_EVENT0("cc", "ThreadProxy::BeginMainFrameNotExpectedSoon");
711 DCHECK(task_runner_provider_->IsMainThread());
712 main().layer_tree_host->BeginMainFrameNotExpectedSoon();
713 }
714
715 void ThreadProxy::StartCommitOnImpl(CompletionEvent* completion,
716 LayerTreeHost* layer_tree_host,
717 base::TimeTicks main_thread_start_time,
718 bool hold_commit_for_activation) {
719 TRACE_EVENT0("cc", "ThreadProxy::StartCommitOnImplThread");
720 DCHECK(!impl().commit_completion_event);
721 DCHECK(task_runner_provider_->IsImplThread() &&
722 task_runner_provider_->IsMainThreadBlocked());
723 DCHECK(impl().scheduler);
724 DCHECK(impl().scheduler->CommitPending());
725
726 if (hold_commit_for_activation) {
727 // This commit may be aborted. Store the value for
728 // hold_commit_for_activation so that whenever the next commit is started,
729 // the main thread will be unblocked only after pending tree activation.
730 impl().next_commit_waits_for_activation = hold_commit_for_activation;
731 }
732
733 if (!impl().layer_tree_host_impl) {
734 TRACE_EVENT_INSTANT0(
735 "cc", "EarlyOut_NoLayerTree", TRACE_EVENT_SCOPE_THREAD);
736 completion->Signal();
737 return;
738 }
739
740 // Ideally, we should inform to impl thread when BeginMainFrame is started.
741 // But, we can avoid a PostTask in here.
742 impl().scheduler->NotifyBeginMainFrameStarted(main_thread_start_time);
743 impl().commit_completion_event = completion;
744 DCHECK(!blocked_main_commit().layer_tree_host);
745 blocked_main_commit().layer_tree_host = layer_tree_host;
746 impl().scheduler->NotifyReadyToCommit();
747 }
748
749 void ThreadProxy::BeginMainFrameAbortedOnImpl(
750 CommitEarlyOutReason reason,
751 base::TimeTicks main_thread_start_time) {
752 TRACE_EVENT1("cc", "ThreadProxy::BeginMainFrameAbortedOnImplThread", "reason",
753 CommitEarlyOutReasonToString(reason));
754 DCHECK(task_runner_provider_->IsImplThread());
755 DCHECK(impl().scheduler);
756 DCHECK(impl().scheduler->CommitPending());
757 DCHECK(!impl().layer_tree_host_impl->pending_tree());
758
759 if (CommitEarlyOutHandledCommit(reason)) {
760 SetInputThrottledUntilCommitOnImpl(false);
761 impl().last_processed_begin_main_frame_args =
762 impl().last_begin_main_frame_args;
763 }
764 impl().layer_tree_host_impl->BeginMainFrameAborted(reason);
765 impl().scheduler->NotifyBeginMainFrameStarted(main_thread_start_time);
766 impl().scheduler->BeginMainFrameAborted(reason);
767 }
768
769 void ThreadProxy::ScheduledActionAnimate() {
770 TRACE_EVENT0("cc", "ThreadProxy::ScheduledActionAnimate");
771 DCHECK(task_runner_provider_->IsImplThread());
772
773 impl().layer_tree_host_impl->Animate();
774 }
775
776 void ThreadProxy::ScheduledActionCommit() {
777 TRACE_EVENT0("cc", "ThreadProxy::ScheduledActionCommit");
778 DCHECK(task_runner_provider_->IsImplThread());
779 DCHECK(task_runner_provider_->IsMainThreadBlocked());
780 DCHECK(impl().commit_completion_event);
781 DCHECK(blocked_main_commit().layer_tree_host);
782
783 impl().layer_tree_host_impl->BeginCommit();
784 blocked_main_commit().layer_tree_host->FinishCommitOnImplThread(
785 impl().layer_tree_host_impl.get());
786
787 // Remove the LayerTreeHost reference before the completion event is signaled
788 // and cleared. This is necessary since blocked_main_commit() allows access
789 // only while we have the completion event to ensure the main thread is
790 // blocked for a commit.
791 blocked_main_commit().layer_tree_host = nullptr;
792
793 if (impl().next_commit_waits_for_activation) {
794 // For some layer types in impl-side painting, the commit is held until
795 // the sync tree is activated. It's also possible that the
796 // sync tree has already activated if there was no work to be done.
797 TRACE_EVENT_INSTANT0("cc", "HoldCommit", TRACE_EVENT_SCOPE_THREAD);
798 } else {
799 impl().commit_completion_event->Signal();
800 impl().commit_completion_event = nullptr;
801 }
802
803 impl().scheduler->DidCommit();
804
805 // Delay this step until afer the main thread has been released as it's
806 // often a good bit of work to update the tree and prepare the new frame.
807 impl().layer_tree_host_impl->CommitComplete();
808
809 SetInputThrottledUntilCommitOnImpl(false);
810
811 impl().next_frame_is_newly_committed_frame = true;
812 }
813
814 void ThreadProxy::ScheduledActionActivateSyncTree() {
815 TRACE_EVENT0("cc", "ThreadProxy::ScheduledActionActivateSyncTree");
816 DCHECK(task_runner_provider_->IsImplThread());
817 impl().layer_tree_host_impl->ActivateSyncTree();
818 }
819
820 void ThreadProxy::ScheduledActionBeginOutputSurfaceCreation() {
821 TRACE_EVENT0("cc", "ThreadProxy::ScheduledActionBeginOutputSurfaceCreation");
822 DCHECK(task_runner_provider_->IsImplThread());
823 impl().channel_impl->RequestNewOutputSurface();
824 }
825
826 DrawResult ThreadProxy::DrawSwapInternal(bool forced_draw) {
827 TRACE_EVENT_SYNTHETIC_DELAY("cc.DrawAndSwap");
828 DrawResult result;
829
830 DCHECK(task_runner_provider_->IsImplThread());
831 DCHECK(impl().layer_tree_host_impl.get());
832
833 base::AutoReset<bool> mark_inside(&impl().inside_draw, true);
834
835 if (impl().layer_tree_host_impl->pending_tree()) {
836 bool update_lcd_text = false;
837 impl().layer_tree_host_impl->pending_tree()->UpdateDrawProperties(
838 update_lcd_text);
839 }
840
841 // This method is called on a forced draw, regardless of whether we are able
842 // to produce a frame, as the calling site on main thread is blocked until its
843 // request completes, and we signal completion here. If CanDraw() is false, we
844 // will indicate success=false to the caller, but we must still signal
845 // completion to avoid deadlock.
846
847 // We guard PrepareToDraw() with CanDraw() because it always returns a valid
848 // frame, so can only be used when such a frame is possible. Since
849 // DrawLayers() depends on the result of PrepareToDraw(), it is guarded on
850 // CanDraw() as well.
851
852 LayerTreeHostImpl::FrameData frame;
853 bool draw_frame = false;
854
855 if (impl().layer_tree_host_impl->CanDraw()) {
856 result = impl().layer_tree_host_impl->PrepareToDraw(&frame);
857 draw_frame = forced_draw || result == DRAW_SUCCESS;
858 } else {
859 result = DRAW_ABORTED_CANT_DRAW;
860 }
861
862 if (draw_frame) {
863 impl().layer_tree_host_impl->DrawLayers(&frame);
864 result = DRAW_SUCCESS;
865 } else {
866 DCHECK_NE(DRAW_SUCCESS, result);
867 }
868 impl().layer_tree_host_impl->DidDrawAllLayers(frame);
869
870 bool start_ready_animations = draw_frame;
871 impl().layer_tree_host_impl->UpdateAnimationState(start_ready_animations);
872
873 if (draw_frame)
874 impl().layer_tree_host_impl->SwapBuffers(frame);
875
876 // Tell the main thread that the the newly-commited frame was drawn.
877 if (impl().next_frame_is_newly_committed_frame) {
878 impl().next_frame_is_newly_committed_frame = false;
879 impl().channel_impl->DidCommitAndDrawFrame();
880 }
881
882 DCHECK_NE(INVALID_RESULT, result);
883 return result;
884 }
885
886 void ThreadProxy::ScheduledActionPrepareTiles() {
887 TRACE_EVENT0("cc", "ThreadProxy::ScheduledActionPrepareTiles");
888 impl().layer_tree_host_impl->PrepareTiles();
889 }
890
891 DrawResult ThreadProxy::ScheduledActionDrawAndSwapIfPossible() {
892 TRACE_EVENT0("cc", "ThreadProxy::ScheduledActionDrawAndSwap");
893
894 // SchedulerStateMachine::DidDrawIfPossibleCompleted isn't set up to
895 // handle DRAW_ABORTED_CANT_DRAW. Moreover, the scheduler should
896 // never generate this call when it can't draw.
897 DCHECK(impl().layer_tree_host_impl->CanDraw());
898
899 bool forced_draw = false;
900 return DrawSwapInternal(forced_draw);
901 }
902
903 DrawResult ThreadProxy::ScheduledActionDrawAndSwapForced() {
904 TRACE_EVENT0("cc", "ThreadProxy::ScheduledActionDrawAndSwapForced");
905 bool forced_draw = true;
906 return DrawSwapInternal(forced_draw);
907 }
908
909 void ThreadProxy::ScheduledActionInvalidateOutputSurface() {
910 TRACE_EVENT0("cc", "ThreadProxy::ScheduledActionInvalidateOutputSurface");
911 DCHECK(impl().layer_tree_host_impl->output_surface());
912 impl().layer_tree_host_impl->output_surface()->Invalidate();
913 }
914
915 void ThreadProxy::DidFinishImplFrame() {
916 impl().layer_tree_host_impl->DidFinishImplFrame();
917 }
918
919 void ThreadProxy::SendBeginFramesToChildren(const BeginFrameArgs& args) {
920 NOTREACHED() << "Only used by SingleThreadProxy";
921 }
922
923 void ThreadProxy::SetAuthoritativeVSyncInterval(
924 const base::TimeDelta& interval) {
925 NOTREACHED() << "Only used by SingleThreadProxy";
926 }
927
928 void ThreadProxy::DidCommitAndDrawFrame() {
929 DCHECK(task_runner_provider_->IsMainThread());
930 main().layer_tree_host->DidCommitAndDrawFrame();
931 }
932
933 void ThreadProxy::DidCompleteSwapBuffers() {
934 DCHECK(task_runner_provider_->IsMainThread());
935 main().layer_tree_host->DidCompleteSwapBuffers();
936 }
937
938 void ThreadProxy::SetAnimationEvents(scoped_ptr<AnimationEventsVector> events) {
939 TRACE_EVENT0("cc", "ThreadProxy::SetAnimationEvents");
940 DCHECK(task_runner_provider_->IsMainThread());
941 main().layer_tree_host->SetAnimationEvents(std::move(events));
942 }
943
944 void ThreadProxy::InitializeImplOnImpl(CompletionEvent* completion,
945 LayerTreeHost* layer_tree_host) {
946 TRACE_EVENT0("cc", "ThreadProxy::InitializeImplOnImplThread");
947 DCHECK(task_runner_provider_->IsImplThread());
948 DCHECK(task_runner_provider_->IsMainThreadBlocked());
949 DCHECK(layer_tree_host);
950
951 // TODO(khushalsagar): ThreadedChannel will create ProxyImpl here and pass a
952 // reference to itself.
953 impl().channel_impl = threaded_channel_.get();
954
955 impl().layer_tree_host_impl = layer_tree_host->CreateLayerTreeHostImpl(this);
956
957 SchedulerSettings scheduler_settings(
958 layer_tree_host->settings().ToSchedulerSettings());
959
960 scoped_ptr<CompositorTimingHistory> compositor_timing_history(
961 new CompositorTimingHistory(CompositorTimingHistory::RENDERER_UMA,
962 impl().rendering_stats_instrumentation));
963
964 impl().scheduler =
965 Scheduler::Create(this, scheduler_settings, impl().layer_tree_host_id,
966 task_runner_provider_->ImplThreadTaskRunner(),
967 impl().external_begin_frame_source.get(),
968 std::move(compositor_timing_history));
969
970 DCHECK_EQ(impl().scheduler->visible(),
971 impl().layer_tree_host_impl->visible());
972 impl_thread_weak_ptr_ = impl().weak_factory.GetWeakPtr();
973 completion->Signal();
974 }
975
976 void ThreadProxy::InitializeOutputSurfaceOnImpl(OutputSurface* output_surface) {
977 TRACE_EVENT0("cc", "ThreadProxy::InitializeOutputSurfaceOnImplThread");
978 DCHECK(task_runner_provider_->IsImplThread());
979
980 LayerTreeHostImpl* host_impl = impl().layer_tree_host_impl.get();
981 bool success = host_impl->InitializeRenderer(output_surface);
982 RendererCapabilities capabilities;
983 if (success) {
984 capabilities =
985 host_impl->GetRendererCapabilities().MainThreadCapabilities();
986 }
987
988 impl().channel_impl->DidInitializeOutputSurface(success, capabilities);
989
990 if (success)
991 impl().scheduler->DidCreateAndInitializeOutputSurface();
992 }
993
994 void ThreadProxy::ReleaseOutputSurfaceOnImpl(CompletionEvent* completion) {
995 DCHECK(task_runner_provider_->IsImplThread());
996
997 // Unlike DidLoseOutputSurfaceOnImplThread, we don't need to call
998 // LayerTreeHost::DidLoseOutputSurface since it already knows.
999 impl().scheduler->DidLoseOutputSurface();
1000 impl().layer_tree_host_impl->ReleaseOutputSurface();
1001 completion->Signal();
1002 }
1003
1004 void ThreadProxy::FinishGLOnImpl(CompletionEvent* completion) {
1005 TRACE_EVENT0("cc", "ThreadProxy::FinishGLOnImplThread");
1006 DCHECK(task_runner_provider_->IsImplThread());
1007 if (impl().layer_tree_host_impl->output_surface()) {
1008 ContextProvider* context_provider =
1009 impl().layer_tree_host_impl->output_surface()->context_provider();
1010 if (context_provider)
1011 context_provider->ContextGL()->Finish();
1012 }
1013 completion->Signal();
1014 }
1015
1016 void ThreadProxy::LayerTreeHostClosedOnImpl(CompletionEvent* completion) {
1017 TRACE_EVENT0("cc", "ThreadProxy::LayerTreeHostClosedOnImplThread");
1018 DCHECK(task_runner_provider_->IsImplThread());
1019 DCHECK(task_runner_provider_->IsMainThreadBlocked());
1020 impl().scheduler = nullptr;
1021 impl().external_begin_frame_source = nullptr;
1022 impl().layer_tree_host_impl = nullptr;
1023 impl().weak_factory.InvalidateWeakPtrs();
1024 // We need to explicitly shutdown the notifier to destroy any weakptrs it is
1025 // holding while still on the compositor thread. This also ensures any
1026 // callbacks holding a ThreadProxy pointer are cancelled.
1027 impl().smoothness_priority_expiration_notifier.Shutdown();
1028 completion->Signal();
1029 }
1030
1031 bool ThreadProxy::MainFrameWillHappenForTesting() {
1032 DCHECK(task_runner_provider_->IsMainThread());
1033 bool main_frame_will_happen = false;
1034 {
1035 DebugScopedSetMainThreadBlocked main_thread_blocked(task_runner_provider_);
1036 CompletionEvent completion;
1037 main().channel_main->MainFrameWillHappenOnImplForTesting(
1038 &completion, &main_frame_will_happen);
1039 completion.Wait();
1040 }
1041 return main_frame_will_happen;
1042 }
1043
1044 void ThreadProxy::SetChildrenNeedBeginFrames(bool children_need_begin_frames) {
1045 NOTREACHED() << "Only used by SingleThreadProxy";
1046 }
1047
1048 void ThreadProxy::MainFrameWillHappenOnImplForTesting(
1049 CompletionEvent* completion,
1050 bool* main_frame_will_happen) {
1051 DCHECK(task_runner_provider_->IsImplThread());
1052 if (impl().layer_tree_host_impl->output_surface()) {
1053 *main_frame_will_happen = impl().scheduler->MainFrameForTestingWillHappen();
1054 } else {
1055 *main_frame_will_happen = false;
1056 }
1057 completion->Signal();
1058 }
1059
1060 void ThreadProxy::RenewTreePriority() {
1061 DCHECK(task_runner_provider_->IsImplThread());
1062 bool smoothness_takes_priority =
1063 impl().layer_tree_host_impl->pinch_gesture_active() ||
1064 impl().layer_tree_host_impl->page_scale_animation_active() ||
1065 impl().layer_tree_host_impl->IsActivelyScrolling();
1066
1067 // Schedule expiration if smoothness currently takes priority.
1068 if (smoothness_takes_priority)
1069 impl().smoothness_priority_expiration_notifier.Schedule();
1070
1071 // We use the same priority for both trees by default.
1072 TreePriority tree_priority = SAME_PRIORITY_FOR_BOTH_TREES;
1073
1074 // Smoothness takes priority if we have an expiration for it scheduled.
1075 if (impl().smoothness_priority_expiration_notifier.HasPendingNotification())
1076 tree_priority = SMOOTHNESS_TAKES_PRIORITY;
1077
1078 // New content always takes priority when there is an invalid viewport size or
1079 // ui resources have been evicted.
1080 if (impl().layer_tree_host_impl->active_tree()->ViewportSizeInvalid() ||
1081 impl().layer_tree_host_impl->EvictedUIResourcesExist() ||
1082 impl().input_throttled_until_commit) {
1083 // Once we enter NEW_CONTENTS_TAKES_PRIORITY mode, visible tiles on active
1084 // tree might be freed. We need to set RequiresHighResToDraw to ensure that
1085 // high res tiles will be required to activate pending tree.
1086 impl().layer_tree_host_impl->SetRequiresHighResToDraw();
1087 tree_priority = NEW_CONTENT_TAKES_PRIORITY;
1088 }
1089
1090 impl().layer_tree_host_impl->SetTreePriority(tree_priority);
1091
1092 // Only put the scheduler in impl latency prioritization mode if we don't
1093 // have a scroll listener. This gives the scroll listener a better chance of
1094 // handling scroll updates within the same frame. The tree itself is still
1095 // kept in prefer smoothness mode to allow checkerboarding.
1096 ScrollHandlerState scroll_handler_state =
1097 impl().layer_tree_host_impl->scroll_affects_scroll_handler()
1098 ? ScrollHandlerState::SCROLL_AFFECTS_SCROLL_HANDLER
1099 : ScrollHandlerState::SCROLL_DOES_NOT_AFFECT_SCROLL_HANDLER;
1100 impl().scheduler->SetTreePrioritiesAndScrollState(tree_priority,
1101 scroll_handler_state);
1102
1103 // Notify the the client of this compositor via the output surface.
1104 // TODO(epenner): Route this to compositor-thread instead of output-surface
1105 // after GTFO refactor of compositor-thread (http://crbug/170828).
1106 if (impl().layer_tree_host_impl->output_surface()) {
1107 impl()
1108 .layer_tree_host_impl->output_surface()
1109 ->UpdateSmoothnessTakesPriority(tree_priority ==
1110 SMOOTHNESS_TAKES_PRIORITY);
1111 }
1112 }
1113
1114 void ThreadProxy::PostDelayedAnimationTaskOnImplThread(
1115 const base::Closure& task,
1116 base::TimeDelta delay) {
1117 task_runner_provider_->ImplThreadTaskRunner()->PostDelayedTask(FROM_HERE,
1118 task, delay);
1119 }
1120
1121 void ThreadProxy::DidActivateSyncTree() {
1122 TRACE_EVENT0("cc", "ThreadProxy::DidActivateSyncTreeOnImplThread");
1123 DCHECK(task_runner_provider_->IsImplThread());
1124
1125 if (impl().next_commit_waits_for_activation) {
1126 TRACE_EVENT_INSTANT0(
1127 "cc", "ReleaseCommitbyActivation", TRACE_EVENT_SCOPE_THREAD);
1128 DCHECK(impl().commit_completion_event);
1129 impl().commit_completion_event->Signal();
1130 impl().commit_completion_event = nullptr;
1131 impl().next_commit_waits_for_activation = false;
1132 }
1133
1134 impl().last_processed_begin_main_frame_args =
1135 impl().last_begin_main_frame_args;
1136 }
1137
1138 void ThreadProxy::WillPrepareTiles() {
1139 DCHECK(task_runner_provider_->IsImplThread());
1140 impl().scheduler->WillPrepareTiles();
1141 }
1142
1143 void ThreadProxy::DidPrepareTiles() {
1144 DCHECK(task_runner_provider_->IsImplThread());
1145 impl().scheduler->DidPrepareTiles();
1146 }
1147
1148 void ThreadProxy::DidCompletePageScaleAnimationOnImplThread() {
1149 DCHECK(task_runner_provider_->IsImplThread());
1150 impl().channel_impl->DidCompletePageScaleAnimation();
1151 }
1152
1153 void ThreadProxy::OnDrawForOutputSurface() {
1154 DCHECK(task_runner_provider_->IsImplThread());
1155 impl().scheduler->OnDrawForOutputSurface();
1156 }
1157
1158 void ThreadProxy::UpdateTopControlsState(TopControlsState constraints,
1159 TopControlsState current,
1160 bool animate) {
1161 main().channel_main->UpdateTopControlsStateOnImpl(constraints, current,
1162 animate);
1163 }
1164
1165 void ThreadProxy::UpdateTopControlsStateOnImpl(TopControlsState constraints,
1166 TopControlsState current,
1167 bool animate) {
1168 DCHECK(task_runner_provider_->IsImplThread());
1169 impl().layer_tree_host_impl->top_controls_manager()->UpdateTopControlsState(
1170 constraints, current, animate);
1171 }
1172
1173 void ThreadProxy::PostFrameTimingEventsOnImplThread(
1174 scoped_ptr<FrameTimingTracker::CompositeTimingSet> composite_events,
1175 scoped_ptr<FrameTimingTracker::MainFrameTimingSet> main_frame_events) {
1176 DCHECK(task_runner_provider_->IsImplThread());
1177 impl().channel_impl->PostFrameTimingEventsOnMain(
1178 std::move(composite_events), std::move(main_frame_events));
1179 }
1180
1181 void ThreadProxy::PostFrameTimingEventsOnMain(
1182 scoped_ptr<FrameTimingTracker::CompositeTimingSet> composite_events,
1183 scoped_ptr<FrameTimingTracker::MainFrameTimingSet> main_frame_events) {
1184 DCHECK(task_runner_provider_->IsMainThread());
1185 main().layer_tree_host->RecordFrameTimingEvents(std::move(composite_events),
1186 std::move(main_frame_events));
1187 }
1188
1189 base::WeakPtr<ProxyMain> ThreadProxy::GetMainWeakPtr() {
1190 return main_thread_weak_ptr_;
1191 }
1192
1193 base::WeakPtr<ProxyImpl> ThreadProxy::GetImplWeakPtr() {
1194 return impl_thread_weak_ptr_;
1195 }
1196
1197 } // namespace cc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698