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

Side by Side Diff: cc/blimp/layer_tree_host_remote.cc

Issue 2646623002: cc: Remove all blimp code from cc. (Closed)
Patch Set: test build Created 3 years, 11 months 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/blimp/layer_tree_host_remote.h ('k') | cc/blimp/layer_tree_host_remote_unittest.cc » ('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 2016 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/blimp/layer_tree_host_remote.h"
6
7 #include "base/atomic_sequence_num.h"
8 #include "base/auto_reset.h"
9 #include "base/memory/ptr_util.h"
10 #include "cc/blimp/compositor_proto_state.h"
11 #include "cc/blimp/engine_picture_cache.h"
12 #include "cc/blimp/picture_data_conversions.h"
13 #include "cc/blimp/remote_compositor_bridge.h"
14 #include "cc/output/compositor_frame_sink.h"
15 #include "cc/proto/compositor_message.pb.h"
16 #include "cc/proto/gfx_conversions.h"
17 #include "cc/proto/layer_tree_host.pb.h"
18 #include "cc/trees/layer_tree.h"
19 #include "cc/trees/layer_tree_host_client.h"
20 #include "cc/trees/layer_tree_host_common.h"
21 #include "cc/trees/mutator_host.h"
22 #include "cc/trees/task_runner_provider.h"
23 #include "ui/gfx/geometry/scroll_offset.h"
24
25 namespace cc {
26 namespace {
27 // We use a 16ms default frame interval because the rate at which the engine
28 // produces main frames doesn't matter.
29 base::TimeDelta kDefaultFrameInterval = base::TimeDelta::FromMilliseconds(16);
30
31 static base::StaticAtomicSequenceNumber s_layer_tree_host_sequence_number;
32
33 bool ShouldUpdateLayer(Layer* layer) {
34 // If the embedder has marked the layer as non-drawable.
35 if (!layer->DrawsContent())
36 return false;
37
38 // If the layer bounds are empty.
39 if (layer->bounds().IsEmpty())
40 return false;
41
42 // If the layer is transparent and has no background filters applied.
43 // See EffectTree::UpdateIsDrawn for the logic details.
44 // A few things have been ignored:
45 // 1) We don't support threaded animations at the moment, so the opacity can
46 // not change on the client.
47 // 2) This does not account for layer hiding its subtree, but that is never
48 // used by the renderer.
49 // 3) Also updates a transparent layer's subtree when it will be skipped while
50 // drawing on the client.
51 if (layer->opacity() == 0.f && layer->background_filters().IsEmpty())
52 return false;
53
54 return true;
55 }
56
57 } // namespace
58
59 LayerTreeHostRemote::InitParams::InitParams() = default;
60
61 LayerTreeHostRemote::InitParams::~InitParams() = default;
62
63 LayerTreeHostRemote::LayerTreeHostRemote(InitParams* params)
64 : LayerTreeHostRemote(
65 params,
66 base::MakeUnique<LayerTree>(params->mutator_host, this)) {}
67
68 LayerTreeHostRemote::LayerTreeHostRemote(InitParams* params,
69 std::unique_ptr<LayerTree> layer_tree)
70 : id_(s_layer_tree_host_sequence_number.GetNext() + 1),
71 main_frame_requested_from_bridge_(false),
72 client_(params->client),
73 task_runner_provider_(
74 TaskRunnerProvider::Create(std::move(params->main_task_runner),
75 nullptr)),
76 remote_compositor_bridge_(std::move(params->remote_compositor_bridge)),
77 engine_picture_cache_(std::move(params->engine_picture_cache)),
78 settings_(*params->settings),
79 layer_tree_(std::move(layer_tree)),
80 weak_factory_(this) {
81 DCHECK(task_runner_provider_->IsMainThread());
82 DCHECK(remote_compositor_bridge_);
83 DCHECK(client_);
84 remote_compositor_bridge_->BindToClient(this);
85 layer_tree_->set_engine_picture_cache(engine_picture_cache_.get());
86 }
87
88 LayerTreeHostRemote::~LayerTreeHostRemote() = default;
89
90 int LayerTreeHostRemote::GetId() const {
91 return id_;
92 }
93
94 int LayerTreeHostRemote::SourceFrameNumber() const {
95 return source_frame_number_;
96 }
97
98 LayerTree* LayerTreeHostRemote::GetLayerTree() {
99 return layer_tree_.get();
100 }
101
102 const LayerTree* LayerTreeHostRemote::GetLayerTree() const {
103 return layer_tree_.get();
104 }
105
106 UIResourceManager* LayerTreeHostRemote::GetUIResourceManager() const {
107 // We shouldn't need a UIResourceManager. The layers which need this
108 // (UIResourceLayers and PaintedScrollbarLayers) are never used by the
109 // renderer compositor in remote mode.
110 NOTREACHED() << "UIResourceManager requested. Unsupported Layer type used";
111 return nullptr;
112 }
113
114 TaskRunnerProvider* LayerTreeHostRemote::GetTaskRunnerProvider() const {
115 return task_runner_provider_.get();
116 }
117
118 const LayerTreeSettings& LayerTreeHostRemote::GetSettings() const {
119 return settings_;
120 }
121
122 void LayerTreeHostRemote::SetFrameSinkId(const FrameSinkId& frame_sink_id) {
123 // We don't need to care about SurfaceLayers. The Surfaces system is
124 // relevant on the client only.
125 }
126
127 void LayerTreeHostRemote::SetLayerTreeMutator(
128 std::unique_ptr<LayerTreeMutator> mutator) {
129 // TODO(khushalsagar): Compositor-worker not supported. See crbug.com/650876.
130 }
131
132 void LayerTreeHostRemote::QueueSwapPromise(
133 std::unique_ptr<SwapPromise> swap_promise) {
134 swap_promise_manager_.QueueSwapPromise(std::move(swap_promise));
135 }
136
137 SwapPromiseManager* LayerTreeHostRemote::GetSwapPromiseManager() {
138 return &swap_promise_manager_;
139 }
140
141 void LayerTreeHostRemote::SetHasGpuRasterizationTrigger(bool has_trigger) {
142 // TODO(khushalsagar) : Take care of Gpu raster. See crbug.com/650431.
143 }
144
145 void LayerTreeHostRemote::SetVisible(bool visible) {
146 // The visibility of the compositor is controlled on the client, which is
147 // why this value is not sent there, since the client has the current true
148 // state.
149 visible_ = visible;
150 }
151
152 bool LayerTreeHostRemote::IsVisible() const {
153 return visible_;
154 }
155
156 void LayerTreeHostRemote::SetCompositorFrameSink(
157 std::unique_ptr<CompositorFrameSink> compositor_frame_sink) {
158 NOTREACHED()
159 << "The LayerTreeHostClient is never asked for a CompositorFrameSink";
160 }
161
162 std::unique_ptr<CompositorFrameSink>
163 LayerTreeHostRemote::ReleaseCompositorFrameSink() {
164 // Since we never have a CompositorFrameSink, this is always a no-op.
165 return nullptr;
166 }
167
168 void LayerTreeHostRemote::SetNeedsAnimate() {
169 MainFrameRequested(FramePipelineStage::ANIMATE);
170 }
171
172 void LayerTreeHostRemote::SetNeedsUpdateLayers() {
173 MainFrameRequested(FramePipelineStage::UPDATE_LAYERS);
174 }
175
176 void LayerTreeHostRemote::SetNeedsCommit() {
177 MainFrameRequested(FramePipelineStage::COMMIT);
178 }
179
180 void LayerTreeHostRemote::SetNeedsRecalculateRasterScales() {
181 // This is used by devtools to reraster content after changing device
182 // emulation modes, so doesn't need to be supported by Blimp.
183 }
184
185 bool LayerTreeHostRemote::BeginMainFrameRequested() const {
186 return requested_pipeline_stage_for_next_frame_ != FramePipelineStage::NONE;
187 }
188
189 bool LayerTreeHostRemote::CommitRequested() const {
190 // We report that a commit is in progress when synchronizing scroll and scale
191 // updates because in threaded mode, scroll/scale synchronization from the
192 // impl thread happens only during the main frame.
193 return synchronizing_client_updates_ ||
194 requested_pipeline_stage_for_next_frame_ == FramePipelineStage::COMMIT;
195 }
196
197 void LayerTreeHostRemote::SetDeferCommits(bool defer_commits) {
198 defer_commits_ = defer_commits;
199 ScheduleMainFrameIfNecessary();
200 }
201
202 void LayerTreeHostRemote::LayoutAndUpdateLayers() {
203 NOTREACHED() << "Only supported in single-threaded mode and this class"
204 << " does not support single-thread since it is out of process";
205 }
206
207 void LayerTreeHostRemote::Composite(base::TimeTicks frame_begin_time) {
208 NOTREACHED() << "Only supported in single-threaded mode and this class"
209 << " does not support single-thread since it is out of process";
210 }
211
212 void LayerTreeHostRemote::SetNeedsRedrawRect(const gfx::Rect& damage_rect) {
213 // The engine shouldn't need to care about draws. CompositorFrames are never
214 // used here.
215 // TODO(khushalsagar): The caller could be waiting for an Ack for this redraw.
216 // We need a better solution for this. See crbug.com/651141.
217 NOTIMPLEMENTED();
218 }
219
220 void LayerTreeHostRemote::SetNextCommitForcesRedraw() {
221 // Ideally the engine shouldn't need to care about draw requests at all. The
222 // compositor that produces CompositorFrames is on the client and draw
223 // requests should be made directly to it on the client itself.
224 NOTIMPLEMENTED();
225 }
226
227 void LayerTreeHostRemote::NotifyInputThrottledUntilCommit() {
228 // This notification is used in the case where the renderer handles an input
229 // event, and needs to send an Ack to the browser when the resulting main
230 // frame is committed. If the compositor is taking too long on the pending
231 // tree, the commit processing will be delayed blocking all input as a result.
232 // So this is used to have the compositor activate the pending tree faster, so
233 // the pending commit can be processed.
234 // In remote mode, we don't send such notifications to the client because the
235 // most likely bottleneck is the transport instead of raster. Also, input is
236 // queued on the client, so if raster does end up being a bottleneck, the
237 // input handling code on the client informs the LayerTreeHostInProcess
238 // directly.
239 NOTIMPLEMENTED();
240 }
241
242 void LayerTreeHostRemote::UpdateBrowserControlsState(
243 BrowserControlsState constraints,
244 BrowserControlsState current,
245 bool animate) {
246 NOTREACHED() << "Using BrowserControls animations is not supported";
247 }
248
249 const base::WeakPtr<InputHandler>& LayerTreeHostRemote::GetInputHandler()
250 const {
251 // Input on the compositor thread is handled on the client, so this is always
252 // null.
253 return input_handler_weak_ptr_;
254 }
255
256 void LayerTreeHostRemote::DidStopFlinging() {
257 // TODO(khushalsagar): This should not happen. See crbug.com/652000.
258 NOTIMPLEMENTED() << "We shouldn't be sending fling gestures to the engine";
259 }
260
261 void LayerTreeHostRemote::SetDebugState(
262 const LayerTreeDebugState& debug_state) {
263 // If any debugging needs to be enabled, ideally it should be using the
264 // compositor on the client directly. But the setup code will always set this
265 // on initialization, even if the settings end up being a no-op.
266 }
267
268 const LayerTreeDebugState& LayerTreeHostRemote::GetDebugState() const {
269 return debug_state_;
270 }
271
272 int LayerTreeHostRemote::ScheduleMicroBenchmark(
273 const std::string& benchmark_name,
274 std::unique_ptr<base::Value> value,
275 const MicroBenchmark::DoneCallback& callback) {
276 NOTREACHED();
277 return 0;
278 }
279
280 bool LayerTreeHostRemote::SendMessageToMicroBenchmark(
281 int id,
282 std::unique_ptr<base::Value> value) {
283 NOTREACHED();
284 return false;
285 }
286
287 SurfaceSequenceGenerator* LayerTreeHostRemote::GetSurfaceSequenceGenerator() {
288 // TODO(khushalsagar): Eliminate the use of this in blink. See
289 // crbug.com/650876.
290 return &surface_sequence_generator_;
291 }
292
293 void LayerTreeHostRemote::SetNextCommitWaitsForActivation() {
294 // This is used only by layers that need resource synchronization, i.e.,
295 // texture and surface layers, both of which are not supported.
296 NOTIMPLEMENTED() << "Unsupported Layer type used";
297 }
298
299 void LayerTreeHostRemote::ResetGpuRasterizationTracking() {
300 // TODO(khushalsagar): Take care of Gpu raster. See crbug.com/650431.
301 }
302
303 void LayerTreeHostRemote::MainFrameRequested(
304 FramePipelineStage requested_pipeline_stage) {
305 DCHECK_NE(FramePipelineStage::NONE, requested_pipeline_stage);
306
307 swap_promise_manager_.NotifySwapPromiseMonitorsOfSetNeedsCommit();
308
309 // If we are inside a main frame update right now and the requested pipeline
310 // stage is higher than the pipeline stage that we are at, then we'll get to
311 // in this main frame update itself. Update the
312 // |max_pipeline_stage_for_current_frame_| to ensure we go through the
313 // requested pipeline stage.
314 if (current_pipeline_stage_ != FramePipelineStage::NONE &&
315 requested_pipeline_stage > current_pipeline_stage_) {
316 max_pipeline_stage_for_current_frame_ = std::max(
317 max_pipeline_stage_for_current_frame_, requested_pipeline_stage);
318 return;
319 }
320
321 // Update the pipeline stage for the next frame and schedule an update if it
322 // has not been scheduled already.
323 requested_pipeline_stage_for_next_frame_ = std::max(
324 requested_pipeline_stage_for_next_frame_, requested_pipeline_stage);
325
326 ScheduleMainFrameIfNecessary();
327 }
328
329 void LayerTreeHostRemote::ScheduleMainFrameIfNecessary() {
330 // If the client hasn't asked for a main frame, don't schedule one.
331 if (requested_pipeline_stage_for_next_frame_ == FramePipelineStage::NONE)
332 return;
333
334 // If the client does not want us to run main frame updates right now, don't
335 // schedule one.
336 if (defer_commits_)
337 return;
338
339 // If a main frame request is already pending with the
340 // RemoteCompositorBridge, we don't need to scheduler another one.
341 if (main_frame_requested_from_bridge_)
342 return;
343
344 remote_compositor_bridge_->ScheduleMainFrame();
345 main_frame_requested_from_bridge_ = true;
346 }
347
348 void LayerTreeHostRemote::BeginMainFrame() {
349 DCHECK(main_frame_requested_from_bridge_);
350 DCHECK(task_runner_provider_->IsMainThread());
351
352 main_frame_requested_from_bridge_ = false;
353
354 // The client might have suspended main frames in the meantime. Early out now,
355 // we'll come back here when they enable main frames again.
356 if (defer_commits_)
357 return;
358
359 DCHECK_EQ(current_pipeline_stage_, FramePipelineStage::NONE);
360 DCHECK_EQ(max_pipeline_stage_for_current_frame_, FramePipelineStage::NONE);
361 DCHECK_NE(requested_pipeline_stage_for_next_frame_, FramePipelineStage::NONE);
362
363 // Start the main frame. It should go till the requested pipeline stage.
364 max_pipeline_stage_for_current_frame_ =
365 requested_pipeline_stage_for_next_frame_;
366 requested_pipeline_stage_for_next_frame_ = FramePipelineStage::NONE;
367
368 client_->WillBeginMainFrame();
369
370 current_pipeline_stage_ = FramePipelineStage::ANIMATE;
371 base::TimeTicks now = base::TimeTicks::Now();
372 client_->BeginMainFrame(BeginFrameArgs::Create(
373 BEGINFRAME_FROM_HERE, begin_frame_source_.source_id(),
374 begin_frame_number_, now, now + kDefaultFrameInterval,
375 kDefaultFrameInterval, BeginFrameArgs::NORMAL));
376 begin_frame_number_++;
377 // We don't run any animations on the layer because threaded animations are
378 // disabled.
379 // TODO(khushalsagar): Revisit this when adding support for animations.
380 client_->UpdateLayerTreeHost();
381
382 current_pipeline_stage_ = FramePipelineStage::UPDATE_LAYERS;
383 LayerList layer_list;
384 if (max_pipeline_stage_for_current_frame_ >=
385 FramePipelineStage::UPDATE_LAYERS) {
386 // Pull updates for all layers from the client.
387 // TODO(khushalsagar): Investigate the data impact from updating all the
388 // layers. See crbug.com/650885.
389 LayerTreeHostCommon::CallFunctionForEveryLayer(
390 layer_tree_.get(), [&layer_list](Layer* layer) {
391 if (!ShouldUpdateLayer(layer))
392 return;
393 layer->SavePaintProperties();
394 layer_list.push_back(layer);
395 });
396
397 bool content_is_suitable_for_gpu = false;
398 bool layers_updated =
399 layer_tree_->UpdateLayers(layer_list, &content_is_suitable_for_gpu);
400
401 // If pulling layer updates resulted in any content updates, we need to go
402 // till the commit stage.
403 if (layers_updated)
404 max_pipeline_stage_for_current_frame_ = FramePipelineStage::COMMIT;
405 }
406
407 current_pipeline_stage_ = FramePipelineStage::COMMIT;
408 client_->WillCommit();
409
410 if (max_pipeline_stage_for_current_frame_ < current_pipeline_stage_) {
411 // There is nothing to commit so break the swap promises.
412 swap_promise_manager_.BreakSwapPromises(
413 SwapPromise::DidNotSwapReason::COMMIT_NO_UPDATE);
414
415 // For the client, the commit was successful.
416 MainFrameComplete();
417 return;
418 }
419
420 std::unique_ptr<CompositorProtoState> compositor_state =
421 base::MakeUnique<CompositorProtoState>();
422 compositor_state->swap_promises = swap_promise_manager_.TakeSwapPromises();
423 compositor_state->compositor_message =
424 base::MakeUnique<proto::CompositorMessage>();
425 SerializeCurrentState(
426 compositor_state->compositor_message->mutable_layer_tree_host());
427 remote_compositor_bridge_->ProcessCompositorStateUpdate(
428 std::move(compositor_state));
429
430 MainFrameComplete();
431
432 // We can not wait for updates dispatched from the client about the state of
433 // drawing or swaps for frames sent. Since these calls can be used by the
434 // LayerTreeHostClient to throttle further frame updates, so dispatch them
435 // right after the update is processed by the bridge.
436 // TODO(khushalsagar): We can not really know what these callbacks end up
437 // being used for. Consider migrating clients to understand/cope with the fact
438 // that there is no actual compositing happening here.
439 task_runner_provider_->MainThreadTaskRunner()->PostTask(
440 FROM_HERE,
441 base::Bind(&LayerTreeHostRemote::DispatchDrawAndSubmitCallbacks,
442 weak_factory_.GetWeakPtr()));
443 }
444
445 void LayerTreeHostRemote::ApplyStateUpdateFromClient(
446 const proto::ClientStateUpdate& client_state_update) {
447 DCHECK(!synchronizing_client_updates_);
448 base::AutoReset<bool> synchronizing_updates(&synchronizing_client_updates_,
449 true);
450
451 gfx::Vector2dF inner_viewport_delta;
452 for (int i = 0; i < client_state_update.scroll_updates_size(); ++i) {
453 const proto::ScrollUpdate& scroll_update =
454 client_state_update.scroll_updates(i);
455 int layer_id = scroll_update.layer_id();
456 Layer* layer = layer_tree_->LayerById(layer_id);
457 gfx::Vector2dF scroll_delta =
458 ProtoToVector2dF(scroll_update.scroll_delta());
459
460 if (!layer)
461 continue;
462
463 if (layer == layer_tree_->inner_viewport_scroll_layer()) {
464 inner_viewport_delta = scroll_delta;
465 } else {
466 layer->SetScrollOffsetFromImplSide(
467 gfx::ScrollOffsetWithDelta(layer->scroll_offset(), scroll_delta));
468 SetNeedsUpdateLayers();
469 }
470 }
471
472 if (!inner_viewport_delta.IsZero()) {
473 layer_tree_->inner_viewport_scroll_layer()->SetScrollOffsetFromImplSide(
474 gfx::ScrollOffsetWithDelta(
475 layer_tree_->inner_viewport_scroll_layer()->scroll_offset(),
476 inner_viewport_delta));
477 }
478
479 float page_scale_delta = 1.0f;
480 if (client_state_update.has_page_scale_delta()) {
481 page_scale_delta = client_state_update.page_scale_delta();
482 layer_tree_->SetPageScaleFromImplSide(layer_tree_->page_scale_factor() *
483 page_scale_delta);
484 }
485
486 if (!inner_viewport_delta.IsZero() || page_scale_delta != 1.0f) {
487 client_->ApplyViewportDeltas(inner_viewport_delta, gfx::Vector2dF(),
488 gfx::Vector2dF(), page_scale_delta, 0.0f);
489 SetNeedsUpdateLayers();
490 }
491 }
492
493 void LayerTreeHostRemote::MainFrameComplete() {
494 DCHECK_EQ(current_pipeline_stage_, FramePipelineStage::COMMIT);
495
496 current_pipeline_stage_ = FramePipelineStage::NONE;
497 max_pipeline_stage_for_current_frame_ = FramePipelineStage::NONE;
498 source_frame_number_++;
499
500 client_->DidCommit();
501 client_->DidBeginMainFrame();
502 }
503
504 void LayerTreeHostRemote::DispatchDrawAndSubmitCallbacks() {
505 client_->DidCommitAndDrawFrame();
506 client_->DidReceiveCompositorFrameAck();
507 }
508
509 void LayerTreeHostRemote::SetTaskRunnerProviderForTesting(
510 std::unique_ptr<TaskRunnerProvider> task_runner_provider) {
511 task_runner_provider_ = std::move(task_runner_provider);
512 }
513
514 void LayerTreeHostRemote::SerializeCurrentState(
515 proto::LayerTreeHost* layer_tree_host_proto) {
516 // Serialize the LayerTree.
517 layer_tree_->ToProtobuf(layer_tree_host_proto->mutable_layer_tree());
518
519 // Serialize the dirty layers.
520 std::unordered_set<Layer*> layers_need_push_properties;
521 layers_need_push_properties.swap(
522 layer_tree_->LayersThatShouldPushProperties());
523
524 for (auto* layer : layers_need_push_properties) {
525 proto::LayerProperties* layer_properties =
526 layer_tree_host_proto->mutable_layer_updates()->add_layers();
527 layer->ToLayerPropertiesProto(layer_properties);
528 }
529
530 std::vector<PictureData> pictures =
531 engine_picture_cache_->CalculateCacheUpdateAndFlush();
532 proto::PictureDataVectorToSkPicturesProto(
533 pictures, layer_tree_host_proto->mutable_pictures());
534 }
535
536 } // namespace cc
OLDNEW
« no previous file with comments | « cc/blimp/layer_tree_host_remote.h ('k') | cc/blimp/layer_tree_host_remote_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698