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

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

Issue 2362073002: cc/blimp: Add a LayerTreeHostRemote implementation. (Closed)
Patch Set: Remaining comments from #4 Created 4 years, 2 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
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/memory/ptr_util.h"
8 #include "cc/animation/animation_host.h"
9 #include "cc/blimp/compositor_proto_state.h"
10 #include "cc/blimp/compositor_proto_state_sink.h"
11 #include "cc/output/begin_frame_args.h"
12 #include "cc/output/compositor_frame_sink.h"
13 #include "cc/trees/layer_tree.h"
14 #include "cc/trees/layer_tree_host_client.h"
15 #include "cc/trees/layer_tree_host_common.h"
16 #include "cc/trees/task_runner_provider.h"
17
18 namespace cc {
19 namespace {
20 // We use a 16ms default frame interval because the rate at which the engine
21 // produces main frames doesn't matter.
22 base::TimeDelta kDefaultFrameInterval = base::TimeDelta::FromMilliseconds(16);
23 } // namespace
24
25 LayerTreeHostRemote::InitParams::InitParams() = default;
26
27 LayerTreeHostRemote::InitParams::~InitParams() = default;
28
29 LayerTreeHostRemote::LayerTreeHostRemote(InitParams* params)
30 : LayerTreeHostRemote(
31 params,
32 base::MakeUnique<LayerTree>(std::move(params->animation_host),
33 this)) {}
34
35 LayerTreeHostRemote::LayerTreeHostRemote(InitParams* params,
36 std::unique_ptr<LayerTree> layer_tree)
37 : id_(LayerTreeHost::GenerateHostId()),
38 source_frame_number_(0),
39 visible_(false),
40 defer_commits_(false),
41 main_frame_requested_from_state_sink_(false),
42 current_pipeline_stage_(FramePipelineStage::NONE),
43 max_pipeline_stage_for_current_frame_(FramePipelineStage::NONE),
44 requested_pipeline_stage_for_next_frame_(FramePipelineStage::NONE),
45 client_(params->client),
46 task_runner_provider_(
47 TaskRunnerProvider::Create(std::move(params->main_task_runner),
48 nullptr)),
49 compositor_proto_state_sink_(
50 std::move(params->compositor_proto_state_sink)),
51 settings_(*params->settings),
52 layer_tree_(std::move(layer_tree)),
53 weak_factory_(this) {
54 DCHECK(task_runner_provider_->IsMainThread());
55 DCHECK(compositor_proto_state_sink_);
56 DCHECK(client_);
57 compositor_proto_state_sink_->BindToClient(this);
58 }
59
60 LayerTreeHostRemote::~LayerTreeHostRemote() = default;
61
62 int LayerTreeHostRemote::GetId() const {
63 return id_;
64 }
65
66 int LayerTreeHostRemote::SourceFrameNumber() const {
67 return source_frame_number_;
68 }
69
70 LayerTree* LayerTreeHostRemote::GetLayerTree() {
71 return layer_tree_.get();
72 }
73
74 const LayerTree* LayerTreeHostRemote::GetLayerTree() const {
75 return layer_tree_.get();
76 }
77
78 UIResourceManager* LayerTreeHostRemote::GetUIResourceManager() {
79 // We shouldn't need a UIResourceManager. The layers which need this
80 // (UIResourceLayers and PaintedScrollbarLayers) are never used by the
81 // renderer compositor in remote mode.
82 NOTREACHED() << "UIResourceManager requested. Unsupported Layer type used";
83 return nullptr;
84 }
85
86 TaskRunnerProvider* LayerTreeHostRemote::GetTaskRunnerProvider() const {
87 return task_runner_provider_.get();
88 }
89
90 const LayerTreeSettings& LayerTreeHostRemote::GetSettings() const {
91 return settings_;
92 }
93
94 void LayerTreeHostRemote::SetSurfaceClientId(uint32_t client_id) {
95 // We don't need to care about SurfaceLayers. The Surfaces system is
96 // relevant on the client only.
97 }
98
99 void LayerTreeHostRemote::SetLayerTreeMutator(
100 std::unique_ptr<LayerTreeMutator> mutator) {
101 // TODO(khushalsagar): Compositor-worker not supported. See crbug.com/650876.
102 }
103
104 void LayerTreeHostRemote::QueueSwapPromise(
105 std::unique_ptr<SwapPromise> swap_promise) {
106 swap_promise_manager_.QueueSwapPromise(std::move(swap_promise));
107 }
108
109 SwapPromiseManager* LayerTreeHostRemote::GetSwapPromiseManager() {
110 return &swap_promise_manager_;
111 }
112
113 void LayerTreeHostRemote::SetHasGpuRasterizationTrigger(bool has_trigger) {
114 // TODO(khushalsagar) : Take care of Gpu raster. See crbug.com/650431.
115 }
116
117 void LayerTreeHostRemote::SetVisible(bool visible) {
118 // The visibility of the compositor is controlled on the client.
119 visible_ = visible;
120 }
121
122 bool LayerTreeHostRemote::IsVisible() const {
123 return visible_;
124 }
125
126 void LayerTreeHostRemote::SetCompositorFrameSink(
127 std::unique_ptr<CompositorFrameSink> compositor_frame_sink) {
128 NOTREACHED()
129 << "The LayerTreeHostClient is never asked for a CompositorFrameSink";
130 }
131
132 std::unique_ptr<CompositorFrameSink>
133 LayerTreeHostRemote::ReleaseCompositorFrameSink() {
134 // Since we never have a CompositorFrameSink, this is always a no-op.
135 return nullptr;
136 }
137
138 void LayerTreeHostRemote::SetNeedsAnimate() {
139 MainFrameRequested(FramePipelineStage::ANIMATE);
140 }
141
142 void LayerTreeHostRemote::SetNeedsUpdateLayers() {
143 MainFrameRequested(FramePipelineStage::UPDATE_LAYERS);
144 }
145
146 void LayerTreeHostRemote::SetNeedsCommit() {
147 MainFrameRequested(FramePipelineStage::COMMIT);
148 }
149
150 bool LayerTreeHostRemote::BeginMainFrameRequested() const {
151 return requested_pipeline_stage_for_next_frame_ != FramePipelineStage::NONE;
152 }
153
154 bool LayerTreeHostRemote::CommitRequested() const {
155 return requested_pipeline_stage_for_next_frame_ == FramePipelineStage::COMMIT;
156 }
157
158 void LayerTreeHostRemote::SetDeferCommits(bool defer_commits) {
159 defer_commits_ = defer_commits;
160 ScheduleMainFrameIfNecessary();
161 }
162
163 void LayerTreeHostRemote::LayoutAndUpdateLayers() {
164 NOTREACHED() << "Only supported in single-threaded mode and this class"
165 << " does not support single-thread since it is out of process";
166 }
167
168 void LayerTreeHostRemote::Composite(base::TimeTicks frame_begin_time) {
169 NOTREACHED() << "Only supported in single-threaded mode and this class"
170 << " does not support single-thread since it is out of process";
171 }
172
173 void LayerTreeHostRemote::SetNeedsRedraw() {
174 // The engine shouldn't need to care about draws. CompositorFrames are never
175 // used here.
176 }
177
178 void LayerTreeHostRemote::SetNeedsRedrawRect(const gfx::Rect& damage_rect) {
179 // The engine shouldn't need to care about draws. CompositorFrames are never
180 // used here.
181 }
182
183 void LayerTreeHostRemote::SetNextCommitForcesRedraw() {
184 // The engine shouldn't need to care about draws. CompositorFrames are never
185 // used here.
186 }
187
188 void LayerTreeHostRemote::NotifyInputThrottledUntilCommit() {
189 NOTIMPLEMENTED();
190 }
191
192 void LayerTreeHostRemote::UpdateTopControlsState(TopControlsState constraints,
193 TopControlsState current,
194 bool animate) {
195 NOTREACHED() << "Using TopControls animations is not supported";
196 }
197
198 const base::WeakPtr<InputHandler>& LayerTreeHostRemote::GetInputHandler()
199 const {
200 // Input on the compositor thread is handled on the client, so this is always
201 // null.
202 return input_handler_weak_ptr_;
203 }
204
205 void LayerTreeHostRemote::DidStopFlinging() {
206 NOTIMPLEMENTED() << "We shouldn't be sending fling gestures to the engine";
207 }
208
209 void LayerTreeHostRemote::SetDebugState(
210 const LayerTreeDebugState& debug_state) {
211 debug_state_ = debug_state;
212 }
213
214 const LayerTreeDebugState& LayerTreeHostRemote::GetDebugState() const {
215 return debug_state_;
216 }
217
218 int LayerTreeHostRemote::ScheduleMicroBenchmark(
219 const std::string& benchmark_name,
220 std::unique_ptr<base::Value> value,
221 const MicroBenchmark::DoneCallback& callback) {
222 NOTREACHED();
223 return 0;
224 }
225
226 bool LayerTreeHostRemote::SendMessageToMicroBenchmark(
227 int id,
228 std::unique_ptr<base::Value> value) {
229 NOTREACHED();
230 return false;
231 }
232
233 SurfaceSequenceGenerator* LayerTreeHostRemote::GetSurfaceSequenceGenerator() {
234 // TODO(khushalsagar): Eliminate the use of this in blink. See
235 // crbug.com/650876.
236 return &surface_sequence_generator_;
237 }
238
239 void LayerTreeHostRemote::SetNextCommitWaitsForActivation() {
240 // This is used only by layers that need resource synchronization, i.e.,
241 // texture and surface layers, both of which are not supported.
242 NOTIMPLEMENTED() << "Unsupported Layer type used";
243 }
244
245 void LayerTreeHostRemote::ResetGpuRasterizationTracking() {
246 // TODO(khushalsagar): Take care of Gpu raster. See crbug.com/650431.
247 }
248
249 void LayerTreeHostRemote::MainFrameRequested(
250 FramePipelineStage requested_pipeline_stage) {
251 DCHECK_NE(FramePipelineStage::NONE, requested_pipeline_stage);
252
253 swap_promise_manager_.NotifySwapPromiseMonitorsOfSetNeedsCommit();
254
255 // If we are inside a main frame update right now and the requested pipeline
256 // stage is higher than the pipeline stage that we are at, then we'll get to
257 // in this main frame update itself. Update the
258 // |max_pipeline_stage_for_current_frame_| to ensure we go through the
259 // requested pipeline stage.
260 if (current_pipeline_stage_ != FramePipelineStage::NONE &&
261 requested_pipeline_stage > current_pipeline_stage_) {
262 max_pipeline_stage_for_current_frame_ = std::max(
263 max_pipeline_stage_for_current_frame_, requested_pipeline_stage);
264 return;
265 }
266
267 // Update the pipeline stage for the next frame and schedule an update if it
268 // has not been scheduled already.
269 requested_pipeline_stage_for_next_frame_ = std::max(
270 requested_pipeline_stage_for_next_frame_, requested_pipeline_stage);
271
272 ScheduleMainFrameIfNecessary();
273 }
274
275 void LayerTreeHostRemote::ScheduleMainFrameIfNecessary() {
276 // If the client hasn't asked for a main frame, don't schedule one.
277 if (requested_pipeline_stage_for_next_frame_ == FramePipelineStage::NONE)
278 return;
279
280 // If the client does not want us to run main frame updates right now, don't
281 // schedule one.
282 if (defer_commits_)
283 return;
284
285 // If a main frame request is already pending with the
286 // CompositorProtoStateSink, we don't need to scheduler another one.
287 if (main_frame_requested_from_state_sink_)
288 return;
289
290 compositor_proto_state_sink_->ScheduleMainFrame();
291 main_frame_requested_from_state_sink_ = true;
292 }
293
294 void LayerTreeHostRemote::BeginMainFrame() {
295 DCHECK(main_frame_requested_from_state_sink_);
296
297 main_frame_requested_from_state_sink_ = false;
298
299 // The client might have suspended main frames in the meantime. Early out now,
300 // we'll come back here when they enable main frames again.
301 if (defer_commits_)
302 return;
303
304 DCHECK_EQ(current_pipeline_stage_, FramePipelineStage::NONE);
305 DCHECK_EQ(max_pipeline_stage_for_current_frame_, FramePipelineStage::NONE);
306 DCHECK_NE(requested_pipeline_stage_for_next_frame_, FramePipelineStage::NONE);
307
308 // Start the main frame. It should go till the requested pipeline stage.
309 max_pipeline_stage_for_current_frame_ =
310 requested_pipeline_stage_for_next_frame_;
311 requested_pipeline_stage_for_next_frame_ = FramePipelineStage::NONE;
312
313 client_->WillBeginMainFrame();
314
315 current_pipeline_stage_ = FramePipelineStage::ANIMATE;
316 base::TimeTicks now = base::TimeTicks::Now();
317 client_->BeginMainFrame(BeginFrameArgs::Create(
318 BEGINFRAME_FROM_HERE, now, now + kDefaultFrameInterval,
319 kDefaultFrameInterval, BeginFrameArgs::NORMAL));
320 // We don't run any animations on the layer because threaded animations are
321 // disabled.
322 // TODO(khushalsagar): Revisit this when adding support for animations.
323 DCHECK(!layer_tree_->animation_host()->needs_push_properties());
324 client_->UpdateLayerTreeHost();
325
326 current_pipeline_stage_ = FramePipelineStage::UPDATE_LAYERS;
327 LayerList layer_list;
328 if (max_pipeline_stage_for_current_frame_ >=
329 FramePipelineStage::UPDATE_LAYERS) {
330 // Pull updates for all layers from the client.
331 // TODO(khushalsagar): Investigate the data impact from updating all the
332 // layers. See crbug.com/650885.
333 LayerTreeHostCommon::CallFunctionForEveryLayer(
334 layer_tree_.get(),
335 [&layer_list](Layer* layer) { layer_list.push_back(layer); });
336
337 bool content_is_suitable_for_gpu = false;
338 bool layers_updated =
339 layer_tree_->UpdateLayers(layer_list, &content_is_suitable_for_gpu);
340
341 // If pulling layer updates resulted in any content updates, we need to go
342 // till the commit stage.
343 if (layers_updated)
344 max_pipeline_stage_for_current_frame_ = FramePipelineStage::COMMIT;
345 }
346
347 current_pipeline_stage_ = FramePipelineStage::COMMIT;
348 client_->WillCommit();
349
350 if (max_pipeline_stage_for_current_frame_ < current_pipeline_stage_) {
351 // There is nothing to commit so break the swap promises.
352 swap_promise_manager_.BreakSwapPromises(
353 SwapPromise::DidNotSwapReason::COMMIT_NO_UPDATE);
354
355 // For the client, the commit was successful.
356 MainFrameComplete();
357 return;
358 }
359
360 // TODO(khushalsagar): Serialize current state/reset dirty state tracking and
361 // return the result to the state sink instead.
362 std::unique_ptr<CompositorProtoState> compositor_state =
363 base::MakeUnique<CompositorProtoState>();
364 compositor_proto_state_sink_->ProcessCompositorStateUpdate(
365 std::move(compositor_state));
366
367 MainFrameComplete();
368
369 // We can not wait for updates dispatched from the client about the state of
370 // drawing or swaps for frames sent. Since these calls can be used by the
371 // LayerTreeHostClient to throttle further frame updates, so dispatch them
372 // right after the update is processed by the state sink.
373 // TODO(khushalsagar): We can not really know what these callbacks end up
374 // being used for. Consider migrating clients to understand/cope with the fact
375 // that there is no actual compositing happening here.
376 GetMainTaskRunner()->PostTask(
377 FROM_HERE, base::Bind(&LayerTreeHostRemote::DispatchDrawAndSwapCallbacks,
378 weak_factory_.GetWeakPtr()));
379 }
380
381 base::SingleThreadTaskRunner* LayerTreeHostRemote::GetMainTaskRunner() {
382 return task_runner_provider_->MainThreadTaskRunner();
383 }
384
385 void LayerTreeHostRemote::MainFrameComplete() {
386 DCHECK_EQ(current_pipeline_stage_, FramePipelineStage::COMMIT);
387
388 current_pipeline_stage_ = FramePipelineStage::NONE;
389 max_pipeline_stage_for_current_frame_ = FramePipelineStage::NONE;
390 source_frame_number_++;
391
392 client_->DidCommit();
393 client_->DidBeginMainFrame();
394 }
395
396 void LayerTreeHostRemote::DispatchDrawAndSwapCallbacks() {
397 client_->DidCommitAndDrawFrame();
398 client_->DidCompleteSwapBuffers();
399 }
400
401 } // namespace cc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698