Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "cc/trees/draw_property_utils.h" | 5 #include "cc/trees/draw_property_utils.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 | 8 |
| 9 #include <vector> | 9 #include <vector> |
| 10 | 10 |
| (...skipping 268 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 279 const TransformTree& tree) { | 279 const TransformTree& tree) { |
| 280 return true; | 280 return true; |
| 281 } | 281 } |
| 282 | 282 |
| 283 template <typename LayerType> | 283 template <typename LayerType> |
| 284 static bool HasInvertibleOrAnimatedTransform(LayerType* layer) { | 284 static bool HasInvertibleOrAnimatedTransform(LayerType* layer) { |
| 285 return layer->transform_is_invertible() || | 285 return layer->transform_is_invertible() || |
| 286 layer->HasPotentiallyRunningTransformAnimation(); | 286 layer->HasPotentiallyRunningTransformAnimation(); |
| 287 } | 287 } |
| 288 | 288 |
| 289 static inline bool SubtreeShouldBeSkipped(LayerImpl* layer, | 289 static inline bool LayerShouldBeSkipped(LayerImpl* layer, |
| 290 bool layer_is_drawn, | 290 bool layer_is_drawn, |
| 291 const TransformTree& tree) { | 291 const TransformTree& transform_tree) { |
| 292 const TransformNode* transform_node = | |
| 293 transform_tree.Node(layer->transform_tree_index()); | |
| 294 const EffectTree& effect_tree = transform_tree.property_trees()->effect_tree; | |
| 295 const EffectNode* effect_node = effect_tree.Node(layer->effect_tree_index()); | |
| 292 // If the layer transform is not invertible, it should not be drawn. | 296 // If the layer transform is not invertible, it should not be drawn. |
| 293 // TODO(ajuma): Correctly process subtrees with singular transform for the | 297 // TODO(ajuma): Correctly process subtrees with singular transform for the |
| 294 // case where we may animate to a non-singular transform and wish to | 298 // case where we may animate to a non-singular transform and wish to |
| 295 // pre-raster. | 299 // pre-raster. |
| 296 if (!HasInvertibleOrAnimatedTransform(layer)) | 300 bool has_inherited_invertible_or_animated_transform = |
| 301 (transform_node->data.is_invertible && | |
| 302 transform_node->data.ancestors_are_invertible) || | |
| 303 transform_node->data.to_screen_is_animated; | |
| 304 if (!has_inherited_invertible_or_animated_transform) | |
| 297 return true; | 305 return true; |
| 298 | 306 |
| 299 // When we need to do a readback/copy of a layer's output, we can not skip | 307 // When we need to do a readback/copy of a layer's output, we can not skip |
| 300 // it or any of its ancestors. | 308 // it or any of its ancestors. |
| 301 if (layer->num_copy_requests_in_target_subtree() > 0) | 309 if (effect_node->data.num_copy_requests_in_subtree > 0) |
| 302 return false; | |
| 303 | |
| 304 // We cannot skip the the subtree if a descendant has a touch handler | |
| 305 // or the hit testing code will break (it requires fresh transforms, etc). | |
| 306 // Though we don't need visible rect for hit testing, we need render surface's | |
| 307 // drawable content rect which depends on layer's drawable content rect which | |
| 308 // in turn depends on layer's clip rect that is computed while computing | |
| 309 // visible rects. | |
| 310 if (layer->layer_or_descendant_has_touch_handler()) | |
| 311 return false; | 310 return false; |
| 312 | 311 |
| 313 // If the layer is not drawn, then skip it and its subtree. | 312 // If the layer is not drawn, then skip it and its subtree. |
| 314 if (!layer_is_drawn) | 313 if (!effect_node->data.is_drawn) |
| 315 return true; | 314 return true; |
| 316 | 315 |
| 317 if (layer->render_surface() && !layer->double_sided() && | 316 if (!layer->double_sided() && |
|
ajuma
2016/03/30 17:10:11
I think it's the surface's double-sidedness that m
sunxd
2016/03/31 16:55:57
I think it would be fine, as property_tree takes t
| |
| 318 IsSurfaceBackFaceVisible(layer, tree)) | 317 effect_node->data.node_or_ancestor_has_backface_visible_surface) |
| 319 return true; | 318 return true; |
| 320 | 319 |
| 321 // If layer is on the pending tree and opacity is being animated then | 320 // If layer is on the pending tree and opacity is being animated then |
| 322 // this subtree can't be skipped as we need to create, prioritize and | 321 // this subtree can't be skipped as we need to create, prioritize and |
| 323 // include tiles for this layer when deciding if tree can be activated. | 322 // include tiles for this layer when deciding if tree can be activated. |
| 324 if (layer->layer_tree_impl()->IsPendingTree() && | 323 if (!transform_tree.property_trees()->is_active && |
| 325 layer->HasPotentiallyRunningOpacityAnimation()) | 324 effect_node->data.to_screen_opacity_is_animated) |
| 326 return false; | 325 return false; |
| 327 | 326 |
| 328 // If layer has a background filter, don't skip the layer, even it the | 327 // If layer has a background filter, don't skip the layer, even it the |
| 329 // opacity is 0. | 328 // opacity is 0. |
| 330 if (!layer->background_filters().IsEmpty()) | 329 if (effect_node->data.node_or_ancestor_has_background_filters) |
| 331 return false; | 330 return false; |
| 332 | 331 |
| 333 // The opacity of a layer always applies to its children (either implicitly | 332 // The opacity of a layer always applies to its children (either implicitly |
| 334 // via a render surface or explicitly if the parent preserves 3D), so the | 333 // via a render surface or explicitly if the parent preserves 3D), so the |
| 335 // entire subtree can be skipped if this layer is fully transparent. | 334 // entire subtree can be skipped if this layer is fully transparent. |
| 336 return !layer->EffectiveOpacity(); | 335 return !effect_node->data.screen_space_opacity; |
| 337 } | 336 } |
| 338 | 337 |
| 339 static inline bool SubtreeShouldBeSkipped(Layer* layer, | 338 static inline bool SubtreeShouldBeSkipped(Layer* layer, |
| 340 bool layer_is_drawn, | 339 bool layer_is_drawn, |
| 341 const TransformTree& tree) { | 340 const TransformTree& tree) { |
| 342 // If the layer transform is not invertible, it should not be drawn. | 341 // If the layer transform is not invertible, it should not be drawn. |
| 343 if (!layer->transform_is_invertible() && | 342 if (!layer->transform_is_invertible() && |
| 344 !layer->HasPotentiallyRunningTransformAnimation()) | 343 !layer->HasPotentiallyRunningTransformAnimation()) |
| 345 return true; | 344 return true; |
| 346 | 345 |
| (...skipping 21 matching lines...) Expand all Loading... | |
| 368 // should not be trusted. | 367 // should not be trusted. |
| 369 // In particular, it should not cause the subtree to be skipped. | 368 // In particular, it should not cause the subtree to be skipped. |
| 370 // Similarly, for layers that might animate opacity using an impl-only | 369 // Similarly, for layers that might animate opacity using an impl-only |
| 371 // animation, their subtree should also not be skipped. | 370 // animation, their subtree should also not be skipped. |
| 372 return !layer->EffectiveOpacity() && | 371 return !layer->EffectiveOpacity() && |
| 373 !layer->HasPotentiallyRunningOpacityAnimation() && | 372 !layer->HasPotentiallyRunningOpacityAnimation() && |
| 374 !layer->OpacityCanAnimateOnImplThread(); | 373 !layer->OpacityCanAnimateOnImplThread(); |
| 375 } | 374 } |
| 376 | 375 |
| 377 template <typename LayerType> | 376 template <typename LayerType> |
| 378 static bool LayerShouldBeSkipped(LayerType* layer, | 377 static bool LayerNeedsUpdate(LayerType* layer, |
| 379 bool layer_is_drawn, | 378 bool layer_is_drawn, |
| 380 const TransformTree& tree) { | 379 const TransformTree& tree) { |
| 381 // Layers can be skipped if any of these conditions are met. | 380 // Layers can be skipped if any of these conditions are met. |
| 382 // - is not drawn due to it or one of its ancestors being hidden (or having | 381 // - is not drawn due to it or one of its ancestors being hidden (or having |
| 383 // no copy requests). | 382 // no copy requests). |
| 384 // - does not draw content. | 383 // - does not draw content. |
| 385 // - is transparent. | 384 // - is transparent. |
| 386 // - has empty bounds | 385 // - has empty bounds |
| 387 // - the layer is not double-sided, but its back face is visible. | 386 // - the layer is not double-sided, but its back face is visible. |
| 388 // | 387 // |
| 389 // Some additional conditions need to be computed at a later point after the | 388 // Some additional conditions need to be computed at a later point after the |
| 390 // recursion is finished. | 389 // recursion is finished. |
| 391 // - the intersection of render_surface content and layer clip_rect is empty | 390 // - the intersection of render_surface content and layer clip_rect is empty |
| 392 // - the visible_layer_rect is empty | 391 // - the visible_layer_rect is empty |
| 393 // | 392 // |
| 394 // Note, if the layer should not have been drawn due to being fully | 393 // Note, if the layer should not have been drawn due to being fully |
| 395 // transparent, we would have skipped the entire subtree and never made it | 394 // transparent, we would have skipped the entire subtree and never made it |
| 396 // into this function, so it is safe to omit this check here. | 395 // into this function, so it is safe to omit this check here. |
| 397 if (!layer_is_drawn) | 396 if (!layer_is_drawn) |
| 398 return true; | 397 return false; |
| 399 | 398 |
| 400 if (!layer->DrawsContent() || layer->bounds().IsEmpty()) | 399 if (!layer->DrawsContent() || layer->bounds().IsEmpty()) |
| 401 return true; | 400 return false; |
| 402 | 401 |
| 403 // The layer should not be drawn if (1) it is not double-sided and (2) the | 402 // The layer should not be drawn if (1) it is not double-sided and (2) the |
| 404 // back of the layer is known to be facing the screen. | 403 // back of the layer is known to be facing the screen. |
| 405 if (layer->should_check_backface_visibility()) { | 404 if (layer->should_check_backface_visibility()) { |
| 406 int backface_transform_id = | 405 int backface_transform_id = |
| 407 TransformTreeIndexForBackfaceVisibility(layer, tree); | 406 TransformTreeIndexForBackfaceVisibility(layer, tree); |
| 408 // A layer with singular transform is not drawn. So, we can assume that its | 407 // A layer with singular transform is not drawn. So, we can assume that its |
| 409 // backface is not visible. | 408 // backface is not visible. |
| 410 if (TransformToScreenIsKnown(layer, backface_transform_id, tree) && | 409 if (TransformToScreenIsKnown(layer, backface_transform_id, tree) && |
| 411 !HasSingularTransform(backface_transform_id, tree) && | 410 !HasSingularTransform(backface_transform_id, tree) && |
| 412 IsLayerBackFaceVisible(layer, backface_transform_id, tree)) | 411 IsLayerBackFaceVisible(layer, backface_transform_id, tree)) |
| 413 return true; | 412 return false; |
| 414 } | 413 } |
| 415 | 414 |
| 416 return false; | 415 return true; |
| 417 } | 416 } |
| 418 | 417 |
| 419 template <typename LayerType> | 418 void FindLayersThatNeedUpdates(Layer* layer, |
| 420 void FindLayersThatNeedUpdates( | 419 const TransformTree& transform_tree, |
| 421 LayerType* layer, | 420 const EffectTree& effect_tree, |
| 422 const TransformTree& transform_tree, | 421 LayerList* update_layer_list, |
| 423 const EffectTree& effect_tree, | 422 std::vector<Layer*>* visible_layer_list) { |
| 424 typename LayerType::LayerListType* update_layer_list, | |
| 425 std::vector<LayerType*>* visible_layer_list) { | |
| 426 DCHECK_GE(layer->effect_tree_index(), 0); | 423 DCHECK_GE(layer->effect_tree_index(), 0); |
| 427 bool layer_is_drawn = | 424 bool layer_is_drawn = |
| 428 effect_tree.Node(layer->effect_tree_index())->data.is_drawn; | 425 effect_tree.Node(layer->effect_tree_index())->data.is_drawn; |
| 429 | 426 |
| 430 if (layer->parent() && | 427 if (layer->parent() && |
| 431 SubtreeShouldBeSkipped(layer, layer_is_drawn, transform_tree)) | 428 SubtreeShouldBeSkipped(layer, layer_is_drawn, transform_tree)) |
| 432 return; | 429 return; |
| 433 | 430 |
| 434 if (!LayerShouldBeSkipped(layer, layer_is_drawn, transform_tree)) { | 431 if (LayerNeedsUpdate(layer, layer_is_drawn, transform_tree)) { |
| 435 visible_layer_list->push_back(layer); | 432 visible_layer_list->push_back(layer); |
| 436 update_layer_list->push_back(layer); | 433 update_layer_list->push_back(layer); |
| 437 } | 434 } |
| 438 | 435 |
| 439 // Append mask layers to the update layer list. They don't have valid visible | 436 // Append mask layers to the update layer list. They don't have valid visible |
| 440 // rects, so need to get added after the above calculation. Replica layers | 437 // rects, so need to get added after the above calculation. Replica layers |
| 441 // don't need to be updated. | 438 // don't need to be updated. |
| 442 if (LayerType* mask_layer = layer->mask_layer()) | 439 if (Layer* mask_layer = layer->mask_layer()) |
| 443 update_layer_list->push_back(mask_layer); | 440 update_layer_list->push_back(mask_layer); |
| 444 if (LayerType* replica_layer = layer->replica_layer()) { | 441 if (Layer* replica_layer = layer->replica_layer()) { |
| 445 if (LayerType* mask_layer = replica_layer->mask_layer()) | 442 if (Layer* mask_layer = replica_layer->mask_layer()) |
| 446 update_layer_list->push_back(mask_layer); | 443 update_layer_list->push_back(mask_layer); |
| 447 } | 444 } |
| 448 | 445 |
| 449 for (size_t i = 0; i < layer->children().size(); ++i) { | 446 for (size_t i = 0; i < layer->children().size(); ++i) { |
| 450 FindLayersThatNeedUpdates(layer->child_at(i), transform_tree, effect_tree, | 447 FindLayersThatNeedUpdates(layer->child_at(i), transform_tree, effect_tree, |
| 451 update_layer_list, visible_layer_list); | 448 update_layer_list, visible_layer_list); |
| 452 } | 449 } |
| 453 } | 450 } |
| 454 | 451 |
| 452 void FindLayersThatNeedUpdates(LayerImpl* layer, | |
| 453 const TransformTree& transform_tree, | |
| 454 const EffectTree& effect_tree, | |
| 455 LayerImplList* update_layer_list, | |
| 456 std::vector<LayerImpl*>* visible_layer_list) { | |
| 457 DCHECK_GE(layer->effect_tree_index(), 0); | |
| 458 for (auto* layer_impl : *layer->layer_tree_impl()) { | |
| 459 bool layer_is_drawn = | |
| 460 effect_tree.Node(layer->effect_tree_index())->data.is_drawn; | |
| 461 | |
| 462 if (layer_impl->parent() && | |
| 463 LayerShouldBeSkipped(layer_impl, layer_is_drawn, transform_tree)) | |
| 464 continue; | |
| 465 | |
| 466 if (LayerNeedsUpdate(layer_impl, layer_is_drawn, transform_tree)) { | |
| 467 visible_layer_list->push_back(layer_impl); | |
| 468 update_layer_list->push_back(layer_impl); | |
| 469 } | |
| 470 | |
| 471 if (LayerImpl* mask_layer = layer->mask_layer()) | |
| 472 update_layer_list->push_back(mask_layer); | |
| 473 if (LayerImpl* replica_layer = layer->replica_layer()) { | |
| 474 if (LayerImpl* mask_layer = replica_layer->mask_layer()) | |
| 475 update_layer_list->push_back(mask_layer); | |
| 476 } | |
| 477 } | |
| 478 } | |
| 479 | |
| 455 template <typename LayerType> | 480 template <typename LayerType> |
| 456 void UpdateRenderSurfaceForLayer(EffectTree* effect_tree, | 481 void UpdateRenderSurfaceForLayer(EffectTree* effect_tree, |
| 457 bool non_root_surfaces_enabled, | 482 bool non_root_surfaces_enabled, |
| 458 LayerType* layer) { | 483 LayerType* layer) { |
| 459 if (!non_root_surfaces_enabled) { | 484 if (!non_root_surfaces_enabled) { |
| 460 layer->SetHasRenderSurface(!layer->parent()); | 485 layer->SetHasRenderSurface(!layer->parent()); |
| 461 return; | 486 return; |
| 462 } | 487 } |
| 463 EffectNode* node = effect_tree->Node(layer->effect_tree_index()); | 488 EffectNode* node = effect_tree->Node(layer->effect_tree_index()); |
| 464 | 489 |
| (...skipping 655 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1120 void UpdateElasticOverscroll(PropertyTrees* property_trees, | 1145 void UpdateElasticOverscroll(PropertyTrees* property_trees, |
| 1121 const Layer* overscroll_elasticity_layer, | 1146 const Layer* overscroll_elasticity_layer, |
| 1122 const gfx::Vector2dF& elastic_overscroll) { | 1147 const gfx::Vector2dF& elastic_overscroll) { |
| 1123 UpdateElasticOverscrollInternal(property_trees, overscroll_elasticity_layer, | 1148 UpdateElasticOverscrollInternal(property_trees, overscroll_elasticity_layer, |
| 1124 elastic_overscroll); | 1149 elastic_overscroll); |
| 1125 } | 1150 } |
| 1126 | 1151 |
| 1127 } // namespace draw_property_utils | 1152 } // namespace draw_property_utils |
| 1128 | 1153 |
| 1129 } // namespace cc | 1154 } // namespace cc |
| OLD | NEW |