Chromium Code Reviews| Index: cc/trees/draw_property_utils.cc |
| diff --git a/cc/trees/draw_property_utils.cc b/cc/trees/draw_property_utils.cc |
| index 2be0874d95eb62853bcbc8f51c480b352dd3da51..77343a04bfc4b02716ef617afbc122c72285ab42 100644 |
| --- a/cc/trees/draw_property_utils.cc |
| +++ b/cc/trees/draw_property_utils.cc |
| @@ -175,6 +175,31 @@ static ConditionalClip ComputeTargetRectInLocalSpace( |
| MathUtil::ProjectClippedRect(target_to_local, rect)}; |
| } |
| +static ConditionalClip ComputeTargetRectInTargetSpace( |
|
weiliangc
2016/10/26 16:57:03
This functions seems more like "ConvertRectBetween
ajuma
2016/10/31 17:43:07
Done.
|
| + gfx::RectF rect, |
| + const PropertyTrees* property_trees, |
| + int source_transform_id, |
| + int source_effect_id, |
| + int dest_transform_id, |
| + int dest_effect_id) { |
| + gfx::Transform source_to_dest; |
| + bool success = property_trees->ComputeTransformToTarget( |
| + source_transform_id, dest_effect_id, &source_to_dest); |
| + if (!success) |
| + return ConditionalClip{false, gfx::RectF()}; |
| + const EffectTree& effect_tree = property_trees->effect_tree; |
| + const EffectNode* source_effect_node = effect_tree.Node(source_effect_id); |
| + const EffectNode* dest_effect_node = effect_tree.Node(dest_effect_id); |
| + ConcatInverseSurfaceContentsScale(source_effect_node, &source_to_dest); |
| + PostConcatSurfaceContentsScale(dest_effect_node, &source_to_dest); |
| + if (source_transform_id > dest_transform_id) { |
| + return ConditionalClip{true, // is_clipped |
| + MathUtil::MapClippedRect(source_to_dest, rect)}; |
| + } |
| + return ConditionalClip{true, // is_clipped |
| + MathUtil::ProjectClippedRect(source_to_dest, rect)}; |
| +} |
| + |
| static ConditionalClip ComputeLocalRectInTargetSpace( |
| gfx::RectF rect, |
| const PropertyTrees* property_trees, |
| @@ -227,6 +252,7 @@ static ConditionalClip ComputeCurrentClip(const ClipNode* clip_node, |
| static ConditionalClip ComputeAccumulatedClip( |
| const PropertyTrees* property_trees, |
| bool include_clip_applied_by_target, |
| + bool include_expanding_clips, |
|
weiliangc
2016/10/26 16:57:03
This seem to be not used?
ajuma
2016/10/31 17:43:07
Oops, I forgot to handle that case, thanks for cat
|
| int local_clip_id, |
| int target_id) { |
| const ClipTree& clip_tree = property_trees->clip_tree; |
| @@ -265,14 +291,14 @@ static ConditionalClip ComputeAccumulatedClip( |
| } |
| // TODO(weiliangc): If we don't create clip for render surface, we don't need |
| - // to check applies_local_clip. |
| - while (clip_node->clip_type != ClipNode::ClipType::APPLIES_LOCAL_CLIP && |
| + // to check clip_type. |
| + while (clip_node->clip_type == ClipNode::ClipType::NONE && |
|
ajuma
2016/10/31 17:43:07
I wasn't handling the case where the first clip in
|
| parent_chain.size() > 0) { |
| clip_node = parent_chain.top(); |
| parent_chain.pop(); |
| } |
| - if (clip_node->clip_type != ClipNode::ClipType::APPLIES_LOCAL_CLIP) |
| + if (clip_node->clip_type == ClipNode::ClipType::NONE) |
| // No clip node applying clip in between. |
| return ConditionalClip{false, gfx::RectF()}; |
| @@ -284,19 +310,55 @@ static ConditionalClip ComputeAccumulatedClip( |
| while (parent_chain.size() > 0) { |
| clip_node = parent_chain.top(); |
| parent_chain.pop(); |
| - if (clip_node->clip_type != ClipNode::ClipType::APPLIES_LOCAL_CLIP) { |
| - continue; |
| + switch (clip_node->clip_type) { |
|
weiliangc
2016/10/26 16:57:03
Nit: maybe make a helper function that applies cli
ajuma
2016/10/31 17:43:07
Done.
|
| + case ClipNode::ClipType::APPLIES_LOCAL_CLIP: { |
| + ConditionalClip current_clip = ComputeCurrentClip( |
| + clip_node, property_trees, target_transform_id, target_id); |
| + |
| + // If transform is not invertible, no clip will be applied. |
| + if (!current_clip.is_clipped) |
| + return ConditionalClip{false, gfx::RectF()}; |
| + |
| + is_clipped = true; |
| + accumulated_clip = |
| + gfx::IntersectRects(accumulated_clip, current_clip.clip_rect); |
| + break; |
| + } |
| + case ClipNode::ClipType::EXPANDS_CLIP: { |
| + // Bring the accumulated clip to the space of the expanding effect. |
| + const EffectNode* expanding_effect_node = |
| + effect_tree.Node(clip_node->clip_expander.target_effect_id()); |
| + ConditionalClip accumulated_clip_in_expanding_space = |
| + ComputeTargetRectInTargetSpace(accumulated_clip, property_trees, |
| + target_transform_id, target_id, |
| + expanding_effect_node->transform_id, |
| + expanding_effect_node->id); |
| + // If transform is not invertible, no clip will be applied. |
| + if (!accumulated_clip_in_expanding_space.is_clipped) |
| + return ConditionalClip{false, gfx::RectF()}; |
| + |
| + // Do the expansion. |
| + gfx::RectF expanded_clip_in_expanding_space = |
| + gfx::RectF(clip_node->clip_expander.MapRectReverse( |
| + gfx::ToEnclosingRect( |
| + accumulated_clip_in_expanding_space.clip_rect), |
| + property_trees)); |
| + |
| + // Put the expanded clip back into the original target space. |
| + ConditionalClip expanded_clip_in_target_space = |
| + ComputeTargetRectInTargetSpace( |
| + expanded_clip_in_expanding_space, property_trees, |
| + expanding_effect_node->transform_id, expanding_effect_node->id, |
| + target_transform_id, target_id); |
| + // If transform is not invertible, no clip will be applied. |
| + if (!expanded_clip_in_target_space.is_clipped) |
| + return ConditionalClip{false, gfx::RectF()}; |
| + accumulated_clip = expanded_clip_in_target_space.clip_rect; |
| + break; |
| + } |
| + case ClipNode::ClipType::NONE: |
| + break; |
| } |
| - ConditionalClip current_clip = ComputeCurrentClip( |
| - clip_node, property_trees, target_transform_id, target_id); |
| - |
| - // If transform is not invertible, no clip will be applied. |
| - if (!current_clip.is_clipped) |
| - return ConditionalClip{false, gfx::RectF()}; |
| - |
| - is_clipped = true; |
| - accumulated_clip = |
| - gfx::IntersectRects(accumulated_clip, current_clip.clip_rect); |
| } |
| return ConditionalClip{ |
| @@ -308,9 +370,10 @@ static gfx::RectF ComputeAccumulatedClipInRootSpaceForVisibleRect( |
| int local_clip_id) { |
| const int root_effect_id = EffectTree::kContentsRootNodeId; |
| bool include_clip_applied_by_target = true; |
| - ConditionalClip accumulated_clip = |
| - ComputeAccumulatedClip(property_trees, include_clip_applied_by_target, |
| - local_clip_id, root_effect_id); |
| + bool include_expanding_clips = true; |
| + ConditionalClip accumulated_clip = ComputeAccumulatedClip( |
| + property_trees, include_clip_applied_by_target, include_expanding_clips, |
| + local_clip_id, root_effect_id); |
| DCHECK(accumulated_clip.is_clipped); |
| return accumulated_clip.clip_rect; |
| } |
| @@ -382,9 +445,11 @@ void CalculateVisibleRects(const LayerImplList& visible_layer_list, |
| if (effect_ancestor_with_copy_request > 1) { |
| // Non root copy request. |
| bool include_clip_applied_by_target = false; |
| + bool include_expanding_clips = true; |
| ConditionalClip accumulated_clip_rect = ComputeAccumulatedClip( |
| property_trees, include_clip_applied_by_target, |
| - layer->clip_tree_index(), effect_ancestor_with_copy_request); |
| + include_expanding_clips, 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; |
| @@ -848,6 +913,12 @@ void ComputeClips(PropertyTrees* property_trees, |
| continue; |
| parent_combined_clip_in_target_space = MathUtil::ProjectClippedRect( |
| parent_to_current, parent_clip_node->combined_clip_in_target_space); |
| + if (clip_node->clip_type == ClipNode::ClipType::EXPANDS_CLIP) { |
| + parent_combined_clip_in_target_space = |
| + gfx::RectF(clip_node->clip_expander.MapRectReverse( |
| + gfx::ToEnclosingRect(parent_combined_clip_in_target_space), |
| + property_trees)); |
| + } |
| parent_clip_in_target_space = MathUtil::ProjectClippedRect( |
| parent_to_current, parent_clip_node->clip_in_target_space); |
| } |
| @@ -995,9 +1066,10 @@ static void ComputeClipsWithEffectTree(PropertyTrees* property_trees) { |
| EffectNode* effect_node = effect_tree->Node(i); |
| const EffectNode* target_node = effect_tree->Node(effect_node->target_id); |
| bool include_clip_applied_by_target = false; |
| - ConditionalClip accumulated_clip_rect = |
| - ComputeAccumulatedClip(property_trees, include_clip_applied_by_target, |
| - effect_node->clip_id, target_node->id); |
| + bool include_expanding_clips = false; |
| + ConditionalClip accumulated_clip_rect = ComputeAccumulatedClip( |
| + property_trees, include_clip_applied_by_target, include_expanding_clips, |
| + effect_node->clip_id, target_node->id); |
| gfx::RectF accumulated_clip = accumulated_clip_rect.clip_rect; |
| const RenderSurfaceImpl* render_surface = effect_node->render_surface; |
| if (render_surface && render_surface->is_clipped()) { |
| @@ -1027,9 +1099,10 @@ static void ComputeLayerClipRect(const PropertyTrees* property_trees, |
| } |
| bool include_clip_applied_by_target = false; |
| - ConditionalClip accumulated_clip_rect = |
| - ComputeAccumulatedClip(property_trees, include_clip_applied_by_target, |
| - layer->clip_tree_index(), target_node->id); |
| + bool include_expanding_clips = false; |
| + ConditionalClip accumulated_clip_rect = ComputeAccumulatedClip( |
| + property_trees, include_clip_applied_by_target, include_expanding_clips, |
| + layer->clip_tree_index(), target_node->id); |
| gfx::RectF accumulated_clip = accumulated_clip_rect.clip_rect; |
| @@ -1211,8 +1284,9 @@ gfx::Rect ComputeLayerVisibleRectDynamic(const PropertyTrees* property_trees, |
| gfx::RectF accumulated_clip_in_root_space; |
| if (non_root_copy_request) { |
| bool include_clip_applied_by_target = false; |
| + bool include_expanding_clips = true; |
| ConditionalClip accumulated_clip = ComputeAccumulatedClip( |
| - property_trees, include_clip_applied_by_target, |
| + property_trees, include_clip_applied_by_target, include_expanding_clips, |
| layer->clip_tree_index(), effect_ancestor_with_copy_request); |
| if (!accumulated_clip.is_clipped) |
| return layer_content_rect; |