| OLD | NEW |
| (Empty) |
| 1 // Copyright 2011 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/trees/layer_tree_host.h" | |
| 6 | |
| 7 #include <stddef.h> | |
| 8 #include <stdint.h> | |
| 9 | |
| 10 #include <algorithm> | |
| 11 #include <memory> | |
| 12 #include <stack> | |
| 13 #include <string> | |
| 14 #include <unordered_map> | |
| 15 | |
| 16 #include "base/atomic_sequence_num.h" | |
| 17 #include "base/bind.h" | |
| 18 #include "base/command_line.h" | |
| 19 #include "base/location.h" | |
| 20 #include "base/memory/ptr_util.h" | |
| 21 #include "base/metrics/histogram_macros.h" | |
| 22 #include "base/numerics/safe_math.h" | |
| 23 #include "base/single_thread_task_runner.h" | |
| 24 #include "base/stl_util.h" | |
| 25 #include "base/strings/string_number_conversions.h" | |
| 26 #include "base/threading/thread_task_runner_handle.h" | |
| 27 #include "base/trace_event/trace_event.h" | |
| 28 #include "base/trace_event/trace_event_argument.h" | |
| 29 #include "cc/animation/animation_events.h" | |
| 30 #include "cc/animation/animation_host.h" | |
| 31 #include "cc/base/math_util.h" | |
| 32 #include "cc/blimp/client_picture_cache.h" | |
| 33 #include "cc/blimp/engine_picture_cache.h" | |
| 34 #include "cc/blimp/image_serialization_processor.h" | |
| 35 #include "cc/blimp/picture_data.h" | |
| 36 #include "cc/blimp/picture_data_conversions.h" | |
| 37 #include "cc/debug/devtools_instrumentation.h" | |
| 38 #include "cc/debug/frame_viewer_instrumentation.h" | |
| 39 #include "cc/debug/rendering_stats_instrumentation.h" | |
| 40 #include "cc/input/layer_selection_bound.h" | |
| 41 #include "cc/input/page_scale_animation.h" | |
| 42 #include "cc/layers/heads_up_display_layer.h" | |
| 43 #include "cc/layers/heads_up_display_layer_impl.h" | |
| 44 #include "cc/layers/layer.h" | |
| 45 #include "cc/layers/layer_iterator.h" | |
| 46 #include "cc/layers/layer_proto_converter.h" | |
| 47 #include "cc/layers/painted_scrollbar_layer.h" | |
| 48 #include "cc/proto/gfx_conversions.h" | |
| 49 #include "cc/proto/layer_tree.pb.h" | |
| 50 #include "cc/proto/layer_tree_host.pb.h" | |
| 51 #include "cc/resources/ui_resource_manager.h" | |
| 52 #include "cc/scheduler/begin_frame_source.h" | |
| 53 #include "cc/trees/draw_property_utils.h" | |
| 54 #include "cc/trees/layer_tree_host_client.h" | |
| 55 #include "cc/trees/layer_tree_host_common.h" | |
| 56 #include "cc/trees/layer_tree_host_impl.h" | |
| 57 #include "cc/trees/layer_tree_impl.h" | |
| 58 #include "cc/trees/property_tree_builder.h" | |
| 59 #include "cc/trees/proxy_main.h" | |
| 60 #include "cc/trees/remote_channel_impl.h" | |
| 61 #include "cc/trees/single_thread_proxy.h" | |
| 62 #include "cc/trees/swap_promise_manager.h" | |
| 63 #include "cc/trees/tree_synchronizer.h" | |
| 64 #include "ui/gfx/geometry/size_conversions.h" | |
| 65 #include "ui/gfx/geometry/vector2d_conversions.h" | |
| 66 | |
| 67 namespace { | |
| 68 static base::StaticAtomicSequenceNumber s_layer_tree_host_sequence_number; | |
| 69 } | |
| 70 | |
| 71 namespace cc { | |
| 72 namespace { | |
| 73 | |
| 74 std::unique_ptr<base::trace_event::TracedValue> | |
| 75 ComputeLayerTreeHostProtoSizeSplitAsValue(proto::LayerTreeHost* proto) { | |
| 76 std::unique_ptr<base::trace_event::TracedValue> value( | |
| 77 new base::trace_event::TracedValue()); | |
| 78 base::CheckedNumeric<int> base_layer_properties_size = 0; | |
| 79 base::CheckedNumeric<int> picture_layer_properties_size = 0; | |
| 80 base::CheckedNumeric<int> display_item_list_size = 0; | |
| 81 base::CheckedNumeric<int> drawing_display_items_size = 0; | |
| 82 | |
| 83 const proto::LayerUpdate& layer_update_proto = proto->layer_updates(); | |
| 84 for (int i = 0; i < layer_update_proto.layers_size(); ++i) { | |
| 85 const proto::LayerProperties layer_properties_proto = | |
| 86 layer_update_proto.layers(i); | |
| 87 base_layer_properties_size += layer_properties_proto.base().ByteSize(); | |
| 88 | |
| 89 if (layer_properties_proto.has_picture()) { | |
| 90 const proto::PictureLayerProperties& picture_proto = | |
| 91 layer_properties_proto.picture(); | |
| 92 picture_layer_properties_size += picture_proto.ByteSize(); | |
| 93 | |
| 94 const proto::DisplayItemList& display_list_proto = | |
| 95 picture_proto.display_list(); | |
| 96 display_item_list_size += display_list_proto.ByteSize(); | |
| 97 | |
| 98 for (int j = 0; j < display_list_proto.items_size(); ++j) { | |
| 99 const proto::DisplayItem& display_item = display_list_proto.items(j); | |
| 100 if (display_item.type() == proto::DisplayItem::Type_Drawing) | |
| 101 drawing_display_items_size += display_item.ByteSize(); | |
| 102 } | |
| 103 } | |
| 104 } | |
| 105 | |
| 106 value->SetInteger("TotalLayerTreeHostProtoSize", proto->ByteSize()); | |
| 107 value->SetInteger("LayerTreeHierarchySize", | |
| 108 proto->layer_tree().root_layer().ByteSize()); | |
| 109 value->SetInteger("LayerUpdatesSize", proto->layer_updates().ByteSize()); | |
| 110 value->SetInteger("PropertyTreesSize", | |
| 111 proto->layer_tree().property_trees().ByteSize()); | |
| 112 | |
| 113 // LayerUpdate size breakdown. | |
| 114 value->SetInteger("TotalBasePropertiesSize", | |
| 115 base_layer_properties_size.ValueOrDefault(-1)); | |
| 116 value->SetInteger("PictureLayerPropertiesSize", | |
| 117 picture_layer_properties_size.ValueOrDefault(-1)); | |
| 118 value->SetInteger("DisplayItemListSize", | |
| 119 display_item_list_size.ValueOrDefault(-1)); | |
| 120 value->SetInteger("DrawingDisplayItemsSize", | |
| 121 drawing_display_items_size.ValueOrDefault(-1)); | |
| 122 return value; | |
| 123 } | |
| 124 | |
| 125 } // namespace | |
| 126 | |
| 127 LayerTreeHost::InitParams::InitParams() { | |
| 128 } | |
| 129 | |
| 130 LayerTreeHost::InitParams::~InitParams() { | |
| 131 } | |
| 132 | |
| 133 std::unique_ptr<LayerTreeHostInterface> LayerTreeHost::CreateThreaded( | |
| 134 scoped_refptr<base::SingleThreadTaskRunner> impl_task_runner, | |
| 135 InitParams* params) { | |
| 136 DCHECK(params->main_task_runner.get()); | |
| 137 DCHECK(impl_task_runner.get()); | |
| 138 DCHECK(params->settings); | |
| 139 std::unique_ptr<LayerTreeHost> layer_tree_host( | |
| 140 new LayerTreeHost(params, CompositorMode::THREADED)); | |
| 141 layer_tree_host->InitializeThreaded( | |
| 142 params->main_task_runner, impl_task_runner, | |
| 143 std::move(params->external_begin_frame_source)); | |
| 144 return std::move(layer_tree_host); | |
| 145 } | |
| 146 | |
| 147 std::unique_ptr<LayerTreeHost> LayerTreeHost::CreateSingleThreaded( | |
| 148 LayerTreeHostSingleThreadClient* single_thread_client, | |
| 149 InitParams* params) { | |
| 150 DCHECK(params->settings); | |
| 151 std::unique_ptr<LayerTreeHost> layer_tree_host( | |
| 152 new LayerTreeHost(params, CompositorMode::SINGLE_THREADED)); | |
| 153 layer_tree_host->InitializeSingleThreaded( | |
| 154 single_thread_client, params->main_task_runner, | |
| 155 std::move(params->external_begin_frame_source)); | |
| 156 return layer_tree_host; | |
| 157 } | |
| 158 | |
| 159 std::unique_ptr<LayerTreeHostInterface> LayerTreeHost::CreateRemoteServer( | |
| 160 RemoteProtoChannel* remote_proto_channel, | |
| 161 InitParams* params) { | |
| 162 DCHECK(params->main_task_runner.get()); | |
| 163 DCHECK(params->settings); | |
| 164 DCHECK(remote_proto_channel); | |
| 165 TRACE_EVENT0("cc.remote", "LayerTreeHost::CreateRemoteServer"); | |
| 166 | |
| 167 // Using an external begin frame source is not supported on the server in | |
| 168 // remote mode. | |
| 169 DCHECK(!params->settings->use_external_begin_frame_source); | |
| 170 DCHECK(!params->external_begin_frame_source); | |
| 171 DCHECK(params->image_serialization_processor); | |
| 172 | |
| 173 std::unique_ptr<LayerTreeHost> layer_tree_host( | |
| 174 new LayerTreeHost(params, CompositorMode::REMOTE)); | |
| 175 layer_tree_host->InitializeRemoteServer(remote_proto_channel, | |
| 176 params->main_task_runner); | |
| 177 return std::move(layer_tree_host); | |
| 178 } | |
| 179 | |
| 180 std::unique_ptr<LayerTreeHostInterface> LayerTreeHost::CreateRemoteClient( | |
| 181 RemoteProtoChannel* remote_proto_channel, | |
| 182 scoped_refptr<base::SingleThreadTaskRunner> impl_task_runner, | |
| 183 InitParams* params) { | |
| 184 DCHECK(params->main_task_runner.get()); | |
| 185 DCHECK(params->settings); | |
| 186 DCHECK(remote_proto_channel); | |
| 187 | |
| 188 // Using an external begin frame source is not supported in remote mode. | |
| 189 // TODO(khushalsagar): Add support for providing an external begin frame | |
| 190 // source on the client LayerTreeHost. crbug/576962 | |
| 191 DCHECK(!params->settings->use_external_begin_frame_source); | |
| 192 DCHECK(!params->external_begin_frame_source); | |
| 193 DCHECK(params->image_serialization_processor); | |
| 194 | |
| 195 std::unique_ptr<LayerTreeHost> layer_tree_host( | |
| 196 new LayerTreeHost(params, CompositorMode::REMOTE)); | |
| 197 layer_tree_host->InitializeRemoteClient( | |
| 198 remote_proto_channel, params->main_task_runner, impl_task_runner); | |
| 199 return std::move(layer_tree_host); | |
| 200 } | |
| 201 | |
| 202 LayerTreeHost::LayerTreeHost(InitParams* params, CompositorMode mode) | |
| 203 : LayerTreeHost( | |
| 204 params, | |
| 205 mode, | |
| 206 base::MakeUnique<LayerTree>(std::move(params->animation_host), | |
| 207 this)) {} | |
| 208 | |
| 209 LayerTreeHost::LayerTreeHost(InitParams* params, | |
| 210 CompositorMode mode, | |
| 211 std::unique_ptr<LayerTree> layer_tree) | |
| 212 : micro_benchmark_controller_(this), | |
| 213 layer_tree_(std::move(layer_tree)), | |
| 214 compositor_mode_(mode), | |
| 215 ui_resource_manager_(base::MakeUnique<UIResourceManager>()), | |
| 216 client_(params->client), | |
| 217 source_frame_number_(0), | |
| 218 rendering_stats_instrumentation_(RenderingStatsInstrumentation::Create()), | |
| 219 settings_(*params->settings), | |
| 220 debug_state_(settings_.initial_debug_state), | |
| 221 visible_(false), | |
| 222 has_gpu_rasterization_trigger_(false), | |
| 223 content_is_suitable_for_gpu_rasterization_(true), | |
| 224 gpu_rasterization_histogram_recorded_(false), | |
| 225 did_complete_scale_animation_(false), | |
| 226 id_(s_layer_tree_host_sequence_number.GetNext() + 1), | |
| 227 next_commit_forces_redraw_(false), | |
| 228 shared_bitmap_manager_(params->shared_bitmap_manager), | |
| 229 gpu_memory_buffer_manager_(params->gpu_memory_buffer_manager), | |
| 230 task_graph_runner_(params->task_graph_runner), | |
| 231 image_serialization_processor_(params->image_serialization_processor) { | |
| 232 DCHECK(task_graph_runner_); | |
| 233 DCHECK(layer_tree_); | |
| 234 | |
| 235 rendering_stats_instrumentation_->set_record_rendering_stats( | |
| 236 debug_state_.RecordRenderingStats()); | |
| 237 } | |
| 238 | |
| 239 void LayerTreeHost::InitializeThreaded( | |
| 240 scoped_refptr<base::SingleThreadTaskRunner> main_task_runner, | |
| 241 scoped_refptr<base::SingleThreadTaskRunner> impl_task_runner, | |
| 242 std::unique_ptr<BeginFrameSource> external_begin_frame_source) { | |
| 243 task_runner_provider_ = | |
| 244 TaskRunnerProvider::Create(main_task_runner, impl_task_runner); | |
| 245 std::unique_ptr<ProxyMain> proxy_main = | |
| 246 ProxyMain::CreateThreaded(this, task_runner_provider_.get()); | |
| 247 InitializeProxy(std::move(proxy_main), | |
| 248 std::move(external_begin_frame_source)); | |
| 249 } | |
| 250 | |
| 251 void LayerTreeHost::InitializeSingleThreaded( | |
| 252 LayerTreeHostSingleThreadClient* single_thread_client, | |
| 253 scoped_refptr<base::SingleThreadTaskRunner> main_task_runner, | |
| 254 std::unique_ptr<BeginFrameSource> external_begin_frame_source) { | |
| 255 task_runner_provider_ = TaskRunnerProvider::Create(main_task_runner, nullptr); | |
| 256 InitializeProxy(SingleThreadProxy::Create(this, single_thread_client, | |
| 257 task_runner_provider_.get()), | |
| 258 std::move(external_begin_frame_source)); | |
| 259 } | |
| 260 | |
| 261 void LayerTreeHost::InitializeRemoteServer( | |
| 262 RemoteProtoChannel* remote_proto_channel, | |
| 263 scoped_refptr<base::SingleThreadTaskRunner> main_task_runner) { | |
| 264 task_runner_provider_ = TaskRunnerProvider::Create(main_task_runner, nullptr); | |
| 265 | |
| 266 if (image_serialization_processor_) { | |
| 267 engine_picture_cache_ = | |
| 268 image_serialization_processor_->CreateEnginePictureCache(); | |
| 269 } | |
| 270 InitializeProxy(ProxyMain::CreateRemote(remote_proto_channel, this, | |
| 271 task_runner_provider_.get()), | |
| 272 nullptr); | |
| 273 } | |
| 274 | |
| 275 void LayerTreeHost::InitializeRemoteClient( | |
| 276 RemoteProtoChannel* remote_proto_channel, | |
| 277 scoped_refptr<base::SingleThreadTaskRunner> main_task_runner, | |
| 278 scoped_refptr<base::SingleThreadTaskRunner> impl_task_runner) { | |
| 279 task_runner_provider_ = | |
| 280 TaskRunnerProvider::Create(main_task_runner, impl_task_runner); | |
| 281 | |
| 282 if (image_serialization_processor_) { | |
| 283 client_picture_cache_ = | |
| 284 image_serialization_processor_->CreateClientPictureCache(); | |
| 285 } | |
| 286 | |
| 287 // For the remote mode, the RemoteChannelImpl implements the Proxy, which is | |
| 288 // owned by the LayerTreeHost. The RemoteChannelImpl pipes requests which need | |
| 289 // to handled locally, for instance the Output Surface creation to the | |
| 290 // LayerTreeHost on the client, while the other requests are sent to the | |
| 291 // RemoteChannelMain on the server which directs them to ProxyMain and the | |
| 292 // remote server LayerTreeHost. | |
| 293 InitializeProxy(base::MakeUnique<RemoteChannelImpl>( | |
| 294 this, remote_proto_channel, task_runner_provider_.get()), | |
| 295 nullptr); | |
| 296 } | |
| 297 | |
| 298 void LayerTreeHost::InitializeForTesting( | |
| 299 std::unique_ptr<TaskRunnerProvider> task_runner_provider, | |
| 300 std::unique_ptr<Proxy> proxy_for_testing, | |
| 301 std::unique_ptr<BeginFrameSource> external_begin_frame_source) { | |
| 302 task_runner_provider_ = std::move(task_runner_provider); | |
| 303 | |
| 304 InitializePictureCacheForTesting(); | |
| 305 | |
| 306 InitializeProxy(std::move(proxy_for_testing), | |
| 307 std::move(external_begin_frame_source)); | |
| 308 } | |
| 309 | |
| 310 void LayerTreeHost::InitializePictureCacheForTesting() { | |
| 311 if (!image_serialization_processor_) | |
| 312 return; | |
| 313 | |
| 314 // Initialize both engine and client cache to ensure serialization tests | |
| 315 // with a single LayerTreeHost can work correctly. | |
| 316 engine_picture_cache_ = | |
| 317 image_serialization_processor_->CreateEnginePictureCache(); | |
| 318 client_picture_cache_ = | |
| 319 image_serialization_processor_->CreateClientPictureCache(); | |
| 320 } | |
| 321 | |
| 322 void LayerTreeHost::SetTaskRunnerProviderForTesting( | |
| 323 std::unique_ptr<TaskRunnerProvider> task_runner_provider) { | |
| 324 DCHECK(!task_runner_provider_); | |
| 325 task_runner_provider_ = std::move(task_runner_provider); | |
| 326 } | |
| 327 | |
| 328 void LayerTreeHost::SetUIResourceManagerForTesting( | |
| 329 std::unique_ptr<UIResourceManager> ui_resource_manager) { | |
| 330 ui_resource_manager_ = std::move(ui_resource_manager); | |
| 331 } | |
| 332 | |
| 333 void LayerTreeHost::InitializeProxy( | |
| 334 std::unique_ptr<Proxy> proxy, | |
| 335 std::unique_ptr<BeginFrameSource> external_begin_frame_source) { | |
| 336 TRACE_EVENT0("cc", "LayerTreeHost::InitializeForReal"); | |
| 337 DCHECK(task_runner_provider_); | |
| 338 | |
| 339 proxy_ = std::move(proxy); | |
| 340 proxy_->Start(std::move(external_begin_frame_source)); | |
| 341 | |
| 342 layer_tree_->animation_host()->SetSupportsScrollAnimations( | |
| 343 proxy_->SupportsImplScrolling()); | |
| 344 } | |
| 345 | |
| 346 LayerTreeHost::~LayerTreeHost() { | |
| 347 TRACE_EVENT0("cc", "LayerTreeHost::~LayerTreeHost"); | |
| 348 | |
| 349 // Clear any references into the LayerTreeHost. | |
| 350 layer_tree_.reset(); | |
| 351 | |
| 352 if (proxy_) { | |
| 353 DCHECK(task_runner_provider_->IsMainThread()); | |
| 354 proxy_->Stop(); | |
| 355 | |
| 356 // Proxy must be destroyed before the Task Runner Provider. | |
| 357 proxy_ = nullptr; | |
| 358 } | |
| 359 } | |
| 360 | |
| 361 int LayerTreeHost::GetId() const { | |
| 362 return id_; | |
| 363 } | |
| 364 | |
| 365 int LayerTreeHost::SourceFrameNumber() const { | |
| 366 return source_frame_number_; | |
| 367 } | |
| 368 | |
| 369 LayerTree* LayerTreeHost::GetLayerTree() { | |
| 370 return layer_tree_.get(); | |
| 371 } | |
| 372 | |
| 373 const LayerTree* LayerTreeHost::GetLayerTree() const { | |
| 374 return layer_tree_.get(); | |
| 375 } | |
| 376 | |
| 377 UIResourceManager* LayerTreeHost::GetUIResourceManager() const { | |
| 378 return ui_resource_manager_.get(); | |
| 379 } | |
| 380 | |
| 381 TaskRunnerProvider* LayerTreeHost::GetTaskRunnerProvider() const { | |
| 382 return task_runner_provider_.get(); | |
| 383 } | |
| 384 | |
| 385 SwapPromiseManager* LayerTreeHost::GetSwapPromiseManager() { | |
| 386 return &swap_promise_manager_; | |
| 387 } | |
| 388 | |
| 389 const LayerTreeSettings& LayerTreeHost::GetSettings() const { | |
| 390 return settings_; | |
| 391 } | |
| 392 | |
| 393 void LayerTreeHost::SetSurfaceClientId(uint32_t client_id) { | |
| 394 surface_sequence_generator_.set_surface_client_id(client_id); | |
| 395 } | |
| 396 | |
| 397 void LayerTreeHost::QueueSwapPromise( | |
| 398 std::unique_ptr<SwapPromise> swap_promise) { | |
| 399 swap_promise_manager_.QueueSwapPromise(std::move(swap_promise)); | |
| 400 } | |
| 401 | |
| 402 SurfaceSequenceGenerator* LayerTreeHost::GetSurfaceSequenceGenerator() { | |
| 403 return &surface_sequence_generator_; | |
| 404 } | |
| 405 | |
| 406 void LayerTreeHost::WillBeginMainFrame() { | |
| 407 devtools_instrumentation::WillBeginMainThreadFrame(GetId(), | |
| 408 SourceFrameNumber()); | |
| 409 client_->WillBeginMainFrame(); | |
| 410 } | |
| 411 | |
| 412 void LayerTreeHost::DidBeginMainFrame() { | |
| 413 client_->DidBeginMainFrame(); | |
| 414 } | |
| 415 | |
| 416 void LayerTreeHost::BeginMainFrameNotExpectedSoon() { | |
| 417 client_->BeginMainFrameNotExpectedSoon(); | |
| 418 } | |
| 419 | |
| 420 void LayerTreeHost::BeginMainFrame(const BeginFrameArgs& args) { | |
| 421 client_->BeginMainFrame(args); | |
| 422 } | |
| 423 | |
| 424 void LayerTreeHost::DidStopFlinging() { | |
| 425 proxy_->MainThreadHasStoppedFlinging(); | |
| 426 } | |
| 427 | |
| 428 const LayerTreeDebugState& LayerTreeHost::GetDebugState() const { | |
| 429 return debug_state_; | |
| 430 } | |
| 431 | |
| 432 void LayerTreeHost::RequestMainFrameUpdate() { | |
| 433 client_->UpdateLayerTreeHost(); | |
| 434 } | |
| 435 | |
| 436 // This function commits the LayerTreeHost to an impl tree. When modifying | |
| 437 // this function, keep in mind that the function *runs* on the impl thread! Any | |
| 438 // code that is logically a main thread operation, e.g. deletion of a Layer, | |
| 439 // should be delayed until the LayerTreeHost::CommitComplete, which will run | |
| 440 // after the commit, but on the main thread. | |
| 441 void LayerTreeHost::FinishCommitOnImplThread(LayerTreeHostImpl* host_impl) { | |
| 442 DCHECK(!IsRemoteServer()); | |
| 443 DCHECK(task_runner_provider_->IsImplThread()); | |
| 444 | |
| 445 bool is_new_trace; | |
| 446 TRACE_EVENT_IS_NEW_TRACE(&is_new_trace); | |
| 447 if (is_new_trace && | |
| 448 frame_viewer_instrumentation::IsTracingLayerTreeSnapshots() && | |
| 449 layer_tree_->root_layer()) { | |
| 450 LayerTreeHostCommon::CallFunctionForEveryLayer( | |
| 451 layer_tree_.get(), [](Layer* layer) { layer->DidBeginTracing(); }); | |
| 452 } | |
| 453 | |
| 454 LayerTreeImpl* sync_tree = host_impl->sync_tree(); | |
| 455 | |
| 456 if (next_commit_forces_redraw_) { | |
| 457 sync_tree->ForceRedrawNextActivation(); | |
| 458 next_commit_forces_redraw_ = false; | |
| 459 } | |
| 460 | |
| 461 sync_tree->set_source_frame_number(SourceFrameNumber()); | |
| 462 | |
| 463 if (layer_tree_->needs_full_tree_sync()) | |
| 464 TreeSynchronizer::SynchronizeTrees(layer_tree_->root_layer(), sync_tree); | |
| 465 | |
| 466 layer_tree_->PushPropertiesTo(sync_tree); | |
| 467 | |
| 468 sync_tree->PassSwapPromises(swap_promise_manager_.TakeSwapPromises()); | |
| 469 | |
| 470 host_impl->SetHasGpuRasterizationTrigger(has_gpu_rasterization_trigger_); | |
| 471 host_impl->SetContentIsSuitableForGpuRasterization( | |
| 472 content_is_suitable_for_gpu_rasterization_); | |
| 473 RecordGpuRasterizationHistogram(); | |
| 474 | |
| 475 host_impl->SetViewportSize(layer_tree_->device_viewport_size()); | |
| 476 // TODO(senorblanco): Move this to LayerTree::PushPropertiesTo so that it | |
| 477 // happens before GPU rasterization properties are set, since those trigger an | |
| 478 // update of GPU rasterization status, which depends on the device scale | |
| 479 // factor. (crbug.com/535700) | |
| 480 sync_tree->SetDeviceScaleFactor(layer_tree_->device_scale_factor()); | |
| 481 host_impl->SetDebugState(debug_state_); | |
| 482 | |
| 483 sync_tree->set_ui_resource_request_queue( | |
| 484 ui_resource_manager_->TakeUIResourcesRequests()); | |
| 485 | |
| 486 { | |
| 487 TRACE_EVENT0("cc", "LayerTreeHost::PushProperties"); | |
| 488 | |
| 489 TreeSynchronizer::PushLayerProperties(layer_tree_.get(), sync_tree); | |
| 490 | |
| 491 // This must happen after synchronizing property trees and after push | |
| 492 // properties, which updates property tree indices, but before animation | |
| 493 // host pushes properties as animation host push properties can change | |
| 494 // Animation::InEffect and we want the old InEffect value for updating | |
| 495 // property tree scrolling and animation. | |
| 496 sync_tree->UpdatePropertyTreeScrollingAndAnimationFromMainThread(); | |
| 497 | |
| 498 TRACE_EVENT0("cc", "LayerTreeHost::AnimationHost::PushProperties"); | |
| 499 DCHECK(host_impl->animation_host()); | |
| 500 layer_tree_->animation_host()->PushPropertiesTo( | |
| 501 host_impl->animation_host()); | |
| 502 } | |
| 503 | |
| 504 // This must happen after synchronizing property trees and after pushing | |
| 505 // properties, which updates the clobber_active_value flag. | |
| 506 sync_tree->UpdatePropertyTreeScrollOffset(layer_tree_->property_trees()); | |
| 507 | |
| 508 micro_benchmark_controller_.ScheduleImplBenchmarks(host_impl); | |
| 509 layer_tree_->property_trees()->ResetAllChangeTracking(); | |
| 510 } | |
| 511 | |
| 512 void LayerTreeHost::WillCommit() { | |
| 513 swap_promise_manager_.WillCommit(); | |
| 514 client_->WillCommit(); | |
| 515 } | |
| 516 | |
| 517 void LayerTreeHost::UpdateHudLayer() { | |
| 518 } | |
| 519 | |
| 520 void LayerTreeHost::CommitComplete() { | |
| 521 source_frame_number_++; | |
| 522 client_->DidCommit(); | |
| 523 if (did_complete_scale_animation_) { | |
| 524 client_->DidCompletePageScaleAnimation(); | |
| 525 did_complete_scale_animation_ = false; | |
| 526 } | |
| 527 } | |
| 528 | |
| 529 void LayerTreeHost::SetOutputSurface(std::unique_ptr<OutputSurface> surface) { | |
| 530 TRACE_EVENT0("cc", "LayerTreeHost::SetOutputSurface"); | |
| 531 DCHECK(surface); | |
| 532 | |
| 533 DCHECK(!new_output_surface_); | |
| 534 new_output_surface_ = std::move(surface); | |
| 535 proxy_->SetOutputSurface(new_output_surface_.get()); | |
| 536 } | |
| 537 | |
| 538 std::unique_ptr<OutputSurface> LayerTreeHost::ReleaseOutputSurface() { | |
| 539 DCHECK(!visible_); | |
| 540 | |
| 541 DidLoseOutputSurface(); | |
| 542 proxy_->ReleaseOutputSurface(); | |
| 543 return std::move(current_output_surface_); | |
| 544 } | |
| 545 | |
| 546 void LayerTreeHost::RequestNewOutputSurface() { | |
| 547 client_->RequestNewOutputSurface(); | |
| 548 } | |
| 549 | |
| 550 void LayerTreeHost::DidInitializeOutputSurface() { | |
| 551 DCHECK(new_output_surface_); | |
| 552 current_output_surface_ = std::move(new_output_surface_); | |
| 553 client_->DidInitializeOutputSurface(); | |
| 554 } | |
| 555 | |
| 556 void LayerTreeHost::DidFailToInitializeOutputSurface() { | |
| 557 DCHECK(new_output_surface_); | |
| 558 // Note: It is safe to drop all output surface references here as | |
| 559 // LayerTreeHostImpl will not keep a pointer to either the old or | |
| 560 // new output surface after failing to initialize the new one. | |
| 561 current_output_surface_ = nullptr; | |
| 562 new_output_surface_ = nullptr; | |
| 563 client_->DidFailToInitializeOutputSurface(); | |
| 564 } | |
| 565 | |
| 566 std::unique_ptr<LayerTreeHostImpl> LayerTreeHost::CreateLayerTreeHostImpl( | |
| 567 LayerTreeHostImplClient* client) { | |
| 568 DCHECK(!IsRemoteServer()); | |
| 569 DCHECK(task_runner_provider_->IsImplThread()); | |
| 570 | |
| 571 const bool supports_impl_scrolling = task_runner_provider_->HasImplThread(); | |
| 572 std::unique_ptr<AnimationHost> animation_host_impl = | |
| 573 layer_tree_->animation_host()->CreateImplInstance( | |
| 574 supports_impl_scrolling); | |
| 575 | |
| 576 std::unique_ptr<LayerTreeHostImpl> host_impl = LayerTreeHostImpl::Create( | |
| 577 settings_, client, task_runner_provider_.get(), | |
| 578 rendering_stats_instrumentation_.get(), shared_bitmap_manager_, | |
| 579 gpu_memory_buffer_manager_, task_graph_runner_, | |
| 580 std::move(animation_host_impl), id_); | |
| 581 host_impl->SetHasGpuRasterizationTrigger(has_gpu_rasterization_trigger_); | |
| 582 host_impl->SetContentIsSuitableForGpuRasterization( | |
| 583 content_is_suitable_for_gpu_rasterization_); | |
| 584 shared_bitmap_manager_ = NULL; | |
| 585 gpu_memory_buffer_manager_ = NULL; | |
| 586 task_graph_runner_ = NULL; | |
| 587 input_handler_weak_ptr_ = host_impl->AsWeakPtr(); | |
| 588 return host_impl; | |
| 589 } | |
| 590 | |
| 591 void LayerTreeHost::DidLoseOutputSurface() { | |
| 592 TRACE_EVENT0("cc", "LayerTreeHost::DidLoseOutputSurface"); | |
| 593 DCHECK(task_runner_provider_->IsMainThread()); | |
| 594 SetNeedsCommit(); | |
| 595 } | |
| 596 | |
| 597 void LayerTreeHost::SetDeferCommits(bool defer_commits) { | |
| 598 proxy_->SetDeferCommits(defer_commits); | |
| 599 } | |
| 600 | |
| 601 DISABLE_CFI_PERF | |
| 602 void LayerTreeHost::SetNeedsAnimate() { | |
| 603 proxy_->SetNeedsAnimate(); | |
| 604 swap_promise_manager_.NotifySwapPromiseMonitorsOfSetNeedsCommit(); | |
| 605 } | |
| 606 | |
| 607 DISABLE_CFI_PERF | |
| 608 void LayerTreeHost::SetNeedsUpdateLayers() { | |
| 609 proxy_->SetNeedsUpdateLayers(); | |
| 610 swap_promise_manager_.NotifySwapPromiseMonitorsOfSetNeedsCommit(); | |
| 611 } | |
| 612 | |
| 613 void LayerTreeHost::SetNeedsCommit() { | |
| 614 proxy_->SetNeedsCommit(); | |
| 615 swap_promise_manager_.NotifySwapPromiseMonitorsOfSetNeedsCommit(); | |
| 616 } | |
| 617 | |
| 618 void LayerTreeHost::SetNeedsRedraw() { | |
| 619 SetNeedsRedrawRect(gfx::Rect(layer_tree_->device_viewport_size())); | |
| 620 } | |
| 621 | |
| 622 void LayerTreeHost::SetNeedsRedrawRect(const gfx::Rect& damage_rect) { | |
| 623 proxy_->SetNeedsRedraw(damage_rect); | |
| 624 } | |
| 625 | |
| 626 bool LayerTreeHost::CommitRequested() const { | |
| 627 return proxy_->CommitRequested(); | |
| 628 } | |
| 629 | |
| 630 bool LayerTreeHost::BeginMainFrameRequested() const { | |
| 631 return proxy_->BeginMainFrameRequested(); | |
| 632 } | |
| 633 | |
| 634 void LayerTreeHost::SetNextCommitWaitsForActivation() { | |
| 635 proxy_->SetNextCommitWaitsForActivation(); | |
| 636 } | |
| 637 | |
| 638 void LayerTreeHost::SetNextCommitForcesRedraw() { | |
| 639 next_commit_forces_redraw_ = true; | |
| 640 proxy_->SetNeedsUpdateLayers(); | |
| 641 } | |
| 642 | |
| 643 void LayerTreeHost::SetAnimationEvents( | |
| 644 std::unique_ptr<AnimationEvents> events) { | |
| 645 DCHECK(task_runner_provider_->IsMainThread()); | |
| 646 layer_tree_->animation_host()->SetAnimationEvents(std::move(events)); | |
| 647 } | |
| 648 | |
| 649 void LayerTreeHost::SetDebugState(const LayerTreeDebugState& debug_state) { | |
| 650 LayerTreeDebugState new_debug_state = | |
| 651 LayerTreeDebugState::Unite(settings_.initial_debug_state, debug_state); | |
| 652 | |
| 653 if (LayerTreeDebugState::Equal(debug_state_, new_debug_state)) | |
| 654 return; | |
| 655 | |
| 656 debug_state_ = new_debug_state; | |
| 657 | |
| 658 rendering_stats_instrumentation_->set_record_rendering_stats( | |
| 659 debug_state_.RecordRenderingStats()); | |
| 660 | |
| 661 SetNeedsCommit(); | |
| 662 } | |
| 663 | |
| 664 void LayerTreeHost::ResetGpuRasterizationTracking() { | |
| 665 content_is_suitable_for_gpu_rasterization_ = true; | |
| 666 gpu_rasterization_histogram_recorded_ = false; | |
| 667 } | |
| 668 | |
| 669 void LayerTreeHost::SetHasGpuRasterizationTrigger(bool has_trigger) { | |
| 670 if (has_trigger == has_gpu_rasterization_trigger_) | |
| 671 return; | |
| 672 | |
| 673 has_gpu_rasterization_trigger_ = has_trigger; | |
| 674 TRACE_EVENT_INSTANT1("cc", | |
| 675 "LayerTreeHost::SetHasGpuRasterizationTrigger", | |
| 676 TRACE_EVENT_SCOPE_THREAD, | |
| 677 "has_trigger", | |
| 678 has_gpu_rasterization_trigger_); | |
| 679 } | |
| 680 | |
| 681 void LayerTreeHost::ApplyPageScaleDeltaFromImplSide(float page_scale_delta) { | |
| 682 DCHECK(CommitRequested()); | |
| 683 if (page_scale_delta == 1.f) | |
| 684 return; | |
| 685 float page_scale = layer_tree_->page_scale_factor() * page_scale_delta; | |
| 686 layer_tree_->SetPageScaleFromImplSide(page_scale); | |
| 687 } | |
| 688 | |
| 689 void LayerTreeHost::SetVisible(bool visible) { | |
| 690 if (visible_ == visible) | |
| 691 return; | |
| 692 visible_ = visible; | |
| 693 proxy_->SetVisible(visible); | |
| 694 } | |
| 695 | |
| 696 bool LayerTreeHost::IsVisible() const { | |
| 697 return visible_; | |
| 698 } | |
| 699 | |
| 700 void LayerTreeHost::NotifyInputThrottledUntilCommit() { | |
| 701 proxy_->NotifyInputThrottledUntilCommit(); | |
| 702 } | |
| 703 | |
| 704 void LayerTreeHost::LayoutAndUpdateLayers() { | |
| 705 DCHECK(IsSingleThreaded()); | |
| 706 // This function is only valid when not using the scheduler. | |
| 707 DCHECK(!settings_.single_thread_proxy_scheduler); | |
| 708 RequestMainFrameUpdate(); | |
| 709 UpdateLayers(); | |
| 710 } | |
| 711 | |
| 712 void LayerTreeHost::Composite(base::TimeTicks frame_begin_time) { | |
| 713 DCHECK(IsSingleThreaded()); | |
| 714 // This function is only valid when not using the scheduler. | |
| 715 DCHECK(!settings_.single_thread_proxy_scheduler); | |
| 716 SingleThreadProxy* proxy = static_cast<SingleThreadProxy*>(proxy_.get()); | |
| 717 | |
| 718 proxy->CompositeImmediately(frame_begin_time); | |
| 719 } | |
| 720 | |
| 721 bool LayerTreeHost::UpdateLayers() { | |
| 722 if (!layer_tree_->root_layer()) | |
| 723 return false; | |
| 724 DCHECK(!layer_tree_->root_layer()->parent()); | |
| 725 bool result = DoUpdateLayers(layer_tree_->root_layer()); | |
| 726 micro_benchmark_controller_.DidUpdateLayers(); | |
| 727 return result || next_commit_forces_redraw_; | |
| 728 } | |
| 729 | |
| 730 void LayerTreeHost::DidCompletePageScaleAnimation() { | |
| 731 did_complete_scale_animation_ = true; | |
| 732 } | |
| 733 | |
| 734 void LayerTreeHost::RecordGpuRasterizationHistogram() { | |
| 735 // Gpu rasterization is only supported for Renderer compositors. | |
| 736 // Checking for IsSingleThreaded() to exclude Browser compositors. | |
| 737 if (gpu_rasterization_histogram_recorded_ || IsSingleThreaded()) | |
| 738 return; | |
| 739 | |
| 740 // Record how widely gpu rasterization is enabled. | |
| 741 // This number takes device/gpu whitelisting/backlisting into account. | |
| 742 // Note that we do not consider the forced gpu rasterization mode, which is | |
| 743 // mostly used for debugging purposes. | |
| 744 UMA_HISTOGRAM_BOOLEAN("Renderer4.GpuRasterizationEnabled", | |
| 745 settings_.gpu_rasterization_enabled); | |
| 746 if (settings_.gpu_rasterization_enabled) { | |
| 747 UMA_HISTOGRAM_BOOLEAN("Renderer4.GpuRasterizationTriggered", | |
| 748 has_gpu_rasterization_trigger_); | |
| 749 UMA_HISTOGRAM_BOOLEAN("Renderer4.GpuRasterizationSuitableContent", | |
| 750 content_is_suitable_for_gpu_rasterization_); | |
| 751 // Record how many pages actually get gpu rasterization when enabled. | |
| 752 UMA_HISTOGRAM_BOOLEAN("Renderer4.GpuRasterizationUsed", | |
| 753 (has_gpu_rasterization_trigger_ && | |
| 754 content_is_suitable_for_gpu_rasterization_)); | |
| 755 } | |
| 756 | |
| 757 gpu_rasterization_histogram_recorded_ = true; | |
| 758 } | |
| 759 | |
| 760 bool LayerTreeHost::DoUpdateLayers(Layer* root_layer) { | |
| 761 TRACE_EVENT1("cc", "LayerTreeHost::DoUpdateLayers", "source_frame_number", | |
| 762 SourceFrameNumber()); | |
| 763 | |
| 764 layer_tree_->UpdateHudLayer(debug_state_.ShowHudInfo()); | |
| 765 UpdateHudLayer(); | |
| 766 | |
| 767 Layer* root_scroll = | |
| 768 PropertyTreeBuilder::FindFirstScrollableLayer(root_layer); | |
| 769 Layer* page_scale_layer = layer_tree_->page_scale_layer(); | |
| 770 if (!page_scale_layer && root_scroll) | |
| 771 page_scale_layer = root_scroll->parent(); | |
| 772 | |
| 773 if (layer_tree_->hud_layer()) { | |
| 774 layer_tree_->hud_layer()->PrepareForCalculateDrawProperties( | |
| 775 layer_tree_->device_viewport_size(), | |
| 776 layer_tree_->device_scale_factor()); | |
| 777 } | |
| 778 | |
| 779 gfx::Transform identity_transform; | |
| 780 LayerList update_layer_list; | |
| 781 | |
| 782 { | |
| 783 TRACE_EVENT0("cc", "LayerTreeHost::UpdateLayers::BuildPropertyTrees"); | |
| 784 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug.cdp-perf"), | |
| 785 "LayerTreeHostCommon::ComputeVisibleRectsWithPropertyTrees"); | |
| 786 PropertyTreeBuilder::PreCalculateMetaInformation(root_layer); | |
| 787 bool can_render_to_separate_surface = true; | |
| 788 PropertyTrees* property_trees = layer_tree_->property_trees(); | |
| 789 if (!settings_.use_layer_lists) { | |
| 790 // If use_layer_lists is set, then the property trees should have been | |
| 791 // built by the client already. | |
| 792 PropertyTreeBuilder::BuildPropertyTrees( | |
| 793 root_layer, page_scale_layer, | |
| 794 layer_tree_->inner_viewport_scroll_layer(), | |
| 795 layer_tree_->outer_viewport_scroll_layer(), | |
| 796 layer_tree_->overscroll_elasticity_layer(), | |
| 797 layer_tree_->elastic_overscroll(), layer_tree_->page_scale_factor(), | |
| 798 layer_tree_->device_scale_factor(), | |
| 799 gfx::Rect(layer_tree_->device_viewport_size()), identity_transform, | |
| 800 property_trees); | |
| 801 TRACE_EVENT_INSTANT1("cc", | |
| 802 "LayerTreeHost::UpdateLayers_BuiltPropertyTrees", | |
| 803 TRACE_EVENT_SCOPE_THREAD, "property_trees", | |
| 804 property_trees->AsTracedValue()); | |
| 805 } else { | |
| 806 TRACE_EVENT_INSTANT1("cc", | |
| 807 "LayerTreeHost::UpdateLayers_ReceivedPropertyTrees", | |
| 808 TRACE_EVENT_SCOPE_THREAD, "property_trees", | |
| 809 property_trees->AsTracedValue()); | |
| 810 } | |
| 811 draw_property_utils::UpdatePropertyTrees(property_trees, | |
| 812 can_render_to_separate_surface); | |
| 813 draw_property_utils::FindLayersThatNeedUpdates( | |
| 814 layer_tree_.get(), property_trees->transform_tree, | |
| 815 property_trees->effect_tree, &update_layer_list); | |
| 816 } | |
| 817 | |
| 818 for (const auto& layer : update_layer_list) | |
| 819 layer->SavePaintProperties(); | |
| 820 | |
| 821 bool content_is_suitable_for_gpu = true; | |
| 822 bool did_paint_content = layer_tree_->UpdateLayers( | |
| 823 update_layer_list, &content_is_suitable_for_gpu); | |
| 824 | |
| 825 if (content_is_suitable_for_gpu) { | |
| 826 ++num_consecutive_frames_suitable_for_gpu_; | |
| 827 if (num_consecutive_frames_suitable_for_gpu_ >= | |
| 828 kNumFramesToConsiderBeforeGpuRasterization) { | |
| 829 content_is_suitable_for_gpu_rasterization_ = true; | |
| 830 } | |
| 831 } else { | |
| 832 num_consecutive_frames_suitable_for_gpu_ = 0; | |
| 833 content_is_suitable_for_gpu_rasterization_ = false; | |
| 834 } | |
| 835 return did_paint_content; | |
| 836 } | |
| 837 | |
| 838 void LayerTreeHost::ApplyViewportDeltas(ScrollAndScaleSet* info) { | |
| 839 gfx::Vector2dF inner_viewport_scroll_delta; | |
| 840 if (info->inner_viewport_scroll.layer_id != Layer::INVALID_ID) | |
| 841 inner_viewport_scroll_delta = info->inner_viewport_scroll.scroll_delta; | |
| 842 | |
| 843 if (inner_viewport_scroll_delta.IsZero() && info->page_scale_delta == 1.f && | |
| 844 info->elastic_overscroll_delta.IsZero() && !info->top_controls_delta) | |
| 845 return; | |
| 846 | |
| 847 // Preemptively apply the scroll offset and scale delta here before sending | |
| 848 // it to the client. If the client comes back and sets it to the same | |
| 849 // value, then the layer can early out without needing a full commit. | |
| 850 if (layer_tree_->inner_viewport_scroll_layer()) { | |
| 851 layer_tree_->inner_viewport_scroll_layer()->SetScrollOffsetFromImplSide( | |
| 852 gfx::ScrollOffsetWithDelta( | |
| 853 layer_tree_->inner_viewport_scroll_layer()->scroll_offset(), | |
| 854 inner_viewport_scroll_delta)); | |
| 855 } | |
| 856 | |
| 857 ApplyPageScaleDeltaFromImplSide(info->page_scale_delta); | |
| 858 layer_tree_->SetElasticOverscrollFromImplSide( | |
| 859 layer_tree_->elastic_overscroll() + info->elastic_overscroll_delta); | |
| 860 // TODO(ccameron): pass the elastic overscroll here so that input events | |
| 861 // may be translated appropriately. | |
| 862 client_->ApplyViewportDeltas(inner_viewport_scroll_delta, gfx::Vector2dF(), | |
| 863 info->elastic_overscroll_delta, | |
| 864 info->page_scale_delta, | |
| 865 info->top_controls_delta); | |
| 866 SetNeedsUpdateLayers(); | |
| 867 } | |
| 868 | |
| 869 void LayerTreeHost::ApplyScrollAndScale(ScrollAndScaleSet* info) { | |
| 870 for (auto& swap_promise : info->swap_promises) { | |
| 871 TRACE_EVENT_WITH_FLOW1("input,benchmark", | |
| 872 "LatencyInfo.Flow", | |
| 873 TRACE_ID_DONT_MANGLE(swap_promise->TraceId()), | |
| 874 TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT, | |
| 875 "step", "Main thread scroll update"); | |
| 876 swap_promise_manager_.QueueSwapPromise(std::move(swap_promise)); | |
| 877 } | |
| 878 | |
| 879 if (layer_tree_->root_layer()) { | |
| 880 for (size_t i = 0; i < info->scrolls.size(); ++i) { | |
| 881 Layer* layer = layer_tree_->LayerById(info->scrolls[i].layer_id); | |
| 882 if (!layer) | |
| 883 continue; | |
| 884 layer->SetScrollOffsetFromImplSide(gfx::ScrollOffsetWithDelta( | |
| 885 layer->scroll_offset(), info->scrolls[i].scroll_delta)); | |
| 886 SetNeedsUpdateLayers(); | |
| 887 } | |
| 888 } | |
| 889 | |
| 890 // This needs to happen after scroll deltas have been sent to prevent top | |
| 891 // controls from clamping the layout viewport both on the compositor and | |
| 892 // on the main thread. | |
| 893 ApplyViewportDeltas(info); | |
| 894 } | |
| 895 | |
| 896 const base::WeakPtr<InputHandler>& LayerTreeHost::GetInputHandler() const { | |
| 897 return input_handler_weak_ptr_; | |
| 898 } | |
| 899 | |
| 900 void LayerTreeHost::UpdateTopControlsState(TopControlsState constraints, | |
| 901 TopControlsState current, | |
| 902 bool animate) { | |
| 903 // Top controls are only used in threaded or remote mode. | |
| 904 DCHECK(IsThreaded() || IsRemoteServer()); | |
| 905 proxy_->UpdateTopControlsState(constraints, current, animate); | |
| 906 } | |
| 907 | |
| 908 void LayerTreeHost::AnimateLayers(base::TimeTicks monotonic_time) { | |
| 909 AnimationHost* animation_host = layer_tree_->animation_host(); | |
| 910 std::unique_ptr<AnimationEvents> events = animation_host->CreateEvents(); | |
| 911 | |
| 912 if (animation_host->AnimateLayers(monotonic_time)) | |
| 913 animation_host->UpdateAnimationState(true, events.get()); | |
| 914 | |
| 915 if (!events->events_.empty()) | |
| 916 layer_tree_->property_trees()->needs_rebuild = true; | |
| 917 } | |
| 918 | |
| 919 int LayerTreeHost::ScheduleMicroBenchmark( | |
| 920 const std::string& benchmark_name, | |
| 921 std::unique_ptr<base::Value> value, | |
| 922 const MicroBenchmark::DoneCallback& callback) { | |
| 923 return micro_benchmark_controller_.ScheduleRun(benchmark_name, | |
| 924 std::move(value), callback); | |
| 925 } | |
| 926 | |
| 927 bool LayerTreeHost::SendMessageToMicroBenchmark( | |
| 928 int id, | |
| 929 std::unique_ptr<base::Value> value) { | |
| 930 return micro_benchmark_controller_.SendMessage(id, std::move(value)); | |
| 931 } | |
| 932 | |
| 933 void LayerTreeHost::SetLayerTreeMutator( | |
| 934 std::unique_ptr<LayerTreeMutator> mutator) { | |
| 935 proxy_->SetMutator(std::move(mutator)); | |
| 936 } | |
| 937 | |
| 938 bool LayerTreeHost::IsSingleThreaded() const { | |
| 939 DCHECK(compositor_mode_ != CompositorMode::SINGLE_THREADED || | |
| 940 !task_runner_provider_->HasImplThread()); | |
| 941 return compositor_mode_ == CompositorMode::SINGLE_THREADED; | |
| 942 } | |
| 943 | |
| 944 bool LayerTreeHost::IsThreaded() const { | |
| 945 DCHECK(compositor_mode_ != CompositorMode::THREADED || | |
| 946 task_runner_provider_->HasImplThread()); | |
| 947 return compositor_mode_ == CompositorMode::THREADED; | |
| 948 } | |
| 949 | |
| 950 bool LayerTreeHost::IsRemoteServer() const { | |
| 951 // The LayerTreeHost on the server does not have an impl task runner. | |
| 952 return compositor_mode_ == CompositorMode::REMOTE && | |
| 953 !task_runner_provider_->HasImplThread(); | |
| 954 } | |
| 955 | |
| 956 bool LayerTreeHost::IsRemoteClient() const { | |
| 957 return compositor_mode_ == CompositorMode::REMOTE && | |
| 958 task_runner_provider_->HasImplThread(); | |
| 959 } | |
| 960 | |
| 961 void LayerTreeHost::ToProtobufForCommit( | |
| 962 proto::LayerTreeHost* proto, | |
| 963 std::vector<std::unique_ptr<SwapPromise>>* swap_promises) { | |
| 964 DCHECK(engine_picture_cache_); | |
| 965 // Not all fields are serialized, as they are either not needed for a commit, | |
| 966 // or implementation isn't ready yet. | |
| 967 // Unsupported items: | |
| 968 // - animations | |
| 969 // - UI resources | |
| 970 // - instrumentation of stats | |
| 971 // - histograms | |
| 972 // Skipped items: | |
| 973 // - SwapPromise as they are mostly used for perf measurements. | |
| 974 // - The bitmap and GPU memory related items. | |
| 975 // Other notes: | |
| 976 // - The output surfaces are only valid on the client-side so they are | |
| 977 // therefore not serialized. | |
| 978 // - LayerTreeSettings are needed only during construction of the | |
| 979 // LayerTreeHost, so they are serialized outside of the LayerTreeHost | |
| 980 // serialization. | |
| 981 // - The |visible_| flag will be controlled from the client separately and | |
| 982 // will need special handling outside of the serialization of the | |
| 983 // LayerTreeHost. | |
| 984 // TODO(nyquist): Figure out how to support animations. See crbug.com/570376. | |
| 985 TRACE_EVENT0("cc.remote", "LayerTreeHost::ToProtobufForCommit"); | |
| 986 *swap_promises = swap_promise_manager_.TakeSwapPromises(); | |
| 987 | |
| 988 proto->set_source_frame_number(source_frame_number_); | |
| 989 | |
| 990 // Serialize the LayerTree before serializing the properties. During layer | |
| 991 // property serialization, we clear the list |layer_that_should_properties_| | |
| 992 // from the LayerTree. | |
| 993 layer_tree_->ToProtobuf(proto->mutable_layer_tree()); | |
| 994 | |
| 995 LayerProtoConverter::SerializeLayerProperties(this, | |
| 996 proto->mutable_layer_updates()); | |
| 997 | |
| 998 std::vector<PictureData> pictures = | |
| 999 engine_picture_cache_->CalculateCacheUpdateAndFlush(); | |
| 1000 proto::PictureDataVectorToSkPicturesProto(pictures, | |
| 1001 proto->mutable_pictures()); | |
| 1002 | |
| 1003 debug_state_.ToProtobuf(proto->mutable_debug_state()); | |
| 1004 proto->set_has_gpu_rasterization_trigger(has_gpu_rasterization_trigger_); | |
| 1005 proto->set_content_is_suitable_for_gpu_rasterization( | |
| 1006 content_is_suitable_for_gpu_rasterization_); | |
| 1007 proto->set_id(id_); | |
| 1008 proto->set_next_commit_forces_redraw(next_commit_forces_redraw_); | |
| 1009 | |
| 1010 TRACE_EVENT_OBJECT_SNAPSHOT_WITH_ID( | |
| 1011 "cc.remote", "LayerTreeHostProto", source_frame_number_, | |
| 1012 ComputeLayerTreeHostProtoSizeSplitAsValue(proto)); | |
| 1013 } | |
| 1014 | |
| 1015 void LayerTreeHost::FromProtobufForCommit(const proto::LayerTreeHost& proto) { | |
| 1016 DCHECK(client_picture_cache_); | |
| 1017 source_frame_number_ = proto.source_frame_number(); | |
| 1018 | |
| 1019 layer_tree_->FromProtobuf(proto.layer_tree()); | |
| 1020 | |
| 1021 // Ensure ClientPictureCache contains all the necessary SkPictures before | |
| 1022 // deserializing the properties. | |
| 1023 proto::SkPictures proto_pictures = proto.pictures(); | |
| 1024 std::vector<PictureData> pictures = | |
| 1025 SkPicturesProtoToPictureDataVector(proto_pictures); | |
| 1026 client_picture_cache_->ApplyCacheUpdate(pictures); | |
| 1027 | |
| 1028 LayerProtoConverter::DeserializeLayerProperties(layer_tree_->root_layer(), | |
| 1029 proto.layer_updates()); | |
| 1030 | |
| 1031 // The deserialization is finished, so now clear the cache. | |
| 1032 client_picture_cache_->Flush(); | |
| 1033 | |
| 1034 debug_state_.FromProtobuf(proto.debug_state()); | |
| 1035 has_gpu_rasterization_trigger_ = proto.has_gpu_rasterization_trigger(); | |
| 1036 content_is_suitable_for_gpu_rasterization_ = | |
| 1037 proto.content_is_suitable_for_gpu_rasterization(); | |
| 1038 id_ = proto.id(); | |
| 1039 next_commit_forces_redraw_ = proto.next_commit_forces_redraw(); | |
| 1040 } | |
| 1041 | |
| 1042 } // namespace cc | |
| OLD | NEW |