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

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

Powered by Google App Engine
This is Rietveld 408576698