| Index: cc/trees/draw_property_utils.cc
|
| diff --git a/cc/trees/draw_property_utils.cc b/cc/trees/draw_property_utils.cc
|
| index a9b6f3d9114204ddd4e546070a07f6bb0dba34f0..3faf8e7676f90ac19fd3eca4cecdef11a49d9868 100644
|
| --- a/cc/trees/draw_property_utils.cc
|
| +++ b/cc/trees/draw_property_utils.cc
|
| @@ -350,189 +350,47 @@ void CalculateClipRects(
|
| }
|
| }
|
|
|
| -bool GetLayerClipRect(const LayerImpl* layer,
|
| - const ClipNode* clip_node,
|
| - const PropertyTrees* property_trees,
|
| - int target_node_id,
|
| - gfx::RectF* clip_rect_in_target_space) {
|
| - // This is equivalent of calling ComputeClipRectInTargetSpace.
|
| - *clip_rect_in_target_space = gfx::RectF(layer->clip_rect());
|
| - return property_trees->transform_tree.Node(target_node_id)
|
| - ->ancestors_are_invertible;
|
| -}
|
| -
|
| void CalculateVisibleRects(const LayerImplList& visible_layer_list,
|
| const PropertyTrees* property_trees,
|
| bool non_root_surfaces_enabled) {
|
| const EffectTree& effect_tree = property_trees->effect_tree;
|
| - const TransformTree& transform_tree = property_trees->transform_tree;
|
| - const ClipTree& clip_tree = property_trees->clip_tree;
|
| for (auto& layer : visible_layer_list) {
|
| gfx::Size layer_bounds = layer->bounds();
|
|
|
| + int root_effect_space = EffectTree::kContentsRootNodeId;
|
| +
|
| int effect_ancestor_with_copy_request =
|
| effect_tree.ClosestAncestorWithCopyRequest(layer->effect_tree_index());
|
| - if (effect_ancestor_with_copy_request > 1) {
|
| - // Non root copy request.
|
| - ConditionalClip accumulated_clip_rect =
|
| - ComputeAccumulatedClip(property_trees, layer->clip_tree_index(),
|
| - effect_ancestor_with_copy_request);
|
| - if (!accumulated_clip_rect.is_clipped) {
|
| - layer->set_visible_layer_rect(gfx::Rect(layer_bounds));
|
| - continue;
|
| - }
|
| -
|
| - gfx::RectF accumulated_clip_in_copy_request_space =
|
| - accumulated_clip_rect.clip_rect;
|
| -
|
| - const EffectNode* copy_request_effect_node =
|
| - effect_tree.Node(effect_ancestor_with_copy_request);
|
| - ConditionalClip clip_in_layer_space = ComputeTargetRectInLocalSpace(
|
| - accumulated_clip_in_copy_request_space, property_trees,
|
| - copy_request_effect_node->transform_id, layer->transform_tree_index(),
|
| - copy_request_effect_node->id);
|
| -
|
| - if (clip_in_layer_space.is_clipped) {
|
| - gfx::RectF clip_rect = clip_in_layer_space.clip_rect;
|
| - clip_rect.Offset(-layer->offset_to_transform_parent());
|
| - gfx::Rect visible_rect = gfx::ToEnclosingRect(clip_rect);
|
| - visible_rect.Intersect(gfx::Rect(layer_bounds));
|
| - layer->set_visible_layer_rect(visible_rect);
|
| - } else {
|
| - layer->set_visible_layer_rect(gfx::Rect(layer_bounds));
|
| - }
|
| - continue;
|
| - }
|
| -
|
| - const ClipNode* clip_node = clip_tree.Node(layer->clip_tree_index());
|
| - const TransformNode* transform_node =
|
| - transform_tree.Node(layer->transform_tree_index());
|
| - if (!non_root_surfaces_enabled) {
|
| - // When we only have a root surface, the clip node and the layer must
|
| - // necessarily have the same target (the root).
|
| - if (transform_node->ancestors_are_invertible) {
|
| - gfx::RectF combined_clip_rect_in_target_space =
|
| - clip_node->combined_clip_in_target_space;
|
| - gfx::Transform target_to_content;
|
| - target_to_content.Translate(-layer->offset_to_transform_parent().x(),
|
| - -layer->offset_to_transform_parent().y());
|
| - target_to_content.PreconcatTransform(
|
| - transform_tree.FromScreen(transform_node->id));
|
| -
|
| - gfx::Rect visible_rect =
|
| - gfx::ToEnclosingRect(MathUtil::ProjectClippedRect(
|
| - target_to_content, combined_clip_rect_in_target_space));
|
| - visible_rect.Intersect(gfx::Rect(layer_bounds));
|
| - layer->set_visible_layer_rect(visible_rect);
|
| - } else {
|
| - layer->set_visible_layer_rect(gfx::Rect(layer_bounds));
|
| - }
|
| - continue;
|
| - }
|
| -
|
| - // When both the layer and the target are unclipped, the entire layer
|
| - // content rect is visible.
|
| - const bool fully_visible =
|
| - !clip_node->layers_are_clipped && !clip_node->target_is_clipped;
|
| -
|
| - if (fully_visible) {
|
| + // If there is copy request, regard copy request as the "root space".
|
| + if (effect_ancestor_with_copy_request > 0)
|
| + root_effect_space = effect_ancestor_with_copy_request;
|
| +
|
| + // Accumulates all clips appied to layer in "root space".
|
| + ConditionalClip accumulated_clip_rect = ComputeAccumulatedClip(
|
| + property_trees, layer->clip_tree_index(), root_effect_space);
|
| + if (!accumulated_clip_rect.is_clipped) {
|
| layer->set_visible_layer_rect(gfx::Rect(layer_bounds));
|
| continue;
|
| }
|
|
|
| - int target_node_id = transform_tree.ContentTargetId(transform_node->id);
|
| -
|
| - // The clip node stores clip rect in its target space. If required,
|
| - // this clip rect should be mapped to the current layer's target space.
|
| - gfx::RectF combined_clip_rect_in_target_space;
|
| -
|
| - if (clip_node->target_transform_id != target_node_id) {
|
| - // In this case, layer has a clip parent or scroll parent (or shares the
|
| - // target with an ancestor layer that has clip parent) and the clip
|
| - // parent's target is different from the layer's target. As the layer's
|
| - // target has unclippped descendants, it is unclippped.
|
| - if (!clip_node->layers_are_clipped) {
|
| - layer->set_visible_layer_rect(gfx::Rect(layer_bounds));
|
| - continue;
|
| - }
|
| -
|
| - // We use the clip node's clip_in_target_space (and not
|
| - // combined_clip_in_target_space) here because we want to clip
|
| - // with respect to clip parent's local clip and not its combined clip as
|
| - // the combined clip has even the clip parent's target's clip baked into
|
| - // it and as our target is different, we don't want to use it in our
|
| - // visible rect computation.
|
| - if (!GetLayerClipRect(layer, clip_node, property_trees, target_node_id,
|
| - &combined_clip_rect_in_target_space)) {
|
| - layer->set_visible_layer_rect(gfx::Rect(layer_bounds));
|
| - continue;
|
| - }
|
| + gfx::RectF accumulated_clip_in_root_space = accumulated_clip_rect.clip_rect;
|
| +
|
| + // Convert accumulated clip into layer space.
|
| + const EffectNode* root_effect_node = effect_tree.Node(root_effect_space);
|
| + ConditionalClip clip_in_layer_space = ComputeTargetRectInLocalSpace(
|
| + accumulated_clip_in_root_space, property_trees,
|
| + root_effect_node->transform_id, layer->transform_tree_index(),
|
| + root_effect_node->id);
|
| +
|
| + if (clip_in_layer_space.is_clipped) {
|
| + gfx::RectF clip_rect = clip_in_layer_space.clip_rect;
|
| + clip_rect.Offset(-layer->offset_to_transform_parent());
|
| + gfx::Rect visible_rect = gfx::ToEnclosingRect(clip_rect);
|
| + visible_rect.Intersect(gfx::Rect(layer_bounds));
|
| + layer->set_visible_layer_rect(visible_rect);
|
| } else {
|
| - if (clip_node->target_is_clipped) {
|
| - combined_clip_rect_in_target_space =
|
| - clip_node->combined_clip_in_target_space;
|
| - } else {
|
| - combined_clip_rect_in_target_space = clip_node->clip_in_target_space;
|
| - }
|
| - }
|
| -
|
| - // The clip rect should be intersected with layer rect in target space.
|
| - gfx::Transform content_to_target = transform_tree.ToTarget(
|
| - transform_node->id, layer->render_target_effect_tree_index());
|
| - content_to_target.Translate(layer->offset_to_transform_parent().x(),
|
| - layer->offset_to_transform_parent().y());
|
| - gfx::Rect layer_content_rect = gfx::Rect(layer_bounds);
|
| - gfx::RectF layer_content_bounds_in_target_space = MathUtil::MapClippedRect(
|
| - content_to_target, gfx::RectF(layer_content_rect));
|
| - // If the layer is fully contained within the clip, treat it as fully
|
| - // visible.
|
| - if (!layer_content_bounds_in_target_space.IsEmpty() &&
|
| - combined_clip_rect_in_target_space.Contains(
|
| - layer_content_bounds_in_target_space)) {
|
| layer->set_visible_layer_rect(gfx::Rect(layer_bounds));
|
| - continue;
|
| - }
|
| -
|
| - combined_clip_rect_in_target_space.Intersect(
|
| - layer_content_bounds_in_target_space);
|
| - if (combined_clip_rect_in_target_space.IsEmpty()) {
|
| - layer->set_visible_layer_rect(gfx::Rect());
|
| - continue;
|
| - }
|
| -
|
| - gfx::Transform target_to_layer;
|
| - if (transform_node->ancestors_are_invertible) {
|
| - target_to_layer = transform_tree.FromTarget(
|
| - transform_node->id, layer->render_target_effect_tree_index());
|
| - } else {
|
| - const EffectNode* target_effect_node =
|
| - ContentsTargetEffectNode(layer->effect_tree_index(), effect_tree);
|
| - bool success = property_trees->ComputeTransformFromTarget(
|
| - transform_node->id, target_effect_node->id, &target_to_layer);
|
| - if (!success) {
|
| - // An animated singular transform may become non-singular during the
|
| - // animation, so we still need to compute a visible rect. In this
|
| - // situation, we treat the entire layer as visible.
|
| - layer->set_visible_layer_rect(gfx::Rect(layer_bounds));
|
| - continue;
|
| - }
|
| - if (target_effect_node->id > EffectTree::kContentsRootNodeId) {
|
| - ConcatInverseSurfaceContentsScale(target_effect_node, &target_to_layer);
|
| -#if DCHECK_IS_ON()
|
| - VerifySurfaceContentsScalesMatch(target_effect_node->id, target_node_id,
|
| - effect_tree, transform_tree);
|
| -#endif
|
| - }
|
| }
|
| - gfx::Transform target_to_content;
|
| - target_to_content.Translate(-layer->offset_to_transform_parent().x(),
|
| - -layer->offset_to_transform_parent().y());
|
| - target_to_content.PreconcatTransform(target_to_layer);
|
| -
|
| - gfx::Rect visible_rect = gfx::ToEnclosingRect(MathUtil::ProjectClippedRect(
|
| - target_to_content, combined_clip_rect_in_target_space));
|
| - visible_rect.Intersect(gfx::Rect(layer_bounds));
|
| - layer->set_visible_layer_rect(visible_rect);
|
| }
|
| }
|
|
|
|
|