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

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

Powered by Google App Engine
This is Rietveld 408576698