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

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

Issue 1811423002: SubtreeShouldBeSkipped uses information from property trees (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Resolve comments 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 268 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698