| 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/atomic_sequence_num.h" | |
| 8 #include "base/memory/ptr_util.h" | |
| 9 #include "cc/animation/animation_host.h" | |
| 10 #include "cc/blimp/compositor_proto_state.h" | |
| 11 #include "cc/blimp/remote_compositor_bridge.h" | |
| 12 #include "cc/output/begin_frame_args.h" | |
| 13 #include "cc/output/compositor_frame_sink.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 | |
| 25 static base::StaticAtomicSequenceNumber s_layer_tree_host_sequence_number; | |
| 26 } // namespace | |
| 27 | |
| 28 LayerTreeHostRemote::InitParams::InitParams() = default; | |
| 29 | |
| 30 LayerTreeHostRemote::InitParams::~InitParams() = default; | |
| 31 | |
| 32 LayerTreeHostRemote::LayerTreeHostRemote(InitParams* params) | |
| 33 : LayerTreeHostRemote( | |
| 34 params, | |
| 35 base::MakeUnique<LayerTree>(std::move(params->animation_host), | |
| 36 this)) {} | |
| 37 | |
| 38 LayerTreeHostRemote::LayerTreeHostRemote(InitParams* params, | |
| 39 std::unique_ptr<LayerTree> layer_tree) | |
| 40 : id_(s_layer_tree_host_sequence_number.GetNext() + 1), | |
| 41 main_frame_requested_from_bridge_(false), | |
| 42 client_(params->client), | |
| 43 task_runner_provider_( | |
| 44 TaskRunnerProvider::Create(std::move(params->main_task_runner), | |
| 45 nullptr)), | |
| 46 remote_compositor_bridge_(std::move(params->remote_compositor_bridge)), | |
| 47 settings_(*params->settings), | |
| 48 layer_tree_(std::move(layer_tree)), | |
| 49 weak_factory_(this) { | |
| 50 DCHECK(task_runner_provider_->IsMainThread()); | |
| 51 DCHECK(remote_compositor_bridge_); | |
| 52 DCHECK(client_); | |
| 53 remote_compositor_bridge_->BindToClient(this); | |
| 54 } | |
| 55 | |
| 56 LayerTreeHostRemote::~LayerTreeHostRemote() = default; | |
| 57 | |
| 58 int LayerTreeHostRemote::GetId() const { | |
| 59 return id_; | |
| 60 } | |
| 61 | |
| 62 int LayerTreeHostRemote::SourceFrameNumber() const { | |
| 63 return source_frame_number_; | |
| 64 } | |
| 65 | |
| 66 LayerTree* LayerTreeHostRemote::GetLayerTree() { | |
| 67 return layer_tree_.get(); | |
| 68 } | |
| 69 | |
| 70 const LayerTree* LayerTreeHostRemote::GetLayerTree() const { | |
| 71 return layer_tree_.get(); | |
| 72 } | |
| 73 | |
| 74 UIResourceManager* LayerTreeHostRemote::GetUIResourceManager() const { | |
| 75 // We shouldn't need a UIResourceManager. The layers which need this | |
| 76 // (UIResourceLayers and PaintedScrollbarLayers) are never used by the | |
| 77 // renderer compositor in remote mode. | |
| 78 NOTREACHED() << "UIResourceManager requested. Unsupported Layer type used"; | |
| 79 return nullptr; | |
| 80 } | |
| 81 | |
| 82 TaskRunnerProvider* LayerTreeHostRemote::GetTaskRunnerProvider() const { | |
| 83 return task_runner_provider_.get(); | |
| 84 } | |
| 85 | |
| 86 const LayerTreeSettings& LayerTreeHostRemote::GetSettings() const { | |
| 87 return settings_; | |
| 88 } | |
| 89 | |
| 90 void LayerTreeHostRemote::SetFrameSinkId(const FrameSinkId& frame_sink_id) { | |
| 91 // We don't need to care about SurfaceLayers. The Surfaces system is | |
| 92 // relevant on the client only. | |
| 93 } | |
| 94 | |
| 95 void LayerTreeHostRemote::SetLayerTreeMutator( | |
| 96 std::unique_ptr<LayerTreeMutator> mutator) { | |
| 97 // TODO(khushalsagar): Compositor-worker not supported. See crbug.com/650876. | |
| 98 } | |
| 99 | |
| 100 void LayerTreeHostRemote::QueueSwapPromise( | |
| 101 std::unique_ptr<SwapPromise> swap_promise) { | |
| 102 swap_promise_manager_.QueueSwapPromise(std::move(swap_promise)); | |
| 103 } | |
| 104 | |
| 105 SwapPromiseManager* LayerTreeHostRemote::GetSwapPromiseManager() { | |
| 106 return &swap_promise_manager_; | |
| 107 } | |
| 108 | |
| 109 void LayerTreeHostRemote::SetHasGpuRasterizationTrigger(bool has_trigger) { | |
| 110 // TODO(khushalsagar) : Take care of Gpu raster. See crbug.com/650431. | |
| 111 } | |
| 112 | |
| 113 void LayerTreeHostRemote::SetVisible(bool visible) { | |
| 114 // The visibility of the compositor is controlled on the client, which is | |
| 115 // why this value is not sent there, since the client has the current true | |
| 116 // state. | |
| 117 visible_ = visible; | |
| 118 } | |
| 119 | |
| 120 bool LayerTreeHostRemote::IsVisible() const { | |
| 121 return visible_; | |
| 122 } | |
| 123 | |
| 124 void LayerTreeHostRemote::SetCompositorFrameSink( | |
| 125 std::unique_ptr<CompositorFrameSink> compositor_frame_sink) { | |
| 126 NOTREACHED() | |
| 127 << "The LayerTreeHostClient is never asked for a CompositorFrameSink"; | |
| 128 } | |
| 129 | |
| 130 std::unique_ptr<CompositorFrameSink> | |
| 131 LayerTreeHostRemote::ReleaseCompositorFrameSink() { | |
| 132 // Since we never have a CompositorFrameSink, this is always a no-op. | |
| 133 return nullptr; | |
| 134 } | |
| 135 | |
| 136 void LayerTreeHostRemote::SetNeedsAnimate() { | |
| 137 MainFrameRequested(FramePipelineStage::ANIMATE); | |
| 138 } | |
| 139 | |
| 140 void LayerTreeHostRemote::SetNeedsUpdateLayers() { | |
| 141 MainFrameRequested(FramePipelineStage::UPDATE_LAYERS); | |
| 142 } | |
| 143 | |
| 144 void LayerTreeHostRemote::SetNeedsCommit() { | |
| 145 MainFrameRequested(FramePipelineStage::COMMIT); | |
| 146 } | |
| 147 | |
| 148 bool LayerTreeHostRemote::BeginMainFrameRequested() const { | |
| 149 return requested_pipeline_stage_for_next_frame_ != FramePipelineStage::NONE; | |
| 150 } | |
| 151 | |
| 152 bool LayerTreeHostRemote::CommitRequested() const { | |
| 153 return requested_pipeline_stage_for_next_frame_ == FramePipelineStage::COMMIT; | |
| 154 } | |
| 155 | |
| 156 void LayerTreeHostRemote::SetDeferCommits(bool defer_commits) { | |
| 157 defer_commits_ = defer_commits; | |
| 158 ScheduleMainFrameIfNecessary(); | |
| 159 } | |
| 160 | |
| 161 void LayerTreeHostRemote::LayoutAndUpdateLayers() { | |
| 162 NOTREACHED() << "Only supported in single-threaded mode and this class" | |
| 163 << " does not support single-thread since it is out of process"; | |
| 164 } | |
| 165 | |
| 166 void LayerTreeHostRemote::Composite(base::TimeTicks frame_begin_time) { | |
| 167 NOTREACHED() << "Only supported in single-threaded mode and this class" | |
| 168 << " does not support single-thread since it is out of process"; | |
| 169 } | |
| 170 | |
| 171 void LayerTreeHostRemote::SetNeedsRedraw() { | |
| 172 // The engine shouldn't need to care about draws. CompositorFrames are never | |
| 173 // used here. | |
| 174 NOTREACHED(); | |
| 175 } | |
| 176 | |
| 177 void LayerTreeHostRemote::SetNeedsRedrawRect(const gfx::Rect& damage_rect) { | |
| 178 // The engine shouldn't need to care about draws. CompositorFrames are never | |
| 179 // used here. | |
| 180 // TODO(khushalsagar): The caller could be waiting for an Ack for this redraw. | |
| 181 // We need a better solution for this. See crbug.com/651141. | |
| 182 NOTIMPLEMENTED(); | |
| 183 } | |
| 184 | |
| 185 void LayerTreeHostRemote::SetNextCommitForcesRedraw() { | |
| 186 // Ideally the engine shouldn't need to care about draw requests at all. The | |
| 187 // compositor that produces CompositorFrames is on the client and draw | |
| 188 // requests should be made directly to it on the client itself. | |
| 189 NOTREACHED(); | |
| 190 } | |
| 191 | |
| 192 void LayerTreeHostRemote::NotifyInputThrottledUntilCommit() { | |
| 193 // This notification is used in the case where the renderer handles an input | |
| 194 // event, and needs to send an Ack to the browser when the resulting main | |
| 195 // frame is committed. If the compositor is taking too long on the pending | |
| 196 // tree, the commit processing will be delayed blocking all input as a result. | |
| 197 // So this is used to have the compositor activate the pending tree faster, so | |
| 198 // the pending commit can be processed. | |
| 199 // In remote mode, we don't send such notifications to the client because the | |
| 200 // most likely bottleneck is the transport instead of raster. Also, input is | |
| 201 // queued on the client, so if raster does end up being a bottleneck, the | |
| 202 // input handling code on the client informs the LayerTreeHostInProcess | |
| 203 // directly. | |
| 204 NOTIMPLEMENTED(); | |
| 205 } | |
| 206 | |
| 207 void LayerTreeHostRemote::UpdateTopControlsState(TopControlsState constraints, | |
| 208 TopControlsState current, | |
| 209 bool animate) { | |
| 210 NOTREACHED() << "Using TopControls animations is not supported"; | |
| 211 } | |
| 212 | |
| 213 const base::WeakPtr<InputHandler>& LayerTreeHostRemote::GetInputHandler() | |
| 214 const { | |
| 215 // Input on the compositor thread is handled on the client, so this is always | |
| 216 // null. | |
| 217 return input_handler_weak_ptr_; | |
| 218 } | |
| 219 | |
| 220 void LayerTreeHostRemote::DidStopFlinging() { | |
| 221 // TODO(khushalsagar): This should not happen. See crbug.com/652000. | |
| 222 NOTIMPLEMENTED() << "We shouldn't be sending fling gestures to the engine"; | |
| 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 task_runner_provider_->MainThreadTaskRunner()->PostTask( | |
| 395 FROM_HERE, base::Bind(&LayerTreeHostRemote::DispatchDrawAndSwapCallbacks, | |
| 396 weak_factory_.GetWeakPtr())); | |
| 397 } | |
| 398 | |
| 399 void LayerTreeHostRemote::MainFrameComplete() { | |
| 400 DCHECK_EQ(current_pipeline_stage_, FramePipelineStage::COMMIT); | |
| 401 | |
| 402 current_pipeline_stage_ = FramePipelineStage::NONE; | |
| 403 max_pipeline_stage_for_current_frame_ = FramePipelineStage::NONE; | |
| 404 source_frame_number_++; | |
| 405 | |
| 406 client_->DidCommit(); | |
| 407 client_->DidBeginMainFrame(); | |
| 408 } | |
| 409 | |
| 410 void LayerTreeHostRemote::DispatchDrawAndSwapCallbacks() { | |
| 411 client_->DidCommitAndDrawFrame(); | |
| 412 client_->DidCompleteSwapBuffers(); | |
| 413 } | |
| 414 | |
| 415 } // namespace cc | |
| OLD | NEW |