Index: cc/trees/property_tree.cc |
diff --git a/cc/trees/property_tree.cc b/cc/trees/property_tree.cc |
index 00a0025a3a2f29b145520de41f0eb6910fc56faa..4f2c950bf333125e0f3a0e44fd03ab079242d0e8 100644 |
--- a/cc/trees/property_tree.cc |
+++ b/cc/trees/property_tree.cc |
@@ -415,11 +415,14 @@ gfx::Vector2dF StickyPositionOffset(TransformTree* tree, TransformNode* node) { |
tree->property_trees()->scroll_tree.current_scroll_offset( |
scroll_node->owner_id); |
gfx::PointF scroll_position(scroll_offset.x(), scroll_offset.y()); |
- // The scroll position does not include snapping which shifts the scroll |
- // offset to align to a pixel boundary, we need to manually include it here. |
- scroll_position -= tree->property_trees() |
- ->transform_tree.Node(scroll_node->transform_id) |
- ->scroll_snap; |
+ TransformNode* scroll_ancestor_transform_node = |
+ tree->Node(scroll_node->transform_id); |
+ if (scroll_ancestor_transform_node->scrolls) { |
+ // The scroll position does not include snapping which shifts the scroll |
+ // offset to align to a pixel boundary, we need to manually include it here. |
+ // In this case, snapping is caused by a scroll. |
+ scroll_position -= scroll_ancestor_transform_node->snap_amount; |
+ } |
gfx::RectF clip( |
scroll_position, |
@@ -499,14 +502,20 @@ void TransformTree::UpdateLocalTransform(TransformNode* node) { |
gfx::Vector2dF unsnapping; |
TransformNode* current; |
TransformNode* parent_node; |
+ // Since we are calculating the adjustment for fixed position node or a |
+ // scroll child, we need to unsnap only if the snap was caused by a scroll. |
for (current = Node(node->source_node_id); current->id > node->parent_id; |
current = parent(current)) { |
- unsnapping.Subtract(current->scroll_snap); |
+ DCHECK(current->scrolls || current->snap_amount.IsZero()); |
+ if (current->scrolls) |
+ unsnapping.Subtract(current->snap_amount); |
} |
for (parent_node = Node(node->parent_id); |
parent_node->id > node->source_node_id; |
parent_node = parent(parent_node)) { |
- unsnapping.Add(parent_node->scroll_snap); |
+ DCHECK(parent_node->scrolls || parent_node->snap_amount.IsZero()); |
+ if (parent_node->scrolls) |
+ unsnapping.Add(parent_node->snap_amount); |
} |
// If a node NeedsSourceToParentUpdate, the node is either a fixed position |
// node or a scroll child. |
@@ -583,25 +592,27 @@ void TransformTree::UpdateAnimationProperties(TransformNode* node, |
} |
void TransformTree::UndoSnapping(TransformNode* node) { |
- // to_parent transform has the scroll snap from previous frame baked in. |
+ // to_parent transform has snapping from previous frame baked in. |
// We need to undo it and use the un-snapped transform to compute current |
// target and screen space transforms. |
- node->to_parent.Translate(-node->scroll_snap.x(), -node->scroll_snap.y()); |
+ node->to_parent.Translate(-node->snap_amount.x(), -node->snap_amount.y()); |
} |
void TransformTree::UpdateSnapping(TransformNode* node) { |
- if (!node->scrolls || node->to_screen_is_potentially_animated || |
+ if (!node->should_be_snapped || node->to_screen_is_potentially_animated || |
!ToScreen(node->id).IsScaleOrTranslation() || |
!node->ancestors_are_invertible) { |
return; |
} |
- // Scroll snapping must be done in screen space (the pixels we care about). |
- // This means we effectively snap the screen space transform. If ST is the |
+ // Snapping must be done in target space (the pixels we care about) and then |
+ // the render pass should also be snapped if necessary. But, we do it in |
+ // screen space because it is easier and works most of the time if there is |
+ // no intermediate render pass with a snap-destrying transform. If ST is the |
// screen space transform and ST' is ST with its translation components |
// rounded, then what we're after is the scroll delta X, where ST * X = ST'. |
- // I.e., we want a transform that will realize our scroll snap. It follows |
- // that X = ST^-1 * ST'. We cache ST and ST^-1 to make this more efficient. |
+ // I.e., we want a transform that will realize our snap. It follows that |
+ // X = ST^-1 * ST'. We cache ST and ST^-1 to make this more efficient. |
gfx::Transform rounded = ToScreen(node->id); |
rounded.RoundTranslationComponents(); |
gfx::Transform delta = FromScreen(node->id); |
@@ -612,14 +623,14 @@ void TransformTree::UpdateSnapping(TransformNode* node) { |
gfx::Vector2dF translation = delta.To2dTranslation(); |
- // Now that we have our scroll delta, we must apply it to each of our |
- // combined, to/from matrices. |
+ // Now that we have our delta, we must apply it to each of our combined, |
+ // to/from matrices. |
SetToScreen(node->id, rounded); |
node->to_parent.Translate(translation.x(), translation.y()); |
gfx::Transform from_screen = FromScreen(node->id); |
from_screen.matrix().postTranslate(-translation.x(), -translation.y(), 0); |
SetFromScreen(node->id, from_screen); |
- node->scroll_snap = translation; |
+ node->snap_amount = translation; |
} |
void TransformTree::UpdateTransformChanged(TransformNode* node, |