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