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

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

Issue 2362073002: cc/blimp: Add a LayerTreeHostRemote implementation. (Closed)
Patch Set: win 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/remote_compositor_bridge.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),
danakj 2016/09/30 22:37:13 can you move constant initializers like this out t
Khushal 2016/10/01 00:53:48 Done.
39 visible_(false),
40 defer_commits_(false),
41 main_frame_requested_from_bridge_(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 remote_compositor_bridge_(std::move(params->remote_compositor_bridge)),
50 settings_(*params->settings),
51 layer_tree_(std::move(layer_tree)),
52 weak_factory_(this) {
53 DCHECK(task_runner_provider_->IsMainThread());
54 DCHECK(remote_compositor_bridge_);
55 DCHECK(client_);
56 remote_compositor_bridge_->BindToClient(this);
57 }
58
59 LayerTreeHostRemote::~LayerTreeHostRemote() = default;
60
61 int LayerTreeHostRemote::GetId() const {
62 return id_;
63 }
64
65 int LayerTreeHostRemote::SourceFrameNumber() const {
66 return source_frame_number_;
67 }
68
69 LayerTree* LayerTreeHostRemote::GetLayerTree() {
70 return layer_tree_.get();
71 }
72
73 const LayerTree* LayerTreeHostRemote::GetLayerTree() const {
74 return layer_tree_.get();
75 }
76
77 UIResourceManager* LayerTreeHostRemote::GetUIResourceManager() {
78 // We shouldn't need a UIResourceManager. The layers which need this
79 // (UIResourceLayers and PaintedScrollbarLayers) are never used by the
80 // renderer compositor in remote mode.
81 NOTREACHED() << "UIResourceManager requested. Unsupported Layer type used";
82 return nullptr;
83 }
84
85 TaskRunnerProvider* LayerTreeHostRemote::GetTaskRunnerProvider() const {
86 return task_runner_provider_.get();
87 }
88
89 const LayerTreeSettings& LayerTreeHostRemote::GetSettings() const {
90 return settings_;
91 }
92
93 void LayerTreeHostRemote::SetSurfaceClientId(uint32_t client_id) {
94 // We don't need to care about SurfaceLayers. The Surfaces system is
95 // relevant on the client only.
96 }
97
98 void LayerTreeHostRemote::SetLayerTreeMutator(
99 std::unique_ptr<LayerTreeMutator> mutator) {
100 // TODO(khushalsagar): Compositor-worker not supported. See crbug.com/650876.
101 }
102
103 void LayerTreeHostRemote::QueueSwapPromise(
104 std::unique_ptr<SwapPromise> swap_promise) {
105 swap_promise_manager_.QueueSwapPromise(std::move(swap_promise));
danakj 2016/09/30 22:37:13 API feedback it's a bit weird that this class can
Khushal 2016/10/01 00:53:48 For this one you would have to talk to piman@, htt
danakj 2016/10/03 21:02:48 Thanks for the pointer.
106 }
107
108 SwapPromiseManager* LayerTreeHostRemote::GetSwapPromiseManager() {
109 return &swap_promise_manager_;
110 }
111
112 void LayerTreeHostRemote::SetHasGpuRasterizationTrigger(bool has_trigger) {
113 // TODO(khushalsagar) : Take care of Gpu raster. See crbug.com/650431.
114 }
115
116 void LayerTreeHostRemote::SetVisible(bool visible) {
117 // The visibility of the compositor is controlled on the client.
danakj 2016/09/30 22:37:13 ".. but we fake it for blink because .."
danakj 2016/09/30 22:38:31 oops i lied we shouldnt say blink here. "for the c
Khushal 2016/10/01 00:53:48 Not sure what you mean, we don't fake anything her
danakj 2016/10/03 21:02:48 What I mean by fake, this doesn't actually change
118 visible_ = visible;
119 }
120
121 bool LayerTreeHostRemote::IsVisible() const {
122 return visible_;
123 }
124
125 void LayerTreeHostRemote::SetCompositorFrameSink(
126 std::unique_ptr<CompositorFrameSink> compositor_frame_sink) {
127 NOTREACHED()
128 << "The LayerTreeHostClient is never asked for a CompositorFrameSink";
129 }
130
131 std::unique_ptr<CompositorFrameSink>
132 LayerTreeHostRemote::ReleaseCompositorFrameSink() {
133 // Since we never have a CompositorFrameSink, this is always a no-op.
134 return nullptr;
135 }
136
137 void LayerTreeHostRemote::SetNeedsAnimate() {
138 MainFrameRequested(FramePipelineStage::ANIMATE);
139 }
140
141 void LayerTreeHostRemote::SetNeedsUpdateLayers() {
142 MainFrameRequested(FramePipelineStage::UPDATE_LAYERS);
143 }
144
145 void LayerTreeHostRemote::SetNeedsCommit() {
146 MainFrameRequested(FramePipelineStage::COMMIT);
147 }
148
149 bool LayerTreeHostRemote::BeginMainFrameRequested() const {
150 return requested_pipeline_stage_for_next_frame_ != FramePipelineStage::NONE;
151 }
152
153 bool LayerTreeHostRemote::CommitRequested() const {
154 return requested_pipeline_stage_for_next_frame_ == FramePipelineStage::COMMIT;
155 }
156
157 void LayerTreeHostRemote::SetDeferCommits(bool defer_commits) {
158 defer_commits_ = defer_commits;
159 ScheduleMainFrameIfNecessary();
160 }
161
162 void LayerTreeHostRemote::LayoutAndUpdateLayers() {
163 NOTREACHED() << "Only supported in single-threaded mode and this class"
164 << " does not support single-thread since it is out of process";
165 }
166
167 void LayerTreeHostRemote::Composite(base::TimeTicks frame_begin_time) {
168 NOTREACHED() << "Only supported in single-threaded mode and this class"
169 << " does not support single-thread since it is out of process";
170 }
171
172 void LayerTreeHostRemote::SetNeedsRedraw() {
173 // The engine shouldn't need to care about draws. CompositorFrames are never
174 // used here.
175 NOTREACHED();
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 // TODO(khushalsagar): The caller could be waiting for an Ack for this redraw.
182 // We need a better solution for this. See crbug.com/651141.
183 NOTIMPLEMENTED();
184 }
185
186 void LayerTreeHostRemote::SetNextCommitForcesRedraw() {
187 // Ideally the engine shouldn't need to care about draw requests at all. The
188 // compositor that produces CompositorFrames is on the client and draw
189 // requests should be made directly to it on the client itself.
190 NOTREACHED();
191 }
192
193 void LayerTreeHostRemote::NotifyInputThrottledUntilCommit() {
194 // This notification is used in the case where the renderer handles an input
195 // event, and needs to send an Ack to the browser when the resulting main
196 // frame is committed. If the compositor is taking too long on the pending
197 // tree, the commit processing will be delayed blocking all input as a result.
198 // So this is used to have the compositor activate the pending tree faster, so
199 // the pending commit can be processed.
200 // In remote mode, we don't send such notifications to the client because the
201 // most likely bottleneck is the transport instead of raster. Also, input is
202 // queued on the client, so if raster does end up being a bottleneck, the
203 // input handling code on the client informs the LayerTreeHostInProcess
204 // directly.
205 NOTIMPLEMENTED();
206 }
207
208 void LayerTreeHostRemote::UpdateTopControlsState(TopControlsState constraints,
209 TopControlsState current,
210 bool animate) {
211 NOTREACHED() << "Using TopControls animations is not supported";
212 }
213
214 const base::WeakPtr<InputHandler>& LayerTreeHostRemote::GetInputHandler()
215 const {
216 // Input on the compositor thread is handled on the client, so this is always
217 // null.
218 return input_handler_weak_ptr_;
219 }
220
221 void LayerTreeHostRemote::DidStopFlinging() {
222 NOTIMPLEMENTED() << "We shouldn't be sending fling gestures to the engine";
danakj 2016/09/30 22:37:13 NOTREACHED() unless we are sending fling gestures,
Khushal 2016/10/01 00:53:48 This will probably be a long running bug to unders
223 }
224
225 void LayerTreeHostRemote::SetDebugState(
226 const LayerTreeDebugState& debug_state) {
227 // TODO(khushalsagar): Figure out if we need to send these to the client.
228 NOTREACHED();
229 }
230
231 const LayerTreeDebugState& LayerTreeHostRemote::GetDebugState() const {
232 return debug_state_;
233 }
234
235 int LayerTreeHostRemote::ScheduleMicroBenchmark(
236 const std::string& benchmark_name,
237 std::unique_ptr<base::Value> value,
238 const MicroBenchmark::DoneCallback& callback) {
239 NOTREACHED();
240 return 0;
241 }
242
243 bool LayerTreeHostRemote::SendMessageToMicroBenchmark(
244 int id,
245 std::unique_ptr<base::Value> value) {
246 NOTREACHED();
247 return false;
248 }
249
250 SurfaceSequenceGenerator* LayerTreeHostRemote::GetSurfaceSequenceGenerator() {
251 // TODO(khushalsagar): Eliminate the use of this in blink. See
252 // crbug.com/650876.
253 return &surface_sequence_generator_;
254 }
255
256 void LayerTreeHostRemote::SetNextCommitWaitsForActivation() {
257 // This is used only by layers that need resource synchronization, i.e.,
258 // texture and surface layers, both of which are not supported.
259 NOTIMPLEMENTED() << "Unsupported Layer type used";
260 }
261
262 void LayerTreeHostRemote::ResetGpuRasterizationTracking() {
263 // TODO(khushalsagar): Take care of Gpu raster. See crbug.com/650431.
264 }
265
266 void LayerTreeHostRemote::MainFrameRequested(
267 FramePipelineStage requested_pipeline_stage) {
268 DCHECK_NE(FramePipelineStage::NONE, requested_pipeline_stage);
269
270 swap_promise_manager_.NotifySwapPromiseMonitorsOfSetNeedsCommit();
271
272 // If we are inside a main frame update right now and the requested pipeline
273 // stage is higher than the pipeline stage that we are at, then we'll get to
274 // in this main frame update itself. Update the
275 // |max_pipeline_stage_for_current_frame_| to ensure we go through the
276 // requested pipeline stage.
277 if (current_pipeline_stage_ != FramePipelineStage::NONE &&
278 requested_pipeline_stage > current_pipeline_stage_) {
279 max_pipeline_stage_for_current_frame_ = std::max(
280 max_pipeline_stage_for_current_frame_, requested_pipeline_stage);
281 return;
282 }
283
284 // Update the pipeline stage for the next frame and schedule an update if it
285 // has not been scheduled already.
286 requested_pipeline_stage_for_next_frame_ = std::max(
287 requested_pipeline_stage_for_next_frame_, requested_pipeline_stage);
288
289 ScheduleMainFrameIfNecessary();
290 }
291
292 void LayerTreeHostRemote::ScheduleMainFrameIfNecessary() {
293 // If the client hasn't asked for a main frame, don't schedule one.
294 if (requested_pipeline_stage_for_next_frame_ == FramePipelineStage::NONE)
295 return;
296
297 // If the client does not want us to run main frame updates right now, don't
298 // schedule one.
299 if (defer_commits_)
300 return;
301
302 // If a main frame request is already pending with the
303 // RemoteCompositorBridge, we don't need to scheduler another one.
304 if (main_frame_requested_from_bridge_)
305 return;
306
307 remote_compositor_bridge_->ScheduleMainFrame();
308 main_frame_requested_from_bridge_ = true;
309 }
310
311 void LayerTreeHostRemote::BeginMainFrame() {
312 DCHECK(main_frame_requested_from_bridge_);
313 DCHECK(task_runner_provider_->IsMainThread());
314
315 main_frame_requested_from_bridge_ = false;
316
317 // The client might have suspended main frames in the meantime. Early out now,
318 // we'll come back here when they enable main frames again.
319 if (defer_commits_)
320 return;
321
322 DCHECK_EQ(current_pipeline_stage_, FramePipelineStage::NONE);
323 DCHECK_EQ(max_pipeline_stage_for_current_frame_, FramePipelineStage::NONE);
324 DCHECK_NE(requested_pipeline_stage_for_next_frame_, FramePipelineStage::NONE);
325
326 // Start the main frame. It should go till the requested pipeline stage.
327 max_pipeline_stage_for_current_frame_ =
328 requested_pipeline_stage_for_next_frame_;
329 requested_pipeline_stage_for_next_frame_ = FramePipelineStage::NONE;
330
331 client_->WillBeginMainFrame();
332
333 current_pipeline_stage_ = FramePipelineStage::ANIMATE;
334 base::TimeTicks now = base::TimeTicks::Now();
335 client_->BeginMainFrame(BeginFrameArgs::Create(
336 BEGINFRAME_FROM_HERE, now, now + kDefaultFrameInterval,
337 kDefaultFrameInterval, BeginFrameArgs::NORMAL));
338 // We don't run any animations on the layer because threaded animations are
339 // disabled.
340 // TODO(khushalsagar): Revisit this when adding support for animations.
341 DCHECK(!layer_tree_->animation_host()->needs_push_properties());
342 client_->UpdateLayerTreeHost();
343
344 current_pipeline_stage_ = FramePipelineStage::UPDATE_LAYERS;
345 LayerList layer_list;
346 if (max_pipeline_stage_for_current_frame_ >=
347 FramePipelineStage::UPDATE_LAYERS) {
348 // Pull updates for all layers from the client.
349 // TODO(khushalsagar): Investigate the data impact from updating all the
350 // layers. See crbug.com/650885.
351 LayerTreeHostCommon::CallFunctionForEveryLayer(
352 layer_tree_.get(),
353 [&layer_list](Layer* layer) { layer_list.push_back(layer); });
354
355 bool content_is_suitable_for_gpu = false;
356 bool layers_updated =
357 layer_tree_->UpdateLayers(layer_list, &content_is_suitable_for_gpu);
358
359 // If pulling layer updates resulted in any content updates, we need to go
360 // till the commit stage.
361 if (layers_updated)
362 max_pipeline_stage_for_current_frame_ = FramePipelineStage::COMMIT;
363 }
364
365 current_pipeline_stage_ = FramePipelineStage::COMMIT;
366 client_->WillCommit();
367
368 if (max_pipeline_stage_for_current_frame_ < current_pipeline_stage_) {
369 // There is nothing to commit so break the swap promises.
370 swap_promise_manager_.BreakSwapPromises(
371 SwapPromise::DidNotSwapReason::COMMIT_NO_UPDATE);
372
373 // For the client, the commit was successful.
374 MainFrameComplete();
375 return;
376 }
377
378 // TODO(khushalsagar): Serialize current state/reset dirty state tracking and
379 // return the result to the bridge instead.
380 std::unique_ptr<CompositorProtoState> compositor_state =
381 base::MakeUnique<CompositorProtoState>();
382 remote_compositor_bridge_->ProcessCompositorStateUpdate(
383 std::move(compositor_state));
384
385 MainFrameComplete();
386
387 // We can not wait for updates dispatched from the client about the state of
388 // drawing or swaps for frames sent. Since these calls can be used by the
389 // LayerTreeHostClient to throttle further frame updates, so dispatch them
390 // right after the update is processed by the bridge.
391 // TODO(khushalsagar): We can not really know what these callbacks end up
392 // being used for. Consider migrating clients to understand/cope with the fact
393 // that there is no actual compositing happening here.
394 MainTaskRunner()->PostTask(
danakj 2016/09/30 22:37:13 This is the only user of MainTaskRunner? Just use
Khushal 2016/10/01 00:53:48 Done.
395 FROM_HERE, base::Bind(&LayerTreeHostRemote::DispatchDrawAndSwapCallbacks,
396 weak_factory_.GetWeakPtr()));
397 }
398
399 base::SingleThreadTaskRunner* LayerTreeHostRemote::MainTaskRunner() {
400 return task_runner_provider_->MainThreadTaskRunner();
401 }
402
403 void LayerTreeHostRemote::MainFrameComplete() {
404 DCHECK_EQ(current_pipeline_stage_, FramePipelineStage::COMMIT);
405
406 current_pipeline_stage_ = FramePipelineStage::NONE;
407 max_pipeline_stage_for_current_frame_ = FramePipelineStage::NONE;
408 source_frame_number_++;
409
410 client_->DidCommit();
411 client_->DidBeginMainFrame();
412 }
413
414 void LayerTreeHostRemote::DispatchDrawAndSwapCallbacks() {
415 client_->DidCommitAndDrawFrame();
416 client_->DidCompleteSwapBuffers();
417 }
418
419 } // namespace cc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698