OLD | NEW |
---|---|
(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 | |
OLD | NEW |