summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--cc/layer_tree_host_common.cc122
-rw-r--r--cc/layer_tree_host_common_unittest.cc94
-rw-r--r--cc/layer_tree_host_impl_unittest.cc45
-rw-r--r--cc/layer_tree_host_unittest.cc102
-rw-r--r--cc/test/layer_test_common.cc25
-rw-r--r--cc/test/layer_tree_test_common.cc10
-rw-r--r--cc/test/layer_tree_test_common.h4
7 files changed, 237 insertions, 165 deletions
diff --git a/cc/layer_tree_host_common.cc b/cc/layer_tree_host_common.cc
index 92b44d1..b51fd00 100644
--- a/cc/layer_tree_host_common.cc
+++ b/cc/layer_tree_host_common.cc
@@ -53,6 +53,12 @@ IntRect LayerTreeHostCommon::calculateVisibleRect(const IntRect& targetSurfaceRe
return layerRect;
}
+template <typename LayerType>
+static inline bool isRootLayer(LayerType* layer)
+{
+ return !layer->parent();
+}
+
template<typename LayerType>
static inline bool layerIsInExisting3DRenderingContext(LayerType* layer)
{
@@ -62,7 +68,7 @@ static inline bool layerIsInExisting3DRenderingContext(LayerType* layer)
}
template<typename LayerType>
-static bool layerIsRootOfNewRenderingContext(LayerType* layer)
+static bool isRootLayerOfNewRenderingContext(LayerType* layer)
{
// According to current W3C spec on CSS transforms (Section 6.1), a layer is the
// beginning of 3d rendering context if its parent does not have transform-style:
@@ -95,7 +101,7 @@ static bool isSurfaceBackFaceVisible(LayerType* layer, const WebTransformationMa
if (layerIsInExisting3DRenderingContext(layer))
return drawTransform.isBackFaceVisible();
- if (layerIsRootOfNewRenderingContext(layer))
+ if (isRootLayerOfNewRenderingContext(layer))
return layer->transform().isBackFaceVisible();
// If the renderSurface is not part of a new or existing rendering context, then the
@@ -218,18 +224,14 @@ static inline bool subtreeShouldBeSkipped(Layer* layer)
template<typename LayerType>
static bool subtreeShouldRenderToSeparateSurface(LayerType* layer, bool axisAlignedWithRespectToParent)
{
- // The root layer has a special render surface that is set up externally, so
- // it shouldn't be treated as a surface in this code.
- if (!layer->parent())
- return false;
-
- // Cache this value, because otherwise it walks the entire subtree several times.
- bool descendantDrawsContent = layer->descendantDrawsContent();
-
//
// A layer and its descendants should render onto a new RenderSurfaceImpl if any of these rules hold:
//
+ // The root layer should always have a renderSurface.
+ if (isRootLayer(layer))
+ return true;
+
// If we force it.
if (layer->forceRenderSurface())
return true;
@@ -246,6 +248,9 @@ static bool subtreeShouldRenderToSeparateSurface(LayerType* layer, bool axisAlig
if (!layer->filters().isEmpty() || !layer->backgroundFilters().isEmpty() || layer->filter())
return true;
+ // Cache this value, because otherwise it walks the entire subtree several times.
+ bool descendantDrawsContent = layer->descendantDrawsContent();
+
// If the layer flattens its subtree (i.e. the layer doesn't preserve-3d), but it is
// treated as a 3D object by its parent (i.e. parent does preserve-3d).
if (layerIsInExisting3DRenderingContext(layer) && !layer->preserves3D() && descendantDrawsContent)
@@ -307,8 +312,8 @@ WebTransformationMatrix computeScrollCompensationMatrixForChildren(LayerImpl* la
// it is fixed to an ancestor, and is a container for any fixed-position descendants.
// - A layer that is a fixed-position container and has a renderSurface should behave the same as a container
// without a renderSurface, the renderSurface is irrelevant in that case.
- // - A layer that does not have an explicit container is simply fixed to the viewport
- // (i.e. the root renderSurface, and it would still compensate for root layer's scrollDelta).
+ // - A layer that does not have an explicit container is simply fixed to the viewport.
+ // (i.e. the root renderSurface.)
// - If the fixed-position layer has its own renderSurface, then the renderSurface is
// the one who gets fixed.
//
@@ -377,24 +382,10 @@ static inline void updateLayerContentsScale(Layer* layer, const WebTransformatio
replicaMaskLayer->setContentsScale(contentsScale);
}
-// Should be called just before the recursive calculateDrawTransformsInternal().
-template<typename LayerType, typename LayerList>
-void setupRootLayerAndSurfaceForRecursion(LayerType* rootLayer, LayerList& renderSurfaceLayerList, const IntSize& deviceViewportSize)
-{
- if (!rootLayer->renderSurface())
- rootLayer->createRenderSurface();
-
- rootLayer->renderSurface()->setContentRect(IntRect(IntPoint::zero(), deviceViewportSize));
- rootLayer->renderSurface()->clearLayerLists();
-
- DCHECK(renderSurfaceLayerList.empty());
- renderSurfaceLayerList.push_back(rootLayer);
-}
-
// Recursively walks the layer tree starting at the given node and computes all the
// necessary transformations, clipRects, render surfaces, etc.
template<typename LayerType, typename LayerList, typename RenderSurfaceType, typename LayerSorter>
-static void calculateDrawTransformsInternal(LayerType* layer, LayerType* rootLayer, const WebTransformationMatrix& parentMatrix,
+static void calculateDrawTransformsInternal(LayerType* layer, const WebTransformationMatrix& parentMatrix,
const WebTransformationMatrix& fullHierarchyMatrix, const WebTransformationMatrix& currentScrollCompensationMatrix,
const IntRect& clipRectFromAncestor, bool ancestorClipsSubtree,
RenderSurfaceType* nearestAncestorThatMovesPixels, LayerList& renderSurfaceLayerList, LayerList& layerList,
@@ -485,7 +476,8 @@ static void calculateDrawTransformsInternal(LayerType* layer, LayerType* rootLay
// If we early-exit anywhere in this function, the drawableContentRect of this subtree should be considered empty.
drawableContentRectOfSubtree = IntRect();
- if (subtreeShouldBeSkipped(layer))
+ // The root layer cannot skip calcDrawTransforms.
+ if (!isRootLayer(layer) && subtreeShouldBeSkipped(layer))
return;
IntRect clipRectForSubtree;
@@ -642,6 +634,8 @@ static void calculateDrawTransformsInternal(LayerType* layer, LayerType* rootLay
renderSurfaceLayerList.push_back(layer);
} else {
+ DCHECK(layer->parent());
+
layer->setDrawTransform(drawTransform);
layer->setDrawTransformIsAnimating(animatingTransformToTarget);
layer->setScreenSpaceTransformIsAnimating(animatingTransformToScreen);
@@ -650,25 +644,15 @@ static void calculateDrawTransformsInternal(LayerType* layer, LayerType* rootLay
layer->setDrawOpacity(drawOpacity);
layer->setDrawOpacityIsAnimating(drawOpacityIsAnimating);
- if (layer != rootLayer) {
- DCHECK(layer->parent());
- layer->clearRenderSurface();
+ layer->clearRenderSurface();
- // Layers without renderSurfaces directly inherit the ancestor's clip status.
- subtreeShouldBeClipped = ancestorClipsSubtree;
- if (ancestorClipsSubtree)
- clipRectForSubtree = clipRectFromAncestor;
-
- // Layers that are not their own renderTarget will render into the target of their nearest ancestor.
- layer->setRenderTarget(layer->parent()->renderTarget());
- } else {
- // FIXME: This root layer special case code should eventually go away. https://bugs.webkit.org/show_bug.cgi?id=92290
- DCHECK(!layer->parent());
- DCHECK(layer->renderSurface());
- DCHECK(ancestorClipsSubtree);
- layer->renderSurface()->setClipRect(clipRectFromAncestor);
- subtreeShouldBeClipped = false;
- }
+ // Layers without renderSurfaces directly inherit the ancestor's clip status.
+ subtreeShouldBeClipped = ancestorClipsSubtree;
+ if (ancestorClipsSubtree)
+ clipRectForSubtree = clipRectFromAncestor;
+
+ // Layers that are not their own renderTarget will render into the target of their nearest ancestor.
+ layer->setRenderTarget(layer->parent()->renderTarget());
}
IntRect rectInTargetSpace = enclosingIntRect(MathUtil::mapClippedRect(layer->drawTransform(), contentRect));
@@ -705,7 +689,7 @@ static void calculateDrawTransformsInternal(LayerType* layer, LayerType* rootLay
for (size_t i = 0; i < layer->children().size(); ++i) {
LayerType* child = LayerTreeHostCommon::getChildAsRawPtr(layer->children(), i);
IntRect drawableContentRectOfChildSubtree;
- calculateDrawTransformsInternal<LayerType, LayerList, RenderSurfaceType, LayerSorter>(child, rootLayer, sublayerMatrix, nextHierarchyMatrix, nextScrollCompensationMatrix,
+ calculateDrawTransformsInternal<LayerType, LayerList, RenderSurfaceType, LayerSorter>(child, sublayerMatrix, nextHierarchyMatrix, nextScrollCompensationMatrix,
clipRectForSubtree, subtreeShouldBeClipped, nearestAncestorThatMovesPixels,
renderSurfaceLayerList, descendants, layerSorter, maxTextureSize, deviceScaleFactor, pageScaleFactor, drawableContentRectOfChildSubtree);
if (!drawableContentRectOfChildSubtree.isEmpty()) {
@@ -733,7 +717,11 @@ static void calculateDrawTransformsInternal(LayerType* layer, LayerType* rootLay
layer->setVisibleContentRect(visibleContentRectOfLayer);
// Compute the remaining properties for the render surface, if the layer has one.
- if (layer->renderSurface() && layer != rootLayer) {
+ if (isRootLayer(layer)) {
+ // The root layer's surface's contentRect is always the entire viewport.
+ DCHECK(layer->renderSurface());
+ layer->renderSurface()->setContentRect(clipRectFromAncestor);
+ } else if (layer->renderSurface() && !isRootLayer(layer)) {
RenderSurfaceType* renderSurface = layer->renderSurface();
IntRect clippedContentRect = localDrawableContentRectOfSubtree;
@@ -830,14 +818,25 @@ void LayerTreeHostCommon::calculateDrawTransforms(Layer* rootLayer, const IntSiz
WebTransformationMatrix identityMatrix;
WebTransformationMatrix deviceScaleTransform;
deviceScaleTransform.scale(deviceScaleFactor);
+ std::vector<scoped_refptr<Layer> > dummyLayerList;
+
+ // The root layer's renderSurface should receive the deviceViewport as the initial clipRect.
+ bool subtreeShouldBeClipped = true;
+ IntRect deviceViewportRect(IntPoint::zero(), deviceViewportSize);
- setupRootLayerAndSurfaceForRecursion<Layer, std::vector<scoped_refptr<Layer> > >(rootLayer, renderSurfaceLayerList, deviceViewportSize);
+ // This function should have received a root layer.
+ DCHECK(isRootLayer(rootLayer));
cc::calculateDrawTransformsInternal<Layer, std::vector<scoped_refptr<Layer> >, RenderSurface, void>(
- rootLayer, rootLayer, deviceScaleTransform, identityMatrix, identityMatrix,
- rootLayer->renderSurface()->contentRect(), true, 0, renderSurfaceLayerList,
- rootLayer->renderSurface()->layerList(), 0, maxTextureSize,
+ rootLayer, deviceScaleTransform, identityMatrix, identityMatrix,
+ deviceViewportRect, subtreeShouldBeClipped, 0, renderSurfaceLayerList,
+ dummyLayerList, 0, maxTextureSize,
deviceScaleFactor, pageScaleFactor, totalDrawableContentRect);
+
+ // The dummy layer list should not have been used.
+ DCHECK(dummyLayerList.size() == 0);
+ // A root layer renderSurface should always exist after calculateDrawTransforms.
+ DCHECK(rootLayer->renderSurface());
}
void LayerTreeHostCommon::calculateDrawTransforms(LayerImpl* rootLayer, const IntSize& deviceViewportSize, float deviceScaleFactor, float pageScaleFactor, LayerSorter* layerSorter, int maxTextureSize, std::vector<LayerImpl*>& renderSurfaceLayerList)
@@ -846,14 +845,25 @@ void LayerTreeHostCommon::calculateDrawTransforms(LayerImpl* rootLayer, const In
WebTransformationMatrix identityMatrix;
WebTransformationMatrix deviceScaleTransform;
deviceScaleTransform.scale(deviceScaleFactor);
+ std::vector<LayerImpl*> dummyLayerList;
+
+ // The root layer's renderSurface should receive the deviceViewport as the initial clipRect.
+ bool subtreeShouldBeClipped = true;
+ IntRect deviceViewportRect(IntPoint::zero(), deviceViewportSize);
- setupRootLayerAndSurfaceForRecursion<LayerImpl, std::vector<LayerImpl*> >(rootLayer, renderSurfaceLayerList, deviceViewportSize);
+ // This function should have received a root layer.
+ DCHECK(isRootLayer(rootLayer));
cc::calculateDrawTransformsInternal<LayerImpl, std::vector<LayerImpl*>, RenderSurfaceImpl, LayerSorter>(
- rootLayer, rootLayer, deviceScaleTransform, identityMatrix, identityMatrix,
- rootLayer->renderSurface()->contentRect(), true, 0, renderSurfaceLayerList,
- rootLayer->renderSurface()->layerList(), layerSorter, maxTextureSize,
+ rootLayer, deviceScaleTransform, identityMatrix, identityMatrix,
+ deviceViewportRect, subtreeShouldBeClipped, 0, renderSurfaceLayerList,
+ dummyLayerList, layerSorter, maxTextureSize,
deviceScaleFactor, pageScaleFactor, totalDrawableContentRect);
+
+ // The dummy layer list should not have been used.
+ DCHECK(dummyLayerList.size() == 0);
+ // A root layer renderSurface should always exist after calculateDrawTransforms.
+ DCHECK(rootLayer->renderSurface());
}
static bool pointHitsRect(const IntPoint& screenSpacePoint, const WebTransformationMatrix& localSpaceToScreenSpaceTransform, FloatRect localSpaceRect)
diff --git a/cc/layer_tree_host_common_unittest.cc b/cc/layer_tree_host_common_unittest.cc
index 8e924f6..cf864f9 100644
--- a/cc/layer_tree_host_common_unittest.cc
+++ b/cc/layer_tree_host_common_unittest.cc
@@ -173,11 +173,15 @@ TEST(LayerTreeHostCommonTest, verifyTransformsForSingleLayer)
WebTransformationMatrix identityMatrix;
scoped_refptr<Layer> layer = Layer::create();
+ scoped_refptr<Layer> root = Layer::create();
+ setLayerPropertiesForTesting(root.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(1, 2), false);
+ root->addChild(layer);
+
// Case 1: setting the sublayer transform should not affect this layer's draw transform or screen-space transform.
WebTransformationMatrix arbitraryTranslation;
arbitraryTranslation.translate(10, 20);
setLayerPropertiesForTesting(layer.get(), identityMatrix, arbitraryTranslation, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false);
- executeCalculateDrawTransformsAndVisibility(layer.get());
+ executeCalculateDrawTransformsAndVisibility(root.get());
WebTransformationMatrix expectedDrawTransform = identityMatrix;
EXPECT_TRANSFORMATION_MATRIX_EQ(expectedDrawTransform, layer->drawTransform());
EXPECT_TRANSFORMATION_MATRIX_EQ(identityMatrix, layer->screenSpaceTransform());
@@ -186,13 +190,13 @@ TEST(LayerTreeHostCommonTest, verifyTransformsForSingleLayer)
WebTransformationMatrix translationToCenter;
translationToCenter.translate(5, 6);
setLayerPropertiesForTesting(layer.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(10, 12), false);
- executeCalculateDrawTransformsAndVisibility(layer.get());
+ executeCalculateDrawTransformsAndVisibility(root.get());
EXPECT_TRANSFORMATION_MATRIX_EQ(identityMatrix, layer->drawTransform());
EXPECT_TRANSFORMATION_MATRIX_EQ(identityMatrix, layer->screenSpaceTransform());
// Case 3: The anchor point by itself (without a layer transform) should have no effect on the transforms.
setLayerPropertiesForTesting(layer.get(), identityMatrix, identityMatrix, FloatPoint(0.25, 0.25), FloatPoint(0, 0), IntSize(10, 12), false);
- executeCalculateDrawTransformsAndVisibility(layer.get());
+ executeCalculateDrawTransformsAndVisibility(root.get());
EXPECT_TRANSFORMATION_MATRIX_EQ(identityMatrix, layer->drawTransform());
EXPECT_TRANSFORMATION_MATRIX_EQ(identityMatrix, layer->screenSpaceTransform());
@@ -200,7 +204,7 @@ TEST(LayerTreeHostCommonTest, verifyTransformsForSingleLayer)
WebTransformationMatrix positionTransform;
positionTransform.translate(0, 1.2);
setLayerPropertiesForTesting(layer.get(), identityMatrix, identityMatrix, FloatPoint(0.25, 0.25), FloatPoint(0, 1.2f), IntSize(10, 12), false);
- executeCalculateDrawTransformsAndVisibility(layer.get());
+ executeCalculateDrawTransformsAndVisibility(root.get());
EXPECT_TRANSFORMATION_MATRIX_EQ(positionTransform, layer->drawTransform());
EXPECT_TRANSFORMATION_MATRIX_EQ(positionTransform, layer->screenSpaceTransform());
@@ -209,7 +213,7 @@ TEST(LayerTreeHostCommonTest, verifyTransformsForSingleLayer)
WebTransformationMatrix layerTransform;
layerTransform.scale3d(2, 2, 1);
setLayerPropertiesForTesting(layer.get(), layerTransform, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(10, 12), false);
- executeCalculateDrawTransformsAndVisibility(layer.get());
+ executeCalculateDrawTransformsAndVisibility(root.get());
EXPECT_TRANSFORMATION_MATRIX_EQ(layerTransform, layer->drawTransform());
EXPECT_TRANSFORMATION_MATRIX_EQ(layerTransform, layer->screenSpaceTransform());
@@ -218,7 +222,7 @@ TEST(LayerTreeHostCommonTest, verifyTransformsForSingleLayer)
translationToAnchor.translate(5, 0);
WebTransformationMatrix expectedResult = translationToAnchor * layerTransform * translationToAnchor.inverse();
setLayerPropertiesForTesting(layer.get(), layerTransform, identityMatrix, FloatPoint(0.5, 0), FloatPoint(0, 0), IntSize(10, 12), false);
- executeCalculateDrawTransformsAndVisibility(layer.get());
+ executeCalculateDrawTransformsAndVisibility(root.get());
EXPECT_TRANSFORMATION_MATRIX_EQ(expectedResult, layer->drawTransform());
EXPECT_TRANSFORMATION_MATRIX_EQ(expectedResult, layer->screenSpaceTransform());
@@ -227,7 +231,7 @@ TEST(LayerTreeHostCommonTest, verifyTransformsForSingleLayer)
// still worth testing to detect accidental regressions.
expectedResult = positionTransform * translationToAnchor * layerTransform * translationToAnchor.inverse();
setLayerPropertiesForTesting(layer.get(), layerTransform, identityMatrix, FloatPoint(0.5, 0), FloatPoint(0, 1.2f), IntSize(10, 12), false);
- executeCalculateDrawTransformsAndVisibility(layer.get());
+ executeCalculateDrawTransformsAndVisibility(root.get());
EXPECT_TRANSFORMATION_MATRIX_EQ(expectedResult, layer->drawTransform());
EXPECT_TRANSFORMATION_MATRIX_EQ(expectedResult, layer->screenSpaceTransform());
}
@@ -235,17 +239,22 @@ TEST(LayerTreeHostCommonTest, verifyTransformsForSingleLayer)
TEST(LayerTreeHostCommonTest, verifyTransformsForSimpleHierarchy)
{
WebTransformationMatrix identityMatrix;
+ scoped_refptr<Layer> root = Layer::create();
scoped_refptr<Layer> parent = Layer::create();
scoped_refptr<Layer> child = Layer::create();
scoped_refptr<Layer> grandChild = Layer::create();
+ root->addChild(parent);
parent->addChild(child);
child->addChild(grandChild);
+ // One-time setup of root layer
+ setLayerPropertiesForTesting(root.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(1, 2), false);
+
// Case 1: parent's anchorPoint should not affect child or grandChild.
setLayerPropertiesForTesting(parent.get(), identityMatrix, identityMatrix, FloatPoint(0.25, 0.25), FloatPoint(0, 0), IntSize(10, 12), false);
setLayerPropertiesForTesting(child.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(16, 18), false);
setLayerPropertiesForTesting(grandChild.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(76, 78), false);
- executeCalculateDrawTransformsAndVisibility(parent.get());
+ executeCalculateDrawTransformsAndVisibility(root.get());
EXPECT_TRANSFORMATION_MATRIX_EQ(identityMatrix, child->drawTransform());
EXPECT_TRANSFORMATION_MATRIX_EQ(identityMatrix, child->screenSpaceTransform());
EXPECT_TRANSFORMATION_MATRIX_EQ(identityMatrix, grandChild->drawTransform());
@@ -257,7 +266,7 @@ TEST(LayerTreeHostCommonTest, verifyTransformsForSimpleHierarchy)
setLayerPropertiesForTesting(parent.get(), identityMatrix, identityMatrix, FloatPoint(0.25, 0.25), FloatPoint(0, 1.2f), IntSize(10, 12), false);
setLayerPropertiesForTesting(child.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(16, 18), false);
setLayerPropertiesForTesting(grandChild.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(76, 78), false);
- executeCalculateDrawTransformsAndVisibility(parent.get());
+ executeCalculateDrawTransformsAndVisibility(root.get());
EXPECT_TRANSFORMATION_MATRIX_EQ(parentPositionTransform, child->drawTransform());
EXPECT_TRANSFORMATION_MATRIX_EQ(parentPositionTransform, child->screenSpaceTransform());
EXPECT_TRANSFORMATION_MATRIX_EQ(parentPositionTransform, grandChild->drawTransform());
@@ -272,7 +281,7 @@ TEST(LayerTreeHostCommonTest, verifyTransformsForSimpleHierarchy)
setLayerPropertiesForTesting(parent.get(), parentLayerTransform, identityMatrix, FloatPoint(0.25, 0.25), FloatPoint(0, 0), IntSize(10, 12), false);
setLayerPropertiesForTesting(child.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(16, 18), false);
setLayerPropertiesForTesting(grandChild.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(76, 78), false);
- executeCalculateDrawTransformsAndVisibility(parent.get());
+ executeCalculateDrawTransformsAndVisibility(root.get());
EXPECT_TRANSFORMATION_MATRIX_EQ(parentCompositeTransform, child->drawTransform());
EXPECT_TRANSFORMATION_MATRIX_EQ(parentCompositeTransform, child->screenSpaceTransform());
EXPECT_TRANSFORMATION_MATRIX_EQ(parentCompositeTransform, grandChild->drawTransform());
@@ -293,7 +302,7 @@ TEST(LayerTreeHostCommonTest, verifyTransformsForSimpleHierarchy)
setLayerPropertiesForTesting(parent.get(), parentLayerTransform, parentSublayerMatrix, FloatPoint(0.25, 0.25), FloatPoint(0, 0), IntSize(10, 12), false);
setLayerPropertiesForTesting(child.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(16, 18), false);
setLayerPropertiesForTesting(grandChild.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(76, 78), false);
- executeCalculateDrawTransformsAndVisibility(parent.get());
+ executeCalculateDrawTransformsAndVisibility(root.get());
EXPECT_TRANSFORMATION_MATRIX_EQ(parentCompositeTransform, child->drawTransform());
EXPECT_TRANSFORMATION_MATRIX_EQ(parentCompositeTransform, child->screenSpaceTransform());
EXPECT_TRANSFORMATION_MATRIX_EQ(flattenedCompositeTransform, grandChild->drawTransform());
@@ -304,7 +313,7 @@ TEST(LayerTreeHostCommonTest, verifyTransformsForSimpleHierarchy)
setLayerPropertiesForTesting(parent.get(), parentLayerTransform, parentSublayerMatrix, FloatPoint(0.25, 0.25), FloatPoint(0, 0), IntSize(10, 12), false);
setLayerPropertiesForTesting(child.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(16, 18), true);
setLayerPropertiesForTesting(grandChild.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(76, 78), false);
- executeCalculateDrawTransformsAndVisibility(parent.get());
+ executeCalculateDrawTransformsAndVisibility(root.get());
EXPECT_TRANSFORMATION_MATRIX_EQ(parentCompositeTransform, child->drawTransform());
EXPECT_TRANSFORMATION_MATRIX_EQ(parentCompositeTransform, child->screenSpaceTransform());
EXPECT_TRANSFORMATION_MATRIX_EQ(parentCompositeTransform, grandChild->drawTransform());
@@ -313,16 +322,21 @@ TEST(LayerTreeHostCommonTest, verifyTransformsForSimpleHierarchy)
TEST(LayerTreeHostCommonTest, verifyTransformsForSingleRenderSurface)
{
+ scoped_refptr<Layer> root = Layer::create();
scoped_refptr<Layer> parent = Layer::create();
scoped_refptr<Layer> child = Layer::create();
scoped_refptr<LayerWithForcedDrawsContent> grandChild = make_scoped_refptr(new LayerWithForcedDrawsContent());
+ root->addChild(parent);
parent->addChild(child);
child->addChild(grandChild);
+ // One-time setup of root layer
+ WebTransformationMatrix identityMatrix;
+ setLayerPropertiesForTesting(root.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(1, 2), false);
+
// Child is set up so that a new render surface should be created.
child->setOpacity(0.5);
- WebTransformationMatrix identityMatrix;
WebTransformationMatrix parentLayerTransform;
parentLayerTransform.scale3d(1, 0.9, 1);
WebTransformationMatrix parentTranslationToAnchor;
@@ -344,7 +358,7 @@ TEST(LayerTreeHostCommonTest, verifyTransformsForSingleRenderSurface)
setLayerPropertiesForTesting(parent.get(), parentLayerTransform, parentSublayerMatrix, FloatPoint(0.25, 0.25), FloatPoint(0, 0), IntSize(100, 120), false);
setLayerPropertiesForTesting(child.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(16, 18), false);
setLayerPropertiesForTesting(grandChild.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(8, 10), false);
- executeCalculateDrawTransformsAndVisibility(parent.get());
+ executeCalculateDrawTransformsAndVisibility(root.get());
// Render surface should have been created now.
ASSERT_TRUE(child->renderSurface());
@@ -365,18 +379,23 @@ TEST(LayerTreeHostCommonTest, verifyTransformsForSingleRenderSurface)
TEST(LayerTreeHostCommonTest, verifyTransformsForReplica)
{
+ scoped_refptr<Layer> root = Layer::create();
scoped_refptr<Layer> parent = Layer::create();
scoped_refptr<Layer> child = Layer::create();
scoped_refptr<Layer> childReplica = Layer::create();
scoped_refptr<LayerWithForcedDrawsContent> grandChild = make_scoped_refptr(new LayerWithForcedDrawsContent());
+ root->addChild(parent);
parent->addChild(child);
child->addChild(grandChild);
child->setReplicaLayer(childReplica.get());
+ // One-time setup of root layer
+ WebTransformationMatrix identityMatrix;
+ setLayerPropertiesForTesting(root.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(1, 2), false);
+
// Child is set up so that a new render surface should be created.
child->setOpacity(0.5);
- WebTransformationMatrix identityMatrix;
WebTransformationMatrix parentLayerTransform;
parentLayerTransform.scale3d(2, 2, 1);
WebTransformationMatrix parentTranslationToAnchor;
@@ -403,7 +422,7 @@ TEST(LayerTreeHostCommonTest, verifyTransformsForReplica)
setLayerPropertiesForTesting(child.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(16, 18), false);
setLayerPropertiesForTesting(grandChild.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(-0.5, -0.5), IntSize(1, 1), false);
setLayerPropertiesForTesting(childReplica.get(), replicaLayerTransform, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(0, 0), false);
- executeCalculateDrawTransformsAndVisibility(parent.get());
+ executeCalculateDrawTransformsAndVisibility(root.get());
// Render surface should have been created now.
ASSERT_TRUE(child->renderSurface());
@@ -422,6 +441,7 @@ TEST(LayerTreeHostCommonTest, verifyTransformsForRenderSurfaceHierarchy)
// - Sanity check on recursion: verify transforms of layers described w.r.t. a render surface that is described w.r.t. an ancestor render surface.
// - verifying that each layer has a reference to the correct renderSurface and renderTarget values.
+ scoped_refptr<Layer> root = Layer::create();
scoped_refptr<Layer> parent = Layer::create();
scoped_refptr<Layer> renderSurface1 = Layer::create();
scoped_refptr<Layer> renderSurface2 = Layer::create();
@@ -433,6 +453,7 @@ TEST(LayerTreeHostCommonTest, verifyTransformsForRenderSurfaceHierarchy)
scoped_refptr<Layer> grandChildOfRoot = Layer::create();
scoped_refptr<LayerWithForcedDrawsContent> grandChildOfRS1 = make_scoped_refptr(new LayerWithForcedDrawsContent());
scoped_refptr<LayerWithForcedDrawsContent> grandChildOfRS2 = make_scoped_refptr(new LayerWithForcedDrawsContent());
+ root->addChild(parent);
parent->addChild(renderSurface1);
parent->addChild(childOfRoot);
renderSurface1->addChild(childOfRS1);
@@ -448,6 +469,10 @@ TEST(LayerTreeHostCommonTest, verifyTransformsForRenderSurfaceHierarchy)
renderSurface1->setOpacity(0.5);
renderSurface2->setOpacity(0.33f);
+ // One-time setup of root layer
+ WebTransformationMatrix identityMatrix;
+ setLayerPropertiesForTesting(root.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(1, 2), false);
+
// All layers in the tree are initialized with an anchor at .25 and a size of (10,10).
// matrix "A" is the composite layer transform used in all layers, centered about the anchor point
// matrix "B" is the sublayer transform used in all layers, centered about the center position of the layer.
@@ -469,7 +494,6 @@ TEST(LayerTreeHostCommonTest, verifyTransformsForRenderSurfaceHierarchy)
WebTransformationMatrix A = translationToAnchor * layerTransform * translationToAnchor.inverse();
WebTransformationMatrix B = translationToCenter * sublayerTransform * translationToCenter.inverse();
WebTransformationMatrix R = A * translationToAnchor * replicaLayerTransform * translationToAnchor.inverse();
- WebTransformationMatrix identityMatrix;
FloatPoint surface1ParentTransformScale = MathUtil::computeTransform2dScaleComponents(A * B);
WebTransformationMatrix surface1SublayerTransform;
@@ -501,11 +525,11 @@ TEST(LayerTreeHostCommonTest, verifyTransformsForRenderSurfaceHierarchy)
setLayerPropertiesForTesting(replicaOfRS1.get(), replicaLayerTransform, sublayerTransform, FloatPoint(0.25, 0), FloatPoint(0, 0), IntSize(), false);
setLayerPropertiesForTesting(replicaOfRS2.get(), replicaLayerTransform, sublayerTransform, FloatPoint(0.25, 0), FloatPoint(0, 0), IntSize(), false);
- executeCalculateDrawTransformsAndVisibility(parent.get());
+ executeCalculateDrawTransformsAndVisibility(root.get());
// Only layers that are associated with render surfaces should have an actual renderSurface() value.
//
- ASSERT_TRUE(parent->renderSurface());
+ ASSERT_TRUE(root->renderSurface());
ASSERT_FALSE(childOfRoot->renderSurface());
ASSERT_FALSE(grandChildOfRoot->renderSurface());
@@ -519,9 +543,9 @@ TEST(LayerTreeHostCommonTest, verifyTransformsForRenderSurfaceHierarchy)
// Verify all renderTarget accessors
//
- EXPECT_EQ(parent, parent->renderTarget());
- EXPECT_EQ(parent, childOfRoot->renderTarget());
- EXPECT_EQ(parent, grandChildOfRoot->renderTarget());
+ EXPECT_EQ(root, parent->renderTarget());
+ EXPECT_EQ(root, childOfRoot->renderTarget());
+ EXPECT_EQ(root, grandChildOfRoot->renderTarget());
EXPECT_EQ(renderSurface1, renderSurface1->renderTarget());
EXPECT_EQ(renderSurface1, childOfRS1->renderTarget());
@@ -1297,25 +1321,25 @@ TEST(LayerTreeHostCommonTest, verifyScrollCompensationForFixedPositionLayerThatH
root->setScrollDelta(IntSize(0, 0));
executeCalculateDrawTransformsAndVisibility(root.get());
- WebTransformationMatrix expectedChildTransform;
- expectedChildTransform.multiply(rotationByZ);
-
- WebTransformationMatrix expectedGrandChildTransform;
- expectedGrandChildTransform.multiply(rotationByZ);
+ WebTransformationMatrix identityMatrix;
- EXPECT_TRANSFORMATION_MATRIX_EQ(expectedChildTransform, child->drawTransform());
- EXPECT_TRANSFORMATION_MATRIX_EQ(expectedGrandChildTransform, grandChild->drawTransform());
+ EXPECT_TRANSFORMATION_MATRIX_EQ(identityMatrix, child->drawTransform());
+ EXPECT_TRANSFORMATION_MATRIX_EQ(identityMatrix, grandChild->drawTransform());
// Case 2: root scrollDelta of 10, 10
- root->setScrollDelta(IntSize(10, 10));
+ root->setScrollDelta(IntSize(10, 20));
executeCalculateDrawTransformsAndVisibility(root.get());
- // Here the child is affected by scrollDelta, but the fixed position grandChild should not be affected.
- expectedChildTransform.makeIdentity();
- expectedChildTransform.translate(-10, -10); // the scrollDelta
- expectedChildTransform.multiply(rotationByZ);
+ // The child is affected by scrollDelta, but it is already implcitly accounted for by
+ // the child's target surface (i.e. the root renderSurface). The grandChild is not
+ // affected by the scrollDelta, so its drawTransform needs to explicitly
+ // inverse-compensate for the scroll that's embedded in the target surface.
+ WebTransformationMatrix expectedGrandChildTransform;
+ expectedGrandChildTransform.multiply(rotationByZ.inverse());
+ expectedGrandChildTransform.translate(10, 20); // explicit canceling out the scrollDelta that gets embedded in the fixed position layer's surface.
+ expectedGrandChildTransform.multiply(rotationByZ);
- EXPECT_TRANSFORMATION_MATRIX_EQ(expectedChildTransform, child->drawTransform());
+ EXPECT_TRANSFORMATION_MATRIX_EQ(identityMatrix, child->drawTransform());
EXPECT_TRANSFORMATION_MATRIX_EQ(expectedGrandChildTransform, grandChild->drawTransform());
}
diff --git a/cc/layer_tree_host_impl_unittest.cc b/cc/layer_tree_host_impl_unittest.cc
index 2d50654..e2ecdce 100644
--- a/cc/layer_tree_host_impl_unittest.cc
+++ b/cc/layer_tree_host_impl_unittest.cc
@@ -1791,19 +1791,20 @@ TEST_P(LayerTreeHostImplTest, viewportCovered)
IntSize viewportSize(1000, 1000);
m_hostImpl->setViewportSize(viewportSize, viewportSize);
- m_hostImpl->setRootLayer(BlendStateCheckLayer::create(1, m_hostImpl->resourceProvider()));
- BlendStateCheckLayer* root = static_cast<BlendStateCheckLayer*>(m_hostImpl->rootLayer());
- root->setExpectation(false, true);
- root->setContentsOpaque(true);
+ m_hostImpl->setRootLayer(LayerImpl::create(1));
+ m_hostImpl->rootLayer()->addChild(BlendStateCheckLayer::create(2, m_hostImpl->resourceProvider()));
+ BlendStateCheckLayer* child = static_cast<BlendStateCheckLayer*>(m_hostImpl->rootLayer()->children()[0]);
+ child->setExpectation(false, false);
+ child->setContentsOpaque(true);
// No gutter rects
{
IntRect layerRect(0, 0, 1000, 1000);
- root->setPosition(layerRect.location());
- root->setBounds(layerRect.size());
- root->setContentBounds(layerRect.size());
- root->setQuadRect(IntRect(IntPoint(), layerRect.size()));
- root->setQuadVisibleRect(IntRect(IntPoint(), layerRect.size()));
+ child->setPosition(layerRect.location());
+ child->setBounds(layerRect.size());
+ child->setContentBounds(layerRect.size());
+ child->setQuadRect(IntRect(IntPoint(), layerRect.size()));
+ child->setQuadVisibleRect(IntRect(IntPoint(), layerRect.size()));
LayerTreeHostImpl::FrameData frame;
EXPECT_TRUE(m_hostImpl->prepareToDraw(frame));
@@ -1815,18 +1816,18 @@ TEST_P(LayerTreeHostImplTest, viewportCovered)
EXPECT_EQ(0u, numGutterQuads);
EXPECT_EQ(1u, frame.renderPasses[0]->quadList().size());
- verifyQuadsExactlyCoverRect(frame.renderPasses[0]->quadList(), IntRect(-layerRect.location(), viewportSize));
+ verifyQuadsExactlyCoverRect(frame.renderPasses[0]->quadList(), IntRect(IntPoint::zero(), viewportSize));
m_hostImpl->didDrawAllLayers(frame);
}
// Empty visible content area (fullscreen gutter rect)
{
IntRect layerRect(0, 0, 0, 0);
- root->setPosition(layerRect.location());
- root->setBounds(layerRect.size());
- root->setContentBounds(layerRect.size());
- root->setQuadRect(IntRect(IntPoint(), layerRect.size()));
- root->setQuadVisibleRect(IntRect(IntPoint(), layerRect.size()));
+ child->setPosition(layerRect.location());
+ child->setBounds(layerRect.size());
+ child->setContentBounds(layerRect.size());
+ child->setQuadRect(IntRect(IntPoint(), layerRect.size()));
+ child->setQuadVisibleRect(IntRect(IntPoint(), layerRect.size()));
LayerTreeHostImpl::FrameData frame;
EXPECT_TRUE(m_hostImpl->prepareToDraw(frame));
@@ -1839,18 +1840,18 @@ TEST_P(LayerTreeHostImplTest, viewportCovered)
EXPECT_EQ(1u, numGutterQuads);
EXPECT_EQ(1u, frame.renderPasses[0]->quadList().size());
- verifyQuadsExactlyCoverRect(frame.renderPasses[0]->quadList(), IntRect(-layerRect.location(), viewportSize));
+ verifyQuadsExactlyCoverRect(frame.renderPasses[0]->quadList(), IntRect(IntPoint::zero(), viewportSize));
m_hostImpl->didDrawAllLayers(frame);
}
// Content area in middle of clip rect (four surrounding gutter rects)
{
IntRect layerRect(500, 500, 200, 200);
- root->setPosition(layerRect.location());
- root->setBounds(layerRect.size());
- root->setContentBounds(layerRect.size());
- root->setQuadRect(IntRect(IntPoint(), layerRect.size()));
- root->setQuadVisibleRect(IntRect(IntPoint(), layerRect.size()));
+ child->setPosition(layerRect.location());
+ child->setBounds(layerRect.size());
+ child->setContentBounds(layerRect.size());
+ child->setQuadRect(IntRect(IntPoint(), layerRect.size()));
+ child->setQuadVisibleRect(IntRect(IntPoint(), layerRect.size()));
LayerTreeHostImpl::FrameData frame;
EXPECT_TRUE(m_hostImpl->prepareToDraw(frame));
@@ -1862,7 +1863,7 @@ TEST_P(LayerTreeHostImplTest, viewportCovered)
EXPECT_EQ(4u, numGutterQuads);
EXPECT_EQ(5u, frame.renderPasses[0]->quadList().size());
- verifyQuadsExactlyCoverRect(frame.renderPasses[0]->quadList(), IntRect(-layerRect.location(), viewportSize));
+ verifyQuadsExactlyCoverRect(frame.renderPasses[0]->quadList(), IntRect(IntPoint::zero(), viewportSize));
m_hostImpl->didDrawAllLayers(frame);
}
diff --git a/cc/layer_tree_host_unittest.cc b/cc/layer_tree_host_unittest.cc
index 030ee97..f91cec6 100644
--- a/cc/layer_tree_host_unittest.cc
+++ b/cc/layer_tree_host_unittest.cc
@@ -651,7 +651,7 @@ public:
virtual void beginTest() OVERRIDE
{
- postAddAnimationToMainThread();
+ postAddAnimationToMainThread(m_layerTreeHost->rootLayer());
}
virtual void afterTest() OVERRIDE
@@ -694,7 +694,7 @@ public:
virtual void beginTest() OVERRIDE
{
- postAddAnimationToMainThread();
+ postAddAnimationToMainThread(m_layerTreeHost->rootLayer());
}
// Use willAnimateLayers to set visible false before the animation runs and
@@ -732,7 +732,7 @@ public:
virtual void beginTest() OVERRIDE
{
- postAddAnimationToMainThread();
+ postAddAnimationToMainThread(m_layerTreeHost->rootLayer());
}
virtual void animateLayers(LayerTreeHostImpl* layerTreeHostImpl, base::TimeTicks monotonicTime) OVERRIDE
@@ -761,40 +761,6 @@ private:
SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestAddAnimationWithTimingFunction)
-// Ensures that when opacity is being animated, this value does not cause the subtree to be skipped.
-class LayerTreeHostTestDoNotSkipLayersWithAnimatedOpacity : public LayerTreeHostTest {
-public:
- LayerTreeHostTestDoNotSkipLayersWithAnimatedOpacity()
- {
- }
-
- virtual void beginTest() OVERRIDE
- {
- m_layerTreeHost->rootLayer()->setDrawOpacity(1);
- m_layerTreeHost->setViewportSize(IntSize(10, 10), IntSize(10, 10));
- m_layerTreeHost->rootLayer()->setOpacity(0);
- postAddAnimationToMainThread();
- }
-
- virtual void commitCompleteOnThread(LayerTreeHostImpl*) OVERRIDE
- {
- // If the subtree was skipped when preparing to draw, the layer's draw opacity
- // will not have been updated. It should be set to 0 due to the animation.
- // Without the animation, the layer will be skipped since it has zero opacity.
- EXPECT_EQ(0, m_layerTreeHost->rootLayer()->drawOpacity());
- endTest();
- }
-
- virtual void afterTest() OVERRIDE
- {
- }
-};
-
-TEST_F(LayerTreeHostTestDoNotSkipLayersWithAnimatedOpacity, runMultiThread)
-{
- runTest(true);
-}
-
// Ensures that main thread animations have their start times synchronized with impl thread animations.
class LayerTreeHostTestSynchronizeAnimationStartTimes : public LayerTreeHostTest {
public:
@@ -805,7 +771,7 @@ public:
virtual void beginTest() OVERRIDE
{
- postAddAnimationToMainThread();
+ postAddAnimationToMainThread(m_layerTreeHost->rootLayer());
}
// This is guaranteed to be called before CCLayerTreeHostImpl::animateLayers.
@@ -1155,19 +1121,25 @@ TEST_F(LayerTreeHostTestSetVisible, runMultiThread)
class TestOpacityChangeLayerDelegate : public ContentLayerClient {
public:
- TestOpacityChangeLayerDelegate(LayerTreeHostTest* test)
- : m_test(test)
+ TestOpacityChangeLayerDelegate()
+ : m_testLayer(0)
+ {
+ }
+
+ void setTestLayer(Layer* testLayer)
{
+ m_testLayer = testLayer;
}
virtual void paintContents(SkCanvas*, const IntRect&, FloatRect&) OVERRIDE
{
// Set layer opacity to 0.
- m_test->layerTreeHost()->rootLayer()->setOpacity(0);
+ if (m_testLayer)
+ m_testLayer->setOpacity(0);
}
private:
- LayerTreeHostTest* m_test;
+ Layer* m_testLayer;
};
class ContentLayerWithUpdateTracking : public ContentLayer {
@@ -1203,15 +1175,16 @@ private:
class LayerTreeHostTestOpacityChange : public LayerTreeHostTest {
public:
LayerTreeHostTestOpacityChange()
- : m_testOpacityChangeDelegate(this)
+ : m_testOpacityChangeDelegate()
, m_updateCheckLayer(ContentLayerWithUpdateTracking::create(&m_testOpacityChangeDelegate))
{
+ m_testOpacityChangeDelegate.setTestLayer(m_updateCheckLayer.get());
}
virtual void beginTest() OVERRIDE
{
- m_layerTreeHost->setRootLayer(m_updateCheckLayer);
m_layerTreeHost->setViewportSize(IntSize(10, 10), IntSize(10, 10));
+ m_layerTreeHost->rootLayer()->addChild(m_updateCheckLayer);
postSetNeedsCommitToMainThread();
}
@@ -1260,6 +1233,47 @@ private:
virtual ~NoScaleContentLayer() { }
};
+// Ensures that when opacity is being animated, this value does not cause the subtree to be skipped.
+class LayerTreeHostTestDoNotSkipLayersWithAnimatedOpacity : public LayerTreeHostTest {
+public:
+ LayerTreeHostTestDoNotSkipLayersWithAnimatedOpacity()
+ : m_updateCheckLayer(ContentLayerWithUpdateTracking::create(&m_client))
+ {
+ }
+
+ virtual void beginTest() OVERRIDE
+ {
+ m_layerTreeHost->setViewportSize(IntSize(10, 10), IntSize(10, 10));
+ m_layerTreeHost->rootLayer()->addChild(m_updateCheckLayer);
+ m_updateCheckLayer->setOpacity(0);
+ m_updateCheckLayer->setDrawOpacity(0);
+ postAddAnimationToMainThread(m_updateCheckLayer.get());
+ }
+
+ virtual void commitCompleteOnThread(LayerTreeHostImpl*) OVERRIDE
+ {
+ endTest();
+ }
+
+ virtual void afterTest() OVERRIDE
+ {
+ // update() should have been called once, proving that the layer was not skipped.
+ EXPECT_EQ(1, m_updateCheckLayer->paintContentsCount());
+
+ // clear m_updateCheckLayer so LayerTreeHost dies.
+ m_updateCheckLayer = NULL;
+ }
+
+private:
+ MockContentLayerClient m_client;
+ scoped_refptr<ContentLayerWithUpdateTracking> m_updateCheckLayer;
+};
+
+TEST_F(LayerTreeHostTestDoNotSkipLayersWithAnimatedOpacity, runMultiThread)
+{
+ runTest(true);
+}
+
class LayerTreeHostTestDeviceScaleFactorScalesViewportAndLayers : public LayerTreeHostTest {
public:
diff --git a/cc/test/layer_test_common.cc b/cc/test/layer_test_common.cc
index 1a41eec..72546dd 100644
--- a/cc/test/layer_test_common.cc
+++ b/cc/test/layer_test_common.cc
@@ -7,6 +7,7 @@
#include "cc/test/layer_test_common.h"
#include "cc/draw_quad.h"
+#include "cc/math_util.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace LayerTestCommon {
@@ -14,13 +15,35 @@ namespace LayerTestCommon {
// Align with expected and actual output
const char* quadString = " Quad: ";
+bool floatRectCanBeSafelyRoundedToIntRect(const cc::FloatRect& r)
+{
+ // Ensure that range of float values is not beyond integer range.
+ if (!r.isExpressibleAsIntRect())
+ return false;
+
+ // Ensure that the values are actually integers.
+ if (floorf(r.x()) == r.x()
+ && floorf(r.y()) == r.y()
+ && floorf(r.width()) == r.width()
+ && floorf(r.height()) == r.height())
+ return true;
+
+ return false;
+}
+
void verifyQuadsExactlyCoverRect(const cc::QuadList& quads,
const cc::IntRect& rect) {
cc::Region remaining(rect);
for (size_t i = 0; i < quads.size(); ++i) {
cc::DrawQuad* quad = quads[i];
- cc::IntRect quadRect = cc::IntRect(quad->quadRect());
+ cc::FloatRect floatQuadRect = cc::MathUtil::mapClippedRect(quad->sharedQuadState()->quadTransform, cc::FloatRect(quad->quadRect()));
+
+ // Before testing for exact coverage in the integer world, assert that rounding
+ // will not round the rect incorrectly.
+ ASSERT_TRUE(floatRectCanBeSafelyRoundedToIntRect(floatQuadRect));
+
+ cc::IntRect quadRect = enclosingIntRect(floatQuadRect);
EXPECT_TRUE(rect.contains(quadRect)) << quadString << i;
EXPECT_TRUE(remaining.contains(quadRect)) << quadString << i;
diff --git a/cc/test/layer_tree_test_common.cc b/cc/test/layer_tree_test_common.cc
index 2bb5d41..0d77c67 100644
--- a/cc/test/layer_tree_test_common.cc
+++ b/cc/test/layer_tree_test_common.cc
@@ -350,9 +350,9 @@ void ThreadedTest::postSetNeedsAnimateToMainThread()
m_mainThreadProxy->postTask(createThreadTask(this, &ThreadedTest::dispatchSetNeedsAnimate));
}
-void ThreadedTest::postAddAnimationToMainThread()
+void ThreadedTest::postAddAnimationToMainThread(Layer* layerToReceiveAnimation)
{
- m_mainThreadProxy->postTask(createThreadTask(this, &ThreadedTest::dispatchAddAnimation));
+ m_mainThreadProxy->postTask(createThreadTask(this, &ThreadedTest::dispatchAddAnimation, layerToReceiveAnimation));
}
void ThreadedTest::postAddInstantAnimationToMainThread()
@@ -456,15 +456,15 @@ void ThreadedTest::dispatchAddInstantAnimation()
addOpacityTransitionToLayer(*m_layerTreeHost->rootLayer(), 0, 0, 0.5, false);
}
-void ThreadedTest::dispatchAddAnimation()
+void ThreadedTest::dispatchAddAnimation(Layer* layerToReceiveAnimation)
{
DCHECK(Proxy::isMainThread());
if (m_finished)
return;
- if (m_layerTreeHost.get() && m_layerTreeHost->rootLayer())
- addOpacityTransitionToLayer(*m_layerTreeHost->rootLayer(), 10, 0, 0.5, true);
+ if (layerToReceiveAnimation)
+ addOpacityTransitionToLayer(*layerToReceiveAnimation, 10, 0, 0.5, true);
}
void ThreadedTest::dispatchSetNeedsAnimateAndCommit()
diff --git a/cc/test/layer_tree_test_common.h b/cc/test/layer_tree_test_common.h
index 10f35ca..c8d1c36 100644
--- a/cc/test/layer_tree_test_common.h
+++ b/cc/test/layer_tree_test_common.h
@@ -77,7 +77,7 @@ public:
void endTestAfterDelay(int delayMilliseconds);
void postSetNeedsAnimateToMainThread();
- void postAddAnimationToMainThread();
+ void postAddAnimationToMainThread(cc::Layer*);
void postAddInstantAnimationToMainThread();
void postSetNeedsCommitToMainThread();
void postAcquireLayerTextures();
@@ -104,7 +104,7 @@ protected:
void dispatchSetNeedsAnimate();
void dispatchAddInstantAnimation();
- void dispatchAddAnimation();
+ void dispatchAddAnimation(cc::Layer*);
void dispatchSetNeedsAnimateAndCommit();
void dispatchSetNeedsCommit();
void dispatchAcquireLayerTextures();