Index: cc/trees/layer_tree_host_common.cc |
diff --git a/cc/trees/layer_tree_host_common.cc b/cc/trees/layer_tree_host_common.cc |
index 931b6f9fd5565bd6af77c26c5f8fc6a2b6e11d8c..319c1a3d8deb1cf5763f31adec4bcae56aea3aa2 100644 |
--- a/cc/trees/layer_tree_host_common.cc |
+++ b/cc/trees/layer_tree_host_common.cc |
@@ -316,6 +316,65 @@ static bool subtreeShouldRenderToSeparateSurface(LayerType* layer, bool axisAlig |
return false; |
} |
+static LayerImpl* nextTargetSurface(LayerImpl* layer) |
+{ |
+ return layer->parent() ? layer->parent()->render_target() : 0; |
+} |
+ |
+void applyPositionAdjustment(Layer*, Layer*, const gfx::Transform&, gfx::Transform*) { } |
+void applyPositionAdjustment(LayerImpl* layer, LayerImpl* container, const gfx::Transform& scrollCompensation, gfx::Transform* combinedTransform) |
+{ |
+ if (layer->position_constraint().is_fixed_position()) { |
+ // Special case: this layer is a composited fixed-position layer; we need to |
+ // explicitly compensate for all ancestors' nonzero scrollDeltas to keep this layer |
+ // fixed correctly. |
+ // Note carefully: this is Concat, not Preconcat (currentScrollCompensation * combinedTransform). |
+ combinedTransform->ConcatTransform(scrollCompensation); |
+ |
+ // For right-edge or bottom-edge anchored fixed position layers, |
+ // the layer should relocate itself if the container changes its size. |
+ bool fixedToRightEdge = layer->position_constraint().is_fixed_to_right_edge(); |
+ bool fixedToBottomEdge = layer->position_constraint().is_fixed_to_bottom_edge(); |
+ gfx::Vector2dF positionOffset = container ? container->fixed_container_size_delta() : gfx::Vector2dF(); |
+ positionOffset.set_x(fixedToRightEdge ? positionOffset.x() : 0); |
+ positionOffset.set_y(fixedToBottomEdge ? positionOffset.y() : 0); |
+ if (positionOffset.IsZero()) |
+ return; |
+ |
+ // To apply bottom-right anchor compensation in the container's layer space, |
+ // the following steps need to be done: |
+ // Step 1a. transform from target surface space to the container's target surface space |
+ // Step 1b. transform from container's target surface space to the container's layer space |
+ // Step 2. apply the compensation |
+ // Step 3. transform back to target surface space |
+ |
+ gfx::Transform targetSurfaceSpaceToContainerLayerSpace; |
+ |
+ // Step 1a |
+ LayerImpl* containerTargetSurface = container ? container->render_target() : 0; |
+ for (LayerImpl* currentTargetSurface = nextTargetSurface(layer); |
+ currentTargetSurface && currentTargetSurface != containerTargetSurface; |
+ currentTargetSurface = nextTargetSurface(currentTargetSurface)) { |
+ targetSurfaceSpaceToContainerLayerSpace.ConcatTransform(currentTargetSurface->render_surface()->draw_transform()); |
+ } |
+ |
+ // Step 1b |
+ gfx::Transform containerTargetSurfaceSpaceToContainerLayerSpace; |
+ if (container && container->draw_transform().GetInverse(&containerTargetSurfaceSpaceToContainerLayerSpace)) |
+ targetSurfaceSpaceToContainerLayerSpace.ConcatTransform(containerTargetSurfaceSpaceToContainerLayerSpace); |
+ |
+ combinedTransform->ConcatTransform(targetSurfaceSpaceToContainerLayerSpace); |
+ |
+ // Step 2 |
+ combinedTransform->Translate(positionOffset.x(), positionOffset.y()); |
+ |
+ // Step 3 |
+ gfx::Transform containerLayerSpaceTotargetSurfaceSpace; |
+ if (targetSurfaceSpaceToContainerLayerSpace.GetInverse(&containerLayerSpaceTotargetSurfaceSpace)) |
+ combinedTransform->ConcatTransform(containerLayerSpaceTotargetSurfaceSpace); |
+ } |
+} |
+ |
gfx::Transform computeScrollCompensationForThisLayer(LayerImpl* scrollingLayer, const gfx::Transform& parentMatrix) |
{ |
// For every layer that has non-zero scrollDelta, we have to compute a transform that can undo the |
@@ -553,7 +612,7 @@ static void roundTranslationComponents(gfx::Transform* transform) |
// necessary transformations, clipRects, render surfaces, etc. |
template<typename LayerType, typename LayerList, typename RenderSurfaceType> |
static void calculateDrawPropertiesInternal(LayerType* layer, const gfx::Transform& parentMatrix, |
- const gfx::Transform& fullHierarchyMatrix, const gfx::Transform& currentScrollCompensationMatrix, |
+ const gfx::Transform& fullHierarchyMatrix, const gfx::Transform& currentScrollCompensationMatrix, LayerType* currentFixedContainer, |
const gfx::Rect& clipRectFromAncestor, const gfx::Rect& clipRectFromAncestorInDescendantSpace, bool ancestorClipsSubtree, |
RenderSurfaceType* nearestAncestorThatMovesPixels, LayerList& renderSurfaceLayerList, LayerList& layerList, |
LayerSorter* layerSorter, int maxTextureSize, float deviceScaleFactor, float pageScaleFactor, bool subtreeCanUseLCDText, |
@@ -709,13 +768,8 @@ static void calculateDrawPropertiesInternal(LayerType* layer, const gfx::Transfo |
roundTranslationComponents(&combinedTransform); |
} |
- if (layer->fixed_to_container_layer()) { |
- // Special case: this layer is a composited fixed-position layer; we need to |
- // explicitly compensate for all ancestors' nonzero scrollDeltas to keep this layer |
- // fixed correctly. |
- // Note carefully: this is Concat, not Preconcat (currentScrollCompensation * combinedTransform). |
- combinedTransform.ConcatTransform(currentScrollCompensationMatrix); |
- } |
+ // Apply adjustment from position constraints. |
+ applyPositionAdjustment(layer, currentFixedContainer, currentScrollCompensationMatrix, &combinedTransform); |
// The drawTransform that gets computed below is effectively the layer's drawTransform, unless |
// the layer itself creates a renderSurface. In that case, the renderSurface re-parents the transforms. |
@@ -898,12 +952,13 @@ static void calculateDrawPropertiesInternal(LayerType* layer, const gfx::Transfo |
descendants.push_back(layer); |
gfx::Transform nextScrollCompensationMatrix = computeScrollCompensationMatrixForChildren(layer, parentMatrix, currentScrollCompensationMatrix);; |
+ LayerType* nextFixedContainer = layer->is_container_for_fixed_position_layers() ? layer : currentFixedContainer; |
gfx::Rect accumulatedDrawableContentRectOfChildren; |
for (size_t i = 0; i < layer->children().size(); ++i) { |
LayerType* child = LayerTreeHostCommon::getChildAsRawPtr(layer->children(), i); |
gfx::Rect drawableContentRectOfChildSubtree; |
- calculateDrawPropertiesInternal<LayerType, LayerList, RenderSurfaceType>(child, sublayerMatrix, nextHierarchyMatrix, nextScrollCompensationMatrix, |
+ calculateDrawPropertiesInternal<LayerType, LayerList, RenderSurfaceType>(child, sublayerMatrix, nextHierarchyMatrix, nextScrollCompensationMatrix, nextFixedContainer, |
clipRectForSubtree, clipRectForSubtreeInDescendantSpace, subtreeShouldBeClipped, nearestAncestorThatMovesPixels, |
renderSurfaceLayerList, descendants, layerSorter, maxTextureSize, deviceScaleFactor, pageScaleFactor, |
subtreeCanUseLCDText, drawableContentRectOfChildSubtree, updateTilePriorities); |
@@ -1046,7 +1101,7 @@ void LayerTreeHostCommon::calculateDrawProperties(Layer* rootLayer, const gfx::S |
preCalculateMetaInformation<Layer>(rootLayer); |
calculateDrawPropertiesInternal<Layer, std::vector<scoped_refptr<Layer> >, RenderSurface>( |
- rootLayer, deviceScaleTransform, identityMatrix, identityMatrix, |
+ rootLayer, deviceScaleTransform, identityMatrix, identityMatrix, 0, |
deviceViewportRect, deviceViewportRect, subtreeShouldBeClipped, 0, renderSurfaceLayerList, |
dummyLayerList, 0, maxTextureSize, |
deviceScaleFactor, pageScaleFactor, canUseLCDText, totalDrawableContentRect, |
@@ -1076,7 +1131,7 @@ void LayerTreeHostCommon::calculateDrawProperties(LayerImpl* rootLayer, const gf |
preCalculateMetaInformation<LayerImpl>(rootLayer); |
calculateDrawPropertiesInternal<LayerImpl, std::vector<LayerImpl*>, RenderSurfaceImpl>( |
- rootLayer, deviceScaleTransform, identityMatrix, identityMatrix, |
+ rootLayer, deviceScaleTransform, identityMatrix, identityMatrix, 0, |
deviceViewportRect, deviceViewportRect, subtreeShouldBeClipped, 0, renderSurfaceLayerList, |
dummyLayerList, &layerSorter, maxTextureSize, |
deviceScaleFactor, pageScaleFactor, canUseLCDText, totalDrawableContentRect, |