summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordanakj@chromium.org <danakj@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-10-12 01:41:18 +0000
committerdanakj@chromium.org <danakj@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-10-12 01:41:18 +0000
commit8a000dd636d22d254773bdf92e853ea74d5ae0d8 (patch)
treed84e16a799bef4f488d1102ee51797eb0371a66c
parent289495963093bb67589054fade2164cb8d1826fb (diff)
downloadchromium_src-8a000dd636d22d254773bdf92e853ea74d5ae0d8.zip
chromium_src-8a000dd636d22d254773bdf92e853ea74d5ae0d8.tar.gz
chromium_src-8a000dd636d22d254773bdf92e853ea74d5ae0d8.tar.bz2
cc: Apply the layer's initial CSS scale to the contentsScale to render text at the right resolution.
Currently the transform does not affect the scale of a layer's contents. This means that when a layer with a scale on it becomes composited, its text is rendered at 1x and then scaled up during rendering, which makes for very fuzzy text. This change applies the scale from the layer's CSS transform to the contentsScale so that text is rendered at the same pixel resolution as it will be drawn on screen. Tests: cc_unittests:CCLayerTreeHostCommonTest.verifyContentsScale cc_unittests:CCLayerTreeHostCommonTest.verifyContentsScaleForSurfaces BUG=149943 Review URL: https://chromiumcodereview.appspot.com/10915313 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@161472 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--cc/CCDamageTrackerTest.cpp2
-rw-r--r--cc/CCLayerIteratorTest.cpp6
-rw-r--r--cc/CCLayerTreeHost.cpp29
-rw-r--r--cc/CCLayerTreeHostCommon.cpp102
-rw-r--r--cc/CCLayerTreeHostCommon.h4
-rw-r--r--cc/CCLayerTreeHostCommonTest.cpp344
-rw-r--r--cc/CCLayerTreeHostImpl.cpp3
-rw-r--r--cc/CCLayerTreeHostImplTest.cpp8
-rw-r--r--cc/CCMathUtil.cpp15
-rw-r--r--cc/CCMathUtil.h2
-rw-r--r--cc/CCOcclusionTrackerTest.cpp96
-rw-r--r--cc/LayerChromium.cpp1
-rw-r--r--cc/LayerChromium.h6
13 files changed, 461 insertions, 157 deletions
diff --git a/cc/CCDamageTrackerTest.cpp b/cc/CCDamageTrackerTest.cpp
index eac6658..49d0b67 100644
--- a/cc/CCDamageTrackerTest.cpp
+++ b/cc/CCDamageTrackerTest.cpp
@@ -34,7 +34,7 @@ void executeCalculateDrawTransformsAndVisibility(CCLayerImpl* root, std::vector<
ASSERT_TRUE(root->renderSurface());
ASSERT_FALSE(renderSurfaceLayerList.size());
- CCLayerTreeHostCommon::calculateDrawTransforms(root, root->bounds(), 1, &layerSorter, dummyMaxTextureSize, renderSurfaceLayerList);
+ CCLayerTreeHostCommon::calculateDrawTransforms(root, root->bounds(), 1, 1, &layerSorter, dummyMaxTextureSize, renderSurfaceLayerList);
}
void clearDamageForAllSurfaces(CCLayerImpl* layer)
diff --git a/cc/CCLayerIteratorTest.cpp b/cc/CCLayerIteratorTest.cpp
index c364b96..41a2711 100644
--- a/cc/CCLayerIteratorTest.cpp
+++ b/cc/CCLayerIteratorTest.cpp
@@ -130,7 +130,7 @@ TEST(CCLayerIteratorTest, simpleTree)
rootLayer->addChild(fourth);
std::vector<scoped_refptr<LayerChromium> > renderSurfaceLayerList;
- CCLayerTreeHostCommon::calculateDrawTransforms(rootLayer.get(), rootLayer->bounds(), 1, 256, renderSurfaceLayerList);
+ CCLayerTreeHostCommon::calculateDrawTransforms(rootLayer.get(), rootLayer->bounds(), 1, 1, 256, renderSurfaceLayerList);
iterateBackToFront(&renderSurfaceLayerList);
EXPECT_COUNT(rootLayer, 0, -1, 1);
@@ -172,7 +172,7 @@ TEST(CCLayerIteratorTest, complexTree)
root23->addChild(root231);
std::vector<scoped_refptr<LayerChromium> > renderSurfaceLayerList;
- CCLayerTreeHostCommon::calculateDrawTransforms(rootLayer.get(), rootLayer->bounds(), 1, 256, renderSurfaceLayerList);
+ CCLayerTreeHostCommon::calculateDrawTransforms(rootLayer.get(), rootLayer->bounds(), 1, 1, 256, renderSurfaceLayerList);
iterateBackToFront(&renderSurfaceLayerList);
EXPECT_COUNT(rootLayer, 0, -1, 1);
@@ -227,7 +227,7 @@ TEST(CCLayerIteratorTest, complexTreeMultiSurface)
root23->addChild(root231);
std::vector<scoped_refptr<LayerChromium> > renderSurfaceLayerList;
- CCLayerTreeHostCommon::calculateDrawTransforms(rootLayer.get(), rootLayer->bounds(), 1, 256, renderSurfaceLayerList);
+ CCLayerTreeHostCommon::calculateDrawTransforms(rootLayer.get(), rootLayer->bounds(), 1, 1, 256, renderSurfaceLayerList);
iterateBackToFront(&renderSurfaceLayerList);
EXPECT_COUNT(rootLayer, 0, -1, 1);
diff --git a/cc/CCLayerTreeHost.cpp b/cc/CCLayerTreeHost.cpp
index d75a3d3..6b53c4c 100644
--- a/cc/CCLayerTreeHost.cpp
+++ b/cc/CCLayerTreeHost.cpp
@@ -530,14 +530,6 @@ void CCLayerTreeHost::updateLayers(CCTextureUpdateQueue& queue, size_t memoryAll
updateLayers(rootLayer(), queue);
}
-static void setScale(LayerChromium* layer, float deviceScaleFactor, float pageScaleFactor)
-{
- if (layer->boundsContainPageScale())
- layer->setContentsScale(deviceScaleFactor);
- else
- layer->setContentsScale(deviceScaleFactor * pageScaleFactor);
-}
-
static LayerChromium* findFirstScrollableLayer(LayerChromium* layer)
{
if (!layer)
@@ -555,29 +547,10 @@ static LayerChromium* findFirstScrollableLayer(LayerChromium* layer)
return 0;
}
-static void updateLayerScale(LayerChromium* layer, float deviceScaleFactor, float pageScaleFactor)
-{
- setScale(layer, deviceScaleFactor, pageScaleFactor);
-
- LayerChromium* maskLayer = layer->maskLayer();
- if (maskLayer)
- setScale(maskLayer, deviceScaleFactor, pageScaleFactor);
-
- LayerChromium* replicaMaskLayer = layer->replicaLayer() ? layer->replicaLayer()->maskLayer() : 0;
- if (replicaMaskLayer)
- setScale(replicaMaskLayer, deviceScaleFactor, pageScaleFactor);
-
- const std::vector<scoped_refptr<LayerChromium> >& children = layer->children();
- for (unsigned int i = 0; i < children.size(); ++i)
- updateLayerScale(children[i].get(), deviceScaleFactor, pageScaleFactor);
-}
-
void CCLayerTreeHost::updateLayers(LayerChromium* rootLayer, CCTextureUpdateQueue& queue)
{
TRACE_EVENT0("cc", "CCLayerTreeHost::updateLayers");
- updateLayerScale(rootLayer, m_deviceScaleFactor, m_pageScaleFactor);
-
LayerList updateList;
{
@@ -588,7 +561,7 @@ void CCLayerTreeHost::updateLayers(LayerChromium* rootLayer, CCTextureUpdateQueu
}
TRACE_EVENT0("cc", "CCLayerTreeHost::updateLayers::calcDrawEtc");
- CCLayerTreeHostCommon::calculateDrawTransforms(rootLayer, deviceViewportSize(), m_deviceScaleFactor, rendererCapabilities().maxTextureSize, updateList);
+ CCLayerTreeHostCommon::calculateDrawTransforms(rootLayer, deviceViewportSize(), m_deviceScaleFactor, m_pageScaleFactor, rendererCapabilities().maxTextureSize, updateList);
}
// Reset partial texture update requests.
diff --git a/cc/CCLayerTreeHostCommon.cpp b/cc/CCLayerTreeHostCommon.cpp
index 24274a6f..10d4aa9 100644
--- a/cc/CCLayerTreeHostCommon.cpp
+++ b/cc/CCLayerTreeHostCommon.cpp
@@ -16,6 +16,7 @@
#include "IntRect.h"
#include "LayerChromium.h"
#include "RenderSurfaceChromium.h"
+#include <algorithm>
#include <public/WebTransformationMatrix.h>
using WebKit::WebTransformationMatrix;
@@ -344,6 +345,35 @@ WebTransformationMatrix computeScrollCompensationMatrixForChildren(CCLayerImpl*
return nextScrollCompensationMatrix;
}
+// There is no contentsScale on impl thread.
+static inline void updateLayerContentsScale(CCLayerImpl*, const WebTransformationMatrix&, float, float) { }
+
+static inline void updateLayerContentsScale(LayerChromium* layer, const WebTransformationMatrix& combinedTransform, float deviceScaleFactor, float pageScaleFactor)
+{
+ float cssScale = layer->initialCssScale();
+ if (!cssScale) {
+ FloatPoint transformScale = CCMathUtil::computeTransform2dScaleComponents(combinedTransform);
+ float combinedScale = std::max(transformScale.x(), transformScale.y());
+ cssScale = combinedScale / deviceScaleFactor;
+ if (!layer->boundsContainPageScale())
+ cssScale /= pageScaleFactor;
+ layer->setInitialCssScale(cssScale);
+ }
+
+ float contentsScale = cssScale * deviceScaleFactor;
+ if (!layer->boundsContainPageScale())
+ contentsScale *= pageScaleFactor;
+ layer->setContentsScale(contentsScale);
+
+ LayerChromium* maskLayer = layer->maskLayer();
+ if (maskLayer)
+ maskLayer->setContentsScale(contentsScale);
+
+ LayerChromium* replicaMaskLayer = layer->replicaLayer() ? layer->replicaLayer()->maskLayer() : 0;
+ if (replicaMaskLayer)
+ 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)
@@ -365,7 +395,7 @@ static void calculateDrawTransformsInternal(LayerType* layer, LayerType* rootLay
const WebTransformationMatrix& fullHierarchyMatrix, const WebTransformationMatrix& currentScrollCompensationMatrix,
const IntRect& clipRectFromAncestor, bool ancestorClipsSubtree,
RenderSurfaceType* nearestAncestorThatMovesPixels, LayerList& renderSurfaceLayerList, LayerList& layerList,
- LayerSorter* layerSorter, int maxTextureSize, float deviceScaleFactor, IntRect& drawableContentRectOfSubtree)
+ LayerSorter* layerSorter, int maxTextureSize, float deviceScaleFactor, float pageScaleFactor, IntRect& drawableContentRectOfSubtree)
{
// This function computes the new matrix transformations recursively for this
// layer and all its descendants. It also computes the appropriate render surfaces.
@@ -470,18 +500,24 @@ static void calculateDrawTransformsInternal(LayerType* layer, LayerType* rootLay
FloatPoint position = layer->position() - layer->scrollDelta();
WebTransformationMatrix layerLocalTransform;
- // LT = M[impl transformation]
- layerLocalTransform.multiply(layer->implTransform());
- // LT = M[impl transformation] * Tr[origin] * Tr[origin2anchor]
+ // LT = Tr[origin] * Tr[origin2anchor]
layerLocalTransform.translate3d(position.x() + anchorPoint.x() * bounds.width(), position.y() + anchorPoint.y() * bounds.height(), layer->anchorPointZ());
- // LT = M[impl transformation] * Tr[origin] * Tr[origin2anchor] * M[layer]
+ // LT = Tr[origin] * Tr[origin2anchor] * M[layer]
layerLocalTransform.multiply(layer->transform());
- // LT = S[impl transformation] * Tr[origin] * Tr[origin2anchor] * M[layer] * Tr[anchor2origin]
+ // LT = Tr[origin] * Tr[origin2anchor] * M[layer] * Tr[anchor2origin]
layerLocalTransform.translate3d(-anchorPoint.x() * bounds.width(), -anchorPoint.y() * bounds.height(), -layer->anchorPointZ());
WebTransformationMatrix combinedTransform = parentMatrix;
combinedTransform.multiply(layerLocalTransform);
+ // The layer's contentsSize is determined from the combinedTransform, which then informs the
+ // layer's drawTransform.
+ updateLayerContentsScale(layer, combinedTransform, deviceScaleFactor, pageScaleFactor);
+
+ // If there is a tranformation from the impl thread then it should be at the
+ // start of the combinedTransform, but we don't want it to affect the contentsScale.
+ combinedTransform = layer->implTransform() * combinedTransform;
+
if (layer->fixedToContainerLayer()) {
// Special case: this layer is a composited fixed-position layer; we need to
// explicitly compensate for all ancestors' nonzero scrollDeltas to keep this layer
@@ -519,6 +555,8 @@ static void calculateDrawTransformsInternal(LayerType* layer, LayerType* rootLay
WebTransformationMatrix nextHierarchyMatrix = fullHierarchyMatrix;
WebTransformationMatrix sublayerMatrix;
+ FloatPoint renderSurfaceSublayerScale = CCMathUtil::computeTransform2dScaleComponents(combinedTransform);
+
if (subtreeShouldRenderToSeparateSurface(layer, isScaleOrTranslation(combinedTransform))) {
// Check back-face visibility before continuing with this surface and its subtree
if (!layer->doubleSided() && transformToParentIsKnown(layer) && isSurfaceBackFaceVisible(layer, combinedTransform))
@@ -530,20 +568,29 @@ static void calculateDrawTransformsInternal(LayerType* layer, LayerType* rootLay
RenderSurfaceType* renderSurface = layer->renderSurface();
renderSurface->clearLayerLists();
- // The origin of the new surface is the upper left corner of the layer.
+ // The owning layer's draw transform has a scale from content to layer space which we need to undo and
+ // replace with a scale from the surface's subtree into layer space.
+ if (!layer->contentBounds().isEmpty() && !layer->bounds().isEmpty()) {
+ drawTransform.scaleNonUniform(layer->contentBounds().width() / static_cast<double>(layer->bounds().width()),
+ layer->contentBounds().height() / static_cast<double>(layer->bounds().height()));
+ }
+ drawTransform.scaleNonUniform(1 / renderSurfaceSublayerScale.x(), 1 / renderSurfaceSublayerScale.y());
renderSurface->setDrawTransform(drawTransform);
+
+ // The origin of the new surface is the upper left corner of the layer.
WebTransformationMatrix layerDrawTransform;
- layerDrawTransform.scale(deviceScaleFactor);
+ layerDrawTransform.scaleNonUniform(renderSurfaceSublayerScale.x(), renderSurfaceSublayerScale.y());
if (!layer->contentBounds().isEmpty() && !layer->bounds().isEmpty()) {
layerDrawTransform.scaleNonUniform(layer->bounds().width() / static_cast<double>(layer->contentBounds().width()),
layer->bounds().height() / static_cast<double>(layer->contentBounds().height()));
}
layer->setDrawTransform(layerDrawTransform);
+ // Inside the surface's subtree, we scale everything to the owning layer's scale.
// The sublayer matrix transforms centered layer rects into target
// surface content space.
sublayerMatrix.makeIdentity();
- sublayerMatrix.scale(deviceScaleFactor);
+ sublayerMatrix.scaleNonUniform(renderSurfaceSublayerScale.x(), renderSurfaceSublayerScale.y());
// The opacity value is moved from the layer to its surface, so that the entire subtree properly inherits opacity.
renderSurface->setDrawOpacity(drawOpacity);
@@ -655,7 +702,7 @@ static void calculateDrawTransformsInternal(LayerType* layer, LayerType* rootLay
IntRect drawableContentRectOfChildSubtree;
calculateDrawTransformsInternal<LayerType, LayerList, RenderSurfaceType, LayerSorter>(child, rootLayer, sublayerMatrix, nextHierarchyMatrix, nextScrollCompensationMatrix,
clipRectForSubtree, subtreeShouldBeClipped, nearestAncestorThatMovesPixels,
- renderSurfaceLayerList, descendants, layerSorter, maxTextureSize, deviceScaleFactor, drawableContentRectOfChildSubtree);
+ renderSurfaceLayerList, descendants, layerSorter, maxTextureSize, deviceScaleFactor, pageScaleFactor, drawableContentRectOfChildSubtree);
if (!drawableContentRectOfChildSubtree.isEmpty()) {
accumulatedDrawableContentRectOfChildren.unite(drawableContentRectOfChildSubtree);
if (child->renderSurface())
@@ -706,16 +753,25 @@ static void calculateDrawTransformsInternal(LayerType* layer, LayerType* rootLay
renderSurface->clearLayerLists();
renderSurface->setContentRect(clippedContentRect);
- renderSurface->setScreenSpaceTransform(layer->screenSpaceTransform());
+
+ // The owning layer's screenSpaceTransform has a scale from content to layer space which we need to undo and
+ // replace with a scale from the surface's subtree into layer space.
+ WebTransformationMatrix screenSpaceTransform = layer->screenSpaceTransform();
+ if (!layer->contentBounds().isEmpty() && !layer->bounds().isEmpty()) {
+ screenSpaceTransform.scaleNonUniform(layer->contentBounds().width() / static_cast<double>(layer->bounds().width()),
+ layer->contentBounds().height() / static_cast<double>(layer->bounds().height()));
+ }
+ screenSpaceTransform.scaleNonUniform(1 / renderSurfaceSublayerScale.x(), 1 / renderSurfaceSublayerScale.y());
+ renderSurface->setScreenSpaceTransform(screenSpaceTransform);
if (layer->replicaLayer()) {
WebTransformationMatrix surfaceOriginToReplicaOriginTransform;
- surfaceOriginToReplicaOriginTransform.scale(deviceScaleFactor);
+ surfaceOriginToReplicaOriginTransform.scaleNonUniform(renderSurfaceSublayerScale.x(), renderSurfaceSublayerScale.y());
surfaceOriginToReplicaOriginTransform.translate(layer->replicaLayer()->position().x() + layer->replicaLayer()->anchorPoint().x() * bounds.width(),
layer->replicaLayer()->position().y() + layer->replicaLayer()->anchorPoint().y() * bounds.height());
surfaceOriginToReplicaOriginTransform.multiply(layer->replicaLayer()->transform());
surfaceOriginToReplicaOriginTransform.translate(-layer->replicaLayer()->anchorPoint().x() * bounds.width(), -layer->replicaLayer()->anchorPoint().y() * bounds.height());
- surfaceOriginToReplicaOriginTransform.scale(1 / deviceScaleFactor);
+ surfaceOriginToReplicaOriginTransform.scaleNonUniform(1 / renderSurfaceSublayerScale.x(), 1 / renderSurfaceSublayerScale.y());
// Compute the replica's "originTransform" that maps from the replica's origin space to the target surface origin space.
WebTransformationMatrix replicaOriginTransform = layer->renderSurface()->drawTransform() * surfaceOriginToReplicaOriginTransform;
@@ -763,7 +819,7 @@ static void calculateDrawTransformsInternal(LayerType* layer, LayerType* rootLay
layer->renderTarget()->renderSurface()->addContributingDelegatedRenderPassLayer(layer);
}
-void CCLayerTreeHostCommon::calculateDrawTransforms(LayerChromium* rootLayer, const IntSize& deviceViewportSize, float deviceScaleFactor, int maxTextureSize, std::vector<scoped_refptr<LayerChromium> >& renderSurfaceLayerList)
+void CCLayerTreeHostCommon::calculateDrawTransforms(LayerChromium* rootLayer, const IntSize& deviceViewportSize, float deviceScaleFactor, float pageScaleFactor, int maxTextureSize, std::vector<scoped_refptr<LayerChromium> >& renderSurfaceLayerList)
{
IntRect totalDrawableContentRect;
WebTransformationMatrix identityMatrix;
@@ -772,12 +828,14 @@ void CCLayerTreeHostCommon::calculateDrawTransforms(LayerChromium* rootLayer, co
setupRootLayerAndSurfaceForRecursion<LayerChromium, std::vector<scoped_refptr<LayerChromium> > >(rootLayer, renderSurfaceLayerList, deviceViewportSize);
- cc::calculateDrawTransformsInternal<LayerChromium, std::vector<scoped_refptr<LayerChromium> >, RenderSurfaceChromium, void>(rootLayer, rootLayer, deviceScaleTransform, identityMatrix, identityMatrix,
- rootLayer->renderSurface()->contentRect(), true, 0, renderSurfaceLayerList,
- rootLayer->renderSurface()->layerList(), 0, maxTextureSize, deviceScaleFactor, totalDrawableContentRect);
+ cc::calculateDrawTransformsInternal<LayerChromium, std::vector<scoped_refptr<LayerChromium> >, RenderSurfaceChromium, void>(
+ rootLayer, rootLayer, deviceScaleTransform, identityMatrix, identityMatrix,
+ rootLayer->renderSurface()->contentRect(), true, 0, renderSurfaceLayerList,
+ rootLayer->renderSurface()->layerList(), 0, maxTextureSize,
+ deviceScaleFactor, pageScaleFactor, totalDrawableContentRect);
}
-void CCLayerTreeHostCommon::calculateDrawTransforms(CCLayerImpl* rootLayer, const IntSize& deviceViewportSize, float deviceScaleFactor, CCLayerSorter* layerSorter, int maxTextureSize, std::vector<CCLayerImpl*>& renderSurfaceLayerList)
+void CCLayerTreeHostCommon::calculateDrawTransforms(CCLayerImpl* rootLayer, const IntSize& deviceViewportSize, float deviceScaleFactor, float pageScaleFactor, CCLayerSorter* layerSorter, int maxTextureSize, std::vector<CCLayerImpl*>& renderSurfaceLayerList)
{
IntRect totalDrawableContentRect;
WebTransformationMatrix identityMatrix;
@@ -786,9 +844,11 @@ void CCLayerTreeHostCommon::calculateDrawTransforms(CCLayerImpl* rootLayer, cons
setupRootLayerAndSurfaceForRecursion<CCLayerImpl, std::vector<CCLayerImpl*> >(rootLayer, renderSurfaceLayerList, deviceViewportSize);
- cc::calculateDrawTransformsInternal<CCLayerImpl, std::vector<CCLayerImpl*>, CCRenderSurface, CCLayerSorter>(rootLayer, rootLayer, deviceScaleTransform, identityMatrix, identityMatrix,
- rootLayer->renderSurface()->contentRect(), true, 0, renderSurfaceLayerList,
- rootLayer->renderSurface()->layerList(), layerSorter, maxTextureSize, deviceScaleFactor, totalDrawableContentRect);
+ cc::calculateDrawTransformsInternal<CCLayerImpl, std::vector<CCLayerImpl*>, CCRenderSurface, CCLayerSorter>(
+ rootLayer, rootLayer, deviceScaleTransform, identityMatrix, identityMatrix,
+ rootLayer->renderSurface()->contentRect(), true, 0, renderSurfaceLayerList,
+ rootLayer->renderSurface()->layerList(), layerSorter, maxTextureSize,
+ deviceScaleFactor, pageScaleFactor, totalDrawableContentRect);
}
static bool pointHitsRect(const IntPoint& viewportPoint, const WebTransformationMatrix& localSpaceToScreenSpaceTransform, FloatRect localSpaceRect)
diff --git a/cc/CCLayerTreeHostCommon.h b/cc/CCLayerTreeHostCommon.h
index f5bcf2b..cf80a0cc 100644
--- a/cc/CCLayerTreeHostCommon.h
+++ b/cc/CCLayerTreeHostCommon.h
@@ -22,8 +22,8 @@ class CCLayerTreeHostCommon {
public:
static IntRect calculateVisibleRect(const IntRect& targetSurfaceRect, const IntRect& layerBoundRect, const WebKit::WebTransformationMatrix&);
- static void calculateDrawTransforms(LayerChromium* rootLayer, const IntSize& deviceViewportSize, float deviceScaleFactor, int maxTextureSize, std::vector<scoped_refptr<LayerChromium> >& renderSurfaceLayerList);
- static void calculateDrawTransforms(CCLayerImpl* rootLayer, const IntSize& deviceViewportSize, float deviceScaleFactor, CCLayerSorter*, int maxTextureSize, std::vector<CCLayerImpl*>& renderSurfaceLayerList);
+ static void calculateDrawTransforms(LayerChromium* rootLayer, const IntSize& deviceViewportSize, float deviceScaleFactor, float pageScaleFactor, int maxTextureSize, std::vector<scoped_refptr<LayerChromium> >& renderSurfaceLayerList);
+ static void calculateDrawTransforms(CCLayerImpl* rootLayer, const IntSize& deviceViewportSize, float deviceScaleFactor, float pageScaleFactor, CCLayerSorter*, int maxTextureSize, std::vector<CCLayerImpl*>& renderSurfaceLayerList);
// Performs hit testing for a given renderSurfaceLayerList.
static CCLayerImpl* findLayerThatIsHitByPoint(const IntPoint& viewportPoint, std::vector<CCLayerImpl*>& renderSurfaceLayerList);
diff --git a/cc/CCLayerTreeHostCommonTest.cpp b/cc/CCLayerTreeHostCommonTest.cpp
index 2fb4fe8..5d46962 100644
--- a/cc/CCLayerTreeHostCommonTest.cpp
+++ b/cc/CCLayerTreeHostCommonTest.cpp
@@ -51,7 +51,7 @@ void setLayerPropertiesForTesting(CCLayerImpl* layer, const WebTransformationMat
layer->setContentBounds(bounds);
}
-void executeCalculateDrawTransformsAndVisibility(LayerChromium* rootLayer, float deviceScaleFactor = 1)
+void executeCalculateDrawTransformsAndVisibility(LayerChromium* rootLayer, float deviceScaleFactor = 1, float pageScaleFactor = 1)
{
WebTransformationMatrix identityMatrix;
std::vector<scoped_refptr<LayerChromium> > dummyRenderSurfaceLayerList;
@@ -60,10 +60,10 @@ void executeCalculateDrawTransformsAndVisibility(LayerChromium* rootLayer, float
// We are probably not testing what is intended if the rootLayer bounds are empty.
ASSERT(!rootLayer->bounds().isEmpty());
- CCLayerTreeHostCommon::calculateDrawTransforms(rootLayer, deviceViewportSize, deviceScaleFactor, dummyMaxTextureSize, dummyRenderSurfaceLayerList);
+ CCLayerTreeHostCommon::calculateDrawTransforms(rootLayer, deviceViewportSize, deviceScaleFactor, pageScaleFactor, dummyMaxTextureSize, dummyRenderSurfaceLayerList);
}
-void executeCalculateDrawTransformsAndVisibility(CCLayerImpl* rootLayer, float deviceScaleFactor = 1)
+void executeCalculateDrawTransformsAndVisibility(CCLayerImpl* rootLayer, float deviceScaleFactor = 1, float pageScaleFactor = 1)
{
// Note: this version skips layer sorting.
@@ -74,7 +74,7 @@ void executeCalculateDrawTransformsAndVisibility(CCLayerImpl* rootLayer, float d
// We are probably not testing what is intended if the rootLayer bounds are empty.
ASSERT(!rootLayer->bounds().isEmpty());
- CCLayerTreeHostCommon::calculateDrawTransforms(rootLayer, deviceViewportSize, deviceScaleFactor, 0, dummyMaxTextureSize, dummyRenderSurfaceLayerList);
+ CCLayerTreeHostCommon::calculateDrawTransforms(rootLayer, deviceViewportSize, deviceScaleFactor, pageScaleFactor, 0, dummyMaxTextureSize, dummyRenderSurfaceLayerList);
}
WebTransformationMatrix remove3DComponentOfMatrix(const WebTransformationMatrix& mat)
@@ -333,6 +333,10 @@ TEST(CCLayerTreeHostCommonTest, verifyTransformsForSingleRenderSurface)
parentTranslationToCenter.translate(50, 60);
WebTransformationMatrix parentCompositeTransform = parentTranslationToAnchor * parentLayerTransform * parentTranslationToAnchor.inverse()
* parentTranslationToCenter * parentSublayerMatrix * parentTranslationToCenter.inverse();
+ FloatPoint parentCompositeScale = CCMathUtil::computeTransform2dScaleComponents(parentCompositeTransform);
+ WebTransformationMatrix surfaceSublayerTransform;
+ surfaceSublayerTransform.scaleNonUniform(parentCompositeScale.x(), parentCompositeScale.y());
+ WebTransformationMatrix surfaceSublayerCompositeTransform = parentCompositeTransform * surfaceSublayerTransform.inverse();
// Child's render surface should not exist yet.
ASSERT_FALSE(child->renderSurface());
@@ -348,14 +352,15 @@ TEST(CCLayerTreeHostCommonTest, verifyTransformsForSingleRenderSurface)
// The child layer's draw transform should refer to its new render surface.
// The screen-space transform, however, should still refer to the root.
- EXPECT_TRANSFORMATION_MATRIX_EQ(identityMatrix, child->drawTransform());
+ EXPECT_TRANSFORMATION_MATRIX_EQ(surfaceSublayerTransform, child->drawTransform());
EXPECT_TRANSFORMATION_MATRIX_EQ(parentCompositeTransform, child->screenSpaceTransform());
// Because the grandChild is the only drawable content, the child's renderSurface will tighten its bounds to the grandChild.
- EXPECT_TRANSFORMATION_MATRIX_EQ(parentCompositeTransform, child->renderTarget()->renderSurface()->drawTransform());
+ // The scale at which the surface's subtree is drawn must be removed from the composite transform.
+ EXPECT_TRANSFORMATION_MATRIX_EQ(surfaceSublayerCompositeTransform, child->renderTarget()->renderSurface()->drawTransform());
// The screen space is the same as the target since the child surface draws into the root.
- EXPECT_TRANSFORMATION_MATRIX_EQ(parentCompositeTransform, child->renderTarget()->renderSurface()->screenSpaceTransform());
+ EXPECT_TRANSFORMATION_MATRIX_EQ(surfaceSublayerCompositeTransform, child->renderTarget()->renderSurface()->screenSpaceTransform());
}
TEST(CCLayerTreeHostCommonTest, verifyTransformsForReplica)
@@ -386,7 +391,10 @@ TEST(CCLayerTreeHostCommonTest, verifyTransformsForReplica)
childTranslationToCenter.translate(8, 9);
WebTransformationMatrix replicaLayerTransform;
replicaLayerTransform.scale3d(3, 3, 1);
- WebTransformationMatrix replicaCompositeTransform = parentCompositeTransform * replicaLayerTransform;
+ FloatPoint parentCompositeScale = CCMathUtil::computeTransform2dScaleComponents(parentCompositeTransform);
+ WebTransformationMatrix surfaceSublayerTransform;
+ surfaceSublayerTransform.scaleNonUniform(parentCompositeScale.x(), parentCompositeScale.y());
+ WebTransformationMatrix replicaCompositeTransform = parentCompositeTransform * replicaLayerTransform * surfaceSublayerTransform.inverse();
// Child's render surface should not exist yet.
ASSERT_FALSE(child->renderSurface());
@@ -463,6 +471,24 @@ TEST(CCLayerTreeHostCommonTest, verifyTransformsForRenderSurfaceHierarchy)
WebTransformationMatrix R = A * translationToAnchor * replicaLayerTransform * translationToAnchor.inverse();
WebTransformationMatrix identityMatrix;
+ FloatPoint surface1ParentTransformScale = CCMathUtil::computeTransform2dScaleComponents(A * B);
+ WebTransformationMatrix surface1SublayerTransform;
+ surface1SublayerTransform.scaleNonUniform(surface1ParentTransformScale.x(), surface1ParentTransformScale.y());
+
+ // SS1 = transform given to the subtree of renderSurface1
+ WebTransformationMatrix SS1 = surface1SublayerTransform;
+ // S1 = transform to move from renderSurface1 pixels to the layer space of the owning layer
+ WebTransformationMatrix S1 = surface1SublayerTransform.inverse();
+
+ FloatPoint surface2ParentTransformScale = CCMathUtil::computeTransform2dScaleComponents(SS1 * A * B);
+ WebTransformationMatrix surface2SublayerTransform;
+ surface2SublayerTransform.scaleNonUniform(surface2ParentTransformScale.x(), surface2ParentTransformScale.y());
+
+ // SS2 = transform given to the subtree of renderSurface2
+ WebTransformationMatrix SS2 = surface2SublayerTransform;
+ // S2 = transform to move from renderSurface2 pixels to the layer space of the owning layer
+ WebTransformationMatrix S2 = surface2SublayerTransform.inverse();
+
setLayerPropertiesForTesting(parent.get(), layerTransform, sublayerTransform, FloatPoint(0.25, 0), FloatPoint(0, 0), IntSize(10, 10), false);
setLayerPropertiesForTesting(renderSurface1.get(), layerTransform, sublayerTransform, FloatPoint(0.25, 0), FloatPoint(0, 0), IntSize(10, 10), false);
setLayerPropertiesForTesting(renderSurface2.get(), layerTransform, sublayerTransform, FloatPoint(0.25, 0), FloatPoint(0, 0), IntSize(10, 10), false);
@@ -513,13 +539,13 @@ TEST(CCLayerTreeHostCommonTest, verifyTransformsForRenderSurfaceHierarchy)
EXPECT_TRANSFORMATION_MATRIX_EQ(A * B * A, childOfRoot->drawTransform());
EXPECT_TRANSFORMATION_MATRIX_EQ(A * B * A * B * A, grandChildOfRoot->drawTransform());
- EXPECT_TRANSFORMATION_MATRIX_EQ(identityMatrix, renderSurface1->drawTransform());
- EXPECT_TRANSFORMATION_MATRIX_EQ(B * A, childOfRS1->drawTransform());
- EXPECT_TRANSFORMATION_MATRIX_EQ(B * A * B * A, grandChildOfRS1->drawTransform());
+ EXPECT_TRANSFORMATION_MATRIX_EQ(SS1, renderSurface1->drawTransform());
+ EXPECT_TRANSFORMATION_MATRIX_EQ(SS1 * B * A, childOfRS1->drawTransform());
+ EXPECT_TRANSFORMATION_MATRIX_EQ(SS1 * B * A * B * A, grandChildOfRS1->drawTransform());
- EXPECT_TRANSFORMATION_MATRIX_EQ(identityMatrix, renderSurface2->drawTransform());
- EXPECT_TRANSFORMATION_MATRIX_EQ(B * A, childOfRS2->drawTransform());
- EXPECT_TRANSFORMATION_MATRIX_EQ(B * A * B * A, grandChildOfRS2->drawTransform());
+ EXPECT_TRANSFORMATION_MATRIX_EQ(SS2, renderSurface2->drawTransform());
+ EXPECT_TRANSFORMATION_MATRIX_EQ(SS2 * B * A, childOfRS2->drawTransform());
+ EXPECT_TRANSFORMATION_MATRIX_EQ(SS2 * B * A * B * A, grandChildOfRS2->drawTransform());
// Verify layer screen-space transforms
//
@@ -538,15 +564,15 @@ TEST(CCLayerTreeHostCommonTest, verifyTransformsForRenderSurfaceHierarchy)
// Verify render surface transforms.
//
// Draw transform of render surface 1 is described with respect to root.
- EXPECT_TRANSFORMATION_MATRIX_EQ(A * B * A, renderSurface1->renderSurface()->drawTransform());
- EXPECT_TRANSFORMATION_MATRIX_EQ(A * B * R, renderSurface1->renderSurface()->replicaDrawTransform());
- EXPECT_TRANSFORMATION_MATRIX_EQ(A * B * A, renderSurface1->renderSurface()->screenSpaceTransform());
- EXPECT_TRANSFORMATION_MATRIX_EQ(A * B * R, renderSurface1->renderSurface()->replicaScreenSpaceTransform());
- // Draw transform of render surface 2 is described with respect to render surface 2.
- EXPECT_TRANSFORMATION_MATRIX_EQ(B * A, renderSurface2->renderSurface()->drawTransform());
- EXPECT_TRANSFORMATION_MATRIX_EQ(B * R, renderSurface2->renderSurface()->replicaDrawTransform());
- EXPECT_TRANSFORMATION_MATRIX_EQ(A * B * A * B * A, renderSurface2->renderSurface()->screenSpaceTransform());
- EXPECT_TRANSFORMATION_MATRIX_EQ(A * B * A * B * R, renderSurface2->renderSurface()->replicaScreenSpaceTransform());
+ EXPECT_TRANSFORMATION_MATRIX_EQ(A * B * A * S1, renderSurface1->renderSurface()->drawTransform());
+ EXPECT_TRANSFORMATION_MATRIX_EQ(A * B * R * S1, renderSurface1->renderSurface()->replicaDrawTransform());
+ EXPECT_TRANSFORMATION_MATRIX_EQ(A * B * A * S1, renderSurface1->renderSurface()->screenSpaceTransform());
+ EXPECT_TRANSFORMATION_MATRIX_EQ(A * B * R * S1, renderSurface1->renderSurface()->replicaScreenSpaceTransform());
+ // Draw transform of render surface 2 is described with respect to render surface 1.
+ EXPECT_TRANSFORMATION_MATRIX_EQ(SS1 * B * A * S2, renderSurface2->renderSurface()->drawTransform());
+ EXPECT_TRANSFORMATION_MATRIX_EQ(SS1 * B * R * S2, renderSurface2->renderSurface()->replicaDrawTransform());
+ EXPECT_TRANSFORMATION_MATRIX_EQ(A * B * A * B * A * S2, renderSurface2->renderSurface()->screenSpaceTransform());
+ EXPECT_TRANSFORMATION_MATRIX_EQ(A * B * A * B * R * S2, renderSurface2->renderSurface()->replicaScreenSpaceTransform());
// Sanity check. If these fail there is probably a bug in the test itself.
// It is expected that we correctly set up transforms so that the y-component of the screen-space transform
@@ -657,7 +683,7 @@ TEST(CCLayerTreeHostCommonTest, verifyRenderSurfaceListForRenderSurfaceWithClipp
std::vector<scoped_refptr<LayerChromium> > renderSurfaceLayerList;
int dummyMaxTextureSize = 512;
- CCLayerTreeHostCommon::calculateDrawTransforms(parent.get(), parent->bounds(), 1, dummyMaxTextureSize, renderSurfaceLayerList);
+ CCLayerTreeHostCommon::calculateDrawTransforms(parent.get(), parent->bounds(), 1, 1, dummyMaxTextureSize, renderSurfaceLayerList);
// The child layer's content is entirely outside the parent's clip rect, so the intermediate
// render surface should not be listed here, even if it was forced to be created. Render surfaces without children or visible
@@ -684,7 +710,7 @@ TEST(CCLayerTreeHostCommonTest, verifyRenderSurfaceListForTransparentChild)
std::vector<scoped_refptr<LayerChromium> > renderSurfaceLayerList;
int dummyMaxTextureSize = 512;
- CCLayerTreeHostCommon::calculateDrawTransforms(parent.get(), parent->bounds(), 1, dummyMaxTextureSize, renderSurfaceLayerList);
+ CCLayerTreeHostCommon::calculateDrawTransforms(parent.get(), parent->bounds(), 1, 1, dummyMaxTextureSize, renderSurfaceLayerList);
// Since the layer is transparent, renderSurface1->renderSurface() should not have gotten added anywhere.
// Also, the drawable content rect should not have been extended by the children.
@@ -716,7 +742,7 @@ TEST(CCLayerTreeHostCommonTest, verifyForceRenderSurface)
std::vector<scoped_refptr<LayerChromium> > renderSurfaceLayerList;
int dummyMaxTextureSize = 512;
- CCLayerTreeHostCommon::calculateDrawTransforms(parent.get(), parent->bounds(), 1, dummyMaxTextureSize, renderSurfaceLayerList);
+ CCLayerTreeHostCommon::calculateDrawTransforms(parent.get(), parent->bounds(), 1, 1, dummyMaxTextureSize, renderSurfaceLayerList);
// The root layer always creates a renderSurface
EXPECT_TRUE(parent->renderSurface());
@@ -725,7 +751,7 @@ TEST(CCLayerTreeHostCommonTest, verifyForceRenderSurface)
renderSurfaceLayerList.clear();
renderSurface1->setForceRenderSurface(false);
- CCLayerTreeHostCommon::calculateDrawTransforms(parent.get(), parent->bounds(), 1, dummyMaxTextureSize, renderSurfaceLayerList);
+ CCLayerTreeHostCommon::calculateDrawTransforms(parent.get(), parent->bounds(), 1, 1, dummyMaxTextureSize, renderSurfaceLayerList);
EXPECT_TRUE(parent->renderSurface());
EXPECT_FALSE(renderSurface1->renderSurface());
EXPECT_EQ(1U, renderSurfaceLayerList.size());
@@ -1339,7 +1365,7 @@ TEST(CCLayerTreeHostCommonTest, verifyClipRectCullsRenderSurfaces)
std::vector<scoped_refptr<LayerChromium> > renderSurfaceLayerList;
int dummyMaxTextureSize = 512;
- CCLayerTreeHostCommon::calculateDrawTransforms(parent.get(), parent->bounds(), 1, dummyMaxTextureSize, renderSurfaceLayerList);
+ CCLayerTreeHostCommon::calculateDrawTransforms(parent.get(), parent->bounds(), 1, 1, dummyMaxTextureSize, renderSurfaceLayerList);
ASSERT_EQ(2U, renderSurfaceLayerList.size());
EXPECT_EQ(parent->id(), renderSurfaceLayerList[0]->id());
@@ -1384,7 +1410,7 @@ TEST(CCLayerTreeHostCommonTest, verifyClipRectCullsSurfaceWithoutVisibleContent)
std::vector<scoped_refptr<LayerChromium> > renderSurfaceLayerList;
int dummyMaxTextureSize = 512;
- CCLayerTreeHostCommon::calculateDrawTransforms(parent.get(), parent->bounds(), 1, dummyMaxTextureSize, renderSurfaceLayerList);
+ CCLayerTreeHostCommon::calculateDrawTransforms(parent.get(), parent->bounds(), 1, 1, dummyMaxTextureSize, renderSurfaceLayerList);
// Without an animation, we should cull child and grandChild from the renderSurfaceLayerList.
ASSERT_EQ(1U, renderSurfaceLayerList.size());
@@ -1398,7 +1424,7 @@ TEST(CCLayerTreeHostCommonTest, verifyClipRectCullsSurfaceWithoutVisibleContent)
grandChild->clearRenderSurface();
renderSurfaceLayerList.clear();
- CCLayerTreeHostCommon::calculateDrawTransforms(parent.get(), parent->bounds(), 1, dummyMaxTextureSize, renderSurfaceLayerList);
+ CCLayerTreeHostCommon::calculateDrawTransforms(parent.get(), parent->bounds(), 1, 1, dummyMaxTextureSize, renderSurfaceLayerList);
// With an animating transform, we should keep child and grandChild in the renderSurfaceLayerList.
ASSERT_EQ(3U, renderSurfaceLayerList.size());
@@ -1450,7 +1476,7 @@ TEST(CCLayerTreeHostCommonTest, verifyDrawableContentRectForLayers)
std::vector<scoped_refptr<LayerChromium> > renderSurfaceLayerList;
int dummyMaxTextureSize = 512;
- CCLayerTreeHostCommon::calculateDrawTransforms(parent.get(), parent->bounds(), 1, dummyMaxTextureSize, renderSurfaceLayerList);
+ CCLayerTreeHostCommon::calculateDrawTransforms(parent.get(), parent->bounds(), 1, 1, dummyMaxTextureSize, renderSurfaceLayerList);
EXPECT_RECT_EQ(IntRect(IntPoint(5, 5), IntSize(10, 10)), grandChild1->drawableContentRect());
EXPECT_RECT_EQ(IntRect(IntPoint(15, 15), IntSize(5, 5)), grandChild3->drawableContentRect());
@@ -1515,7 +1541,7 @@ TEST(CCLayerTreeHostCommonTest, verifyClipRectIsPropagatedCorrectlyToSurfaces)
std::vector<scoped_refptr<LayerChromium> > renderSurfaceLayerList;
int dummyMaxTextureSize = 512;
- CCLayerTreeHostCommon::calculateDrawTransforms(parent.get(), parent->bounds(), 1, dummyMaxTextureSize, renderSurfaceLayerList);
+ CCLayerTreeHostCommon::calculateDrawTransforms(parent.get(), parent->bounds(), 1, 1, dummyMaxTextureSize, renderSurfaceLayerList);
ASSERT_TRUE(grandChild1->renderSurface());
ASSERT_TRUE(grandChild2->renderSurface());
@@ -2357,7 +2383,7 @@ TEST(CCLayerTreeHostCommonTest, verifyBackFaceCullingWithoutPreserves3d)
std::vector<scoped_refptr<LayerChromium> > renderSurfaceLayerList;
int dummyMaxTextureSize = 512;
- CCLayerTreeHostCommon::calculateDrawTransforms(parent.get(), parent->bounds(), 1, dummyMaxTextureSize, renderSurfaceLayerList);
+ CCLayerTreeHostCommon::calculateDrawTransforms(parent.get(), parent->bounds(), 1, 1, dummyMaxTextureSize, renderSurfaceLayerList);
// Verify which renderSurfaces were created.
EXPECT_FALSE(frontFacingChild->renderSurface());
@@ -2456,7 +2482,7 @@ TEST(CCLayerTreeHostCommonTest, verifyBackFaceCullingWithPreserves3d)
std::vector<scoped_refptr<LayerChromium> > renderSurfaceLayerList;
int dummyMaxTextureSize = 512;
- CCLayerTreeHostCommon::calculateDrawTransforms(parent.get(), parent->bounds(), 1, dummyMaxTextureSize, renderSurfaceLayerList);
+ CCLayerTreeHostCommon::calculateDrawTransforms(parent.get(), parent->bounds(), 1, 1, dummyMaxTextureSize, renderSurfaceLayerList);
// Verify which renderSurfaces were created.
EXPECT_FALSE(frontFacingChild->renderSurface());
@@ -2536,7 +2562,7 @@ TEST(CCLayerTreeHostCommonTest, verifyBackFaceCullingWithAnimatingTransforms)
std::vector<scoped_refptr<LayerChromium> > renderSurfaceLayerList;
int dummyMaxTextureSize = 512;
- CCLayerTreeHostCommon::calculateDrawTransforms(parent.get(), parent->bounds(), 1, dummyMaxTextureSize, renderSurfaceLayerList);
+ CCLayerTreeHostCommon::calculateDrawTransforms(parent.get(), parent->bounds(), 1, 1, dummyMaxTextureSize, renderSurfaceLayerList);
EXPECT_FALSE(child->renderSurface());
EXPECT_TRUE(animatingSurface->renderSurface());
@@ -2602,7 +2628,7 @@ TEST(CCLayerTreeHostCommonTest, verifyBackFaceCullingWithPreserves3dForFlattenin
std::vector<scoped_refptr<LayerChromium> > renderSurfaceLayerList;
int dummyMaxTextureSize = 512;
- CCLayerTreeHostCommon::calculateDrawTransforms(parent.get(), parent->bounds(), 1, dummyMaxTextureSize, renderSurfaceLayerList);
+ CCLayerTreeHostCommon::calculateDrawTransforms(parent.get(), parent->bounds(), 1, 1, dummyMaxTextureSize, renderSurfaceLayerList);
// Verify which renderSurfaces were created.
EXPECT_TRUE(frontFacingSurface->renderSurface());
@@ -2656,7 +2682,7 @@ TEST(CCLayerTreeHostCommonTest, verifyHitTestingForSingleLayer)
std::vector<CCLayerImpl*> renderSurfaceLayerList;
int dummyMaxTextureSize = 512;
- CCLayerTreeHostCommon::calculateDrawTransforms(root.get(), root->bounds(), 1, 0, dummyMaxTextureSize, renderSurfaceLayerList);
+ CCLayerTreeHostCommon::calculateDrawTransforms(root.get(), root->bounds(), 1, 1, 0, dummyMaxTextureSize, renderSurfaceLayerList);
// Sanity check the scenario we just created.
ASSERT_EQ(1u, renderSurfaceLayerList.size());
@@ -2705,7 +2731,7 @@ TEST(CCLayerTreeHostCommonTest, verifyHitTestingForUninvertibleTransform)
std::vector<CCLayerImpl*> renderSurfaceLayerList;
int dummyMaxTextureSize = 512;
- CCLayerTreeHostCommon::calculateDrawTransforms(root.get(), root->bounds(), 1, 0, dummyMaxTextureSize, renderSurfaceLayerList);
+ CCLayerTreeHostCommon::calculateDrawTransforms(root.get(), root->bounds(), 1, 1, 0, dummyMaxTextureSize, renderSurfaceLayerList);
// Sanity check the scenario we just created.
ASSERT_EQ(1u, renderSurfaceLayerList.size());
@@ -2759,7 +2785,7 @@ TEST(CCLayerTreeHostCommonTest, verifyHitTestingForSinglePositionedLayer)
std::vector<CCLayerImpl*> renderSurfaceLayerList;
int dummyMaxTextureSize = 512;
- CCLayerTreeHostCommon::calculateDrawTransforms(root.get(), root->bounds(), 1, 0, dummyMaxTextureSize, renderSurfaceLayerList);
+ CCLayerTreeHostCommon::calculateDrawTransforms(root.get(), root->bounds(), 1, 1, 0, dummyMaxTextureSize, renderSurfaceLayerList);
// Sanity check the scenario we just created.
ASSERT_EQ(1u, renderSurfaceLayerList.size());
@@ -2806,7 +2832,7 @@ TEST(CCLayerTreeHostCommonTest, verifyHitTestingForSingleRotatedLayer)
std::vector<CCLayerImpl*> renderSurfaceLayerList;
int dummyMaxTextureSize = 512;
- CCLayerTreeHostCommon::calculateDrawTransforms(root.get(), root->bounds(), 1, 0, dummyMaxTextureSize, renderSurfaceLayerList);
+ CCLayerTreeHostCommon::calculateDrawTransforms(root.get(), root->bounds(), 1, 1, 0, dummyMaxTextureSize, renderSurfaceLayerList);
// Sanity check the scenario we just created.
ASSERT_EQ(1u, renderSurfaceLayerList.size());
@@ -2862,7 +2888,7 @@ TEST(CCLayerTreeHostCommonTest, verifyHitTestingForSinglePerspectiveLayer)
std::vector<CCLayerImpl*> renderSurfaceLayerList;
int dummyMaxTextureSize = 512;
- CCLayerTreeHostCommon::calculateDrawTransforms(root.get(), root->bounds(), 1, 0, dummyMaxTextureSize, renderSurfaceLayerList);
+ CCLayerTreeHostCommon::calculateDrawTransforms(root.get(), root->bounds(), 1, 1, 0, dummyMaxTextureSize, renderSurfaceLayerList);
// Sanity check the scenario we just created.
ASSERT_EQ(1u, renderSurfaceLayerList.size());
@@ -2926,7 +2952,7 @@ TEST(CCLayerTreeHostCommonTest, verifyHitTestingForSingleLayerWithScaledContents
std::vector<CCLayerImpl*> renderSurfaceLayerList;
int dummyMaxTextureSize = 512;
- CCLayerTreeHostCommon::calculateDrawTransforms(root.get(), root->bounds(), 1, 0, dummyMaxTextureSize, renderSurfaceLayerList);
+ CCLayerTreeHostCommon::calculateDrawTransforms(root.get(), root->bounds(), 1, 1, 0, dummyMaxTextureSize, renderSurfaceLayerList);
// Sanity check the scenario we just created.
// The visibleContentRect for testLayer is actually 100x100, even though its layout size is 50x50, positioned at 25x25.
@@ -2990,7 +3016,7 @@ TEST(CCLayerTreeHostCommonTest, verifyHitTestingForSimpleClippedLayer)
std::vector<CCLayerImpl*> renderSurfaceLayerList;
int dummyMaxTextureSize = 512;
- CCLayerTreeHostCommon::calculateDrawTransforms(root.get(), root->bounds(), 1, 0, dummyMaxTextureSize, renderSurfaceLayerList);
+ CCLayerTreeHostCommon::calculateDrawTransforms(root.get(), root->bounds(), 1, 1, 0, dummyMaxTextureSize, renderSurfaceLayerList);
// Sanity check the scenario we just created.
ASSERT_EQ(1u, renderSurfaceLayerList.size());
@@ -3080,7 +3106,7 @@ TEST(CCLayerTreeHostCommonTest, verifyHitTestingForMultiClippedRotatedLayer)
std::vector<CCLayerImpl*> renderSurfaceLayerList;
int dummyMaxTextureSize = 512;
- CCLayerTreeHostCommon::calculateDrawTransforms(root.get(), root->bounds(), 1, 0, dummyMaxTextureSize, renderSurfaceLayerList);
+ CCLayerTreeHostCommon::calculateDrawTransforms(root.get(), root->bounds(), 1, 1, 0, dummyMaxTextureSize, renderSurfaceLayerList);
// Sanity check the scenario we just created.
// The grandChild is expected to create a renderSurface because it masksToBounds and is not axis aligned.
@@ -3162,7 +3188,7 @@ TEST(CCLayerTreeHostCommonTest, verifyHitTestingForNonClippingIntermediateLayer)
std::vector<CCLayerImpl*> renderSurfaceLayerList;
int dummyMaxTextureSize = 512;
- CCLayerTreeHostCommon::calculateDrawTransforms(root.get(), root->bounds(), 1, 0, dummyMaxTextureSize, renderSurfaceLayerList);
+ CCLayerTreeHostCommon::calculateDrawTransforms(root.get(), root->bounds(), 1, 1, 0, dummyMaxTextureSize, renderSurfaceLayerList);
// Sanity check the scenario we just created.
ASSERT_EQ(1u, renderSurfaceLayerList.size());
@@ -3242,7 +3268,7 @@ TEST(CCLayerTreeHostCommonTest, verifyHitTestingForMultipleLayers)
std::vector<CCLayerImpl*> renderSurfaceLayerList;
int dummyMaxTextureSize = 512;
- CCLayerTreeHostCommon::calculateDrawTransforms(root.get(), root->bounds(), 1, 0, dummyMaxTextureSize, renderSurfaceLayerList);
+ CCLayerTreeHostCommon::calculateDrawTransforms(root.get(), root->bounds(), 1, 1, 0, dummyMaxTextureSize, renderSurfaceLayerList);
// Sanity check the scenario we just created.
ASSERT_TRUE(child1);
@@ -3350,7 +3376,7 @@ TEST(CCLayerTreeHostCommonTest, verifyHitTestingForMultipleLayerLists)
std::vector<CCLayerImpl*> renderSurfaceLayerList;
int dummyMaxTextureSize = 512;
- CCLayerTreeHostCommon::calculateDrawTransforms(root.get(), root->bounds(), 1, 0, dummyMaxTextureSize, renderSurfaceLayerList);
+ CCLayerTreeHostCommon::calculateDrawTransforms(root.get(), root->bounds(), 1, 1, 0, dummyMaxTextureSize, renderSurfaceLayerList);
// Sanity check the scenario we just created.
ASSERT_TRUE(child1);
@@ -3406,6 +3432,25 @@ TEST(CCLayerTreeHostCommonTest, verifyHitTestingForMultipleLayerLists)
EXPECT_EQ(4, resultLayer->id());
}
+class NoScaleContentLayerChromium : public ContentLayerChromium
+{
+public:
+ static scoped_refptr<NoScaleContentLayerChromium> create(ContentLayerChromiumClient* client) { return make_scoped_refptr(new NoScaleContentLayerChromium(client)); }
+
+ virtual bool needsContentsScale() const OVERRIDE { return false; }
+
+protected:
+ explicit NoScaleContentLayerChromium(ContentLayerChromiumClient* client) : ContentLayerChromium(client) { }
+ virtual ~NoScaleContentLayerChromium() { }
+};
+
+scoped_refptr<NoScaleContentLayerChromium> createNoScaleDrawableContentLayerChromium(ContentLayerChromiumClient* delegate)
+{
+ scoped_refptr<NoScaleContentLayerChromium> toReturn = NoScaleContentLayerChromium::create(delegate);
+ toReturn->setIsDrawable(true);
+ return toReturn;
+}
+
TEST(CCLayerTreeHostCommonTest, verifyLayerTransformsInHighDPI)
{
// Verify draw and screen space transforms of layers not in a surface.
@@ -3418,7 +3463,7 @@ TEST(CCLayerTreeHostCommonTest, verifyLayerTransformsInHighDPI)
scoped_refptr<ContentLayerChromium> child = createDrawableContentLayerChromium(&delegate);
setLayerPropertiesForTesting(child.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(2, 2), IntSize(10, 10), true);
- scoped_refptr<ContentLayerChromium> childNoScale = createDrawableContentLayerChromium(&delegate);
+ scoped_refptr<NoScaleContentLayerChromium> childNoScale = createNoScaleDrawableContentLayerChromium(&delegate);
setLayerPropertiesForTesting(childNoScale.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(2, 2), IntSize(10, 10), true);
parent->addChild(child);
@@ -3428,11 +3473,13 @@ TEST(CCLayerTreeHostCommonTest, verifyLayerTransformsInHighDPI)
int dummyMaxTextureSize = 512;
const double deviceScaleFactor = 2.5;
- parent->setContentsScale(deviceScaleFactor);
- child->setContentsScale(deviceScaleFactor);
- EXPECT_EQ(childNoScale->contentsScale(), 1);
+ const double pageScaleFactor = 1;
+
+ CCLayerTreeHostCommon::calculateDrawTransforms(parent.get(), parent->bounds(), deviceScaleFactor, pageScaleFactor, dummyMaxTextureSize, renderSurfaceLayerList);
- CCLayerTreeHostCommon::calculateDrawTransforms(parent.get(), parent->bounds(), deviceScaleFactor, dummyMaxTextureSize, renderSurfaceLayerList);
+ EXPECT_EQ(deviceScaleFactor * pageScaleFactor, parent->contentsScale());
+ EXPECT_EQ(deviceScaleFactor * pageScaleFactor, child->contentsScale());
+ EXPECT_EQ(1, childNoScale->contentsScale());
EXPECT_EQ(1u, renderSurfaceLayerList.size());
@@ -3479,6 +3526,197 @@ TEST(CCLayerTreeHostCommonTest, verifyLayerTransformsInHighDPI)
EXPECT_TRANSFORMATION_MATRIX_EQ(expectedChildNoScaleTransform, childNoScale->screenSpaceTransform());
}
+TEST(CCLayerTreeHostCommonTest, verifyContentsScale)
+{
+ MockContentLayerChromiumClient delegate;
+ WebTransformationMatrix identityMatrix;
+
+ WebTransformationMatrix parentScaleMatrix;
+ const double initialParentScale = 1.75;
+ parentScaleMatrix.scale(initialParentScale);
+
+ WebTransformationMatrix childScaleMatrix;
+ const double initialChildScale = 1.25;
+ childScaleMatrix.scale(initialChildScale);
+
+ scoped_refptr<ContentLayerChromium> parent = createDrawableContentLayerChromium(&delegate);
+ setLayerPropertiesForTesting(parent.get(), parentScaleMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), true);
+
+ scoped_refptr<ContentLayerChromium> childScale = createDrawableContentLayerChromium(&delegate);
+ setLayerPropertiesForTesting(childScale.get(), childScaleMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(2, 2), IntSize(10, 10), true);
+
+ scoped_refptr<NoScaleContentLayerChromium> childNoScale = createNoScaleDrawableContentLayerChromium(&delegate);
+ setLayerPropertiesForTesting(childNoScale.get(), childScaleMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(12, 12), IntSize(10, 10), true);
+
+ // FIXME: Remove this when pageScaleFactor is applied in the compositor.
+ // Page scale should not apply to the parent.
+ parent->setBoundsContainPageScale(true);
+
+ parent->addChild(childScale);
+ parent->addChild(childNoScale);
+
+ std::vector<scoped_refptr<LayerChromium> > renderSurfaceLayerList;
+ int dummyMaxTextureSize = 512;
+
+ double deviceScaleFactor = 2.5;
+ double pageScaleFactor = 1.5;
+
+ // FIXME: Remove this when pageScaleFactor is applied in the compositor.
+ WebTransformationMatrix pageScaleMatrix;
+ pageScaleMatrix.scale(pageScaleFactor);
+ parent->setSublayerTransform(pageScaleMatrix);
+
+ CCLayerTreeHostCommon::calculateDrawTransforms(parent.get(), parent->bounds(), deviceScaleFactor, pageScaleFactor, dummyMaxTextureSize, renderSurfaceLayerList);
+
+ EXPECT_FLOAT_EQ(deviceScaleFactor * initialParentScale, parent->contentsScale());
+ EXPECT_FLOAT_EQ(deviceScaleFactor * pageScaleFactor * initialParentScale * initialChildScale, childScale->contentsScale());
+ EXPECT_FLOAT_EQ(1, childNoScale->contentsScale());
+
+ // The parent is scaled up and shouldn't need to scale during draw. The child that can scale its contents should
+ // also not need to scale during draw. The other should.
+ // There is some rounding error due to contentBounds being a rounded integer.
+ EXPECT_NEAR(parent->drawTransform().m11(), 1, 0.01);
+ EXPECT_NEAR(parent->drawTransform().m22(), 1, 0.01);
+ EXPECT_NEAR(childScale->drawTransform().m11(), 1, 0.01);
+ EXPECT_NEAR(childScale->drawTransform().m22(), 1, 0.01);
+ EXPECT_FLOAT_EQ(deviceScaleFactor * pageScaleFactor * initialParentScale * initialChildScale, childNoScale->drawTransform().m11());
+ EXPECT_FLOAT_EQ(deviceScaleFactor * pageScaleFactor * initialParentScale * initialChildScale, childNoScale->drawTransform().m22());
+
+ // If the transform changes, we expect the contentsScale to remain unchanged.
+ childScale->setTransform(identityMatrix);
+
+ renderSurfaceLayerList.clear();
+ CCLayerTreeHostCommon::calculateDrawTransforms(parent.get(), parent->bounds(), deviceScaleFactor, pageScaleFactor, dummyMaxTextureSize, renderSurfaceLayerList);
+
+ EXPECT_FLOAT_EQ(deviceScaleFactor * initialParentScale, parent->contentsScale());
+ EXPECT_FLOAT_EQ(deviceScaleFactor * pageScaleFactor * initialParentScale * initialChildScale, childScale->contentsScale());
+ EXPECT_FLOAT_EQ(1, childNoScale->contentsScale());
+
+ // But if the deviceScaleFactor or pageScaleFactor changes, then it should be updated, but using the initial transform.
+ deviceScaleFactor = 2.25;
+ pageScaleFactor = 1.25;
+
+ // FIXME: Remove this when pageScaleFactor is applied in the compositor.
+ pageScaleMatrix = identityMatrix;
+ pageScaleMatrix.scale(pageScaleFactor);
+ parent->setSublayerTransform(pageScaleMatrix);
+
+ renderSurfaceLayerList.clear();
+ CCLayerTreeHostCommon::calculateDrawTransforms(parent.get(), parent->bounds(), deviceScaleFactor, pageScaleFactor, dummyMaxTextureSize, renderSurfaceLayerList);
+
+ EXPECT_FLOAT_EQ(deviceScaleFactor * initialParentScale, parent->contentsScale());
+ EXPECT_FLOAT_EQ(deviceScaleFactor * pageScaleFactor * initialParentScale * initialChildScale, childScale->contentsScale());
+ EXPECT_FLOAT_EQ(1, childNoScale->contentsScale());
+}
+
+TEST(CCLayerTreeHostCommonTest, verifyContentsScaleForSurfaces)
+{
+ MockContentLayerChromiumClient delegate;
+ WebTransformationMatrix identityMatrix;
+
+ WebTransformationMatrix parentScaleMatrix;
+ const double initialParentScale = 2;
+ parentScaleMatrix.scale(initialParentScale);
+
+ WebTransformationMatrix childScaleMatrix;
+ const double initialChildScale = 3;
+ childScaleMatrix.scale(initialChildScale);
+
+ scoped_refptr<ContentLayerChromium> parent = createDrawableContentLayerChromium(&delegate);
+ setLayerPropertiesForTesting(parent.get(), parentScaleMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), true);
+
+ scoped_refptr<ContentLayerChromium> surfaceScale = createDrawableContentLayerChromium(&delegate);
+ setLayerPropertiesForTesting(surfaceScale.get(), childScaleMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(2, 2), IntSize(10, 10), true);
+
+ scoped_refptr<ContentLayerChromium> surfaceScaleChildScale = createDrawableContentLayerChromium(&delegate);
+ setLayerPropertiesForTesting(surfaceScaleChildScale.get(), childScaleMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(10, 10), true);
+
+ scoped_refptr<NoScaleContentLayerChromium> surfaceScaleChildNoScale = createNoScaleDrawableContentLayerChromium(&delegate);
+ setLayerPropertiesForTesting(surfaceScaleChildNoScale.get(), childScaleMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(10, 10), true);
+
+ scoped_refptr<NoScaleContentLayerChromium> surfaceNoScale = createNoScaleDrawableContentLayerChromium(&delegate);
+ setLayerPropertiesForTesting(surfaceNoScale.get(), childScaleMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(12, 12), IntSize(10, 10), true);
+
+ scoped_refptr<ContentLayerChromium> surfaceNoScaleChildScale = createDrawableContentLayerChromium(&delegate);
+ setLayerPropertiesForTesting(surfaceNoScaleChildScale.get(), childScaleMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(10, 10), true);
+
+ scoped_refptr<NoScaleContentLayerChromium> surfaceNoScaleChildNoScale = createNoScaleDrawableContentLayerChromium(&delegate);
+ setLayerPropertiesForTesting(surfaceNoScaleChildNoScale.get(), childScaleMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(10, 10), true);
+
+ // FIXME: Remove this when pageScaleFactor is applied in the compositor.
+ // Page scale should not apply to the parent.
+ parent->setBoundsContainPageScale(true);
+
+ parent->addChild(surfaceScale);
+ parent->addChild(surfaceNoScale);
+
+ surfaceScale->setForceRenderSurface(true);
+ surfaceScale->addChild(surfaceScaleChildScale);
+ surfaceScale->addChild(surfaceScaleChildNoScale);
+
+ surfaceNoScale->setForceRenderSurface(true);
+ surfaceNoScale->addChild(surfaceNoScaleChildScale);
+ surfaceNoScale->addChild(surfaceNoScaleChildNoScale);
+
+ std::vector<scoped_refptr<LayerChromium> > renderSurfaceLayerList;
+ int dummyMaxTextureSize = 512;
+
+ double deviceScaleFactor = 5;
+ double pageScaleFactor = 7;
+
+ // FIXME: Remove this when pageScaleFactor is applied in the compositor.
+ WebTransformationMatrix pageScaleMatrix;
+ pageScaleMatrix.scale(pageScaleFactor);
+ parent->setSublayerTransform(pageScaleMatrix);
+
+ CCLayerTreeHostCommon::calculateDrawTransforms(parent.get(), parent->bounds(), deviceScaleFactor, pageScaleFactor, dummyMaxTextureSize, renderSurfaceLayerList);
+
+ EXPECT_EQ(deviceScaleFactor * initialParentScale, parent->contentsScale());
+ EXPECT_EQ(deviceScaleFactor * pageScaleFactor * initialParentScale * initialChildScale, surfaceScale->contentsScale());
+ EXPECT_EQ(1, surfaceNoScale->contentsScale());
+ EXPECT_EQ(deviceScaleFactor * pageScaleFactor * initialParentScale * initialChildScale * initialChildScale, surfaceScaleChildScale->contentsScale());
+ EXPECT_EQ(1, surfaceScaleChildNoScale->contentsScale());
+ EXPECT_EQ(deviceScaleFactor * pageScaleFactor * initialParentScale * initialChildScale * initialChildScale, surfaceNoScaleChildScale->contentsScale());
+ EXPECT_EQ(1, surfaceNoScaleChildNoScale->contentsScale());
+
+ // The parent is scaled up and shouldn't need to scale during draw.
+ EXPECT_FLOAT_EQ(1, parent->drawTransform().m11());
+ EXPECT_FLOAT_EQ(1, parent->drawTransform().m22());
+
+ // RenderSurfaces should always be 1:1 with their target.
+ EXPECT_FLOAT_EQ(1, surfaceScale->renderSurface()->drawTransform().m11());
+ EXPECT_FLOAT_EQ(1, surfaceScale->renderSurface()->drawTransform().m22());
+
+ // The surfaceScale can apply contents scale so the layer shouldn't need to scale during draw.
+ EXPECT_FLOAT_EQ(1, surfaceScale->drawTransform().m11());
+ EXPECT_FLOAT_EQ(1, surfaceScale->drawTransform().m22());
+
+ // The surfaceScaleChildScale can apply contents scale so it shouldn't need to scale during draw.
+ EXPECT_FLOAT_EQ(1, surfaceScaleChildScale->drawTransform().m11());
+ EXPECT_FLOAT_EQ(1, surfaceScaleChildScale->drawTransform().m22());
+
+ // The surfaceScaleChildNoScale can not apply contents scale, so it needs to be scaled during draw.
+ EXPECT_FLOAT_EQ(deviceScaleFactor * pageScaleFactor * initialParentScale * initialChildScale * initialChildScale, surfaceScaleChildNoScale->drawTransform().m11());
+ EXPECT_FLOAT_EQ(deviceScaleFactor * pageScaleFactor * initialParentScale * initialChildScale * initialChildScale, surfaceScaleChildNoScale->drawTransform().m22());
+
+ // RenderSurfaces should always be 1:1 with their target.
+ EXPECT_FLOAT_EQ(1, surfaceNoScale->renderSurface()->drawTransform().m11());
+ EXPECT_FLOAT_EQ(1, surfaceNoScale->renderSurface()->drawTransform().m22());
+
+ // The surfaceScale layer can not apply contents scale, so it needs to be scaled during draw.
+ EXPECT_FLOAT_EQ(deviceScaleFactor * pageScaleFactor * initialParentScale * initialChildScale, surfaceNoScale->drawTransform().m11());
+ EXPECT_FLOAT_EQ(deviceScaleFactor * pageScaleFactor * initialParentScale * initialChildScale, surfaceNoScale->drawTransform().m22());
+
+ // The surfaceScaleChildScale can apply contents scale so it shouldn't need to scale during draw.
+ EXPECT_FLOAT_EQ(1, surfaceNoScaleChildScale->drawTransform().m11());
+ EXPECT_FLOAT_EQ(1, surfaceNoScaleChildScale->drawTransform().m22());
+
+ // The surfaceScaleChildNoScale can not apply contents scale, so it needs to be scaled during draw.
+ EXPECT_FLOAT_EQ(deviceScaleFactor * pageScaleFactor * initialParentScale * initialChildScale * initialChildScale, surfaceNoScaleChildNoScale->drawTransform().m11());
+ EXPECT_FLOAT_EQ(deviceScaleFactor * pageScaleFactor * initialParentScale * initialChildScale * initialChildScale, surfaceNoScaleChildNoScale->drawTransform().m22());
+
+}
+
TEST(CCLayerTreeHostCommonTest, verifyRenderSurfaceTransformsInHighDPI)
{
MockContentLayerChromiumClient delegate;
@@ -3513,7 +3751,7 @@ TEST(CCLayerTreeHostCommonTest, verifyRenderSurfaceTransformsInHighDPI)
duplicateChildNonOwner->setContentsScale(deviceScaleFactor);
replica->setContentsScale(deviceScaleFactor);
- CCLayerTreeHostCommon::calculateDrawTransforms(parent.get(), parent->bounds(), deviceScaleFactor, dummyMaxTextureSize, renderSurfaceLayerList);
+ CCLayerTreeHostCommon::calculateDrawTransforms(parent.get(), parent->bounds(), deviceScaleFactor, 1, dummyMaxTextureSize, renderSurfaceLayerList);
// We should have two render surfaces. The root's render surface and child's
// render surface (it needs one because it has a replica layer).
diff --git a/cc/CCLayerTreeHostImpl.cpp b/cc/CCLayerTreeHostImpl.cpp
index 56043ee..1f7638f 100644
--- a/cc/CCLayerTreeHostImpl.cpp
+++ b/cc/CCLayerTreeHostImpl.cpp
@@ -356,7 +356,8 @@ void CCLayerTreeHostImpl::calculateRenderSurfaceLayerList(CCLayerList& renderSur
updateRootScrollLayerImplTransform();
TRACE_EVENT0("cc", "CCLayerTreeHostImpl::calcDrawEtc");
- CCLayerTreeHostCommon::calculateDrawTransforms(m_rootLayerImpl.get(), deviceViewportSize(), m_deviceScaleFactor, &m_layerSorter, rendererCapabilities().maxTextureSize, renderSurfaceLayerList);
+ float pageScaleFactor = m_pinchZoomViewport.pageScaleFactor();
+ CCLayerTreeHostCommon::calculateDrawTransforms(m_rootLayerImpl.get(), deviceViewportSize(), m_deviceScaleFactor, pageScaleFactor, &m_layerSorter, rendererCapabilities().maxTextureSize, renderSurfaceLayerList);
trackDamageForAllSurfaces(m_rootLayerImpl.get(), renderSurfaceLayerList);
}
diff --git a/cc/CCLayerTreeHostImplTest.cpp b/cc/CCLayerTreeHostImplTest.cpp
index a17209c..790ec0e 100644
--- a/cc/CCLayerTreeHostImplTest.cpp
+++ b/cc/CCLayerTreeHostImplTest.cpp
@@ -3819,9 +3819,9 @@ TEST_P(CCLayerTreeHostImplTest, surfaceTextureCaching)
myHostImpl->didDrawAllLayers(frame);
}
- // Change opacity on the intermediate layer
+ // Change location of the intermediate layer
WebTransformationMatrix transform = intermediateLayerPtr->transform();
- transform.setM11(1.0001);
+ transform.setM41(1.0001);
intermediateLayerPtr->setTransform(transform);
{
CCLayerTreeHostImpl::FrameData frame;
@@ -3982,9 +3982,9 @@ TEST_P(CCLayerTreeHostImplTest, surfaceTextureCachingNoPartialSwap)
myHostImpl->didDrawAllLayers(frame);
}
- // Change opacity on the intermediate layer
+ // Change location of the intermediate layer
WebTransformationMatrix transform = intermediateLayerPtr->transform();
- transform.setM11(1.0001);
+ transform.setM41(1.0001);
intermediateLayerPtr->setTransform(transform);
{
CCLayerTreeHostImpl::FrameData frame;
diff --git a/cc/CCMathUtil.cpp b/cc/CCMathUtil.cpp
index d90eb09..8cb7d2b 100644
--- a/cc/CCMathUtil.cpp
+++ b/cc/CCMathUtil.cpp
@@ -9,6 +9,7 @@
#include "FloatPoint.h"
#include "FloatQuad.h"
#include "IntRect.h"
+#include <cmath>
#include <public/WebTransformationMatrix.h>
using WebKit::WebTransformationMatrix;
@@ -361,6 +362,20 @@ void CCMathUtil::flattenTransformTo2d(WebTransformationMatrix& transform)
transform.setM43(0);
}
+static inline float scaleOnAxis(double a, double b, double c)
+{
+ return std::sqrt(a * a + b * b + c * c);
+}
+
+FloatPoint CCMathUtil::computeTransform2dScaleComponents(const WebTransformationMatrix& transform)
+{
+ if (transform.hasPerspective())
+ return FloatPoint(1, 1);
+ float xScale = scaleOnAxis(transform.m11(), transform.m12(), transform.m13());
+ float yScale = scaleOnAxis(transform.m21(), transform.m22(), transform.m23());
+ return FloatPoint(xScale, yScale);
+}
+
float CCMathUtil::smallestAngleBetweenVectors(const FloatSize& v1, const FloatSize& v2)
{
float dotProduct = (v1.width() * v2.width() + v1.height() * v2.height()) / (v1.diagonalLength() * v2.diagonalLength());
diff --git a/cc/CCMathUtil.h b/cc/CCMathUtil.h
index ed3848e..5f30388 100644
--- a/cc/CCMathUtil.h
+++ b/cc/CCMathUtil.h
@@ -94,6 +94,8 @@ public:
static void flattenTransformTo2d(WebKit::WebTransformationMatrix&);
+ static FloatPoint computeTransform2dScaleComponents(const WebKit::WebTransformationMatrix&);
+
// Returns the smallest angle between the given two vectors in degrees. Neither vector is
// assumed to be normalized.
static float smallestAngleBetweenVectors(const FloatSize&, const FloatSize&);
diff --git a/cc/CCOcclusionTrackerTest.cpp b/cc/CCOcclusionTrackerTest.cpp
index da3a08a..18bb243 100644
--- a/cc/CCOcclusionTrackerTest.cpp
+++ b/cc/CCOcclusionTrackerTest.cpp
@@ -9,14 +9,14 @@
#include "CCAnimationTestCommon.h"
#include "CCGeometryTestUtils.h"
#include "CCLayerAnimationController.h"
-#include "CCLayerImpl.h"
#include "CCLayerTreeHostCommon.h"
#include "CCMathUtil.h"
#include "CCOcclusionTrackerTestCommon.h"
#include "CCOverdrawMetrics.h"
#include "CCSingleThreadProxy.h"
-#include "LayerChromium.h"
+#include "CCTiledLayerImpl.h"
#include "Region.h"
+#include "TiledLayerChromium.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include <public/WebFilterOperation.h>
@@ -29,10 +29,10 @@ using namespace WebKitTests;
namespace {
-class TestContentLayerChromium : public LayerChromium {
+class TestContentLayerChromium : public TiledLayerChromium {
public:
TestContentLayerChromium()
- : LayerChromium()
+ : TiledLayerChromium()
, m_overrideOpaqueContentsRect(false)
{
}
@@ -50,6 +50,9 @@ public:
m_opaqueContentsRect = opaqueContentsRect;
}
+ virtual LayerTextureUpdater* textureUpdater() const OVERRIDE { return 0; }
+ virtual void createTextureUpdaterIfNeeded() OVERRIDE { }
+
private:
virtual ~TestContentLayerChromium()
{
@@ -59,10 +62,10 @@ private:
IntRect m_opaqueContentsRect;
};
-class TestContentLayerImpl : public CCLayerImpl {
+class TestContentLayerImpl : public CCTiledLayerImpl {
public:
TestContentLayerImpl(int id)
- : CCLayerImpl(id)
+ : CCTiledLayerImpl(id)
, m_overrideOpaqueContentsRect(false)
{
setDrawsContent(true);
@@ -254,7 +257,7 @@ protected:
ASSERT(!root->renderSurface());
- CCLayerTreeHostCommon::calculateDrawTransforms(root, root->bounds(), 1, &layerSorter, dummyMaxTextureSize, m_renderSurfaceLayerListImpl);
+ CCLayerTreeHostCommon::calculateDrawTransforms(root, root->bounds(), 1, 1, &layerSorter, dummyMaxTextureSize, m_renderSurfaceLayerListImpl);
m_layerIterator = m_layerIteratorBegin = Types::LayerIterator::begin(&m_renderSurfaceLayerListImpl);
}
@@ -266,7 +269,7 @@ protected:
ASSERT(!root->renderSurface());
- CCLayerTreeHostCommon::calculateDrawTransforms(root, root->bounds(), 1, dummyMaxTextureSize, m_renderSurfaceLayerListChromium);
+ CCLayerTreeHostCommon::calculateDrawTransforms(root, root->bounds(), 1, 1, dummyMaxTextureSize, m_renderSurfaceLayerListChromium);
m_layerIterator = m_layerIteratorBegin = Types::LayerIterator::begin(&m_renderSurfaceLayerListChromium);
}
@@ -414,14 +417,18 @@ private:
RUN_TEST_IMPL_THREAD_OPAQUE_PAINTS(ClassName)
#define MAIN_THREAD_TEST(ClassName) \
- RUN_TEST_MAIN_THREAD_OPAQUE_LAYERS(ClassName)
+ RUN_TEST_MAIN_THREAD_OPAQUE_LAYERS(ClassName) \
+ RUN_TEST_MAIN_THREAD_OPAQUE_PAINTS(ClassName)
#define IMPL_THREAD_TEST(ClassName) \
- RUN_TEST_IMPL_THREAD_OPAQUE_LAYERS(ClassName)
+ RUN_TEST_IMPL_THREAD_OPAQUE_LAYERS(ClassName) \
+ RUN_TEST_IMPL_THREAD_OPAQUE_PAINTS(ClassName)
#define MAIN_AND_IMPL_THREAD_TEST(ClassName) \
RUN_TEST_MAIN_THREAD_OPAQUE_LAYERS(ClassName) \
- RUN_TEST_IMPL_THREAD_OPAQUE_LAYERS(ClassName)
+ RUN_TEST_MAIN_THREAD_OPAQUE_PAINTS(ClassName) \
+ RUN_TEST_IMPL_THREAD_OPAQUE_LAYERS(ClassName) \
+ RUN_TEST_IMPL_THREAD_OPAQUE_PAINTS(ClassName)
template<class Types, bool opaqueLayers>
class CCOcclusionTrackerTestIdentityTransforms : public CCOcclusionTrackerTest<Types, opaqueLayers> {
@@ -2185,7 +2192,7 @@ protected:
typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(500, 500));
typename Types::ContentLayerType* surface = this->createDrawingSurface(parent, surfaceTransform, FloatPoint(0, 0), IntSize(300, 300), false);
typename Types::ContentLayerType* surface2 = this->createDrawingSurface(parent, this->identityMatrix, FloatPoint(50, 50), IntSize(300, 300), false);
- surface->setOpaqueContentsRect(IntRect(0, 0, 200, 200));
+ surface->setOpaqueContentsRect(IntRect(0, 0, 400, 400));
surface2->setOpaqueContentsRect(IntRect(0, 0, 200, 200));
this->calcDrawEtc(parent);
@@ -2213,7 +2220,8 @@ protected:
}
};
-MAIN_AND_IMPL_THREAD_TEST(CCOcclusionTrackerTestSurfaceOcclusionTranslatesToParent);
+// Scale transforms require main thread+commit to get contentBounds right.
+MAIN_THREAD_TEST(CCOcclusionTrackerTestSurfaceOcclusionTranslatesToParent);
template<class Types, bool opaqueLayers>
class CCOcclusionTrackerTestSurfaceOcclusionTranslatesWithClipping : public CCOcclusionTrackerTest<Types, opaqueLayers> {
@@ -2555,15 +2563,15 @@ protected:
// Everything outside the surface/replica is occluded but the surface/replica itself is not.
this->enterLayer(filteredSurface, occlusion);
- EXPECT_RECT_EQ(IntRect(1, 0, 99, 100), occlusion.unoccludedContentRect(filteredSurface, IntRect(1, 0, 100, 100)));
- EXPECT_RECT_EQ(IntRect(0, 1, 100, 99), occlusion.unoccludedContentRect(filteredSurface, IntRect(0, 1, 100, 100)));
- EXPECT_RECT_EQ(IntRect(0, 0, 99, 100), occlusion.unoccludedContentRect(filteredSurface, IntRect(-1, 0, 100, 100)));
- EXPECT_RECT_EQ(IntRect(0, 0, 100, 99), occlusion.unoccludedContentRect(filteredSurface, IntRect(0, -1, 100, 100)));
-
- EXPECT_RECT_EQ(IntRect(300 + 1, 0, 99, 100), occlusion.unoccludedContentRect(filteredSurface, IntRect(300 + 1, 0, 100, 100)));
- EXPECT_RECT_EQ(IntRect(300 + 0, 1, 100, 99), occlusion.unoccludedContentRect(filteredSurface, IntRect(300 + 0, 1, 100, 100)));
- EXPECT_RECT_EQ(IntRect(300 + 0, 0, 99, 100), occlusion.unoccludedContentRect(filteredSurface, IntRect(300 - 1, 0, 100, 100)));
- EXPECT_RECT_EQ(IntRect(300 + 0, 0, 100, 99), occlusion.unoccludedContentRect(filteredSurface, IntRect(300 + 0, -1, 100, 100)));
+ EXPECT_RECT_EQ(IntRect(1, 0, 49, 50), occlusion.unoccludedContentRect(filteredSurface, IntRect(1, 0, 50, 50)));
+ EXPECT_RECT_EQ(IntRect(0, 1, 50, 49), occlusion.unoccludedContentRect(filteredSurface, IntRect(0, 1, 50, 50)));
+ EXPECT_RECT_EQ(IntRect(0, 0, 49, 50), occlusion.unoccludedContentRect(filteredSurface, IntRect(-1, 0, 50, 50)));
+ EXPECT_RECT_EQ(IntRect(0, 0, 50, 49), occlusion.unoccludedContentRect(filteredSurface, IntRect(0, -1, 50, 50)));
+
+ EXPECT_RECT_EQ(IntRect(150 + 1, 0, 49, 50), occlusion.unoccludedContentRect(filteredSurface, IntRect(150 + 1, 0, 50, 50)));
+ EXPECT_RECT_EQ(IntRect(150 + 0, 1, 50, 49), occlusion.unoccludedContentRect(filteredSurface, IntRect(150 + 0, 1, 50, 50)));
+ EXPECT_RECT_EQ(IntRect(150 + 0, 0, 49, 50), occlusion.unoccludedContentRect(filteredSurface, IntRect(150 - 1, 0, 50, 50)));
+ EXPECT_RECT_EQ(IntRect(150 + 0, 0, 50, 49), occlusion.unoccludedContentRect(filteredSurface, IntRect(150 + 0, -1, 50, 50)));
this->leaveLayer(filteredSurface, occlusion);
// The filtered layer/replica does not occlude.
@@ -2573,7 +2581,7 @@ protected:
EXPECT_EQ(0u, occlusion.occlusionInTargetSurface().rects().size());
// The surface has a background blur, so it needs pixels that are currently considered occluded in order to be drawn. So the pixels
- // it needs should be removed some the occluded area so that when we get to the parent they are drawn.
+ // it needs should be removed from the occluded area so that when we get to the parent they are drawn.
this->visitContributingSurface(filteredSurface, occlusion);
this->enterLayer(parent, occlusion);
@@ -2629,7 +2637,8 @@ protected:
}
};
-ALL_CCOCCLUSIONTRACKER_TEST(CCOcclusionTrackerTestDontOccludePixelsNeededForBackgroundFilter);
+// Scale transforms require main thread+commit to get contentBounds right.
+MAIN_THREAD_TEST(CCOcclusionTrackerTestDontOccludePixelsNeededForBackgroundFilter);
template<class Types, bool opaqueLayers>
class CCOcclusionTrackerTestTwoBackgroundFiltersReduceOcclusionTwice : public CCOcclusionTrackerTest<Types, opaqueLayers> {
@@ -2640,12 +2649,12 @@ protected:
scaleByHalf.scale(0.5);
// Makes two surfaces that completely cover |parent|. The occlusion both above and below the filters will be reduced by each of them.
- typename Types::ContentLayerType* root = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(75, 75));
- typename Types::LayerType* parent = this->createSurface(root, scaleByHalf, FloatPoint(0, 0), IntSize(150, 150));
+ typename Types::ContentLayerType* root = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(150, 150));
+ typename Types::LayerType* parent = this->createDrawingSurface(root, scaleByHalf, FloatPoint(0, 0), IntSize(300, 300), false);
parent->setMasksToBounds(true);
- typename Types::LayerType* filteredSurface1 = this->createDrawingLayer(parent, scaleByHalf, FloatPoint(0, 0), IntSize(300, 300), false);
- typename Types::LayerType* filteredSurface2 = this->createDrawingLayer(parent, scaleByHalf, FloatPoint(0, 0), IntSize(300, 300), false);
- typename Types::LayerType* occludingLayerAbove = this->createDrawingLayer(parent, this->identityMatrix, FloatPoint(100, 100), IntSize(50, 50), true);
+ typename Types::LayerType* filteredSurface1 = this->createDrawingLayer(parent, scaleByHalf, FloatPoint(0, 0), IntSize(600, 600), false);
+ typename Types::LayerType* filteredSurface2 = this->createDrawingLayer(parent, scaleByHalf, FloatPoint(0, 0), IntSize(600, 600), false);
+ typename Types::LayerType* occludingLayerAbove = this->createDrawingLayer(parent, this->identityMatrix, FloatPoint(200, 200), IntSize(100, 100), true);
// Filters make the layers own surfaces.
WebFilterOperations filters;
@@ -2663,9 +2672,9 @@ protected:
occlusion.setLayerClipRect(IntRect(0, 0, 1000, 1000));
this->visitLayer(occludingLayerAbove, occlusion);
- EXPECT_RECT_EQ(IntRect(100 / 2, 100 / 2, 50 / 2, 50 / 2), occlusion.occlusionInScreenSpace().bounds());
+ EXPECT_RECT_EQ(IntRect(200 / 2, 200 / 2, 100 / 2, 100 / 2), occlusion.occlusionInScreenSpace().bounds());
EXPECT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
- EXPECT_RECT_EQ(IntRect(100, 100, 50, 50), occlusion.occlusionInTargetSurface().bounds());
+ EXPECT_RECT_EQ(IntRect(200 / 2, 200 / 2, 100 / 2, 100 / 2), occlusion.occlusionInTargetSurface().bounds());
EXPECT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
this->visitLayer(filteredSurface2, occlusion);
@@ -2676,22 +2685,18 @@ protected:
ASSERT_EQ(1u, occlusion.occlusionInScreenSpace().rects().size());
ASSERT_EQ(1u, occlusion.occlusionInTargetSurface().rects().size());
- // Test expectations in the target.
- IntRect expectedOcclusion = IntRect(100 + outsetRight * 2, 100 + outsetBottom * 2, 50 - (outsetLeft + outsetRight) * 2, 50 - (outsetTop + outsetBottom) * 2);
+ // Test expectations in the target. The target is scaled in half so the occlusion should be scaled within its contents as well.
+ IntRect expectedOcclusion = IntRect(200 / 2 + outsetRight * 2, 200 / 2 + outsetBottom * 2, 100 / 2 - (outsetLeft + outsetRight) * 2, 100 / 2 - (outsetTop + outsetBottom) * 2);
EXPECT_RECT_EQ(expectedOcclusion, occlusion.occlusionInTargetSurface().rects()[0]);
- // Test expectations in the screen. Take the ceiling of half of the outsets.
- outsetTop = (outsetTop + 1) / 2;
- outsetRight = (outsetRight + 1) / 2;
- outsetBottom = (outsetBottom + 1) / 2;
- outsetLeft = (outsetLeft + 1) / 2;
- expectedOcclusion = IntRect(100 / 2 + outsetRight * 2, 100 / 2 + outsetBottom * 2, 50 / 2 - (outsetLeft + outsetRight) * 2, 50 /2 - (outsetTop + outsetBottom) * 2);
-
+ // Test expectations in the screen. The parent is scaled in half so it will scale the occlusion to the screen as well.
+ expectedOcclusion = IntRect(200 / 2 + outsetRight * 2, 200 / 2 + outsetBottom * 2, 100 / 2 - (outsetLeft + outsetRight) * 2, 100 / 2 - (outsetTop + outsetBottom) * 2);
EXPECT_RECT_EQ(expectedOcclusion, occlusion.occlusionInScreenSpace().rects()[0]);
}
};
-ALL_CCOCCLUSIONTRACKER_TEST(CCOcclusionTrackerTestTwoBackgroundFiltersReduceOcclusionTwice);
+// Scale transforms require main thread+commit to get contentBounds right.
+MAIN_THREAD_TEST(CCOcclusionTrackerTestTwoBackgroundFiltersReduceOcclusionTwice);
template<class Types, bool opaqueLayers>
class CCOcclusionTrackerTestDontOccludePixelsNeededForBackgroundFilterWithClip : public CCOcclusionTrackerTest<Types, opaqueLayers> {
@@ -2865,7 +2870,8 @@ protected:
}
};
-ALL_CCOCCLUSIONTRACKER_TEST(CCOcclusionTrackerTestDontReduceOcclusionBelowBackgroundFilter);
+// Scale transforms require main thread+commit to get contentBounds right.
+MAIN_THREAD_TEST(CCOcclusionTrackerTestDontReduceOcclusionBelowBackgroundFilter);
template<class Types, bool opaqueLayers>
class CCOcclusionTrackerTestDontReduceOcclusionIfBackgroundFilterIsOccluded : public CCOcclusionTrackerTest<Types, opaqueLayers> {
@@ -2913,7 +2919,8 @@ protected:
}
};
-ALL_CCOCCLUSIONTRACKER_TEST(CCOcclusionTrackerTestDontReduceOcclusionIfBackgroundFilterIsOccluded);
+// Scale transforms require main thread+commit to get contentBounds right.
+MAIN_THREAD_TEST(CCOcclusionTrackerTestDontReduceOcclusionIfBackgroundFilterIsOccluded);
template<class Types, bool opaqueLayers>
class CCOcclusionTrackerTestReduceOcclusionWhenBackgroundFilterIsPartiallyOccluded : public CCOcclusionTrackerTest<Types, opaqueLayers> {
@@ -2985,7 +2992,8 @@ protected:
}
};
-ALL_CCOCCLUSIONTRACKER_TEST(CCOcclusionTrackerTestReduceOcclusionWhenBackgroundFilterIsPartiallyOccluded);
+// Scale transforms require main thread+commit to get contentBounds right.
+MAIN_THREAD_TEST(CCOcclusionTrackerTestReduceOcclusionWhenBackgroundFilterIsPartiallyOccluded);
template<class Types, bool opaqueLayers>
class CCOcclusionTrackerTestMinimumTrackingSize : public CCOcclusionTrackerTest<Types, opaqueLayers> {
diff --git a/cc/LayerChromium.cpp b/cc/LayerChromium.cpp
index d271eb4..43145b6 100644
--- a/cc/LayerChromium.cpp
+++ b/cc/LayerChromium.cpp
@@ -64,6 +64,7 @@ LayerChromium::LayerChromium()
, m_drawTransformIsAnimating(false)
, m_screenSpaceTransformIsAnimating(false)
, m_contentsScale(1.0)
+ , m_initialCssScale(0)
, m_boundsContainPageScale(false)
, m_layerAnimationDelegate(0)
, m_layerScrollClient(0)
diff --git a/cc/LayerChromium.h b/cc/LayerChromium.h
index 2b0b20dc..aecb520 100644
--- a/cc/LayerChromium.h
+++ b/cc/LayerChromium.h
@@ -226,10 +226,15 @@ public:
void setScreenSpaceTransform(const WebKit::WebTransformationMatrix& matrix) { m_screenSpaceTransform = matrix; }
const IntRect& drawableContentRect() const { return m_drawableContentRect; }
void setDrawableContentRect(const IntRect& rect) { m_drawableContentRect = rect; }
+
// The contentsScale converts from logical, non-page-scaled pixels to target pixels.
// The contentsScale is 1 for the root layer as it is already in physical pixels.
float contentsScale() const { return m_contentsScale; }
void setContentsScale(float);
+ // The scale from the initial CSS transform of the layer, including its ancestors, but
+ // not including the deviceScaleFactor or pageScaleFactor.
+ float initialCssScale() const { return m_initialCssScale; }
+ void setInitialCssScale(float scale) { m_initialCssScale = scale; }
// When true, the layer's contents are not scaled by the current page scale factor.
// setBoundsContainPageScale recursively sets the value on all child layers.
@@ -376,6 +381,7 @@ private:
// Uses target surface space.
IntRect m_drawableContentRect;
float m_contentsScale;
+ float m_initialCssScale;
bool m_boundsContainPageScale;
WebKit::WebTransformationMatrix m_implTransform;