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

Side by Side Diff: cc/trees/proxy_main.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_main.h ('k') | cc/trees/thread_proxy.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_main.h"
6
7 #include <algorithm>
8 #include <string>
9
10 #include "base/trace_event/trace_event.h"
11 #include "base/trace_event/trace_event_argument.h"
12 #include "base/trace_event/trace_event_synthetic_delay.h"
13 #include "cc/debug/benchmark_instrumentation.h"
14 #include "cc/debug/devtools_instrumentation.h"
15 #include "cc/output/output_surface.h"
16 #include "cc/output/swap_promise.h"
17 #include "cc/trees/blocking_task_runner.h"
18 #include "cc/trees/layer_tree_host.h"
19 #include "cc/trees/scoped_abort_remaining_swap_promises.h"
20 #include "cc/trees/threaded_channel.h"
21
22 namespace cc {
23
24 scoped_ptr<ProxyMain> ProxyMain::CreateThreaded(
25 LayerTreeHost* layer_tree_host,
26 TaskRunnerProvider* task_runner_provider,
27 scoped_ptr<BeginFrameSource> external_begin_frame_source) {
28 scoped_ptr<ProxyMain> proxy_main(
29 new ProxyMain(layer_tree_host, task_runner_provider,
30 std::move(external_begin_frame_source)));
31 proxy_main->SetChannel(
32 ThreadedChannel::Create(proxy_main.get(), task_runner_provider));
33 return proxy_main;
34 }
35
36 ProxyMain::ProxyMain(LayerTreeHost* layer_tree_host,
37 TaskRunnerProvider* task_runner_provider,
38 scoped_ptr<BeginFrameSource> external_begin_frame_source)
39 : layer_tree_host_(layer_tree_host),
40 task_runner_provider_(task_runner_provider),
41 layer_tree_host_id_(layer_tree_host->id()),
42 max_requested_pipeline_stage_(NO_PIPELINE_STAGE),
43 current_pipeline_stage_(NO_PIPELINE_STAGE),
44 final_pipeline_stage_(NO_PIPELINE_STAGE),
45 commit_waits_for_activation_(false),
46 started_(false),
47 defer_commits_(false),
48 external_begin_frame_source_(std::move(external_begin_frame_source)) {
49 TRACE_EVENT0("cc", "ProxyMain::ProxyMain");
50 DCHECK(task_runner_provider_);
51 DCHECK(IsMainThread());
52 DCHECK(!layer_tree_host_->settings().use_external_begin_frame_source ||
53 external_begin_frame_source_);
54 }
55
56 ProxyMain::~ProxyMain() {
57 TRACE_EVENT0("cc", "ProxyMain::~ProxyMain");
58 DCHECK(IsMainThread());
59 DCHECK(!started_);
60 }
61
62 void ProxyMain::SetChannel(scoped_ptr<ChannelMain> channel_main) {
63 DCHECK(!channel_main_);
64 channel_main_ = std::move(channel_main);
65 }
66
67 void ProxyMain::DidCompleteSwapBuffers() {
68 DCHECK(IsMainThread());
69 layer_tree_host_->DidCompleteSwapBuffers();
70 }
71
72 void ProxyMain::SetRendererCapabilities(
73 const RendererCapabilities& capabilities) {
74 DCHECK(IsMainThread());
75 renderer_capabilities_ = capabilities;
76 }
77
78 void ProxyMain::BeginMainFrameNotExpectedSoon() {
79 TRACE_EVENT0("cc", "ProxyMain::BeginMainFrameNotExpectedSoon");
80 DCHECK(IsMainThread());
81 layer_tree_host_->BeginMainFrameNotExpectedSoon();
82 }
83
84 void ProxyMain::DidCommitAndDrawFrame() {
85 DCHECK(IsMainThread());
86 layer_tree_host_->DidCommitAndDrawFrame();
87 }
88
89 void ProxyMain::SetAnimationEvents(scoped_ptr<AnimationEventsVector> events) {
90 TRACE_EVENT0("cc", "ProxyMain::SetAnimationEvents");
91 DCHECK(IsMainThread());
92 layer_tree_host_->SetAnimationEvents(std::move(events));
93 }
94
95 void ProxyMain::DidLoseOutputSurface() {
96 TRACE_EVENT0("cc", "ProxyMain::DidLoseOutputSurface");
97 DCHECK(IsMainThread());
98 layer_tree_host_->DidLoseOutputSurface();
99 }
100
101 void ProxyMain::RequestNewOutputSurface() {
102 DCHECK(IsMainThread());
103 layer_tree_host_->RequestNewOutputSurface();
104 }
105
106 void ProxyMain::DidInitializeOutputSurface(
107 bool success,
108 const RendererCapabilities& capabilities) {
109 TRACE_EVENT0("cc", "ProxyMain::DidInitializeOutputSurface");
110 DCHECK(IsMainThread());
111
112 if (!success) {
113 layer_tree_host_->DidFailToInitializeOutputSurface();
114 return;
115 }
116 renderer_capabilities_ = capabilities;
117 layer_tree_host_->DidInitializeOutputSurface();
118 }
119
120 void ProxyMain::DidCompletePageScaleAnimation() {
121 DCHECK(IsMainThread());
122 layer_tree_host_->DidCompletePageScaleAnimation();
123 }
124
125 void ProxyMain::PostFrameTimingEventsOnMain(
126 scoped_ptr<FrameTimingTracker::CompositeTimingSet> composite_events,
127 scoped_ptr<FrameTimingTracker::MainFrameTimingSet> main_frame_events) {
128 DCHECK(IsMainThread());
129 layer_tree_host_->RecordFrameTimingEvents(std::move(composite_events),
130 std::move(main_frame_events));
131 }
132
133 void ProxyMain::BeginMainFrame(
134 scoped_ptr<BeginMainFrameAndCommitState> begin_main_frame_state) {
135 benchmark_instrumentation::ScopedBeginFrameTask begin_frame_task(
136 benchmark_instrumentation::kDoBeginFrame,
137 begin_main_frame_state->begin_frame_id);
138
139 base::TimeTicks begin_main_frame_start_time = base::TimeTicks::Now();
140
141 TRACE_EVENT_SYNTHETIC_DELAY_BEGIN("cc.BeginMainFrame");
142 DCHECK(IsMainThread());
143 DCHECK_EQ(NO_PIPELINE_STAGE, current_pipeline_stage_);
144
145 if (defer_commits_) {
146 TRACE_EVENT_INSTANT0("cc", "EarlyOut_DeferCommit",
147 TRACE_EVENT_SCOPE_THREAD);
148 channel_main_->BeginMainFrameAbortedOnImpl(
149 CommitEarlyOutReason::ABORTED_DEFERRED_COMMIT,
150 begin_main_frame_start_time);
151 return;
152 }
153
154 // If the commit finishes, LayerTreeHost will transfer its swap promises to
155 // LayerTreeImpl. The destructor of ScopedSwapPromiseChecker aborts the
156 // remaining swap promises.
157 ScopedAbortRemainingSwapPromises swap_promise_checker(layer_tree_host_);
158
159 final_pipeline_stage_ = max_requested_pipeline_stage_;
160 max_requested_pipeline_stage_ = NO_PIPELINE_STAGE;
161
162 if (!layer_tree_host_->visible()) {
163 TRACE_EVENT_INSTANT0("cc", "EarlyOut_NotVisible", TRACE_EVENT_SCOPE_THREAD);
164 channel_main_->BeginMainFrameAbortedOnImpl(
165 CommitEarlyOutReason::ABORTED_NOT_VISIBLE, begin_main_frame_start_time);
166 return;
167 }
168
169 if (layer_tree_host_->output_surface_lost()) {
170 TRACE_EVENT_INSTANT0("cc", "EarlyOut_OutputSurfaceLost",
171 TRACE_EVENT_SCOPE_THREAD);
172 channel_main_->BeginMainFrameAbortedOnImpl(
173 CommitEarlyOutReason::ABORTED_OUTPUT_SURFACE_LOST,
174 begin_main_frame_start_time);
175 return;
176 }
177
178 current_pipeline_stage_ = ANIMATE_PIPELINE_STAGE;
179
180 layer_tree_host_->ApplyScrollAndScale(
181 begin_main_frame_state->scroll_info.get());
182
183 layer_tree_host_->WillBeginMainFrame();
184
185 layer_tree_host_->BeginMainFrame(begin_main_frame_state->begin_frame_args);
186 layer_tree_host_->AnimateLayers(
187 begin_main_frame_state->begin_frame_args.frame_time);
188
189 // Recreate all UI resources if there were evicted UI resources when the impl
190 // thread initiated the commit.
191 if (begin_main_frame_state->evicted_ui_resources)
192 layer_tree_host_->RecreateUIResources();
193
194 layer_tree_host_->RequestMainFrameUpdate();
195 TRACE_EVENT_SYNTHETIC_DELAY_END("cc.BeginMainFrame");
196
197 bool can_cancel_this_commit = final_pipeline_stage_ < COMMIT_PIPELINE_STAGE &&
198 !begin_main_frame_state->evicted_ui_resources;
199
200 current_pipeline_stage_ = UPDATE_LAYERS_PIPELINE_STAGE;
201 bool should_update_layers =
202 final_pipeline_stage_ >= UPDATE_LAYERS_PIPELINE_STAGE;
203 bool updated = should_update_layers && layer_tree_host_->UpdateLayers();
204
205 layer_tree_host_->WillCommit();
206 devtools_instrumentation::ScopedCommitTrace commit_task(
207 layer_tree_host_->id());
208
209 current_pipeline_stage_ = COMMIT_PIPELINE_STAGE;
210 if (!updated && can_cancel_this_commit) {
211 TRACE_EVENT_INSTANT0("cc", "EarlyOut_NoUpdates", TRACE_EVENT_SCOPE_THREAD);
212 channel_main_->BeginMainFrameAbortedOnImpl(
213 CommitEarlyOutReason::FINISHED_NO_UPDATES, begin_main_frame_start_time);
214
215 // Although the commit is internally aborted, this is because it has been
216 // detected to be a no-op. From the perspective of an embedder, this commit
217 // went through, and input should no longer be throttled, etc.
218 current_pipeline_stage_ = NO_PIPELINE_STAGE;
219 layer_tree_host_->CommitComplete();
220 layer_tree_host_->DidBeginMainFrame();
221 layer_tree_host_->BreakSwapPromises(SwapPromise::COMMIT_NO_UPDATE);
222 return;
223 }
224
225 // Notify the impl thread that the main thread is ready to commit. This will
226 // begin the commit process, which is blocking from the main thread's
227 // point of view, but asynchronously performed on the impl thread,
228 // coordinated by the Scheduler.
229 {
230 TRACE_EVENT0("cc", "ProxyMain::BeginMainFrame::commit");
231
232 DebugScopedSetMainThreadBlocked main_thread_blocked(task_runner_provider_);
233
234 // This CapturePostTasks should be destroyed before CommitComplete() is
235 // called since that goes out to the embedder, and we want the embedder
236 // to receive its callbacks before that.
237 BlockingTaskRunner::CapturePostTasks blocked(
238 task_runner_provider_->blocking_main_thread_task_runner());
239
240 bool hold_commit_for_activation = commit_waits_for_activation_;
241 commit_waits_for_activation_ = false;
242 CompletionEvent completion;
243 channel_main_->StartCommitOnImpl(&completion, layer_tree_host_,
244 begin_main_frame_start_time,
245 hold_commit_for_activation);
246 completion.Wait();
247 }
248
249 current_pipeline_stage_ = NO_PIPELINE_STAGE;
250 layer_tree_host_->CommitComplete();
251 layer_tree_host_->DidBeginMainFrame();
252 }
253
254 void ProxyMain::FinishAllRendering() {
255 DCHECK(IsMainThread());
256 DCHECK(!defer_commits_);
257
258 // Make sure all GL drawing is finished on the impl thread.
259 DebugScopedSetMainThreadBlocked main_thread_blocked(task_runner_provider_);
260 CompletionEvent completion;
261 channel_main_->FinishAllRenderingOnImpl(&completion);
262 completion.Wait();
263 }
264
265 bool ProxyMain::IsStarted() const {
266 DCHECK(IsMainThread());
267 return started_;
268 }
269
270 bool ProxyMain::CommitToActiveTree() const {
271 // With ProxyMain, we use a pending tree and activate it once it's ready to
272 // draw to allow input to modify the active tree and draw during raster.
273 return false;
274 }
275
276 void ProxyMain::SetOutputSurface(OutputSurface* output_surface) {
277 channel_main_->InitializeOutputSurfaceOnImpl(output_surface);
278 }
279
280 void ProxyMain::SetVisible(bool visible) {
281 TRACE_EVENT1("cc", "ProxyMain::SetVisible", "visible", visible);
282 channel_main_->SetVisibleOnImpl(visible);
283 }
284
285 void ProxyMain::SetThrottleFrameProduction(bool throttle) {
286 TRACE_EVENT1("cc", "ProxyMain::SetThrottleFrameProduction", "throttle",
287 throttle);
288 channel_main_->SetThrottleFrameProductionOnImpl(throttle);
289 }
290
291 const RendererCapabilities& ProxyMain::GetRendererCapabilities() const {
292 DCHECK(IsMainThread());
293 DCHECK(!layer_tree_host_->output_surface_lost());
294 return renderer_capabilities_;
295 }
296
297 void ProxyMain::SetNeedsAnimate() {
298 DCHECK(IsMainThread());
299 if (SendCommitRequestToImplThreadIfNeeded(ANIMATE_PIPELINE_STAGE)) {
300 TRACE_EVENT_INSTANT0("cc", "ProxyMain::SetNeedsAnimate",
301 TRACE_EVENT_SCOPE_THREAD);
302 }
303 }
304
305 void ProxyMain::SetNeedsUpdateLayers() {
306 DCHECK(IsMainThread());
307 // If we are currently animating, make sure we also update the layers.
308 if (current_pipeline_stage_ == ANIMATE_PIPELINE_STAGE) {
309 final_pipeline_stage_ =
310 std::max(final_pipeline_stage_, UPDATE_LAYERS_PIPELINE_STAGE);
311 return;
312 }
313 if (SendCommitRequestToImplThreadIfNeeded(UPDATE_LAYERS_PIPELINE_STAGE)) {
314 TRACE_EVENT_INSTANT0("cc", "ProxyMain::SetNeedsUpdateLayers",
315 TRACE_EVENT_SCOPE_THREAD);
316 }
317 }
318
319 void ProxyMain::SetNeedsCommit() {
320 DCHECK(IsMainThread());
321 // If we are currently animating, make sure we don't skip the commit. Note
322 // that requesting a commit during the layer update stage means we need to
323 // schedule another full commit.
324 if (current_pipeline_stage_ == ANIMATE_PIPELINE_STAGE) {
325 final_pipeline_stage_ =
326 std::max(final_pipeline_stage_, COMMIT_PIPELINE_STAGE);
327 return;
328 }
329 if (SendCommitRequestToImplThreadIfNeeded(COMMIT_PIPELINE_STAGE)) {
330 TRACE_EVENT_INSTANT0("cc", "ProxyMain::SetNeedsCommit",
331 TRACE_EVENT_SCOPE_THREAD);
332 }
333 }
334
335 void ProxyMain::SetNeedsRedraw(const gfx::Rect& damage_rect) {
336 TRACE_EVENT0("cc", "ProxyMain::SetNeedsRedraw");
337 DCHECK(IsMainThread());
338 channel_main_->SetNeedsRedrawOnImpl(damage_rect);
339 }
340
341 void ProxyMain::SetNextCommitWaitsForActivation() {
342 DCHECK(IsMainThread());
343 commit_waits_for_activation_ = true;
344 }
345
346 void ProxyMain::NotifyInputThrottledUntilCommit() {
347 DCHECK(IsMainThread());
348 channel_main_->SetInputThrottledUntilCommitOnImpl(true);
349 }
350
351 void ProxyMain::SetDeferCommits(bool defer_commits) {
352 DCHECK(IsMainThread());
353 if (defer_commits_ == defer_commits)
354 return;
355
356 defer_commits_ = defer_commits;
357 if (defer_commits_)
358 TRACE_EVENT_ASYNC_BEGIN0("cc", "ProxyMain::SetDeferCommits", this);
359 else
360 TRACE_EVENT_ASYNC_END0("cc", "ProxyMain::SetDeferCommits", this);
361
362 channel_main_->SetDeferCommitsOnImpl(defer_commits);
363 }
364
365 bool ProxyMain::CommitRequested() const {
366 DCHECK(IsMainThread());
367 // TODO(skyostil): Split this into something like CommitRequested() and
368 // CommitInProgress().
369 return current_pipeline_stage_ != NO_PIPELINE_STAGE ||
370 max_requested_pipeline_stage_ >= COMMIT_PIPELINE_STAGE;
371 }
372
373 bool ProxyMain::BeginMainFrameRequested() const {
374 DCHECK(IsMainThread());
375 return max_requested_pipeline_stage_ != NO_PIPELINE_STAGE;
376 }
377
378 void ProxyMain::MainThreadHasStoppedFlinging() {
379 DCHECK(IsMainThread());
380 channel_main_->MainThreadHasStoppedFlingingOnImpl();
381 }
382
383 void ProxyMain::Start() {
384 DCHECK(IsMainThread());
385 DCHECK(task_runner_provider_->HasImplThread());
386 DCHECK(channel_main_);
387
388 // Create LayerTreeHostImpl.
389 channel_main_->SynchronouslyInitializeImpl(
390 layer_tree_host_, std::move(external_begin_frame_source_));
391
392 started_ = true;
393 }
394
395 void ProxyMain::Stop() {
396 TRACE_EVENT0("cc", "ProxyMain::Stop");
397 DCHECK(IsMainThread());
398 DCHECK(started_);
399
400 channel_main_->SynchronouslyCloseImpl();
401
402 layer_tree_host_ = nullptr;
403 started_ = false;
404 }
405
406 bool ProxyMain::SupportsImplScrolling() const {
407 return true;
408 }
409
410 bool ProxyMain::MainFrameWillHappenForTesting() {
411 DCHECK(IsMainThread());
412 bool main_frame_will_happen = false;
413 {
414 DebugScopedSetMainThreadBlocked main_thread_blocked(task_runner_provider_);
415 CompletionEvent completion;
416 channel_main_->MainFrameWillHappenOnImplForTesting(&completion,
417 &main_frame_will_happen);
418 completion.Wait();
419 }
420 return main_frame_will_happen;
421 }
422
423 void ProxyMain::SetChildrenNeedBeginFrames(bool children_need_begin_frames) {
424 NOTREACHED() << "Only used by SingleThreadProxy";
425 }
426
427 void ProxyMain::SetAuthoritativeVSyncInterval(const base::TimeDelta& interval) {
428 NOTREACHED() << "Only used by SingleProxyMain";
429 }
430
431 void ProxyMain::ReleaseOutputSurface() {
432 DCHECK(IsMainThread());
433 DCHECK(layer_tree_host_->output_surface_lost());
434
435 DebugScopedSetMainThreadBlocked main_thread_blocked(task_runner_provider_);
436 CompletionEvent completion;
437 channel_main_->ReleaseOutputSurfaceOnImpl(&completion);
438 completion.Wait();
439 }
440
441 void ProxyMain::UpdateTopControlsState(TopControlsState constraints,
442 TopControlsState current,
443 bool animate) {
444 DCHECK(IsMainThread());
445 channel_main_->UpdateTopControlsStateOnImpl(constraints, current, animate);
446 }
447
448 bool ProxyMain::SendCommitRequestToImplThreadIfNeeded(
449 CommitPipelineStage required_stage) {
450 DCHECK(IsMainThread());
451 DCHECK_NE(NO_PIPELINE_STAGE, required_stage);
452 bool already_posted = max_requested_pipeline_stage_ != NO_PIPELINE_STAGE;
453 max_requested_pipeline_stage_ =
454 std::max(max_requested_pipeline_stage_, required_stage);
455 if (already_posted)
456 return false;
457 channel_main_->SetNeedsCommitOnImpl();
458 return true;
459 }
460
461 bool ProxyMain::IsMainThread() const {
462 return task_runner_provider_->IsMainThread();
463 }
464
465 } // namespace cc
OLDNEW
« no previous file with comments | « cc/trees/proxy_main.h ('k') | cc/trees/thread_proxy.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698