Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(62)

Side by Side Diff: cc/trees/draw_property_utils.cc

Issue 1884613005: cc : Simplify layer skipping logic (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 264 matching lines...) Expand 10 before | Expand all | Expand 10 after
275 } 275 }
276 276
277 static inline bool TransformToScreenIsKnown(LayerImpl* layer, 277 static inline bool TransformToScreenIsKnown(LayerImpl* layer,
278 int transform_tree_index, 278 int transform_tree_index,
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 LayerNeedsUpdateInternal(LayerType* layer, 284 static bool LayerNeedsUpdateInternal(LayerType* layer,
285 bool layer_is_drawn,
286 const TransformTree& tree) { 285 const TransformTree& tree) {
287 // Layers can be skipped if any of these conditions are met. 286 // Layers can be skipped if any of these conditions are met.
288 // - is not drawn due to it or one of its ancestors being hidden (or having 287 // - is not drawn due to it or one of its ancestors being hidden (or having
289 // no copy requests). 288 // no copy requests).
290 // - does not draw content. 289 // - does not draw content.
291 // - is transparent. 290 // - is transparent.
292 // - has empty bounds 291 // - has empty bounds
293 // - the layer is not double-sided, but its back face is visible. 292 // - the layer is not double-sided, but its back face is visible.
294 // 293 //
295 // Some additional conditions need to be computed at a later point after the 294 // Some additional conditions need to be computed at a later point after the
296 // recursion is finished. 295 // recursion is finished.
297 // - the intersection of render_surface content and layer clip_rect is empty 296 // - the intersection of render_surface content and layer clip_rect is empty
298 // - the visible_layer_rect is empty 297 // - the visible_layer_rect is empty
299 // 298 //
300 // Note, if the layer should not have been drawn due to being fully 299 // Note, if the layer should not have been drawn due to being fully
301 // transparent, we would have skipped the entire subtree and never made it 300 // transparent, we would have skipped the entire subtree and never made it
302 // into this function, so it is safe to omit this check here. 301 // into this function, so it is safe to omit this check here.
303 if (!layer_is_drawn)
304 return false;
305
306 if (!layer->DrawsContent() || layer->bounds().IsEmpty()) 302 if (!layer->DrawsContent() || layer->bounds().IsEmpty())
307 return false; 303 return false;
308 304
309 // The layer should not be drawn if (1) it is not double-sided and (2) the 305 // The layer should not be drawn if (1) it is not double-sided and (2) the
310 // back of the layer is known to be facing the screen. 306 // back of the layer is known to be facing the screen.
311 if (layer->should_check_backface_visibility()) { 307 if (layer->should_check_backface_visibility()) {
312 int backface_transform_id = 308 int backface_transform_id =
313 TransformTreeIndexForBackfaceVisibility(layer, tree); 309 TransformTreeIndexForBackfaceVisibility(layer, tree);
314 // A layer with singular transform is not drawn. So, we can assume that its 310 // A layer with singular transform is not drawn. So, we can assume that its
315 // backface is not visible. 311 // backface is not visible.
316 if (TransformToScreenIsKnown(layer, backface_transform_id, tree) && 312 if (TransformToScreenIsKnown(layer, backface_transform_id, tree) &&
317 !HasSingularTransform(backface_transform_id, tree) && 313 !HasSingularTransform(backface_transform_id, tree) &&
318 IsLayerBackFaceVisible(layer, backface_transform_id, tree)) 314 IsLayerBackFaceVisible(layer, backface_transform_id, tree))
319 return false; 315 return false;
320 } 316 }
321 317
322 return true; 318 return true;
323 } 319 }
324 320
325 void FindLayersThatNeedUpdates(LayerTreeImpl* layer_tree_impl, 321 void FindLayersThatNeedUpdates(LayerTreeImpl* layer_tree_impl,
326 const TransformTree& transform_tree, 322 const TransformTree& transform_tree,
327 const EffectTree& effect_tree, 323 const EffectTree& effect_tree,
328 LayerImplList* update_layer_list, 324 LayerImplList* update_layer_list,
329 std::vector<LayerImpl*>* visible_layer_list) { 325 std::vector<LayerImpl*>* visible_layer_list) {
330 for (auto* layer_impl : *layer_tree_impl) { 326 for (auto* layer_impl : *layer_tree_impl) {
331 bool layer_is_drawn =
332 effect_tree.Node(layer_impl->effect_tree_index())->data.is_drawn;
333
334 if (!IsRootLayer(layer_impl) && 327 if (!IsRootLayer(layer_impl) &&
335 LayerShouldBeSkipped(layer_impl, layer_is_drawn, transform_tree, 328 LayerShouldBeSkipped(layer_impl, transform_tree, effect_tree))
336 effect_tree))
337 continue; 329 continue;
338 330
339 if (LayerNeedsUpdate(layer_impl, layer_is_drawn, transform_tree)) { 331 if (LayerNeedsUpdate(layer_impl, transform_tree)) {
340 visible_layer_list->push_back(layer_impl); 332 visible_layer_list->push_back(layer_impl);
341 update_layer_list->push_back(layer_impl); 333 update_layer_list->push_back(layer_impl);
342 } 334 }
343 335
344 if (LayerImpl* mask_layer = layer_impl->mask_layer()) 336 if (LayerImpl* mask_layer = layer_impl->mask_layer())
345 update_layer_list->push_back(mask_layer); 337 update_layer_list->push_back(mask_layer);
346 if (LayerImpl* replica_layer = layer_impl->replica_layer()) { 338 if (LayerImpl* replica_layer = layer_impl->replica_layer()) {
347 if (LayerImpl* mask_layer = replica_layer->mask_layer()) 339 if (LayerImpl* mask_layer = replica_layer->mask_layer())
348 update_layer_list->push_back(mask_layer); 340 update_layer_list->push_back(mask_layer);
349 } 341 }
(...skipping 21 matching lines...) Expand all
371 Layer* layer) { 363 Layer* layer) {
372 UpdateRenderSurfaceForLayer(effect_tree, true, layer); 364 UpdateRenderSurfaceForLayer(effect_tree, true, layer);
373 365
374 for (size_t i = 0; i < layer->children().size(); ++i) { 366 for (size_t i = 0; i < layer->children().size(); ++i) {
375 UpdateRenderSurfacesForLayersRecursive(effect_tree, layer->child_at(i)); 367 UpdateRenderSurfacesForLayersRecursive(effect_tree, layer->child_at(i));
376 } 368 }
377 } 369 }
378 370
379 } // namespace 371 } // namespace
380 372
381 static inline bool LayerShouldBeSkipped(Layer* layer, 373 template <typename LayerType>
382 bool layer_is_drawn, 374 static inline bool LayerShouldBeSkippedInternal(
383 const TransformTree& transform_tree, 375 LayerType* layer,
384 const EffectTree& effect_tree) { 376 const TransformTree& transform_tree,
377 const EffectTree& effect_tree) {
385 const TransformNode* transform_node = 378 const TransformNode* transform_node =
386 transform_tree.Node(layer->transform_tree_index()); 379 transform_tree.Node(layer->transform_tree_index());
387 const EffectNode* effect_node = effect_tree.Node(layer->effect_tree_index()); 380 const EffectNode* effect_node = effect_tree.Node(layer->effect_tree_index());
388 381
389 // If the layer transform is not invertible, it should not be drawn. 382 bool layer_is_drawn = effect_tree.property_trees()->is_active
390 if (!transform_node->data.node_and_ancestors_are_animated_or_invertible) 383 ? effect_node->data.is_drawn_on_active
391 return true; 384 : effect_node->data.is_drawn_on_main_and_pending;
392 385 // If the layer transform is not invertible, it should be skipped.
393 // When we need to do a readback/copy of a layer's output, we can not skip 386 // TODO(ajuma): Correctly process subtrees with singular transform for the
394 // it or any of its ancestors. 387 // case where we may animate to a non-singular transform and wish to
395 if (effect_node->data.num_copy_requests_in_subtree > 0) 388 // pre-raster.
396 return false; 389 return !transform_node->data.node_and_ancestors_are_animated_or_invertible ||
397 390 effect_node->data.hidden_by_backface_visibility || !layer_is_drawn;
398 // If the layer is not drawn, then skip it and its subtree.
399 if (!effect_node->data.is_drawn)
400 return true;
401
402 if (!transform_node->data.to_screen_is_potentially_animated &&
403 effect_node->data.hidden_by_backface_visibility)
404 return true;
405
406 // If layer has a background filter, don't skip the layer, even it the
407 // opacity is 0.
408 if (effect_node->data.node_or_ancestor_has_background_filters)
409 return false;
410
411 // If the opacity is being animated then the opacity on the main thread is
412 // unreliable (since the impl thread may be using a different opacity), so it
413 // should not be trusted.
414 // In particular, it should not cause the subtree to be skipped.
415 // Similarly, for layers that might animate opacity using an impl-only
416 // animation, their subtree should also not be skipped.
417 return !effect_node->data.screen_space_opacity &&
418 !effect_node->data.to_screen_opacity_is_animated;
419 } 391 }
420 392
421 bool LayerShouldBeSkipped(LayerImpl* layer, 393 bool LayerShouldBeSkipped(LayerImpl* layer,
422 bool layer_is_drawn,
423 const TransformTree& transform_tree, 394 const TransformTree& transform_tree,
424 const EffectTree& effect_tree) { 395 const EffectTree& effect_tree) {
425 const TransformNode* transform_node = 396 return LayerShouldBeSkippedInternal(layer, transform_tree, effect_tree);
426 transform_tree.Node(layer->transform_tree_index()); 397 }
427 const EffectNode* effect_node = effect_tree.Node(layer->effect_tree_index());
428 // If the layer transform is not invertible, it should not be drawn.
429 // TODO(ajuma): Correctly process subtrees with singular transform for the
430 // case where we may animate to a non-singular transform and wish to
431 // pre-raster.
432 if (!transform_node->data.node_and_ancestors_are_animated_or_invertible)
433 return true;
434 398
435 // When we need to do a readback/copy of a layer's output, we can not skip 399 bool LayerShouldBeSkipped(Layer* layer,
436 // it or any of its ancestors. 400 const TransformTree& transform_tree,
437 if (effect_node->data.num_copy_requests_in_subtree > 0) 401 const EffectTree& effect_tree) {
438 return false; 402 return LayerShouldBeSkippedInternal(layer, transform_tree, effect_tree);
439
440 // If the layer is not drawn, then skip it and its subtree.
441 if (!effect_node->data.is_drawn)
442 return true;
443
444 if (effect_node->data.hidden_by_backface_visibility)
445 return true;
446
447 // If layer is on the pending tree and opacity is being animated then
448 // this subtree can't be skipped as we need to create, prioritize and
449 // include tiles for this layer when deciding if tree can be activated.
450 if (!transform_tree.property_trees()->is_active &&
451 effect_node->data.to_screen_opacity_is_animated)
452 return false;
453
454 // If layer has a background filter, don't skip the layer, even it the
455 // opacity is 0.
456 if (effect_node->data.node_or_ancestor_has_background_filters)
457 return false;
458
459 // The opacity of a layer always applies to its children (either implicitly
460 // via a render surface or explicitly if the parent preserves 3D), so the
461 // entire subtree can be skipped if this layer is fully transparent.
462 return !effect_node->data.screen_space_opacity;
463 } 403 }
464 404
465 void FindLayersThatNeedUpdates(LayerTreeHost* layer_tree_host, 405 void FindLayersThatNeedUpdates(LayerTreeHost* layer_tree_host,
466 const TransformTree& transform_tree, 406 const TransformTree& transform_tree,
467 const EffectTree& effect_tree, 407 const EffectTree& effect_tree,
468 LayerList* update_layer_list) { 408 LayerList* update_layer_list) {
469 LayerTreeHostCommon::CallFunctionForEveryLayer( 409 LayerTreeHostCommon::CallFunctionForEveryLayer(
470 layer_tree_host, 410 layer_tree_host,
471 [&](Layer* layer) { 411 [&](Layer* layer) {
472 bool layer_is_drawn =
473 effect_tree.Node(layer->effect_tree_index())->data.is_drawn;
474
475 if (!IsRootLayer(layer) && 412 if (!IsRootLayer(layer) &&
476 LayerShouldBeSkipped(layer, layer_is_drawn, transform_tree, 413 LayerShouldBeSkipped(layer, transform_tree, effect_tree))
477 effect_tree))
478 return; 414 return;
479 415
480 if (LayerNeedsUpdate(layer, layer_is_drawn, transform_tree)) { 416 if (LayerNeedsUpdate(layer, transform_tree)) {
481 update_layer_list->push_back(layer); 417 update_layer_list->push_back(layer);
482 } 418 }
483 419
484 // Append mask layers to the update layer list. They don't have valid 420 // Append mask layers to the update layer list. They don't have valid
485 // visible rects, so need to get added after the above calculation. 421 // visible rects, so need to get added after the above calculation.
486 // Replica layers don't need to be updated. 422 // Replica layers don't need to be updated.
487 if (Layer* mask_layer = layer->mask_layer()) 423 if (Layer* mask_layer = layer->mask_layer())
488 update_layer_list->push_back(mask_layer); 424 update_layer_list->push_back(mask_layer);
489 if (Layer* replica_layer = layer->replica_layer()) { 425 if (Layer* replica_layer = layer->replica_layer()) {
490 if (Layer* mask_layer = replica_layer->mask_layer()) 426 if (Layer* mask_layer = replica_layer->mask_layer())
(...skipping 278 matching lines...) Expand 10 before | Expand all | Expand 10 after
769 ValidateRenderSurfaceForLayer(layer); 705 ValidateRenderSurfaceForLayer(layer);
770 #endif 706 #endif
771 } 707 }
772 LayerImplList update_layer_list; 708 LayerImplList update_layer_list;
773 ComputeVisibleRectsInternal(root_layer, property_trees, 709 ComputeVisibleRectsInternal(root_layer, property_trees,
774 can_render_to_separate_surface, 710 can_render_to_separate_surface,
775 &update_layer_list, visible_layer_list); 711 &update_layer_list, visible_layer_list);
776 } 712 }
777 713
778 bool LayerNeedsUpdate(Layer* layer, 714 bool LayerNeedsUpdate(Layer* layer,
779 bool layer_is_drawn,
780 const TransformTree& tree) { 715 const TransformTree& tree) {
781 return LayerNeedsUpdateInternal(layer, layer_is_drawn, tree); 716 return LayerNeedsUpdateInternal(layer, tree);
782 } 717 }
783 718
784 bool LayerNeedsUpdate(LayerImpl* layer, 719 bool LayerNeedsUpdate(LayerImpl* layer,
785 bool layer_is_drawn,
786 const TransformTree& tree) { 720 const TransformTree& tree) {
787 return LayerNeedsUpdateInternal(layer, layer_is_drawn, tree); 721 return LayerNeedsUpdateInternal(layer, tree);
788 } 722 }
789 723
790 gfx::Transform DrawTransform(const LayerImpl* layer, 724 gfx::Transform DrawTransform(const LayerImpl* layer,
791 const TransformTree& tree) { 725 const TransformTree& tree) {
792 const TransformNode* node = tree.Node(layer->transform_tree_index()); 726 const TransformNode* node = tree.Node(layer->transform_tree_index());
793 gfx::Transform xform; 727 gfx::Transform xform;
794 const bool owns_non_root_surface = 728 const bool owns_non_root_surface =
795 !IsRootLayer(layer) && layer->has_render_surface(); 729 !IsRootLayer(layer) && layer->has_render_surface();
796 if (!owns_non_root_surface) { 730 if (!owns_non_root_surface) {
797 // If you're not the root, or you don't own a surface, you need to apply 731 // If you're not the root, or you don't own a surface, you need to apply
(...skipping 360 matching lines...) Expand 10 before | Expand all | Expand 10 after
1158 void UpdateElasticOverscroll(PropertyTrees* property_trees, 1092 void UpdateElasticOverscroll(PropertyTrees* property_trees,
1159 const Layer* overscroll_elasticity_layer, 1093 const Layer* overscroll_elasticity_layer,
1160 const gfx::Vector2dF& elastic_overscroll) { 1094 const gfx::Vector2dF& elastic_overscroll) {
1161 UpdateElasticOverscrollInternal(property_trees, overscroll_elasticity_layer, 1095 UpdateElasticOverscrollInternal(property_trees, overscroll_elasticity_layer,
1162 elastic_overscroll); 1096 elastic_overscroll);
1163 } 1097 }
1164 1098
1165 } // namespace draw_property_utils 1099 } // namespace draw_property_utils
1166 1100
1167 } // namespace cc 1101 } // namespace cc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698