xingliu | e43518a | 2016-07-28 23:59:47 | [diff] [blame] | 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 | |
rnk | 2f03c7f | 2016-08-17 17:10:59 | [diff] [blame] | 5 | #include "cc/trees/layer_tree.h" |
khushalsagar | 80655645 | 2016-08-17 01:36:26 | [diff] [blame] | 6 | |
khushalsagar | 86928f9 | 2016-08-17 21:49:05 | [diff] [blame] | 7 | #include "base/auto_reset.h" |
| 8 | #include "base/time/time.h" |
| 9 | #include "cc/animation/animation_host.h" |
| 10 | #include "cc/input/page_scale_animation.h" |
| 11 | #include "cc/layers/heads_up_display_layer.h" |
| 12 | #include "cc/layers/heads_up_display_layer_impl.h" |
| 13 | #include "cc/layers/layer.h" |
| 14 | #include "cc/layers/layer_proto_converter.h" |
| 15 | #include "cc/proto/gfx_conversions.h" |
| 16 | #include "cc/proto/layer_tree.pb.h" |
| 17 | #include "cc/trees/layer_tree_host.h" |
| 18 | #include "cc/trees/layer_tree_host_common.h" |
| 19 | #include "cc/trees/layer_tree_impl.h" |
| 20 | |
xingliu | e43518a | 2016-07-28 23:59:47 | [diff] [blame] | 21 | namespace cc { |
| 22 | |
khushalsagar | 86928f9 | 2016-08-17 21:49:05 | [diff] [blame] | 23 | namespace { |
| 24 | |
| 25 | Layer* UpdateAndGetLayer(Layer* current_layer, |
| 26 | int layer_id, |
| 27 | LayerTree* layer_tree) { |
| 28 | if (layer_id == Layer::INVALID_ID) { |
| 29 | if (current_layer) |
| 30 | current_layer->SetLayerTreeHost(nullptr); |
| 31 | |
| 32 | return nullptr; |
| 33 | } |
| 34 | Layer* layer = layer_tree->LayerById(layer_id); |
| 35 | DCHECK(layer); |
| 36 | if (current_layer && current_layer != layer) |
| 37 | current_layer->SetLayerTreeHost(nullptr); |
| 38 | |
| 39 | return layer; |
khushalsagar | 80655645 | 2016-08-17 01:36:26 | [diff] [blame] | 40 | } |
| 41 | |
khushalsagar | 86928f9 | 2016-08-17 21:49:05 | [diff] [blame] | 42 | } // namespace |
| 43 | |
| 44 | LayerTree::Inputs::Inputs() |
| 45 | : top_controls_height(0.f), |
| 46 | top_controls_shown_ratio(0.f), |
| 47 | top_controls_shrink_blink_size(false), |
ianwen | e5fc578 | 2016-08-18 04:05:15 | [diff] [blame] | 48 | bottom_controls_height(0.f), |
khushalsagar | 86928f9 | 2016-08-17 21:49:05 | [diff] [blame] | 49 | device_scale_factor(1.f), |
| 50 | painted_device_scale_factor(1.f), |
| 51 | page_scale_factor(1.f), |
| 52 | min_page_scale_factor(1.f), |
| 53 | max_page_scale_factor(1.f), |
| 54 | background_color(SK_ColorWHITE), |
| 55 | has_transparent_background(false), |
| 56 | have_scroll_event_handlers(false), |
| 57 | event_listener_properties() {} |
| 58 | |
| 59 | LayerTree::Inputs::~Inputs() = default; |
| 60 | |
| 61 | LayerTree::LayerTree(std::unique_ptr<AnimationHost> animation_host, |
| 62 | LayerTreeHost* layer_tree_host) |
| 63 | : needs_full_tree_sync_(true), |
| 64 | needs_meta_info_recomputation_(true), |
| 65 | in_paint_layer_contents_(false), |
| 66 | animation_host_(std::move(animation_host)), |
| 67 | layer_tree_host_(layer_tree_host) { |
| 68 | DCHECK(animation_host_); |
| 69 | DCHECK(layer_tree_host_); |
xingliu | 95d9e6b6 | 2016-08-18 03:53:08 | [diff] [blame] | 70 | animation_host_->SetMutatorHostClient(this); |
khushalsagar | 86928f9 | 2016-08-17 21:49:05 | [diff] [blame] | 71 | } |
| 72 | |
| 73 | LayerTree::~LayerTree() { |
| 74 | animation_host_->SetMutatorHostClient(nullptr); |
| 75 | |
| 76 | // We must clear any pointers into the layer tree prior to destroying it. |
| 77 | RegisterViewportLayers(nullptr, nullptr, nullptr, nullptr); |
| 78 | |
| 79 | if (inputs_.root_layer) { |
| 80 | inputs_.root_layer->SetLayerTreeHost(nullptr); |
| 81 | |
| 82 | // The root layer must be destroyed before the layer tree. We've made a |
| 83 | // contract with our animation controllers that the animation_host will |
| 84 | // outlive them, and we must make good. |
| 85 | inputs_.root_layer = nullptr; |
| 86 | } |
| 87 | } |
| 88 | |
| 89 | void LayerTree::SetRootLayer(scoped_refptr<Layer> root_layer) { |
| 90 | if (inputs_.root_layer.get() == root_layer.get()) |
| 91 | return; |
| 92 | |
| 93 | if (inputs_.root_layer.get()) |
| 94 | inputs_.root_layer->SetLayerTreeHost(nullptr); |
| 95 | inputs_.root_layer = root_layer; |
| 96 | if (inputs_.root_layer.get()) { |
| 97 | DCHECK(!inputs_.root_layer->parent()); |
| 98 | inputs_.root_layer->SetLayerTreeHost(layer_tree_host_); |
| 99 | } |
| 100 | |
| 101 | if (hud_layer_.get()) |
| 102 | hud_layer_->RemoveFromParent(); |
| 103 | |
| 104 | // Reset gpu rasterization tracking. |
| 105 | // This flag is sticky until a new tree comes along. |
| 106 | layer_tree_host_->ResetGpuRasterizationTracking(); |
| 107 | |
| 108 | SetNeedsFullTreeSync(); |
| 109 | } |
| 110 | |
| 111 | void LayerTree::RegisterViewportLayers( |
| 112 | scoped_refptr<Layer> overscroll_elasticity_layer, |
| 113 | scoped_refptr<Layer> page_scale_layer, |
| 114 | scoped_refptr<Layer> inner_viewport_scroll_layer, |
| 115 | scoped_refptr<Layer> outer_viewport_scroll_layer) { |
| 116 | DCHECK(!inner_viewport_scroll_layer || |
| 117 | inner_viewport_scroll_layer != outer_viewport_scroll_layer); |
| 118 | inputs_.overscroll_elasticity_layer = overscroll_elasticity_layer; |
| 119 | inputs_.page_scale_layer = page_scale_layer; |
| 120 | inputs_.inner_viewport_scroll_layer = inner_viewport_scroll_layer; |
| 121 | inputs_.outer_viewport_scroll_layer = outer_viewport_scroll_layer; |
| 122 | } |
| 123 | |
| 124 | void LayerTree::RegisterSelection(const LayerSelection& selection) { |
| 125 | if (inputs_.selection == selection) |
| 126 | return; |
| 127 | |
| 128 | inputs_.selection = selection; |
| 129 | SetNeedsCommit(); |
| 130 | } |
| 131 | |
| 132 | void LayerTree::SetHaveScrollEventHandlers(bool have_event_handlers) { |
| 133 | if (inputs_.have_scroll_event_handlers == have_event_handlers) |
| 134 | return; |
| 135 | |
| 136 | inputs_.have_scroll_event_handlers = have_event_handlers; |
| 137 | SetNeedsCommit(); |
| 138 | } |
| 139 | |
| 140 | void LayerTree::SetEventListenerProperties(EventListenerClass event_class, |
| 141 | EventListenerProperties properties) { |
| 142 | const size_t index = static_cast<size_t>(event_class); |
| 143 | if (inputs_.event_listener_properties[index] == properties) |
| 144 | return; |
| 145 | |
| 146 | inputs_.event_listener_properties[index] = properties; |
| 147 | SetNeedsCommit(); |
| 148 | } |
| 149 | |
| 150 | void LayerTree::SetViewportSize(const gfx::Size& device_viewport_size) { |
| 151 | if (inputs_.device_viewport_size == device_viewport_size) |
| 152 | return; |
| 153 | |
| 154 | inputs_.device_viewport_size = device_viewport_size; |
| 155 | |
| 156 | SetPropertyTreesNeedRebuild(); |
| 157 | SetNeedsCommit(); |
| 158 | } |
| 159 | |
| 160 | void LayerTree::SetTopControlsHeight(float height, bool shrink) { |
| 161 | if (inputs_.top_controls_height == height && |
| 162 | inputs_.top_controls_shrink_blink_size == shrink) |
| 163 | return; |
| 164 | |
| 165 | inputs_.top_controls_height = height; |
| 166 | inputs_.top_controls_shrink_blink_size = shrink; |
| 167 | SetNeedsCommit(); |
| 168 | } |
| 169 | |
| 170 | void LayerTree::SetTopControlsShownRatio(float ratio) { |
| 171 | if (inputs_.top_controls_shown_ratio == ratio) |
| 172 | return; |
| 173 | |
| 174 | inputs_.top_controls_shown_ratio = ratio; |
| 175 | SetNeedsCommit(); |
| 176 | } |
| 177 | |
ianwen | e5fc578 | 2016-08-18 04:05:15 | [diff] [blame] | 178 | void LayerTree::SetBottomControlsHeight(float height) { |
| 179 | if (inputs_.bottom_controls_height == height) |
| 180 | return; |
| 181 | |
| 182 | inputs_.bottom_controls_height = height; |
| 183 | SetNeedsCommit(); |
| 184 | } |
| 185 | |
khushalsagar | 86928f9 | 2016-08-17 21:49:05 | [diff] [blame] | 186 | void LayerTree::SetPageScaleFactorAndLimits(float page_scale_factor, |
| 187 | float min_page_scale_factor, |
| 188 | float max_page_scale_factor) { |
| 189 | if (inputs_.page_scale_factor == page_scale_factor && |
| 190 | inputs_.min_page_scale_factor == min_page_scale_factor && |
| 191 | inputs_.max_page_scale_factor == max_page_scale_factor) |
| 192 | return; |
| 193 | |
| 194 | inputs_.page_scale_factor = page_scale_factor; |
| 195 | inputs_.min_page_scale_factor = min_page_scale_factor; |
| 196 | inputs_.max_page_scale_factor = max_page_scale_factor; |
| 197 | SetPropertyTreesNeedRebuild(); |
| 198 | SetNeedsCommit(); |
| 199 | } |
| 200 | |
| 201 | void LayerTree::StartPageScaleAnimation(const gfx::Vector2d& target_offset, |
| 202 | bool use_anchor, |
| 203 | float scale, |
| 204 | base::TimeDelta duration) { |
| 205 | inputs_.pending_page_scale_animation.reset(new PendingPageScaleAnimation( |
| 206 | target_offset, use_anchor, scale, duration)); |
| 207 | |
| 208 | SetNeedsCommit(); |
| 209 | } |
| 210 | |
| 211 | bool LayerTree::HasPendingPageScaleAnimation() const { |
| 212 | return !!inputs_.pending_page_scale_animation.get(); |
| 213 | } |
| 214 | |
| 215 | void LayerTree::SetDeviceScaleFactor(float device_scale_factor) { |
| 216 | if (inputs_.device_scale_factor == device_scale_factor) |
| 217 | return; |
| 218 | inputs_.device_scale_factor = device_scale_factor; |
| 219 | |
| 220 | property_trees_.needs_rebuild = true; |
| 221 | SetNeedsCommit(); |
| 222 | } |
| 223 | |
| 224 | void LayerTree::SetPaintedDeviceScaleFactor(float painted_device_scale_factor) { |
| 225 | if (inputs_.painted_device_scale_factor == painted_device_scale_factor) |
| 226 | return; |
| 227 | inputs_.painted_device_scale_factor = painted_device_scale_factor; |
| 228 | |
| 229 | SetNeedsCommit(); |
| 230 | } |
xingliu | e43518a | 2016-07-28 23:59:47 | [diff] [blame] | 231 | |
| 232 | void LayerTree::RegisterLayer(Layer* layer) { |
| 233 | DCHECK(!LayerById(layer->id())); |
| 234 | DCHECK(!in_paint_layer_contents_); |
| 235 | layer_id_map_[layer->id()] = layer; |
| 236 | if (layer->element_id()) { |
| 237 | animation_host_->RegisterElement(layer->element_id(), |
| 238 | ElementListType::ACTIVE); |
| 239 | } |
| 240 | } |
| 241 | |
| 242 | void LayerTree::UnregisterLayer(Layer* layer) { |
| 243 | DCHECK(LayerById(layer->id())); |
| 244 | DCHECK(!in_paint_layer_contents_); |
| 245 | if (layer->element_id()) { |
| 246 | animation_host_->UnregisterElement(layer->element_id(), |
| 247 | ElementListType::ACTIVE); |
| 248 | } |
| 249 | RemoveLayerShouldPushProperties(layer); |
| 250 | layer_id_map_.erase(layer->id()); |
| 251 | } |
| 252 | |
| 253 | Layer* LayerTree::LayerById(int id) const { |
| 254 | LayerIdMap::const_iterator iter = layer_id_map_.find(id); |
| 255 | return iter != layer_id_map_.end() ? iter->second : nullptr; |
| 256 | } |
| 257 | |
| 258 | bool LayerTree::UpdateLayers(const LayerList& update_layer_list, |
| 259 | bool* content_is_suitable_for_gpu) { |
| 260 | base::AutoReset<bool> painting(&in_paint_layer_contents_, true); |
| 261 | bool did_paint_content = false; |
| 262 | for (const auto& layer : update_layer_list) { |
| 263 | did_paint_content |= layer->Update(); |
| 264 | *content_is_suitable_for_gpu &= layer->IsSuitableForGpuRasterization(); |
| 265 | } |
| 266 | return did_paint_content; |
| 267 | } |
| 268 | |
| 269 | void LayerTree::AddLayerShouldPushProperties(Layer* layer) { |
| 270 | layers_that_should_push_properties_.insert(layer); |
| 271 | } |
| 272 | |
| 273 | void LayerTree::RemoveLayerShouldPushProperties(Layer* layer) { |
| 274 | layers_that_should_push_properties_.erase(layer); |
| 275 | } |
| 276 | |
| 277 | std::unordered_set<Layer*>& LayerTree::LayersThatShouldPushProperties() { |
| 278 | return layers_that_should_push_properties_; |
| 279 | } |
| 280 | |
| 281 | bool LayerTree::LayerNeedsPushPropertiesForTesting(Layer* layer) const { |
| 282 | return layers_that_should_push_properties_.find(layer) != |
| 283 | layers_that_should_push_properties_.end(); |
| 284 | } |
| 285 | |
khushalsagar | 86928f9 | 2016-08-17 21:49:05 | [diff] [blame] | 286 | void LayerTree::SetNeedsMetaInfoRecomputation(bool needs_recomputation) { |
| 287 | needs_meta_info_recomputation_ = needs_recomputation; |
| 288 | } |
| 289 | |
| 290 | void LayerTree::SetPageScaleFromImplSide(float page_scale) { |
| 291 | DCHECK(layer_tree_host_->CommitRequested()); |
| 292 | inputs_.page_scale_factor = page_scale; |
| 293 | SetPropertyTreesNeedRebuild(); |
| 294 | } |
| 295 | |
| 296 | void LayerTree::SetElasticOverscrollFromImplSide( |
| 297 | gfx::Vector2dF elastic_overscroll) { |
| 298 | DCHECK(layer_tree_host_->CommitRequested()); |
| 299 | elastic_overscroll_ = elastic_overscroll; |
| 300 | } |
| 301 | |
| 302 | void LayerTree::UpdateHudLayer(bool show_hud_info) { |
| 303 | if (show_hud_info) { |
| 304 | if (!hud_layer_.get()) { |
| 305 | hud_layer_ = HeadsUpDisplayLayer::Create(); |
| 306 | } |
| 307 | |
| 308 | if (inputs_.root_layer.get() && !hud_layer_->parent()) |
| 309 | inputs_.root_layer->AddChild(hud_layer_); |
| 310 | } else if (hud_layer_.get()) { |
| 311 | hud_layer_->RemoveFromParent(); |
| 312 | hud_layer_ = nullptr; |
| 313 | } |
| 314 | } |
| 315 | |
| 316 | void LayerTree::SetNeedsFullTreeSync() { |
| 317 | needs_full_tree_sync_ = true; |
| 318 | needs_meta_info_recomputation_ = true; |
| 319 | |
| 320 | property_trees_.needs_rebuild = true; |
| 321 | SetNeedsCommit(); |
| 322 | } |
| 323 | |
| 324 | void LayerTree::SetNeedsCommit() { |
| 325 | layer_tree_host_->SetNeedsCommit(); |
| 326 | } |
| 327 | |
| 328 | void LayerTree::SetPropertyTreesNeedRebuild() { |
| 329 | property_trees_.needs_rebuild = true; |
| 330 | layer_tree_host_->SetNeedsUpdateLayers(); |
| 331 | } |
| 332 | |
| 333 | void LayerTree::PushPropertiesTo(LayerTreeImpl* tree_impl) { |
| 334 | tree_impl->set_needs_full_tree_sync(needs_full_tree_sync_); |
| 335 | needs_full_tree_sync_ = false; |
| 336 | |
| 337 | if (hud_layer_.get()) { |
| 338 | LayerImpl* hud_impl = tree_impl->LayerById(hud_layer_->id()); |
| 339 | tree_impl->set_hud_layer(static_cast<HeadsUpDisplayLayerImpl*>(hud_impl)); |
| 340 | } else { |
| 341 | tree_impl->set_hud_layer(nullptr); |
| 342 | } |
| 343 | |
| 344 | tree_impl->set_background_color(inputs_.background_color); |
| 345 | tree_impl->set_has_transparent_background(inputs_.has_transparent_background); |
| 346 | tree_impl->set_have_scroll_event_handlers(inputs_.have_scroll_event_handlers); |
| 347 | tree_impl->set_event_listener_properties( |
| 348 | EventListenerClass::kTouchStartOrMove, |
| 349 | event_listener_properties(EventListenerClass::kTouchStartOrMove)); |
| 350 | tree_impl->set_event_listener_properties( |
| 351 | EventListenerClass::kMouseWheel, |
| 352 | event_listener_properties(EventListenerClass::kMouseWheel)); |
| 353 | tree_impl->set_event_listener_properties( |
| 354 | EventListenerClass::kTouchEndOrCancel, |
| 355 | event_listener_properties(EventListenerClass::kTouchEndOrCancel)); |
| 356 | |
| 357 | if (inputs_.page_scale_layer && inputs_.inner_viewport_scroll_layer) { |
| 358 | tree_impl->SetViewportLayersFromIds( |
| 359 | inputs_.overscroll_elasticity_layer |
| 360 | ? inputs_.overscroll_elasticity_layer->id() |
| 361 | : Layer::INVALID_ID, |
| 362 | inputs_.page_scale_layer->id(), |
| 363 | inputs_.inner_viewport_scroll_layer->id(), |
| 364 | inputs_.outer_viewport_scroll_layer |
| 365 | ? inputs_.outer_viewport_scroll_layer->id() |
| 366 | : Layer::INVALID_ID); |
| 367 | DCHECK(inputs_.inner_viewport_scroll_layer |
| 368 | ->IsContainerForFixedPositionLayers()); |
| 369 | } else { |
| 370 | tree_impl->ClearViewportLayers(); |
| 371 | } |
| 372 | |
| 373 | tree_impl->RegisterSelection(inputs_.selection); |
| 374 | |
| 375 | bool property_trees_changed_on_active_tree = |
| 376 | tree_impl->IsActiveTree() && tree_impl->property_trees()->changed; |
| 377 | // Property trees may store damage status. We preserve the sync tree damage |
| 378 | // status by pushing the damage status from sync tree property trees to main |
| 379 | // thread property trees or by moving it onto the layers. |
| 380 | if (inputs_.root_layer && property_trees_changed_on_active_tree) { |
| 381 | if (property_trees_.sequence_number == |
| 382 | tree_impl->property_trees()->sequence_number) |
| 383 | tree_impl->property_trees()->PushChangeTrackingTo(&property_trees_); |
| 384 | else |
| 385 | tree_impl->MoveChangeTrackingToLayers(); |
| 386 | } |
| 387 | // Setting property trees must happen before pushing the page scale. |
| 388 | tree_impl->SetPropertyTrees(&property_trees_); |
| 389 | |
| 390 | tree_impl->PushPageScaleFromMainThread(inputs_.page_scale_factor, |
| 391 | inputs_.min_page_scale_factor, |
| 392 | inputs_.max_page_scale_factor); |
| 393 | |
| 394 | tree_impl->set_top_controls_shrink_blink_size( |
| 395 | inputs_.top_controls_shrink_blink_size); |
| 396 | tree_impl->set_top_controls_height(inputs_.top_controls_height); |
ianwen | e5fc578 | 2016-08-18 04:05:15 | [diff] [blame] | 397 | tree_impl->set_bottom_controls_height(inputs_.bottom_controls_height); |
khushalsagar | 86928f9 | 2016-08-17 21:49:05 | [diff] [blame] | 398 | tree_impl->PushTopControlsFromMainThread(inputs_.top_controls_shown_ratio); |
| 399 | tree_impl->elastic_overscroll()->PushFromMainThread(elastic_overscroll_); |
| 400 | if (tree_impl->IsActiveTree()) |
| 401 | tree_impl->elastic_overscroll()->PushPendingToActive(); |
| 402 | |
| 403 | tree_impl->set_painted_device_scale_factor( |
| 404 | inputs_.painted_device_scale_factor); |
| 405 | |
| 406 | if (inputs_.pending_page_scale_animation) { |
| 407 | tree_impl->SetPendingPageScaleAnimation( |
| 408 | std::move(inputs_.pending_page_scale_animation)); |
| 409 | } |
| 410 | |
| 411 | DCHECK(!tree_impl->ViewportSizeInvalid()); |
| 412 | |
| 413 | tree_impl->set_has_ever_been_drawn(false); |
| 414 | } |
| 415 | |
xingliu | e43518a | 2016-07-28 23:59:47 | [diff] [blame] | 416 | void LayerTree::ToProtobuf(proto::LayerTree* proto) { |
khushalsagar | 86928f9 | 2016-08-17 21:49:05 | [diff] [blame] | 417 | LayerProtoConverter::SerializeLayerHierarchy(inputs_.root_layer, |
| 418 | proto->mutable_root_layer()); |
| 419 | |
xingliu | e43518a | 2016-07-28 23:59:47 | [diff] [blame] | 420 | for (auto* layer : layers_that_should_push_properties_) { |
| 421 | proto->add_layers_that_should_push_properties(layer->id()); |
| 422 | } |
| 423 | proto->set_in_paint_layer_contents(in_paint_layer_contents()); |
khushalsagar | 86928f9 | 2016-08-17 21:49:05 | [diff] [blame] | 424 | |
| 425 | proto->set_needs_full_tree_sync(needs_full_tree_sync_); |
| 426 | proto->set_needs_meta_info_recomputation(needs_meta_info_recomputation_); |
| 427 | proto->set_hud_layer_id(hud_layer_ ? hud_layer_->id() : Layer::INVALID_ID); |
| 428 | |
| 429 | // Viewport layers. |
| 430 | proto->set_overscroll_elasticity_layer_id( |
| 431 | inputs_.overscroll_elasticity_layer |
| 432 | ? inputs_.overscroll_elasticity_layer->id() |
| 433 | : Layer::INVALID_ID); |
| 434 | proto->set_page_scale_layer_id(inputs_.page_scale_layer |
| 435 | ? inputs_.page_scale_layer->id() |
| 436 | : Layer::INVALID_ID); |
| 437 | proto->set_inner_viewport_scroll_layer_id( |
| 438 | inputs_.inner_viewport_scroll_layer |
| 439 | ? inputs_.inner_viewport_scroll_layer->id() |
| 440 | : Layer::INVALID_ID); |
| 441 | proto->set_outer_viewport_scroll_layer_id( |
| 442 | inputs_.outer_viewport_scroll_layer |
| 443 | ? inputs_.outer_viewport_scroll_layer->id() |
| 444 | : Layer::INVALID_ID); |
| 445 | |
| 446 | SizeToProto(inputs_.device_viewport_size, |
| 447 | proto->mutable_device_viewport_size()); |
| 448 | proto->set_top_controls_shrink_blink_size( |
| 449 | inputs_.top_controls_shrink_blink_size); |
| 450 | proto->set_top_controls_height(inputs_.top_controls_height); |
| 451 | proto->set_top_controls_shown_ratio(inputs_.top_controls_shown_ratio); |
| 452 | proto->set_device_scale_factor(inputs_.device_scale_factor); |
| 453 | proto->set_painted_device_scale_factor(inputs_.painted_device_scale_factor); |
| 454 | proto->set_page_scale_factor(inputs_.page_scale_factor); |
| 455 | proto->set_min_page_scale_factor(inputs_.min_page_scale_factor); |
| 456 | proto->set_max_page_scale_factor(inputs_.max_page_scale_factor); |
| 457 | |
| 458 | proto->set_background_color(inputs_.background_color); |
| 459 | proto->set_has_transparent_background(inputs_.has_transparent_background); |
| 460 | proto->set_have_scroll_event_handlers(inputs_.have_scroll_event_handlers); |
| 461 | proto->set_wheel_event_listener_properties(static_cast<uint32_t>( |
| 462 | event_listener_properties(EventListenerClass::kMouseWheel))); |
| 463 | proto->set_touch_start_or_move_event_listener_properties( |
| 464 | static_cast<uint32_t>( |
| 465 | event_listener_properties(EventListenerClass::kTouchStartOrMove))); |
| 466 | proto->set_touch_end_or_cancel_event_listener_properties( |
| 467 | static_cast<uint32_t>( |
| 468 | event_listener_properties(EventListenerClass::kTouchEndOrCancel))); |
| 469 | |
| 470 | LayerSelectionToProtobuf(inputs_.selection, proto->mutable_selection()); |
| 471 | property_trees_.ToProtobuf(proto->mutable_property_trees()); |
khushalsagar | f70f776f | 2016-08-19 22:45:29 | [diff] [blame] | 472 | Vector2dFToProto(elastic_overscroll_, proto->mutable_elastic_overscroll()); |
xingliu | e43518a | 2016-07-28 23:59:47 | [diff] [blame] | 473 | } |
| 474 | |
| 475 | void LayerTree::FromProtobuf(const proto::LayerTree& proto) { |
khushalsagar | 86928f9 | 2016-08-17 21:49:05 | [diff] [blame] | 476 | // Layer hierarchy. |
| 477 | scoped_refptr<Layer> new_root_layer = |
| 478 | LayerProtoConverter::DeserializeLayerHierarchy( |
| 479 | inputs_.root_layer, proto.root_layer(), layer_tree_host_); |
| 480 | if (inputs_.root_layer != new_root_layer) { |
| 481 | inputs_.root_layer = new_root_layer; |
| 482 | } |
| 483 | |
xingliu | e43518a | 2016-07-28 23:59:47 | [diff] [blame] | 484 | for (auto layer_id : proto.layers_that_should_push_properties()) { |
| 485 | AddLayerShouldPushProperties(layer_id_map_[layer_id]); |
| 486 | } |
| 487 | in_paint_layer_contents_ = proto.in_paint_layer_contents(); |
khushalsagar | 86928f9 | 2016-08-17 21:49:05 | [diff] [blame] | 488 | |
| 489 | needs_full_tree_sync_ = proto.needs_full_tree_sync(); |
| 490 | needs_meta_info_recomputation_ = proto.needs_meta_info_recomputation(); |
| 491 | |
| 492 | inputs_.overscroll_elasticity_layer = |
| 493 | UpdateAndGetLayer(inputs_.overscroll_elasticity_layer.get(), |
| 494 | proto.overscroll_elasticity_layer_id(), this); |
| 495 | inputs_.page_scale_layer = UpdateAndGetLayer( |
| 496 | inputs_.page_scale_layer.get(), proto.page_scale_layer_id(), this); |
| 497 | inputs_.inner_viewport_scroll_layer = |
| 498 | UpdateAndGetLayer(inputs_.inner_viewport_scroll_layer.get(), |
| 499 | proto.inner_viewport_scroll_layer_id(), this); |
| 500 | inputs_.outer_viewport_scroll_layer = |
| 501 | UpdateAndGetLayer(inputs_.outer_viewport_scroll_layer.get(), |
| 502 | proto.outer_viewport_scroll_layer_id(), this); |
| 503 | |
| 504 | inputs_.device_viewport_size = ProtoToSize(proto.device_viewport_size()); |
| 505 | inputs_.top_controls_shrink_blink_size = |
| 506 | proto.top_controls_shrink_blink_size(); |
| 507 | inputs_.top_controls_height = proto.top_controls_height(); |
| 508 | inputs_.top_controls_shown_ratio = proto.top_controls_shown_ratio(); |
| 509 | inputs_.device_scale_factor = proto.device_scale_factor(); |
| 510 | inputs_.painted_device_scale_factor = proto.painted_device_scale_factor(); |
| 511 | inputs_.page_scale_factor = proto.page_scale_factor(); |
| 512 | inputs_.min_page_scale_factor = proto.min_page_scale_factor(); |
| 513 | inputs_.max_page_scale_factor = proto.max_page_scale_factor(); |
| 514 | inputs_.background_color = proto.background_color(); |
| 515 | inputs_.has_transparent_background = proto.has_transparent_background(); |
| 516 | inputs_.have_scroll_event_handlers = proto.have_scroll_event_handlers(); |
| 517 | inputs_.event_listener_properties[static_cast<size_t>( |
| 518 | EventListenerClass::kMouseWheel)] = |
| 519 | static_cast<EventListenerProperties>( |
| 520 | proto.wheel_event_listener_properties()); |
| 521 | inputs_.event_listener_properties[static_cast<size_t>( |
| 522 | EventListenerClass::kTouchStartOrMove)] = |
| 523 | static_cast<EventListenerProperties>( |
| 524 | proto.touch_start_or_move_event_listener_properties()); |
| 525 | inputs_.event_listener_properties[static_cast<size_t>( |
| 526 | EventListenerClass::kTouchEndOrCancel)] = |
| 527 | static_cast<EventListenerProperties>( |
| 528 | proto.touch_end_or_cancel_event_listener_properties()); |
| 529 | |
| 530 | hud_layer_ = static_cast<HeadsUpDisplayLayer*>( |
| 531 | UpdateAndGetLayer(hud_layer_.get(), proto.hud_layer_id(), this)); |
| 532 | |
| 533 | LayerSelectionFromProtobuf(&inputs_.selection, proto.selection()); |
khushalsagar | f70f776f | 2016-08-19 22:45:29 | [diff] [blame] | 534 | elastic_overscroll_ = ProtoToVector2dF(proto.elastic_overscroll()); |
khushalsagar | 86928f9 | 2016-08-17 21:49:05 | [diff] [blame] | 535 | |
| 536 | // It is required to create new PropertyTrees before deserializing it. |
| 537 | property_trees_ = PropertyTrees(); |
| 538 | property_trees_.FromProtobuf(proto.property_trees()); |
| 539 | |
| 540 | // Forcefully override the sequence number of all layers in the tree to have |
| 541 | // a valid sequence number. Changing the sequence number for a layer does not |
| 542 | // need a commit, so the value will become out of date for layers that are not |
| 543 | // updated for other reasons. All layers that at this point are part of the |
| 544 | // layer tree are valid, so it is OK that they have a valid sequence number. |
| 545 | int seq_num = property_trees_.sequence_number; |
xingliu | 95d9e6b6 | 2016-08-18 03:53:08 | [diff] [blame] | 546 | LayerTreeHostCommon::CallFunctionForEveryLayer(this, [seq_num](Layer* layer) { |
| 547 | layer->set_property_tree_sequence_number(seq_num); |
| 548 | }); |
| 549 | } |
| 550 | |
| 551 | Layer* LayerTree::LayerByElementId(ElementId element_id) const { |
| 552 | ElementLayersMap::const_iterator iter = element_layers_map_.find(element_id); |
| 553 | return iter != element_layers_map_.end() ? iter->second : nullptr; |
| 554 | } |
| 555 | |
| 556 | void LayerTree::RegisterElement(ElementId element_id, |
| 557 | ElementListType list_type, |
| 558 | Layer* layer) { |
| 559 | if (layer->element_id()) { |
| 560 | element_layers_map_[layer->element_id()] = layer; |
| 561 | } |
| 562 | |
| 563 | animation_host_->RegisterElement(element_id, list_type); |
| 564 | } |
| 565 | |
| 566 | void LayerTree::UnregisterElement(ElementId element_id, |
| 567 | ElementListType list_type, |
| 568 | Layer* layer) { |
| 569 | animation_host_->UnregisterElement(element_id, list_type); |
| 570 | |
| 571 | if (layer->element_id()) { |
| 572 | element_layers_map_.erase(layer->element_id()); |
| 573 | } |
| 574 | } |
| 575 | |
| 576 | static void SetElementIdForTesting(Layer* layer) { |
| 577 | layer->SetElementId(LayerIdToElementIdForTesting(layer->id())); |
| 578 | } |
| 579 | |
| 580 | void LayerTree::SetElementIdsForTesting() { |
| 581 | LayerTreeHostCommon::CallFunctionForEveryLayer(this, SetElementIdForTesting); |
| 582 | } |
| 583 | |
| 584 | bool LayerTree::IsElementInList(ElementId element_id, |
| 585 | ElementListType list_type) const { |
| 586 | return list_type == ElementListType::ACTIVE && LayerByElementId(element_id); |
| 587 | } |
| 588 | |
| 589 | void LayerTree::SetMutatorsNeedCommit() { |
| 590 | layer_tree_host_->SetNeedsCommit(); |
| 591 | } |
| 592 | |
| 593 | void LayerTree::SetMutatorsNeedRebuildPropertyTrees() { |
| 594 | property_trees_.needs_rebuild = true; |
| 595 | } |
| 596 | |
| 597 | void LayerTree::SetElementFilterMutated(ElementId element_id, |
| 598 | ElementListType list_type, |
| 599 | const FilterOperations& filters) { |
| 600 | Layer* layer = LayerByElementId(element_id); |
| 601 | DCHECK(layer); |
| 602 | layer->OnFilterAnimated(filters); |
| 603 | } |
| 604 | |
| 605 | void LayerTree::SetElementOpacityMutated(ElementId element_id, |
| 606 | ElementListType list_type, |
| 607 | float opacity) { |
| 608 | Layer* layer = LayerByElementId(element_id); |
| 609 | DCHECK(layer); |
| 610 | layer->OnOpacityAnimated(opacity); |
| 611 | } |
| 612 | |
| 613 | void LayerTree::SetElementTransformMutated(ElementId element_id, |
| 614 | ElementListType list_type, |
| 615 | const gfx::Transform& transform) { |
| 616 | Layer* layer = LayerByElementId(element_id); |
| 617 | DCHECK(layer); |
| 618 | layer->OnTransformAnimated(transform); |
| 619 | } |
| 620 | |
| 621 | void LayerTree::SetElementScrollOffsetMutated( |
| 622 | ElementId element_id, |
| 623 | ElementListType list_type, |
| 624 | const gfx::ScrollOffset& scroll_offset) { |
| 625 | Layer* layer = LayerByElementId(element_id); |
| 626 | DCHECK(layer); |
| 627 | layer->OnScrollOffsetAnimated(scroll_offset); |
| 628 | } |
| 629 | |
| 630 | void LayerTree::ElementTransformIsAnimatingChanged( |
| 631 | ElementId element_id, |
| 632 | ElementListType list_type, |
| 633 | AnimationChangeType change_type, |
| 634 | bool is_animating) { |
| 635 | Layer* layer = LayerByElementId(element_id); |
| 636 | if (layer) { |
| 637 | switch (change_type) { |
| 638 | case AnimationChangeType::POTENTIAL: |
| 639 | layer->OnTransformIsPotentiallyAnimatingChanged(is_animating); |
| 640 | break; |
| 641 | case AnimationChangeType::RUNNING: |
| 642 | layer->OnTransformIsCurrentlyAnimatingChanged(is_animating); |
| 643 | break; |
| 644 | case AnimationChangeType::BOTH: |
| 645 | layer->OnTransformIsPotentiallyAnimatingChanged(is_animating); |
| 646 | layer->OnTransformIsCurrentlyAnimatingChanged(is_animating); |
| 647 | break; |
| 648 | } |
| 649 | } |
| 650 | } |
| 651 | |
| 652 | void LayerTree::ElementOpacityIsAnimatingChanged( |
| 653 | ElementId element_id, |
| 654 | ElementListType list_type, |
| 655 | AnimationChangeType change_type, |
| 656 | bool is_animating) { |
| 657 | Layer* layer = LayerByElementId(element_id); |
| 658 | if (layer) { |
| 659 | switch (change_type) { |
| 660 | case AnimationChangeType::POTENTIAL: |
| 661 | layer->OnOpacityIsPotentiallyAnimatingChanged(is_animating); |
| 662 | break; |
| 663 | case AnimationChangeType::RUNNING: |
| 664 | layer->OnOpacityIsCurrentlyAnimatingChanged(is_animating); |
| 665 | break; |
| 666 | case AnimationChangeType::BOTH: |
| 667 | layer->OnOpacityIsPotentiallyAnimatingChanged(is_animating); |
| 668 | layer->OnOpacityIsCurrentlyAnimatingChanged(is_animating); |
| 669 | break; |
| 670 | } |
| 671 | } |
| 672 | } |
| 673 | |
| 674 | void LayerTree::ElementFilterIsAnimatingChanged(ElementId element_id, |
| 675 | ElementListType list_type, |
| 676 | AnimationChangeType change_type, |
| 677 | bool is_animating) { |
| 678 | Layer* layer = LayerByElementId(element_id); |
| 679 | if (layer) { |
| 680 | switch (change_type) { |
| 681 | case AnimationChangeType::POTENTIAL: |
| 682 | layer->OnFilterIsPotentiallyAnimatingChanged(is_animating); |
| 683 | break; |
| 684 | case AnimationChangeType::RUNNING: |
| 685 | layer->OnFilterIsCurrentlyAnimatingChanged(is_animating); |
| 686 | break; |
| 687 | case AnimationChangeType::BOTH: |
| 688 | layer->OnFilterIsPotentiallyAnimatingChanged(is_animating); |
| 689 | layer->OnFilterIsCurrentlyAnimatingChanged(is_animating); |
| 690 | break; |
| 691 | } |
| 692 | } |
| 693 | } |
| 694 | |
| 695 | gfx::ScrollOffset LayerTree::GetScrollOffsetForAnimation( |
| 696 | ElementId element_id) const { |
| 697 | Layer* layer = LayerByElementId(element_id); |
| 698 | DCHECK(layer); |
| 699 | return layer->ScrollOffsetForAnimation(); |
| 700 | } |
| 701 | |
| 702 | LayerListIterator<Layer> LayerTree::begin() const { |
| 703 | return LayerListIterator<Layer>(inputs_.root_layer.get()); |
| 704 | } |
| 705 | |
| 706 | LayerListIterator<Layer> LayerTree::end() const { |
| 707 | return LayerListIterator<Layer>(nullptr); |
| 708 | } |
| 709 | |
| 710 | LayerListReverseIterator<Layer> LayerTree::rbegin() { |
| 711 | return LayerListReverseIterator<Layer>(inputs_.root_layer.get()); |
| 712 | } |
| 713 | |
| 714 | LayerListReverseIterator<Layer> LayerTree::rend() { |
| 715 | return LayerListReverseIterator<Layer>(nullptr); |
| 716 | } |
| 717 | |
| 718 | void LayerTree::SetNeedsDisplayOnAllLayers() { |
| 719 | for (auto* layer : *this) |
| 720 | layer->SetNeedsDisplay(); |
xingliu | e43518a | 2016-07-28 23:59:47 | [diff] [blame] | 721 | } |
| 722 | |
khushalsagar | 8ec0740 | 2016-09-10 03:13:19 | [diff] [blame^] | 723 | UIResourceManager* LayerTree::GetUIResourceManager() const { |
| 724 | return layer_tree_host_->GetUIResourceManager(); |
| 725 | } |
| 726 | |
| 727 | const LayerTreeSettings& LayerTree::GetSettings() const { |
| 728 | return layer_tree_host_->GetSettings(); |
| 729 | } |
| 730 | |
xingliu | e43518a | 2016-07-28 23:59:47 | [diff] [blame] | 731 | } // namespace cc |