Index: cc/trees/draw_property_utils.cc |
diff --git a/cc/trees/draw_property_utils.cc b/cc/trees/draw_property_utils.cc |
index 877fee2e749ac8886246468b344f320ad2802641..718b97e196c24842c8105eda20e74c95784e8efc 100644 |
--- a/cc/trees/draw_property_utils.cc |
+++ b/cc/trees/draw_property_utils.cc |
@@ -95,14 +95,14 @@ bool ComputeClipRectInTargetSpace(const LayerType* layer, |
int target_node_id, |
gfx::RectF* clip_rect_in_target_space) { |
DCHECK(layer->clip_tree_index() == clip_node->id); |
- DCHECK(clip_node->data.target_id != target_node_id); |
+ DCHECK(clip_node->data.target_transform_id != target_node_id); |
gfx::Transform clip_to_target; |
- if (clip_node->data.target_id > target_node_id) { |
+ if (clip_node->data.target_transform_id > target_node_id) { |
// In this case, layer has a scroll parent. We need to keep the scale |
// at the layer's target but remove the scale at the scroll parent's |
// target. |
- if (transform_tree.ComputeTransform(clip_node->data.target_id, |
+ if (transform_tree.ComputeTransform(clip_node->data.target_transform_id, |
target_node_id, &clip_to_target)) { |
// We don't have to apply sublayer scale when target is root. |
if (target_node_id != 0) { |
@@ -115,7 +115,7 @@ bool ComputeClipRectInTargetSpace(const LayerType* layer, |
} |
const TransformNode* source_node = |
- transform_tree.Node(clip_node->data.target_id); |
+ transform_tree.Node(clip_node->data.target_transform_id); |
if (source_node->data.sublayer_scale.x() != 0.f && |
source_node->data.sublayer_scale.y() != 0.f) |
clip_to_target.Scale(1.0f / source_node->data.sublayer_scale.x(), |
@@ -126,7 +126,7 @@ bool ComputeClipRectInTargetSpace(const LayerType* layer, |
return false; |
} |
} else { |
- if (transform_tree.ComputeTransform(clip_node->data.target_id, |
+ if (transform_tree.ComputeTransform(clip_node->data.target_transform_id, |
target_node_id, &clip_to_target)) { |
*clip_rect_in_target_space = MathUtil::ProjectClippedRect( |
clip_to_target, clip_node->data.clip_in_target_space); |
@@ -164,13 +164,24 @@ static ConditionalClip ComputeTargetRectInLocalSpace( |
static ConditionalClip ComputeLocalRectInTargetSpace( |
gfx::RectF rect, |
const TransformTree& transform_tree, |
+ const EffectTree& effect_tree, |
int current_transform_id, |
- int target_transform_id) { |
+ int target_transform_id, |
+ int target_effect_id) { |
gfx::Transform current_to_target; |
- if (!transform_tree.ComputeTransformWithDestinationSublayerScale( |
- current_transform_id, target_transform_id, ¤t_to_target)) |
+ if (!transform_tree.ComputeTransform(current_transform_id, |
+ target_transform_id, ¤t_to_target)) |
// If transform is not invertible, cannot apply clip. |
return ConditionalClip{false, gfx::RectF()}; |
+ // We don't have to apply sublayer scale when target is root. |
+ if (target_transform_id != 0) { |
+ AddSublayerScaleToTransform(target_effect_id, effect_tree, |
+ ¤t_to_target); |
+#if DCHECK_IS_ON() |
+ VerifySublayerScalesMatch(target_effect_id, target_transform_id, |
+ effect_tree, transform_tree); |
+#endif |
+ } |
if (current_transform_id > target_transform_id) |
return ConditionalClip{true, // is_clipped. |
@@ -182,11 +193,13 @@ static ConditionalClip ComputeLocalRectInTargetSpace( |
static ConditionalClip ComputeCurrentClip(const ClipNode* clip_node, |
const TransformTree& transform_tree, |
- int target_transform_id) { |
+ const EffectTree& effect_tree, |
+ int target_transform_id, |
+ int target_effect_id) { |
if (clip_node->data.transform_id != target_transform_id) |
- return ComputeLocalRectInTargetSpace(clip_node->data.clip, transform_tree, |
- clip_node->data.transform_id, |
- target_transform_id); |
+ return ComputeLocalRectInTargetSpace( |
+ clip_node->data.clip, transform_tree, effect_tree, |
+ clip_node->data.transform_id, target_transform_id, target_effect_id); |
gfx::RectF current_clip = clip_node->data.clip; |
gfx::Vector2dF sublayer_scale = |
@@ -244,8 +257,8 @@ static ConditionalClip ComputeAccumulatedClip( |
// No clip node applying clip in between. |
return ConditionalClip{false, gfx::RectF()}; |
- ConditionalClip current_clip = |
- ComputeCurrentClip(clip_node, transform_tree, target_transform_id); |
+ ConditionalClip current_clip = ComputeCurrentClip( |
+ clip_node, transform_tree, effect_tree, target_transform_id, target_id); |
is_clipped = current_clip.is_clipped; |
gfx::RectF accumulated_clip = current_clip.clip_rect; |
@@ -255,8 +268,8 @@ static ConditionalClip ComputeAccumulatedClip( |
if (!clip_node->data.applies_local_clip) { |
continue; |
} |
- ConditionalClip current_clip = |
- ComputeCurrentClip(clip_node, transform_tree, target_transform_id); |
+ ConditionalClip current_clip = ComputeCurrentClip( |
+ clip_node, transform_tree, effect_tree, target_transform_id, target_id); |
// If transform is not invertible, no clip will be applied. |
if (!current_clip.is_clipped) |
@@ -302,7 +315,7 @@ void CalculateClipRects( |
// If required, this clip rect should be mapped to the current layer's |
// target space. |
- if (clip_node->data.target_id != target_node_id) { |
+ if (clip_node->data.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 |
@@ -434,7 +447,7 @@ void CalculateVisibleRects( |
// this clip rect should be mapped to the current layer's target space. |
gfx::RectF combined_clip_rect_in_target_space; |
- if (clip_node->data.target_id != target_node_id) { |
+ if (clip_node->data.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 |
@@ -706,6 +719,7 @@ static void ResetIfHasNanCoordinate(gfx::RectF* rect) { |
void ComputeClips(ClipTree* clip_tree, |
const TransformTree& transform_tree, |
+ const EffectTree& effect_tree, |
bool non_root_surfaces_enabled) { |
if (!clip_tree->needs_update()) |
return; |
@@ -724,7 +738,7 @@ void ComputeClips(ClipTree* clip_tree, |
gfx::Transform parent_to_current; |
const TransformNode* parent_target_transform_node = |
- transform_tree.Node(parent_clip_node->data.target_id); |
+ transform_tree.Node(parent_clip_node->data.target_transform_id); |
bool success = true; |
// Clips must be combined in target space. We cannot, for example, combine |
@@ -742,11 +756,22 @@ void ComputeClips(ClipTree* clip_tree, |
gfx::RectF parent_clip_in_target_space = |
parent_clip_node->data.clip_in_target_space; |
if (parent_target_transform_node && |
- parent_target_transform_node->id != clip_node->data.target_id && |
+ parent_target_transform_node->id != |
+ clip_node->data.target_transform_id && |
non_root_surfaces_enabled) { |
- success &= transform_tree.ComputeTransformWithDestinationSublayerScale( |
- parent_target_transform_node->id, clip_node->data.target_id, |
+ success &= transform_tree.ComputeTransform( |
+ parent_target_transform_node->id, clip_node->data.target_transform_id, |
&parent_to_current); |
+ // We don't have to apply sublayer scale when target is root. |
+ if (clip_node->data.target_transform_id != 0) { |
+ AddSublayerScaleToTransform(clip_node->data.target_effect_id, |
+ effect_tree, &parent_to_current); |
+#if DCHECK_IS_ON() |
+ VerifySublayerScalesMatch(clip_node->data.target_effect_id, |
+ clip_node->data.target_transform_id, |
+ effect_tree, transform_tree); |
+#endif |
+ } |
if (parent_target_transform_node->data.sublayer_scale.x() > 0 && |
parent_target_transform_node->data.sublayer_scale.y() > 0) |
parent_to_current.Scale( |
@@ -808,12 +833,23 @@ void ComputeClips(ClipTree* clip_tree, |
source_to_target = |
transform_tree.ToScreen(clip_node->data.transform_id); |
} else if (transform_tree.ContentTargetId(transform_node->id) == |
- clip_node->data.target_id) { |
+ clip_node->data.target_transform_id) { |
source_to_target = |
transform_tree.ToTarget(clip_node->data.transform_id); |
} else { |
- success = transform_tree.ComputeTransformWithDestinationSublayerScale( |
- transform_node->id, clip_node->data.target_id, &source_to_target); |
+ success = transform_tree.ComputeTransform( |
+ transform_node->id, clip_node->data.target_transform_id, |
+ &source_to_target); |
+ // We don't have to apply sublayer scale when target is root. |
+ if (clip_node->data.target_transform_id != 0) { |
+ AddSublayerScaleToTransform(clip_node->data.target_effect_id, |
+ effect_tree, &source_to_target); |
+#if DCHECK_IS_ON() |
+ VerifySublayerScalesMatch(clip_node->data.target_effect_id, |
+ clip_node->data.target_transform_id, |
+ effect_tree, transform_tree); |
+#endif |
+ } |
// source_to_target computation should be successful as target is an |
// ancestor of the transform node. |
DCHECK(success); |
@@ -1008,9 +1044,11 @@ static void ComputeVisibleRectsInternal( |
UpdateRenderTarget(&property_trees->effect_tree, |
property_trees->non_root_surfaces_enabled); |
ComputeTransforms(&property_trees->transform_tree); |
- ComputeClips(&property_trees->clip_tree, property_trees->transform_tree, |
- can_render_to_separate_surface); |
+ // Computation of clips uses sublayer scale which is updated while computing |
+ // effects. So, ComputeEffects should be before ComputeClips. |
ComputeEffects(&property_trees->effect_tree); |
+ ComputeClips(&property_trees->clip_tree, property_trees->transform_tree, |
+ property_trees->effect_tree, can_render_to_separate_surface); |
FindLayersThatNeedUpdates(root_layer->layer_tree_impl(), |
property_trees->transform_tree, |
@@ -1037,9 +1075,11 @@ void UpdatePropertyTrees(PropertyTrees* property_trees, |
property_trees->effect_tree.set_needs_update(true); |
} |
ComputeTransforms(&property_trees->transform_tree); |
- ComputeClips(&property_trees->clip_tree, property_trees->transform_tree, |
- can_render_to_separate_surface); |
+ // Computation of clips uses sublayer scale which is updated while computing |
+ // effects. So, ComputeEffects should be before ComputeClips. |
ComputeEffects(&property_trees->effect_tree); |
+ ComputeClips(&property_trees->clip_tree, property_trees->transform_tree, |
+ property_trees->effect_tree, can_render_to_separate_surface); |
} |
void ComputeVisibleRectsForTesting(PropertyTrees* property_trees, |
@@ -1191,6 +1231,7 @@ static void SetSurfaceIsClipped(const ClipNode* clip_node, |
static void SetSurfaceClipRect(const ClipNode* parent_clip_node, |
const TransformTree& transform_tree, |
+ const EffectTree& effect_tree, |
RenderSurfaceImpl* render_surface) { |
if (!render_surface->is_clipped()) { |
render_surface->SetClipRect(gfx::Rect()); |
@@ -1200,7 +1241,7 @@ static void SetSurfaceClipRect(const ClipNode* parent_clip_node, |
const TransformNode* transform_node = |
transform_tree.Node(render_surface->TransformTreeIndex()); |
if (transform_tree.TargetId(transform_node->id) == |
- parent_clip_node->data.target_id) { |
+ parent_clip_node->data.target_transform_id) { |
render_surface->SetClipRect( |
gfx::ToEnclosingRect(parent_clip_node->data.clip_in_target_space)); |
return; |
@@ -1210,18 +1251,28 @@ static void SetSurfaceClipRect(const ClipNode* parent_clip_node, |
// the parent clip node's clip rect is in clip parent's target space and not |
// our target space. We need to transform it to our target space. |
gfx::Transform clip_parent_target_to_target; |
- const bool success = |
- transform_tree.ComputeTransformWithDestinationSublayerScale( |
- parent_clip_node->data.target_id, |
- transform_tree.TargetId(transform_node->id), |
- &clip_parent_target_to_target); |
+ const bool success = transform_tree.ComputeTransform( |
+ parent_clip_node->data.target_transform_id, |
+ transform_tree.TargetId(transform_node->id), |
+ &clip_parent_target_to_target); |
if (!success) { |
render_surface->SetClipRect(gfx::Rect()); |
return; |
} |
- DCHECK_LT(parent_clip_node->data.target_id, |
+ // We don't have to apply sublayer scale when target is root. |
+ if (transform_tree.TargetId(transform_node->id) != 0) { |
+ AddSublayerScaleToTransform(render_surface->EffectTreeIndex(), effect_tree, |
+ &clip_parent_target_to_target); |
+#if DCHECK_IS_ON() |
+ VerifySublayerScalesMatch(render_surface->EffectTreeIndex(), |
+ transform_tree.TargetId(transform_node->id), |
+ effect_tree, transform_tree); |
+#endif |
+ } |
+ |
+ DCHECK_LT(parent_clip_node->data.target_transform_id, |
transform_tree.TargetId(transform_node->id)); |
render_surface->SetClipRect(gfx::ToEnclosingRect(MathUtil::ProjectClippedRect( |
clip_parent_target_to_target, |
@@ -1390,7 +1441,8 @@ void ComputeSurfaceDrawProperties(const PropertyTrees* property_trees, |
} |
SetSurfaceClipRect(property_trees->clip_tree.parent(clip_node), |
- property_trees->transform_tree, render_surface); |
+ property_trees->transform_tree, |
+ property_trees->effect_tree, render_surface); |
} |
#if DCHECK_IS_ON() |