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

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

Issue 1417053005: cc: Split ThreadProxy into ProxyMain and ProxyImpl (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 1 month 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 2015 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/proxy_impl.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 "cc/trees/task_runner_provider.h"
31 #include "gpu/command_buffer/client/gles2_interface.h"
32
33 namespace cc {
34
35 namespace {
36
37 // Measured in seconds.
38 const double kSmoothnessTakesPriorityExpirationDelay = 0.25;
39
40 unsigned int nextBeginFrameId = 0;
41
42 } // namespace
43
44 scoped_ptr<ProxyImpl> ProxyImpl::Create(
45 ChannelImpl* channel_impl,
46 LayerTreeHost* layer_tree_host,
47 TaskRunnerProvider* task_runner_provider,
48 scoped_ptr<BeginFrameSource> external_begin_frame_source) {
49 return make_scoped_ptr(new ProxyImpl(channel_impl, layer_tree_host,
50 task_runner_provider,
51 external_begin_frame_source.Pass()));
52 }
53
54 ProxyImpl::ProxyImpl(ChannelImpl* channel_impl,
55 LayerTreeHost* layer_tree_host,
56 TaskRunnerProvider* task_runner_provider,
57 scoped_ptr<BeginFrameSource> external_begin_frame_source)
58 : layer_tree_host_id_(layer_tree_host->id()),
59 next_commit_waits_for_activation_(false),
60 commit_completion_event_(nullptr),
61 next_frame_is_newly_committed_frame_(false),
62 inside_draw_(false),
63 input_throttled_until_commit_(false),
64 stopped_(false),
65 task_runner_provider_(task_runner_provider),
66 smoothness_priority_expiration_notifier_(
67 task_runner_provider->ImplThreadTaskRunner(),
68 base::Bind(&ProxyImpl::RenewTreePriority, base::Unretained(this)),
69 base::TimeDelta::FromMilliseconds(
70 kSmoothnessTakesPriorityExpirationDelay * 1000)),
71 external_begin_frame_source_(external_begin_frame_source.Pass()),
72 rendering_stats_instrumentation_(
73 layer_tree_host->rendering_stats_instrumentation()),
74 channel_impl_(channel_impl),
75 weak_factory_(this) {
76 TRACE_EVENT0("cc", "ProxyImpl::ProxyImpl");
77 DCHECK(IsImplThread());
78 DCHECK(IsMainThreadBlocked());
79 DCHECK(layer_tree_host);
80
81 layer_tree_host_impl_ = layer_tree_host->CreateLayerTreeHostImpl(this);
82
83 SchedulerSettings scheduler_settings(
84 layer_tree_host->settings().ToSchedulerSettings());
85
86 scoped_ptr<CompositorTimingHistory> compositor_timing_history(
87 new CompositorTimingHistory(CompositorTimingHistory::RENDERER_UMA,
88 rendering_stats_instrumentation_));
89
90 scheduler_ = Scheduler::Create(this, scheduler_settings, layer_tree_host_id_,
91 task_runner_provider_->ImplThreadTaskRunner(),
92 external_begin_frame_source_.get(),
93 compositor_timing_history.Pass());
94
95 DCHECK_EQ(scheduler_->visible(), layer_tree_host_impl_->visible());
96 impl_thread_weak_ptr_ = weak_factory_.GetWeakPtr();
97 }
98
99 ProxyImpl::BlockedMainCommitOnly::BlockedMainCommitOnly()
100 : layer_tree_host(nullptr) {}
101
102 ProxyImpl::BlockedMainCommitOnly::~BlockedMainCommitOnly() {}
103
104 ProxyImpl::~ProxyImpl() {
105 TRACE_EVENT0("cc", "ProxyImpl::~ProxyImpl");
106 DCHECK(IsImplThread());
107 DCHECK(stopped_);
108 }
109
110 void ProxyImpl::SetVisibleOnImpl(bool visible) {
111 TRACE_EVENT1("cc", "ProxyImpl::SetVisibleOnImplThread", "visible", visible);
112 layer_tree_host_impl_->SetVisible(visible);
113 scheduler_->SetVisible(visible);
114 }
115
116 void ProxyImpl::SetThrottleFrameProductionOnImpl(bool throttle) {
117 TRACE_EVENT1("cc", "ProxyImpl::SetThrottleFrameProductionOnImplThread",
118 "throttle", throttle);
119 scheduler_->SetThrottleFrameProduction(throttle);
120 }
121
122 void ProxyImpl::SetNeedsCommitOnImpl() {
123 DCHECK(IsImplThread());
124 SetNeedsCommitOnImplThread();
125 }
126
127 void ProxyImpl::UpdateRendererCapabilitiesOnImplThread() {
128 DCHECK(IsImplThread());
129 channel_impl_->SetRendererCapabilitiesMainCopy(
130 layer_tree_host_impl_->GetRendererCapabilities()
131 .MainThreadCapabilities());
132 }
133
134 void ProxyImpl::DidLoseOutputSurfaceOnImplThread() {
135 TRACE_EVENT0("cc", "ProxyImpl::DidLoseOutputSurfaceOnImplThread");
136 DCHECK(IsImplThread());
137 channel_impl_->DidLoseOutputSurface();
138 scheduler_->DidLoseOutputSurface();
139 }
140
141 void ProxyImpl::CommitVSyncParameters(base::TimeTicks timebase,
142 base::TimeDelta interval) {
143 scheduler_->CommitVSyncParameters(timebase, interval);
144 }
145
146 void ProxyImpl::SetEstimatedParentDrawTime(base::TimeDelta draw_time) {
147 scheduler_->SetEstimatedParentDrawTime(draw_time);
148 }
149
150 void ProxyImpl::SetMaxSwapsPendingOnImplThread(int max) {
151 scheduler_->SetMaxSwapsPending(max);
152 }
153
154 void ProxyImpl::DidSwapBuffersOnImplThread() {
155 scheduler_->DidSwapBuffers();
156 }
157
158 void ProxyImpl::DidSwapBuffersCompleteOnImplThread() {
159 TRACE_EVENT0("cc,benchmark", "ProxyImpl::DidSwapBuffersCompleteOnImplThread");
160 DCHECK(IsImplThread());
161 scheduler_->DidSwapBuffersComplete();
162 channel_impl_->DidCompleteSwapBuffers();
163 }
164
165 void ProxyImpl::WillBeginImplFrame(const BeginFrameArgs& args) {
166 layer_tree_host_impl_->WillBeginImplFrame(args);
167 if (last_processed_begin_main_frame_args_.IsValid()) {
168 // Last processed begin main frame args records the frame args that we sent
169 // to the main thread for the last frame that we've processed. If that is
170 // set, that means the current frame is one past the frame in which we've
171 // finished the processing.
172 layer_tree_host_impl_->RecordMainFrameTiming(
173 last_processed_begin_main_frame_args_,
174 layer_tree_host_impl_->CurrentBeginFrameArgs());
175 last_processed_begin_main_frame_args_ = BeginFrameArgs();
176 }
177 }
178
179 void ProxyImpl::OnResourcelessSoftareDrawStateChanged(bool resourceless_draw) {
180 DCHECK(IsImplThread());
181 scheduler_->SetResourcelessSoftareDraw(resourceless_draw);
182 }
183
184 void ProxyImpl::OnCanDrawStateChanged(bool can_draw) {
185 TRACE_EVENT1("cc", "ProxyImpl::OnCanDrawStateChanged", "can_draw", can_draw);
186 DCHECK(IsImplThread());
187 scheduler_->SetCanDraw(can_draw);
188 }
189
190 void ProxyImpl::NotifyReadyToActivate() {
191 TRACE_EVENT0("cc", "ProxyImpl::NotifyReadyToActivate");
192 scheduler_->NotifyReadyToActivate();
193 }
194
195 void ProxyImpl::NotifyReadyToDraw() {
196 TRACE_EVENT0("cc", "ProxyImpl::NotifyReadyToDraw");
197 scheduler_->NotifyReadyToDraw();
198 }
199
200 void ProxyImpl::SetNeedsCommitOnImplThread() {
201 TRACE_EVENT0("cc", "ProxyImpl::SetNeedsCommitOnImplThread");
202 DCHECK(IsImplThread());
203 scheduler_->SetNeedsBeginMainFrame();
204 }
205
206 void ProxyImpl::SetVideoNeedsBeginFrames(bool needs_begin_frames) {
207 TRACE_EVENT1("cc", "ProxyImpl::SetVideoNeedsBeginFrames",
208 "needs_begin_frames", needs_begin_frames);
209 DCHECK(IsImplThread());
210 // In tests the layer tree is destroyed after the scheduler is.
211 if (scheduler_)
212 scheduler_->SetVideoNeedsBeginFrames(needs_begin_frames);
213 }
214
215 void ProxyImpl::PostAnimationEventsToMainThreadOnImplThread(
216 scoped_ptr<AnimationEventsVector> events) {
217 TRACE_EVENT0("cc", "ProxyImpl::PostAnimationEventsToMainThreadOnImplThread");
218 DCHECK(IsImplThread());
219 channel_impl_->SetAnimationEvents(events.Pass());
220 }
221
222 bool ProxyImpl::IsInsideDraw() {
223 return inside_draw_;
224 }
225
226 void ProxyImpl::SetNeedsRedrawOnImpl(const gfx::Rect& damage_rect) {
227 DCHECK(IsImplThread());
228 SetNeedsRedrawRectOnImplThread(damage_rect);
229 }
230
231 void ProxyImpl::SetDeferCommitsOnImpl(bool defer_commits) const {
232 DCHECK(IsImplThread());
233 scheduler_->SetDeferCommits(defer_commits);
234 }
235
236 void ProxyImpl::SetNeedsRedrawOnImplThread() {
237 TRACE_EVENT0("cc", "ProxyImpl::SetNeedsRedrawOnImplThread");
238 DCHECK(IsImplThread());
239 scheduler_->SetNeedsRedraw();
240 }
241
242 void ProxyImpl::SetNeedsAnimateOnImplThread() {
243 TRACE_EVENT0("cc", "ProxyImpl::SetNeedsAnimateOnImplThread");
244 DCHECK(IsImplThread());
245 scheduler_->SetNeedsAnimate();
246 }
247
248 void ProxyImpl::SetNeedsPrepareTilesOnImplThread() {
249 DCHECK(IsImplThread());
250 scheduler_->SetNeedsPrepareTiles();
251 }
252
253 void ProxyImpl::SetNeedsRedrawRectOnImplThread(const gfx::Rect& damage_rect) {
254 DCHECK(IsImplThread());
255 layer_tree_host_impl_->SetViewportDamage(damage_rect);
256 SetNeedsRedrawOnImplThread();
257 }
258
259 void ProxyImpl::MainThreadHasStoppedFlingingOnImpl() {
260 DCHECK(IsImplThread());
261 layer_tree_host_impl_->MainThreadHasStoppedFlinging();
262 }
263
264 void ProxyImpl::SetInputThrottledUntilCommitOnImpl(bool is_throttled) {
265 DCHECK(IsImplThread());
266 if (is_throttled == input_throttled_until_commit_)
267 return;
268 input_throttled_until_commit_ = is_throttled;
269 RenewTreePriority();
270 }
271
272 ProxyImpl::BlockedMainCommitOnly& ProxyImpl::blocked_main_commit() {
273 DCHECK(IsMainThreadBlocked() && commit_completion_event_);
274 return main_thread_blocked_commit_vars_unsafe_;
275 }
276
277 void ProxyImpl::FinishAllRenderingOnImpl(CompletionEvent* completion) {
278 TRACE_EVENT0("cc", "ProxyImpl::FinishAllRenderingOnImplThread");
279 DCHECK(IsImplThread());
280 layer_tree_host_impl_->FinishAllRendering();
281 completion->Signal();
282 }
283
284 void ProxyImpl::ScheduledActionSendBeginMainFrame() {
285 unsigned int begin_frame_id = nextBeginFrameId++;
286 benchmark_instrumentation::ScopedBeginFrameTask begin_frame_task(
287 benchmark_instrumentation::kSendBeginFrame, begin_frame_id);
288 scoped_ptr<BeginMainFrameAndCommitState> begin_main_frame_state(
289 new BeginMainFrameAndCommitState);
290 begin_main_frame_state->begin_frame_id = begin_frame_id;
291 begin_main_frame_state->begin_frame_args =
292 layer_tree_host_impl_->CurrentBeginFrameArgs();
293 begin_main_frame_state->scroll_info =
294 layer_tree_host_impl_->ProcessScrollDeltas();
295 begin_main_frame_state->memory_allocation_limit_bytes =
296 layer_tree_host_impl_->memory_allocation_limit_bytes();
297 begin_main_frame_state->evicted_ui_resources =
298 layer_tree_host_impl_->EvictedUIResourcesExist();
299 // TODO(vmpstr): This needs to be fixed if
300 // main_frame_before_activation_enabled is set, since we might run this code
301 // twice before recording a duration. crbug.com/469824
302 last_begin_main_frame_args_ = begin_main_frame_state->begin_frame_args;
303 channel_impl_->BeginMainFrame(begin_main_frame_state.Pass());
304 devtools_instrumentation::DidRequestMainThreadFrame(layer_tree_host_id_);
305 }
306
307 void ProxyImpl::SendBeginMainFrameNotExpectedSoon() {
308 channel_impl_->BeginMainFrameNotExpectedSoon();
309 }
310
311 void ProxyImpl::StartCommitOnImpl(CompletionEvent* completion,
312 LayerTreeHost* layer_tree_host,
313 bool hold_commit_for_activation) {
314 TRACE_EVENT0("cc", "ProxyImpl::StartCommitOnImplThread");
315 DCHECK(!commit_completion_event_);
316 DCHECK(IsImplThread() && IsMainThreadBlocked());
317 DCHECK(scheduler_);
318 DCHECK(scheduler_->CommitPending());
319
320 if (hold_commit_for_activation) {
321 // This commit may be aborted. Store the value for
322 // hold_commit_for_activation so that whenever the next commit is started,
323 // the main thread will be unblocked only after pending tree activation.
324 next_commit_waits_for_activation_ = hold_commit_for_activation;
325 }
326
327 if (!layer_tree_host_impl_) {
328 TRACE_EVENT_INSTANT0("cc", "EarlyOut_NoLayerTree",
329 TRACE_EVENT_SCOPE_THREAD);
330 completion->Signal();
331 return;
332 }
333
334 // Ideally, we should inform to impl thread when BeginMainFrame is started.
335 // But, we can avoid a PostTask in here.
336 scheduler_->NotifyBeginMainFrameStarted();
337 commit_completion_event_ = completion;
338 DCHECK(!blocked_main_commit().layer_tree_host);
339 blocked_main_commit().layer_tree_host = layer_tree_host;
340 scheduler_->NotifyReadyToCommit();
341 }
342
343 void ProxyImpl::BeginMainFrameAbortedOnImpl(CommitEarlyOutReason reason) {
344 TRACE_EVENT1("cc", "ProxyImpl::BeginMainFrameAbortedOnImplThread", "reason",
345 CommitEarlyOutReasonToString(reason));
346 DCHECK(IsImplThread());
347 DCHECK(scheduler_);
348 DCHECK(scheduler_->CommitPending());
349 DCHECK(!layer_tree_host_impl_->pending_tree());
350
351 if (CommitEarlyOutHandledCommit(reason)) {
352 SetInputThrottledUntilCommitOnImpl(false);
353 last_processed_begin_main_frame_args_ = last_begin_main_frame_args_;
354 }
355 layer_tree_host_impl_->BeginMainFrameAborted(reason);
356 scheduler_->BeginMainFrameAborted(reason);
357 }
358
359 void ProxyImpl::ScheduledActionAnimate() {
360 TRACE_EVENT0("cc", "ProxyImpl::ScheduledActionAnimate");
361 DCHECK(IsImplThread());
362
363 layer_tree_host_impl_->Animate();
364 }
365
366 void ProxyImpl::ScheduledActionCommit() {
367 TRACE_EVENT0("cc", "ProxyImpl::ScheduledActionCommit");
368 DCHECK(IsImplThread());
369 DCHECK(IsMainThreadBlocked());
370 DCHECK(commit_completion_event_);
371 DCHECK(blocked_main_commit().layer_tree_host);
372
373 layer_tree_host_impl_->BeginCommit();
374 blocked_main_commit().layer_tree_host->FinishCommitOnImplThread(
375 layer_tree_host_impl_.get());
376
377 // Remove the LayerTreeHost reference before the completion event is signaled
378 // and cleared. This is necessary since blocked_main_commit() allows access
379 // only while we have the completion event to ensure the main thread is
380 // blocked for a commit.
381 blocked_main_commit().layer_tree_host = nullptr;
382
383 if (next_commit_waits_for_activation_) {
384 // For some layer types in impl-side painting, the commit is held until
385 // the sync tree is activated. It's also possible that the
386 // sync tree has already activated if there was no work to be done.
387 TRACE_EVENT_INSTANT0("cc", "HoldCommit", TRACE_EVENT_SCOPE_THREAD);
388 } else {
389 commit_completion_event_->Signal();
390 commit_completion_event_ = nullptr;
391 }
392
393 scheduler_->DidCommit();
394
395 // Delay this step until afer the main thread has been released as it's
396 // often a good bit of work to update the tree and prepare the new frame.
397 layer_tree_host_impl_->CommitComplete();
398
399 SetInputThrottledUntilCommitOnImpl(false);
400
401 next_frame_is_newly_committed_frame_ = true;
402 }
403
404 void ProxyImpl::ScheduledActionActivateSyncTree() {
405 TRACE_EVENT0("cc", "ProxyImpl::ScheduledActionActivateSyncTree");
406 DCHECK(IsImplThread());
407 layer_tree_host_impl_->ActivateSyncTree();
408 }
409
410 void ProxyImpl::ScheduledActionBeginOutputSurfaceCreation() {
411 TRACE_EVENT0("cc", "ProxyImpl::ScheduledActionBeginOutputSurfaceCreation");
412 DCHECK(IsImplThread());
413 channel_impl_->RequestNewOutputSurface();
414 }
415
416 DrawResult ProxyImpl::DrawSwapInternal(bool forced_draw) {
417 TRACE_EVENT_SYNTHETIC_DELAY("cc.DrawAndSwap");
418 DrawResult result;
419
420 DCHECK(IsImplThread());
421 DCHECK(layer_tree_host_impl_.get());
422
423 base::AutoReset<bool> mark_inside(&inside_draw_, true);
424
425 if (layer_tree_host_impl_->pending_tree()) {
426 bool update_lcd_text = false;
427 layer_tree_host_impl_->pending_tree()->UpdateDrawProperties(
428 update_lcd_text);
429 }
430
431 // This method is called on a forced draw, regardless of whether we are able
432 // to produce a frame, as the calling site on main thread is blocked until its
433 // request completes, and we signal completion here. If CanDraw() is false, we
434 // will indicate success=false to the caller, but we must still signal
435 // completion to avoid deadlock.
436
437 // We guard PrepareToDraw() with CanDraw() because it always returns a valid
438 // frame, so can only be used when such a frame is possible. Since
439 // DrawLayers() depends on the result of PrepareToDraw(), it is guarded on
440 // CanDraw() as well.
441
442 LayerTreeHostImpl::FrameData frame;
443 bool draw_frame = false;
444
445 if (layer_tree_host_impl_->CanDraw()) {
446 result = layer_tree_host_impl_->PrepareToDraw(&frame);
447 draw_frame = forced_draw || result == DRAW_SUCCESS;
448 } else {
449 result = DRAW_ABORTED_CANT_DRAW;
450 }
451
452 if (draw_frame) {
453 layer_tree_host_impl_->DrawLayers(&frame);
454 result = DRAW_SUCCESS;
455 } else {
456 DCHECK_NE(DRAW_SUCCESS, result);
457 }
458 layer_tree_host_impl_->DidDrawAllLayers(frame);
459
460 bool start_ready_animations = draw_frame;
461 layer_tree_host_impl_->UpdateAnimationState(start_ready_animations);
462
463 if (draw_frame)
464 layer_tree_host_impl_->SwapBuffers(frame);
465
466 // Tell the main thread that the the newly-commited frame was drawn.
467 if (next_frame_is_newly_committed_frame_) {
468 next_frame_is_newly_committed_frame_ = false;
469 channel_impl_->DidCommitAndDrawFrame();
470 }
471
472 DCHECK_NE(INVALID_RESULT, result);
473 return result;
474 }
475
476 void ProxyImpl::ScheduledActionPrepareTiles() {
477 TRACE_EVENT0("cc", "ProxyImpl::ScheduledActionPrepareTiles");
478 layer_tree_host_impl_->PrepareTiles();
479 }
480
481 DrawResult ProxyImpl::ScheduledActionDrawAndSwapIfPossible() {
482 TRACE_EVENT0("cc", "ProxyImpl::ScheduledActionDrawAndSwap");
483
484 // SchedulerStateMachine::DidDrawIfPossibleCompleted isn't set up to
485 // handle DRAW_ABORTED_CANT_DRAW. Moreover, the scheduler should
486 // never generate this call when it can't draw.
487 DCHECK(layer_tree_host_impl_->CanDraw());
488
489 bool forced_draw = false;
490 return DrawSwapInternal(forced_draw);
491 }
492
493 DrawResult ProxyImpl::ScheduledActionDrawAndSwapForced() {
494 TRACE_EVENT0("cc", "ProxyImpl::ScheduledActionDrawAndSwapForced");
495 bool forced_draw = true;
496 return DrawSwapInternal(forced_draw);
497 }
498
499 void ProxyImpl::ScheduledActionInvalidateOutputSurface() {
500 TRACE_EVENT0("cc", "ProxyImpl::ScheduledActionInvalidateOutputSurface");
501 DCHECK(layer_tree_host_impl_->output_surface());
502 layer_tree_host_impl_->output_surface()->Invalidate();
503 }
504
505 void ProxyImpl::DidFinishImplFrame() {
506 layer_tree_host_impl_->DidFinishImplFrame();
507 }
508
509 void ProxyImpl::SendBeginFramesToChildren(const BeginFrameArgs& args) {
510 NOTREACHED() << "Only used by SingleProxyImpl";
511 }
512
513 void ProxyImpl::InitializeOutputSurfaceOnImpl(OutputSurface* output_surface) {
514 TRACE_EVENT0("cc", "ProxyImpl::InitializeOutputSurfaceOnImplThread");
515 DCHECK(IsImplThread());
516
517 LayerTreeHostImpl* host_impl = layer_tree_host_impl_.get();
518 bool success = host_impl->InitializeRenderer(output_surface);
519 RendererCapabilities capabilities;
520 if (success) {
521 capabilities =
522 host_impl->GetRendererCapabilities().MainThreadCapabilities();
523 }
524
525 channel_impl_->DidInitializeOutputSurface(success, capabilities);
526
527 if (success)
528 scheduler_->DidCreateAndInitializeOutputSurface();
529 }
530
531 void ProxyImpl::ReleaseOutputSurfaceOnImpl(CompletionEvent* completion) {
532 DCHECK(IsImplThread());
533
534 // Unlike DidLoseOutputSurfaceOnImplThread, we don't need to call
535 // LayerTreeHost::DidLoseOutputSurface since it already knows.
536 scheduler_->DidLoseOutputSurface();
537 layer_tree_host_impl_->ReleaseOutputSurface();
538 completion->Signal();
539 }
540
541 void ProxyImpl::FinishGLOnImpl(CompletionEvent* completion) {
542 TRACE_EVENT0("cc", "ProxyImpl::FinishGLOnImplThread");
543 DCHECK(IsImplThread());
544 if (layer_tree_host_impl_->output_surface()) {
545 ContextProvider* context_provider =
546 layer_tree_host_impl_->output_surface()->context_provider();
547 if (context_provider)
548 context_provider->ContextGL()->Finish();
549 }
550 completion->Signal();
551 }
552
553 void ProxyImpl::LayerTreeHostClosedOnImpl() {
554 TRACE_EVENT0("cc", "ProxyImpl::LayerTreeHostClosedOnImplThread");
555 DCHECK(IsImplThread());
556 DCHECK(IsMainThreadBlocked());
557
558 scheduler_ = nullptr;
559 external_begin_frame_source_ = nullptr;
560 layer_tree_host_impl_ = nullptr;
561 weak_factory_.InvalidateWeakPtrs();
562 // We need to explicitly shutdown the notifier to destroy any weakptrs it is
563 // holding while still on the compositor thread. This also ensures any
564 // callbacks holding a ProxyImpl pointer are cancelled.
565 smoothness_priority_expiration_notifier_.Shutdown();
566 stopped_ = true;
567 }
568
569 void ProxyImpl::MainFrameWillHappenOnImplForTesting(
570 CompletionEvent* completion,
571 bool* main_frame_will_happen) {
572 DCHECK(IsImplThread());
573 if (layer_tree_host_impl_->output_surface()) {
574 *main_frame_will_happen = scheduler_->MainFrameForTestingWillHappen();
575 } else {
576 *main_frame_will_happen = false;
577 }
578 completion->Signal();
579 }
580
581 void ProxyImpl::RenewTreePriority() {
582 DCHECK(IsImplThread());
583 bool smoothness_takes_priority =
584 layer_tree_host_impl_->pinch_gesture_active() ||
585 layer_tree_host_impl_->page_scale_animation_active() ||
586 layer_tree_host_impl_->IsActivelyScrolling();
587
588 // Schedule expiration if smoothness currently takes priority.
589 if (smoothness_takes_priority)
590 smoothness_priority_expiration_notifier_.Schedule();
591
592 // We use the same priority for both trees by default.
593 TreePriority priority = SAME_PRIORITY_FOR_BOTH_TREES;
594
595 // Smoothness takes priority if we have an expiration for it scheduled.
596 if (smoothness_priority_expiration_notifier_.HasPendingNotification())
597 priority = SMOOTHNESS_TAKES_PRIORITY;
598
599 // New content always takes priority when there is an invalid viewport size or
600 // ui resources have been evicted.
601 if (layer_tree_host_impl_->active_tree()->ViewportSizeInvalid() ||
602 layer_tree_host_impl_->EvictedUIResourcesExist() ||
603 input_throttled_until_commit_) {
604 // Once we enter NEW_CONTENTS_TAKES_PRIORITY mode, visible tiles on active
605 // tree might be freed. We need to set RequiresHighResToDraw to ensure that
606 // high res tiles will be required to activate pending tree.
607 layer_tree_host_impl_->SetRequiresHighResToDraw();
608 priority = NEW_CONTENT_TAKES_PRIORITY;
609 }
610
611 layer_tree_host_impl_->SetTreePriority(priority);
612
613 // Only put the scheduler in impl latency prioritization mode if we don't
614 // have a scroll listener. This gives the scroll listener a better chance of
615 // handling scroll updates within the same frame. The tree itself is still
616 // kept in prefer smoothness mode to allow checkerboarding.
617 scheduler_->SetImplLatencyTakesPriority(
618 priority == SMOOTHNESS_TAKES_PRIORITY &&
619 !layer_tree_host_impl_->scroll_affects_scroll_handler());
620
621 // Notify the the client of this compositor via the output surface.
622 // TODO(epenner): Route this to compositor-thread instead of output-surface
623 // after GTFO refactor of compositor-thread (http://crbug/170828).
624 if (layer_tree_host_impl_->output_surface()) {
625 layer_tree_host_impl_->output_surface()->UpdateSmoothnessTakesPriority(
626 priority == SMOOTHNESS_TAKES_PRIORITY);
627 }
628 }
629
630 void ProxyImpl::PostDelayedAnimationTaskOnImplThread(const base::Closure& task,
631 base::TimeDelta delay) {
632 task_runner_provider_->ImplThreadTaskRunner()->PostDelayedTask(FROM_HERE,
633 task, delay);
634 }
635
636 void ProxyImpl::DidActivateSyncTree() {
637 TRACE_EVENT0("cc", "ProxyImpl::DidActivateSyncTreeOnImplThread");
638 DCHECK(IsImplThread());
639
640 if (next_commit_waits_for_activation_) {
641 TRACE_EVENT_INSTANT0("cc", "ReleaseCommitbyActivation",
642 TRACE_EVENT_SCOPE_THREAD);
643 DCHECK(commit_completion_event_);
644 commit_completion_event_->Signal();
645 commit_completion_event_ = nullptr;
646 next_commit_waits_for_activation_ = false;
647 }
648
649 last_processed_begin_main_frame_args_ = last_begin_main_frame_args_;
650 }
651
652 void ProxyImpl::WillPrepareTiles() {
653 DCHECK(IsImplThread());
654 scheduler_->WillPrepareTiles();
655 }
656
657 void ProxyImpl::DidPrepareTiles() {
658 DCHECK(IsImplThread());
659 scheduler_->DidPrepareTiles();
660 }
661
662 void ProxyImpl::DidCompletePageScaleAnimationOnImplThread() {
663 DCHECK(IsImplThread());
664 channel_impl_->DidCompletePageScaleAnimation();
665 }
666
667 void ProxyImpl::OnDrawForOutputSurface() {
668 DCHECK(IsImplThread());
669 scheduler_->OnDrawForOutputSurface();
670 }
671
672 void ProxyImpl::UpdateTopControlsStateOnImpl(TopControlsState constraints,
673 TopControlsState current,
674 bool animate) {
675 DCHECK(IsImplThread());
676 layer_tree_host_impl_->top_controls_manager()->UpdateTopControlsState(
677 constraints, current, animate);
678 }
679
680 void ProxyImpl::PostFrameTimingEventsOnImplThread(
681 scoped_ptr<FrameTimingTracker::CompositeTimingSet> composite_events,
682 scoped_ptr<FrameTimingTracker::MainFrameTimingSet> main_frame_events) {
683 DCHECK(IsImplThread());
684 channel_impl_->PostFrameTimingEventsOnMain(composite_events.Pass(),
685 main_frame_events.Pass());
686 }
687
688 bool ProxyImpl::IsImplThread() const {
689 return task_runner_provider_->IsImplThread();
690 }
691
692 bool ProxyImpl::IsMainThreadBlocked() const {
693 return task_runner_provider_->IsMainThreadBlocked();
694 }
695
696 base::WeakPtr<ProxyImpl> ProxyImpl::GetWeakPtr() {
697 return impl_thread_weak_ptr_;
698 }
699
700 bool ProxyImpl::HasCommitCompletionEvent() const {
701 return !!commit_completion_event_;
702 }
703
704 } // namespace cc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698