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

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

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

Powered by Google App Engine
This is Rietveld 408576698