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

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

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

Powered by Google App Engine
This is Rietveld 408576698