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

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 (effect_node->data.hidden_by_backface_visibility)
318 IsSurfaceBackFaceVisible(layer, tree))
319 return true; 317 return true;
320 318
321 // If layer is on the pending tree and opacity is being animated then 319 // 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 320 // 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. 321 // include tiles for this layer when deciding if tree can be activated.
324 if (layer->layer_tree_impl()->IsPendingTree() && 322 if (!transform_tree.property_trees()->is_active &&
325 layer->HasPotentiallyRunningOpacityAnimation()) 323 effect_node->data.to_screen_opacity_is_animated)
326 return false; 324 return false;
327 325
328 // If layer has a background filter, don't skip the layer, even it the 326 // If layer has a background filter, don't skip the layer, even it the
329 // opacity is 0. 327 // opacity is 0.
330 if (!layer->background_filters().IsEmpty()) 328 if (effect_node->data.node_or_ancestor_has_background_filters)
331 return false; 329 return false;
332 330
333 // The opacity of a layer always applies to its children (either implicitly 331 // 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 332 // 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. 333 // entire subtree can be skipped if this layer is fully transparent.
336 return !layer->EffectiveOpacity(); 334 return !effect_node->data.screen_space_opacity;
337 } 335 }
338 336
339 static inline bool SubtreeShouldBeSkipped(Layer* layer, 337 static inline bool SubtreeShouldBeSkipped(Layer* layer,
340 bool layer_is_drawn, 338 bool layer_is_drawn,
341 const TransformTree& tree) { 339 const TransformTree& tree) {
342 // If the layer transform is not invertible, it should not be drawn. 340 // If the layer transform is not invertible, it should not be drawn.
343 if (!layer->transform_is_invertible() && 341 if (!layer->transform_is_invertible() &&
344 !layer->HasPotentiallyRunningTransformAnimation()) 342 !layer->HasPotentiallyRunningTransformAnimation())
345 return true; 343 return true;
346 344
(...skipping 21 matching lines...) Expand all
368 // should not be trusted. 366 // should not be trusted.
369 // In particular, it should not cause the subtree to be skipped. 367 // In particular, it should not cause the subtree to be skipped.
370 // Similarly, for layers that might animate opacity using an impl-only 368 // Similarly, for layers that might animate opacity using an impl-only
371 // animation, their subtree should also not be skipped. 369 // animation, their subtree should also not be skipped.
372 return !layer->EffectiveOpacity() && 370 return !layer->EffectiveOpacity() &&
373 !layer->HasPotentiallyRunningOpacityAnimation() && 371 !layer->HasPotentiallyRunningOpacityAnimation() &&
374 !layer->OpacityCanAnimateOnImplThread(); 372 !layer->OpacityCanAnimateOnImplThread();
375 } 373 }
376 374
377 template <typename LayerType> 375 template <typename LayerType>
378 static bool LayerShouldBeSkipped(LayerType* layer, 376 static bool LayerNeedsUpdate(LayerType* layer,
379 bool layer_is_drawn, 377 bool layer_is_drawn,
380 const TransformTree& tree) { 378 const TransformTree& tree) {
381 // Layers can be skipped if any of these conditions are met. 379 // 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 380 // - is not drawn due to it or one of its ancestors being hidden (or having
383 // no copy requests). 381 // no copy requests).
384 // - does not draw content. 382 // - does not draw content.
385 // - is transparent. 383 // - is transparent.
386 // - has empty bounds 384 // - has empty bounds
387 // - the layer is not double-sided, but its back face is visible. 385 // - the layer is not double-sided, but its back face is visible.
388 // 386 //
389 // Some additional conditions need to be computed at a later point after the 387 // Some additional conditions need to be computed at a later point after the
390 // recursion is finished. 388 // recursion is finished.
391 // - the intersection of render_surface content and layer clip_rect is empty 389 // - the intersection of render_surface content and layer clip_rect is empty
392 // - the visible_layer_rect is empty 390 // - the visible_layer_rect is empty
393 // 391 //
394 // Note, if the layer should not have been drawn due to being fully 392 // 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 393 // 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. 394 // into this function, so it is safe to omit this check here.
397 if (!layer_is_drawn) 395 if (!layer_is_drawn)
398 return true; 396 return false;
399 397
400 if (!layer->DrawsContent() || layer->bounds().IsEmpty()) 398 if (!layer->DrawsContent() || layer->bounds().IsEmpty())
401 return true; 399 return false;
402 400
403 // The layer should not be drawn if (1) it is not double-sided and (2) the 401 // 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. 402 // back of the layer is known to be facing the screen.
405 if (layer->should_check_backface_visibility()) { 403 if (layer->should_check_backface_visibility()) {
406 int backface_transform_id = 404 int backface_transform_id =
407 TransformTreeIndexForBackfaceVisibility(layer, tree); 405 TransformTreeIndexForBackfaceVisibility(layer, tree);
408 // A layer with singular transform is not drawn. So, we can assume that its 406 // A layer with singular transform is not drawn. So, we can assume that its
409 // backface is not visible. 407 // backface is not visible.
410 if (TransformToScreenIsKnown(layer, backface_transform_id, tree) && 408 if (TransformToScreenIsKnown(layer, backface_transform_id, tree) &&
411 !HasSingularTransform(backface_transform_id, tree) && 409 !HasSingularTransform(backface_transform_id, tree) &&
412 IsLayerBackFaceVisible(layer, backface_transform_id, tree)) 410 IsLayerBackFaceVisible(layer, backface_transform_id, tree))
413 return true; 411 return false;
414 } 412 }
415 413
416 return false; 414 return true;
417 } 415 }
418 416
419 template <typename LayerType> 417 void FindLayersThatNeedUpdates(Layer* layer,
420 void FindLayersThatNeedUpdates( 418 const TransformTree& transform_tree,
421 LayerType* layer, 419 const EffectTree& effect_tree,
422 const TransformTree& transform_tree, 420 LayerList* update_layer_list,
423 const EffectTree& effect_tree, 421 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); 422 DCHECK_GE(layer->effect_tree_index(), 0);
427 bool layer_is_drawn = 423 bool layer_is_drawn =
428 effect_tree.Node(layer->effect_tree_index())->data.is_drawn; 424 effect_tree.Node(layer->effect_tree_index())->data.is_drawn;
429 425
430 if (layer->parent() && 426 if (layer->parent() &&
431 SubtreeShouldBeSkipped(layer, layer_is_drawn, transform_tree)) 427 SubtreeShouldBeSkipped(layer, layer_is_drawn, transform_tree))
432 return; 428 return;
433 429
434 if (!LayerShouldBeSkipped(layer, layer_is_drawn, transform_tree)) { 430 if (LayerNeedsUpdate(layer, layer_is_drawn, transform_tree)) {
435 visible_layer_list->push_back(layer); 431 visible_layer_list->push_back(layer);
436 update_layer_list->push_back(layer); 432 update_layer_list->push_back(layer);
437 } 433 }
438 434
439 // Append mask layers to the update layer list. They don't have valid visible 435 // 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 436 // rects, so need to get added after the above calculation. Replica layers
441 // don't need to be updated. 437 // don't need to be updated.
442 if (LayerType* mask_layer = layer->mask_layer()) 438 if (Layer* mask_layer = layer->mask_layer())
443 update_layer_list->push_back(mask_layer); 439 update_layer_list->push_back(mask_layer);
444 if (LayerType* replica_layer = layer->replica_layer()) { 440 if (Layer* replica_layer = layer->replica_layer()) {
445 if (LayerType* mask_layer = replica_layer->mask_layer()) 441 if (Layer* mask_layer = replica_layer->mask_layer())
446 update_layer_list->push_back(mask_layer); 442 update_layer_list->push_back(mask_layer);
447 } 443 }
448 444
449 for (size_t i = 0; i < layer->children().size(); ++i) { 445 for (size_t i = 0; i < layer->children().size(); ++i) {
450 FindLayersThatNeedUpdates(layer->child_at(i), transform_tree, effect_tree, 446 FindLayersThatNeedUpdates(layer->child_at(i), transform_tree, effect_tree,
451 update_layer_list, visible_layer_list); 447 update_layer_list, visible_layer_list);
452 } 448 }
453 } 449 }
454 450
451 void FindLayersThatNeedUpdates(LayerImpl* layer,
452 const TransformTree& transform_tree,
453 const EffectTree& effect_tree,
454 LayerImplList* update_layer_list,
455 std::vector<LayerImpl*>* visible_layer_list) {
456 DCHECK_GE(layer->effect_tree_index(), 0);
457 for (auto* layer_impl : *layer->layer_tree_impl()) {
458 bool layer_is_drawn =
459 effect_tree.Node(layer->effect_tree_index())->data.is_drawn;
460
461 if (layer_impl->parent() &&
462 LayerShouldBeSkipped(layer_impl, layer_is_drawn, transform_tree))
463 continue;
464
465 if (LayerNeedsUpdate(layer_impl, layer_is_drawn, transform_tree)) {
466 visible_layer_list->push_back(layer_impl);
467 update_layer_list->push_back(layer_impl);
468 }
469
470 if (LayerImpl* mask_layer = layer->mask_layer())
471 update_layer_list->push_back(mask_layer);
472 if (LayerImpl* replica_layer = layer->replica_layer()) {
473 if (LayerImpl* mask_layer = replica_layer->mask_layer())
474 update_layer_list->push_back(mask_layer);
475 }
476 }
477 }
478
455 template <typename LayerType> 479 template <typename LayerType>
456 void UpdateRenderSurfaceForLayer(EffectTree* effect_tree, 480 void UpdateRenderSurfaceForLayer(EffectTree* effect_tree,
457 bool non_root_surfaces_enabled, 481 bool non_root_surfaces_enabled,
458 LayerType* layer) { 482 LayerType* layer) {
459 if (!non_root_surfaces_enabled) { 483 if (!non_root_surfaces_enabled) {
460 layer->SetHasRenderSurface(!layer->parent()); 484 layer->SetHasRenderSurface(!layer->parent());
461 return; 485 return;
462 } 486 }
463 EffectNode* node = effect_tree->Node(layer->effect_tree_index()); 487 EffectNode* node = effect_tree->Node(layer->effect_tree_index());
464 488
(...skipping 655 matching lines...) Expand 10 before | Expand all | Expand 10 after
1120 void UpdateElasticOverscroll(PropertyTrees* property_trees, 1144 void UpdateElasticOverscroll(PropertyTrees* property_trees,
1121 const Layer* overscroll_elasticity_layer, 1145 const Layer* overscroll_elasticity_layer,
1122 const gfx::Vector2dF& elastic_overscroll) { 1146 const gfx::Vector2dF& elastic_overscroll) {
1123 UpdateElasticOverscrollInternal(property_trees, overscroll_elasticity_layer, 1147 UpdateElasticOverscrollInternal(property_trees, overscroll_elasticity_layer,
1124 elastic_overscroll); 1148 elastic_overscroll);
1125 } 1149 }
1126 1150
1127 } // namespace draw_property_utils 1151 } // namespace draw_property_utils
1128 1152
1129 } // namespace cc 1153 } // namespace cc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698