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

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

Issue 2362073002: cc/blimp: Add a LayerTreeHostRemote implementation. (Closed)
Patch Set: source frame number 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/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 : LayerTreeHostRemote(
32 params,
33 base::MakeUnique<LayerTree>(std::move(params->animation_host),
34 this)) {}
35
36 LayerTreeHostRemote::LayerTreeHostRemote(InitParams* params,
37 std::unique_ptr<LayerTree> layer_tree)
38 : id_(LayerTreeHost::GenerateHostId()),
39 source_frame_number_(0),
40 visible_(false),
41 defer_commits_(false),
42 main_frame_requested_from_state_sink_(false),
43 current_pipeline_stage_(FramePipelineStage::NONE),
44 max_pipeline_stage_for_current_frame_(FramePipelineStage::NONE),
45 requested_pipeline_stage_for_next_frame_(FramePipelineStage::NONE),
46 client_(params->client),
47 task_runner_provider_(
48 TaskRunnerProvider::Create(std::move(params->main_task_runner),
49 nullptr)),
50 compositor_proto_state_sink_(
51 std::move(params->compositor_proto_state_sink)),
52 settings_(*params->settings),
53 layer_tree_(std::move(layer_tree)),
54 ui_resource_manager_(base::MakeUnique<UIResourceManager>()),
danakj 2016/09/26 21:36:53 why is it a pointer?
Khushal 2016/09/27 01:07:49 I just did that because LTHInProcess also had a pt
55 weak_factory_(this) {
56 DCHECK(task_runner_provider_->IsMainThread());
57 DCHECK(compositor_proto_state_sink_);
58 DCHECK(client_);
59 compositor_proto_state_sink_->BindToClient(this);
60 }
61
62 LayerTreeHostRemote::~LayerTreeHostRemote() = default;
63
64 int LayerTreeHostRemote::GetId() const {
65 return id_;
66 }
67
68 int LayerTreeHostRemote::SourceFrameNumber() const {
69 return source_frame_number_;
70 }
71
72 LayerTree* LayerTreeHostRemote::GetLayerTree() {
73 return layer_tree_.get();
74 }
75
76 const LayerTree* LayerTreeHostRemote::GetLayerTree() const {
77 return layer_tree_.get();
78 }
79
80 UIResourceManager* LayerTreeHostRemote::GetUIResourceManager() const {
81 // We shouldn't really need a UIResourceManager. The layers which need this
82 // are never used.
83 LOG(ERROR) << "UIResourceManager requested.";
danakj 2016/09/26 21:36:52 How about notreached and return null then?
Khushal 2016/09/27 01:07:48 This is used by Painted scrollbars only, which bli
danakj 2016/09/27 20:32:43 My response would be "let's find out then" but I i
Khushal 2016/09/27 23:46:56 Okay, so we have turned turn off the use of Painte
84 return ui_resource_manager_.get();
85 }
86
87 TaskRunnerProvider* LayerTreeHostRemote::GetTaskRunnerProvider() const {
88 return task_runner_provider_.get();
89 }
90
91 const LayerTreeSettings& LayerTreeHostRemote::GetSettings() const {
92 return settings_;
93 }
94
95 void LayerTreeHostRemote::SetSurfaceClientId(uint32_t client_id) {
96 // We don't need to care about SurfaceLayers. The Surfaces system is
danakj 2016/09/26 21:36:52 Can we NOTREACHED?
Khushal 2016/09/27 01:07:49 The renderer will always call this still, even if
97 // relevant on the client only.
98 }
99
100 void LayerTreeHostRemote::SetLayerTreeMutator(
101 std::unique_ptr<LayerTreeMutator> mutator) {
102 // Compositor-worker not supported.
danakj 2016/09/26 21:36:52 Can we NOTREACHED?
Khushal 2016/09/27 01:07:49 I think this is all setup code which will still ru
danakj 2016/09/27 20:32:43 Perhaps we should be turning the setup code off if
Khushal 2016/09/27 23:46:56 Sure, we can do it in blink also. For all the feat
103 }
104
105 void LayerTreeHostRemote::QueueSwapPromise(
106 std::unique_ptr<SwapPromise> swap_promise) {
107 swap_promise_manager_.QueueSwapPromise(std::move(swap_promise));
108 }
109
110 SwapPromiseManager* LayerTreeHostRemote::GetSwapPromiseManager() {
111 return &swap_promise_manager_;
112 }
113
114 void LayerTreeHostRemote::SetHasGpuRasterizationTrigger(bool has_trigger) {
115 // TODO(khushalsagar) : Take care of Gpu raster.
danakj 2016/09/26 21:36:52 Can you point at a bug?
Khushal 2016/09/27 01:07:49 Done.
116 }
117
118 void LayerTreeHostRemote::SetVisible(bool visible) {
119 // The visibility is controlled on the client. The value here should always be
120 // true and changes only during page transitions.
danakj 2016/09/26 21:36:52 What do you mean by it should always be true? Call
Khushal 2016/09/27 01:07:49 I was just adding this comment to point out why we
121 visible_ = visible;
122 }
123
124 bool LayerTreeHostRemote::IsVisible() const {
125 return visible_;
126 }
127
128 void LayerTreeHostRemote::SetCompositorFrameSink(
129 std::unique_ptr<CompositorFrameSink> compositor_frame_sink) {
130 NOTREACHED() << "We never ask the client for a CompositorFrameSink";
danakj 2016/09/26 21:36:53 "We" is a bit ambiguous here. "The LayerTreeHostCl
Khushal 2016/09/27 01:07:49 Done.
131 }
132
133 std::unique_ptr<CompositorFrameSink>
134 LayerTreeHostRemote::ReleaseCompositorFrameSink() {
135 // Since we never have a CompositorFrameSink, this is always a no-op.
danakj 2016/09/26 21:36:52 Can we NOTREACHED? ps anything that is NOTREACHED
Khushal 2016/09/27 01:07:49 Well, the API says can be called safely anytime, s
danakj 2016/09/27 20:32:43 I thought this is only used by browser compositors
Khushal 2016/09/27 23:46:56 Its not there right now but I don't think its wron
136 return nullptr;
137 }
138
139 void LayerTreeHostRemote::SetNeedsAnimate() {
140 MainFrameRequested(FramePipelineStage::ANIMATE);
141 }
142
143 void LayerTreeHostRemote::SetNeedsUpdateLayers() {
144 MainFrameRequested(FramePipelineStage::UPDATE_LAYERS);
145 }
146
147 void LayerTreeHostRemote::SetNeedsCommit() {
148 MainFrameRequested(FramePipelineStage::COMMIT);
149 }
150
151 bool LayerTreeHostRemote::BeginMainFrameRequested() const {
152 return requested_pipeline_stage_for_next_frame_ != FramePipelineStage::NONE;
153 }
154
155 bool LayerTreeHostRemote::CommitRequested() const {
156 return requested_pipeline_stage_for_next_frame_ == FramePipelineStage::COMMIT;
157 }
158
159 void LayerTreeHostRemote::SetDeferCommits(bool defer_commits) {
160 defer_commits_ = defer_commits;
161 ScheduleMainFrameIfNecessary();
162 }
163
164 void LayerTreeHostRemote::LayoutAndUpdateLayers() {
165 NOTREACHED() << "Only supported in single-threaded mode";
danakj 2016/09/26 21:36:52 ".. and this class does not support single-thread
Khushal 2016/09/27 01:07:49 Done.
166 }
167
168 void LayerTreeHostRemote::Composite(base::TimeTicks frame_begin_time) {
169 NOTREACHED() << "Only supported in single-threaded mode";
danakj 2016/09/26 21:36:52 ditto
Khushal 2016/09/27 01:07:49 Done.
170 }
171
172 void LayerTreeHostRemote::SetNeedsRedraw() {
173 // The engine shouldn't need to care about draws. CompositorFrames are never
danakj 2016/09/26 21:36:53 I don't know about this. This causes the composito
Khushal 2016/09/27 01:07:49 Its redundant in the blimp case. The RenderWidget
danakj 2016/09/27 20:32:43 Ok actually it looks like browser compositors (ui:
Khushal 2016/09/27 23:46:56 I would be happier to keep consistency with the th
danakj 2016/09/28 00:32:50 Leaving it empty feels like a landmine to me, I'd
Khushal 2016/09/28 19:47:16 Done. I'll remove it from the threaded one as well
174 // used here.
175 }
176
177 void LayerTreeHostRemote::SetNeedsRedrawRect(const gfx::Rect& damage_rect) {
178 // The engine shouldn't need to care about draws. CompositorFrames are never
danakj 2016/09/26 21:36:52 Same.
danakj 2016/09/27 20:32:43 However RenderWidget calls this when it wants a re
Khushal 2016/09/27 23:46:56 Ah, good point. Thanks for pointing that case out.
danakj 2016/09/28 00:32:50 It sounds sketchy in that it's likely to interfere
Khushal 2016/09/28 19:47:16 In this case rather than the client, its elements
179 // used here.
180 }
181
182 void LayerTreeHostRemote::SetNextCommitForcesRedraw() {
183 // The engine shouldn't need to care about draws. CompositorFrames are never
danakj 2016/09/26 21:36:53 This is for testing, to ensure that it completes a
Khushal 2016/09/27 01:07:48 Still no need to send anything to the client thoug
danakj 2016/09/27 20:32:43 I guess it depends if you're running a pixel test.
Khushal 2016/09/27 23:46:56 For pixel tests my plan was to have an implementat
danakj 2016/09/28 00:32:50 I'm thinking more like gpu pixel tests: https://ww
Khushal 2016/09/28 19:47:16 Ah, okay. Can you point me to where this is done?
danakj 2016/09/29 23:59:35 Yes it's the screenshots thing. It's also interest
Khushal 2016/09/30 02:11:18 There is a super-basic complete end-to-end integra
184 // used here.
185 }
186
187 void LayerTreeHostRemote::NotifyInputThrottledUntilCommit() {
188 // We don't throttle commits right now so this is not relevant.
danakj 2016/09/26 21:36:52 NOTREACHED?
Khushal 2016/09/27 01:07:50 NOTIMPLEMENTED is better I think. The engine will
danakj 2016/09/27 20:32:43 OK I'm not actually sure how this will interact wi
Khushal 2016/09/27 23:46:56 So this was when I had looked at the code a while
danakj 2016/09/28 00:32:50 OK Cool that all sounds good, can you put this in
Khushal 2016/09/28 19:47:16 Done. Didn't add where on the client because that'
189 }
190
191 void LayerTreeHostRemote::UpdateTopControlsState(TopControlsState constraints,
192 TopControlsState current,
193 bool animate) {
194 NOTREACHED() << "Using TopControls animations is not supported";
195 }
196
197 const base::WeakPtr<InputHandler>& LayerTreeHostRemote::GetInputHandler()
198 const {
199 // Input on the compositor thread is handled on the client, so this is always
200 // null.
201 return input_handler_weak_ptr_;
danakj 2016/09/26 21:36:53 This is kinda awk, maybe follow up to make this re
Khushal 2016/09/27 01:07:49 Sounds good. I'll clean up in the next patch.
202 }
203
204 void LayerTreeHostRemote::DidStopFlinging() {
205 NOTIMPLEMENTED() << "We shouldn't be sending fling gestures to the engine";
206 }
207
208 void LayerTreeHostRemote::SetDebugState(
209 const LayerTreeDebugState& debug_state) {
210 debug_state_ = debug_state;
danakj 2016/09/26 21:36:53 How does this get to the client? Should it not Set
Khushal 2016/09/27 01:07:49 If there is a need to see debug info, then that ca
danakj 2016/09/27 20:32:43 Ok, why store it at all then? How does inspector
Khushal 2016/09/27 23:46:56 Because things take a const&. I looked through the
danakj 2016/09/28 00:32:50 I can see why you made a member then, but why repl
Khushal 2016/09/28 19:47:16 Good point. I made it a NOTREACHED for now. Will c
211 }
212
213 const LayerTreeDebugState& LayerTreeHostRemote::GetDebugState() const {
214 return debug_state_;
215 }
216
217 int LayerTreeHostRemote::ScheduleMicroBenchmark(
218 const std::string& benchmark_name,
219 std::unique_ptr<base::Value> value,
220 const MicroBenchmark::DoneCallback& callback) {
221 NOTIMPLEMENTED();
danakj 2016/09/26 21:36:53 Or NOTREACHED?
Khushal 2016/09/27 01:07:49 I don't think we want to say that calling this met
danakj 2016/09/27 20:32:43 My thot is that if it doesn't work to use NOTREACH
Khushal 2016/09/27 23:46:56 Okay, you're right. This one's used by Gpu benchma
222 return 0;
223 }
224
225 bool LayerTreeHostRemote::SendMessageToMicroBenchmark(
226 int id,
227 std::unique_ptr<base::Value> value) {
228 NOTIMPLEMENTED();
danakj 2016/09/26 21:36:53 Or NOTREACHED?
Khushal 2016/09/27 01:07:49 Same.
229 return false;
230 }
231
232 SurfaceSequenceGenerator* LayerTreeHostRemote::GetSurfaceSequenceGenerator() {
233 return &surface_sequence_generator_;
danakj 2016/09/26 21:36:53 This is for surfacelayer also like below. So why s
Khushal 2016/09/27 01:07:49 Yeah, it won't work. I still wasn't sure if I shou
danakj 2016/09/27 20:32:43 We shouldn't crash, the code that calls this shoul
Khushal 2016/09/27 23:46:56 Fair point. Added a TODO to turn this off in blink
234 }
235
236 void LayerTreeHostRemote::SetNextCommitWaitsForActivation() {
237 // This is used only by layers that need resource synchronization, i.e.,
238 // texture and surface layers, both of which are not supported.
239 NOTIMPLEMENTED() << "Unsupported Layer type used";
240 }
241
242 void LayerTreeHostRemote::ResetGpuRasterizationTracking() {}
danakj 2016/09/26 21:36:52 TODO? Is there a bug to link to?
Khushal 2016/09/27 01:07:49 Done.
243
244 void LayerTreeHostRemote::MainFrameRequested(
245 FramePipelineStage requested_pipeline_stage) {
246 DCHECK_NE(FramePipelineStage::NONE, requested_pipeline_stage);
247
248 swap_promise_manager_.NotifySwapPromiseMonitorsOfSetNeedsCommit();
249
250 // If we are inside a main frame update right now and the requested pipeline
251 // stage is higher than the pipeline stage that we are at, then we'll get to
252 // in this main frame update itself. Update the
253 // |max_pipeline_stage_for_current_frame_| to ensure we go through the
254 // requested pipeline stage.
255 if (current_pipeline_stage_ != FramePipelineStage::NONE &&
256 requested_pipeline_stage > current_pipeline_stage_) {
257 max_pipeline_stage_for_current_frame_ = std::max(
258 max_pipeline_stage_for_current_frame_, requested_pipeline_stage);
259 return;
260 }
261
262 // Update the pipeline stage for the next frame and schedule an update if it
263 // has not been scheduled already.
264 requested_pipeline_stage_for_next_frame_ = std::max(
265 requested_pipeline_stage_for_next_frame_, requested_pipeline_stage);
266
267 ScheduleMainFrameIfNecessary();
268 }
269
270 void LayerTreeHostRemote::ScheduleMainFrameIfNecessary() {
271 // If the client hasn't asked for a main frame, don't schedule one.
272 if (requested_pipeline_stage_for_next_frame_ == FramePipelineStage::NONE)
273 return;
274
275 // If the client does not want us to run main frame updates right now, don't
276 // schedule one.
277 if (defer_commits_)
278 return;
279
280 // If a main frame request is already pending with the CompositorFrameSink,
danakj 2016/09/26 21:36:53 I don't think you mean CompositorFrameSink
Khushal 2016/09/27 01:07:49 Done. So I was hoping that this name wouldn't cau
281 // we don't need to scheduler another one.
282 if (main_frame_requested_from_state_sink_)
283 return;
284
285 compositor_proto_state_sink_->ScheduleMainFrame();
286 main_frame_requested_from_state_sink_ = true;
287 }
288
289 void LayerTreeHostRemote::BeginMainFrame() {
290 DCHECK(main_frame_requested_from_state_sink_);
291
292 main_frame_requested_from_state_sink_ = false;
293
294 // The client might have suspended main frames in the meantime. Early out now,
295 // we'll come back here when they enable main frames again.
296 if (defer_commits_)
297 return;
298
299 DCHECK_EQ(FramePipelineStage::NONE, current_pipeline_stage_);
danakj 2016/09/26 21:36:52 can you write these in the same order you'd write
Khushal 2016/09/27 01:07:48 Done. I was actually looking for comments above th
300 DCHECK_EQ(FramePipelineStage::NONE, max_pipeline_stage_for_current_frame_);
301 DCHECK_NE(FramePipelineStage::NONE, requested_pipeline_stage_for_next_frame_);
302
303 // Start the main frame. It should go till the requested pipeline stage.
304 max_pipeline_stage_for_current_frame_ =
305 requested_pipeline_stage_for_next_frame_;
306 requested_pipeline_stage_for_next_frame_ = FramePipelineStage::NONE;
307
308 client_->WillBeginMainFrame();
309
310 current_pipeline_stage_ = FramePipelineStage::ANIMATE;
311 base::TimeTicks now = base::TimeTicks::Now();
312 client_->BeginMainFrame(BeginFrameArgs::Create(
313 BEGINFRAME_FROM_HERE, now, now + kDefaultFrameInterval,
314 kDefaultFrameInterval, BeginFrameArgs::NORMAL));
315 // We don't run any animations on the layer because threaded animations are
316 // disabled.
317 // TODO(khushalsagar): Revisit this when adding support for animations.
318 DCHECK(!layer_tree_->animation_host()->needs_push_properties());
319 client_->UpdateLayerTreeHost();
320
321 current_pipeline_stage_ = FramePipelineStage::UPDATE_LAYERS;
322 LayerList layer_list;
323 if (max_pipeline_stage_for_current_frame_ >=
324 FramePipelineStage::UPDATE_LAYERS) {
325 // Pull updates for all layers from the client.
danakj 2016/09/26 21:36:53 Do you really want all layers? Is this something t
Khushal 2016/09/27 01:07:50 I'm glad you asked. So in the regular case we do h
danakj 2016/09/27 20:32:43 I think not optimizing this will make the initial
Khushal 2016/09/27 23:46:56 Thanks. Added a TODO.
326 LayerTreeHostCommon::CallFunctionForEveryLayer(
327 layer_tree_.get(),
328 [&layer_list](Layer* layer) { layer_list.push_back(layer); });
329
330 bool content_is_suitable_for_gpu = false;
331 bool layers_updated =
332 layer_tree_->UpdateLayers(layer_list, &content_is_suitable_for_gpu);
333
334 // If pulling layer updates resulted in any content updates, we need to go
335 // till the commit stage.
336 max_pipeline_stage_for_current_frame_ =
danakj 2016/09/26 21:36:52 This is a weird way to write if (layers_updated)
Khushal 2016/09/27 01:07:49 Done.
337 layers_updated ? FramePipelineStage::COMMIT
338 : max_pipeline_stage_for_current_frame_;
339 }
340
341 current_pipeline_stage_ = FramePipelineStage::COMMIT;
342 client_->WillCommit();
343
344 if (max_pipeline_stage_for_current_frame_ < current_pipeline_stage_) {
345 // There is nothing to commit so break the swap promises.
346 swap_promise_manager_.BreakSwapPromises(
347 SwapPromise::DidNotSwapReason::COMMIT_NO_UPDATE);
348
349 // For the client, the commit was successful.
350 MainFrameComplete();
351 return;
352 }
353
354 // TODO(khushalsagar): Serialize current state/reset dirty state tracking and
355 // return the result to the state sink instead.
356 std::unique_ptr<CompositorProtoState> compositor_state =
357 base::MakeUnique<CompositorProtoState>();
358 compositor_proto_state_sink_->ProcessCompositorStateUpdate(
359 std::move(compositor_state));
360
361 MainFrameComplete();
362
363 // We can not wait for updates dispatched from the client about the state of
danakj 2016/09/26 21:36:53 Why can't you wait?
Khushal 2016/09/27 01:07:49 Because it used to end up throttling updates from
danakj 2016/09/27 20:32:43 OK Can you TODO pointing at a bug with this inform
Khushal 2016/09/27 23:46:56 Done.
364 // drawing or swaps for frames sent. Since these calls can be used by the
365 // LayerTreeHostClient to throttle further frame updates, so dispatch them
366 // right after the update is processed by the state sink.
367 // TODO(khushalsagar): We can not really know what these callbacks end up
368 // being used for. Consider migrating clients to understand/cope with the fact
369 // that there is no actual compositing happening here.
370 GetMainTaskRunner()->PostTask(
371 FROM_HERE, base::Bind(&LayerTreeHostRemote::DispatchDrawAndSwapCallbacks,
372 weak_factory_.GetWeakPtr()));
373 }
374
375 base::SingleThreadTaskRunner* LayerTreeHostRemote::GetMainTaskRunner() {
376 return task_runner_provider_->MainThreadTaskRunner();
377 }
378
379 void LayerTreeHostRemote::MainFrameComplete() {
380 DCHECK_EQ(current_pipeline_stage_, FramePipelineStage::COMMIT);
381
382 current_pipeline_stage_ = FramePipelineStage::NONE;
383 max_pipeline_stage_for_current_frame_ = FramePipelineStage::NONE;
384 source_frame_number_++;
385
386 client_->DidCommit();
387 client_->DidBeginMainFrame();
388 }
389
390 void LayerTreeHostRemote::DispatchDrawAndSwapCallbacks() {
391 client_->DidCommitAndDrawFrame();
392 client_->DidCompleteSwapBuffers();
393 }
394
395 } // namespace cc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698