diff options
author | danakj@chromium.org <danakj@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-12-21 02:59:09 +0000 |
---|---|---|
committer | danakj@chromium.org <danakj@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-12-21 02:59:09 +0000 |
commit | 1b30e8ed7a873ba3eb4fcc53029b0244cbe7a20d (patch) | |
tree | 9b6dddc66f215d33bad07cf585c1b3f4244363e8 | |
parent | d0debcc8ea135cec1fd279d4c48f8ce59e7758c4 (diff) | |
download | chromium_src-1b30e8ed7a873ba3eb4fcc53029b0244cbe7a20d.zip chromium_src-1b30e8ed7a873ba3eb4fcc53029b0244cbe7a20d.tar.gz chromium_src-1b30e8ed7a873ba3eb4fcc53029b0244cbe7a20d.tar.bz2 |
cc: When the transform's scale is unknown, draw into render surfaces at the scale of the screen.
When the transform's scale is not known, we have to use some fixed value. We
were using 1.0 but this means if the transform is close to the identity, the
layers in the surface are rendered small, and then scaled up when the surface
is drawn to the screen by the device scale factor and page scale factor. This
makes for fuzziness.
So, when the transform's scale is not known we should use the device scale
and page scale factors as the default value. This guarantees that the transforms
from the contents of the surface's subtree to the screen will not require
scaling up more than any CSS scales specified by the HTML.
Tests:
LayerTreeHostCommonTest.verifySurfaceLayerTransformsInHighDPI
BUG=167021
Review URL: https://chromiumcodereview.appspot.com/11635037
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@174327 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | cc/layer_tree_host_common.cc | 4 | ||||
-rw-r--r-- | cc/layer_tree_host_common_unittest.cc | 80 | ||||
-rw-r--r-- | cc/math_util.cc | 4 | ||||
-rw-r--r-- | cc/math_util.h | 2 |
4 files changed, 81 insertions, 9 deletions
diff --git a/cc/layer_tree_host_common.cc b/cc/layer_tree_host_common.cc index 3fccbf1..d6fc3b9 100644 --- a/cc/layer_tree_host_common.cc +++ b/cc/layer_tree_host_common.cc @@ -390,7 +390,7 @@ static inline void updateLayerContentsScale(Layer* layer, const gfx::Transform& rasterScale = 1; if (!animatingTransformToScreen && layer->automaticallyComputeRasterScale()) { - gfx::Vector2dF transformScale = MathUtil::computeTransform2dScaleComponents(combinedTransform); + gfx::Vector2dF transformScale = MathUtil::computeTransform2dScaleComponents(combinedTransform, 0.f); float combinedScale = std::max(transformScale.x(), transformScale.y()); rasterScale = combinedScale / deviceScaleFactor; if (!layer->boundsContainPageScale()) @@ -660,7 +660,7 @@ static void calculateDrawPropertiesInternal(LayerType* layer, const gfx::Transfo gfx::Transform nextHierarchyMatrix = fullHierarchyMatrix; gfx::Transform sublayerMatrix; - gfx::Vector2dF renderSurfaceSublayerScale = MathUtil::computeTransform2dScaleComponents(combinedTransform); + gfx::Vector2dF renderSurfaceSublayerScale = MathUtil::computeTransform2dScaleComponents(combinedTransform, deviceScaleFactor * pageScaleFactor); if (subtreeShouldRenderToSeparateSurface(layer, combinedTransform.IsScaleOrTranslation())) { // Check back-face visibility before continuing with this surface and its subtree diff --git a/cc/layer_tree_host_common_unittest.cc b/cc/layer_tree_host_common_unittest.cc index 0fd26e4..25ff83d 100644 --- a/cc/layer_tree_host_common_unittest.cc +++ b/cc/layer_tree_host_common_unittest.cc @@ -337,7 +337,7 @@ TEST(LayerTreeHostCommonTest, verifyTransformsForSingleRenderSurface) parentTranslationToCenter.Translate(50, 60); gfx::Transform parentCompositeTransform = parentTranslationToAnchor * parentLayerTransform * MathUtil::inverse(parentTranslationToAnchor) * parentTranslationToCenter * parentSublayerMatrix * MathUtil::inverse(parentTranslationToCenter); - gfx::Vector2dF parentCompositeScale = MathUtil::computeTransform2dScaleComponents(parentCompositeTransform); + gfx::Vector2dF parentCompositeScale = MathUtil::computeTransform2dScaleComponents(parentCompositeTransform, 1.f); gfx::Transform surfaceSublayerTransform; surfaceSublayerTransform.Scale(parentCompositeScale.x(), parentCompositeScale.y()); gfx::Transform surfaceSublayerCompositeTransform = parentCompositeTransform * MathUtil::inverse(surfaceSublayerTransform); @@ -400,7 +400,7 @@ TEST(LayerTreeHostCommonTest, verifyTransformsForReplica) childTranslationToCenter.Translate(8, 9); gfx::Transform replicaLayerTransform; replicaLayerTransform.Scale3d(3, 3, 1); - gfx::Vector2dF parentCompositeScale = MathUtil::computeTransform2dScaleComponents(parentCompositeTransform); + gfx::Vector2dF parentCompositeScale = MathUtil::computeTransform2dScaleComponents(parentCompositeTransform, 1.f); gfx::Transform surfaceSublayerTransform; surfaceSublayerTransform.Scale(parentCompositeScale.x(), parentCompositeScale.y()); gfx::Transform replicaCompositeTransform = parentCompositeTransform * replicaLayerTransform * MathUtil::inverse(surfaceSublayerTransform); @@ -485,7 +485,7 @@ TEST(LayerTreeHostCommonTest, verifyTransformsForRenderSurfaceHierarchy) gfx::Transform B = translationToCenter * sublayerTransform * MathUtil::inverse(translationToCenter); gfx::Transform R = A * translationToAnchor * replicaLayerTransform * MathUtil::inverse(translationToAnchor); - gfx::Vector2dF surface1ParentTransformScale = MathUtil::computeTransform2dScaleComponents(A * B); + gfx::Vector2dF surface1ParentTransformScale = MathUtil::computeTransform2dScaleComponents(A * B, 1.f); gfx::Transform surface1SublayerTransform; surface1SublayerTransform.Scale(surface1ParentTransformScale.x(), surface1ParentTransformScale.y()); @@ -494,7 +494,7 @@ TEST(LayerTreeHostCommonTest, verifyTransformsForRenderSurfaceHierarchy) // S1 = transform to move from renderSurface1 pixels to the layer space of the owning layer gfx::Transform S1 = MathUtil::inverse(surface1SublayerTransform); - gfx::Vector2dF surface2ParentTransformScale = MathUtil::computeTransform2dScaleComponents(SS1 * A * B); + gfx::Vector2dF surface2ParentTransformScale = MathUtil::computeTransform2dScaleComponents(SS1 * A * B, 1.f); gfx::Transform surface2SublayerTransform; surface2SublayerTransform.Scale(surface2ParentTransformScale.x(), surface2ParentTransformScale.y()); @@ -4081,6 +4081,78 @@ TEST(LayerTreeHostCommonTest, verifyLayerTransformsInHighDPI) EXPECT_TRANSFORMATION_MATRIX_EQ(expectedChildNoScaleTransform, childNoScale->screenSpaceTransform()); } +TEST(LayerTreeHostCommonTest, verifySurfaceLayerTransformsInHighDPI) +{ + // Verify draw and screen space transforms of layers in a surface. + MockContentLayerClient delegate; + gfx::Transform identityMatrix; + + gfx::Transform perspectiveMatrix; + perspectiveMatrix.ApplyPerspectiveDepth(2); + + gfx::Transform scaleSmallMatrix; + scaleSmallMatrix.Scale(1.0 / 10.0, 1.0 / 12.0); + + scoped_refptr<ContentLayer> parent = createDrawableContentLayer(&delegate); + setLayerPropertiesForTesting(parent.get(), identityMatrix, identityMatrix, gfx::PointF(0, 0), gfx::PointF(0, 0), gfx::Size(100, 100), true); + + scoped_refptr<ContentLayer> perspectiveSurface = createDrawableContentLayer(&delegate); + setLayerPropertiesForTesting(perspectiveSurface.get(), perspectiveMatrix * scaleSmallMatrix, identityMatrix, gfx::PointF(0, 0), gfx::PointF(2, 2), gfx::Size(10, 10), true); + + scoped_refptr<ContentLayer> scaleSurface = createDrawableContentLayer(&delegate); + setLayerPropertiesForTesting(scaleSurface.get(), scaleSmallMatrix, identityMatrix, gfx::PointF(0, 0), gfx::PointF(2, 2), gfx::Size(10, 10), true); + + perspectiveSurface->setForceRenderSurface(true); + scaleSurface->setForceRenderSurface(true); + + parent->addChild(perspectiveSurface); + parent->addChild(scaleSurface); + + std::vector<scoped_refptr<Layer> > renderSurfaceLayerList; + int dummyMaxTextureSize = 512; + + const double deviceScaleFactor = 2.5; + const double pageScaleFactor = 3; + + gfx::Transform pageScaleTransform; + pageScaleTransform.Scale(pageScaleFactor, pageScaleFactor); + parent->setImplTransform(pageScaleTransform); + + LayerTreeHostCommon::calculateDrawProperties(parent.get(), parent->bounds(), deviceScaleFactor, pageScaleFactor, dummyMaxTextureSize, false, renderSurfaceLayerList); + + EXPECT_CONTENTS_SCALE_EQ(deviceScaleFactor * pageScaleFactor, parent); + EXPECT_CONTENTS_SCALE_EQ(deviceScaleFactor * pageScaleFactor, perspectiveSurface); + EXPECT_CONTENTS_SCALE_EQ(deviceScaleFactor * pageScaleFactor, scaleSurface); + + EXPECT_EQ(3u, renderSurfaceLayerList.size()); + + gfx::Transform expectedParentDrawTransform; + EXPECT_TRANSFORMATION_MATRIX_EQ(expectedParentDrawTransform, parent->drawTransform()); + + // The scaled surface is rendered at its appropriate scale, and drawn 1:1 + // into its target. + gfx::Transform expectedScaleSurfaceDrawTransform; + expectedScaleSurfaceDrawTransform.Translate( + deviceScaleFactor * pageScaleFactor * scaleSurface->position().x(), + deviceScaleFactor * pageScaleFactor * scaleSurface->position().y()); + gfx::Transform expectedScaleSurfaceLayerDrawTransform; + expectedScaleSurfaceLayerDrawTransform.PreconcatTransform(scaleSmallMatrix); + EXPECT_TRANSFORMATION_MATRIX_EQ(expectedScaleSurfaceDrawTransform, scaleSurface->renderSurface()->drawTransform()); + EXPECT_TRANSFORMATION_MATRIX_EQ(expectedScaleSurfaceLayerDrawTransform, scaleSurface->drawTransform()); + + // The scale for the perspective surface is not known, so it is rendered 1:1 + // with the screen, and then scaled during drawing. + gfx::Transform expectedPerspectiveSurfaceDrawTransform; + expectedPerspectiveSurfaceDrawTransform.Translate( + deviceScaleFactor * pageScaleFactor * perspectiveSurface->position().x(), + deviceScaleFactor * pageScaleFactor * perspectiveSurface->position().y()); + expectedPerspectiveSurfaceDrawTransform.PreconcatTransform(perspectiveMatrix); + expectedPerspectiveSurfaceDrawTransform.PreconcatTransform(scaleSmallMatrix); + gfx::Transform expectedPerspectiveSurfaceLayerDrawTransform; + EXPECT_TRANSFORMATION_MATRIX_EQ(expectedPerspectiveSurfaceDrawTransform, perspectiveSurface->renderSurface()->drawTransform()); + EXPECT_TRANSFORMATION_MATRIX_EQ(expectedPerspectiveSurfaceLayerDrawTransform, perspectiveSurface->drawTransform()); +} + TEST(LayerTreeHostCommonTest, verifyLayerTransformsInHighDPIAccurateScaleZeroChildPosition) { // Verify draw and screen space transforms of layers not in a surface. diff --git a/cc/math_util.cc b/cc/math_util.cc index 46d1c27..38b609b 100644 --- a/cc/math_util.cc +++ b/cc/math_util.cc @@ -383,10 +383,10 @@ static inline float scaleOnAxis(double a, double b, double c) return std::sqrt(a * a + b * b + c * c); } -gfx::Vector2dF MathUtil::computeTransform2dScaleComponents(const gfx::Transform& transform) +gfx::Vector2dF MathUtil::computeTransform2dScaleComponents(const gfx::Transform& transform, float fallbackValue) { if (transform.HasPerspective()) - return gfx::Vector2dF(1, 1); + return gfx::Vector2dF(fallbackValue, fallbackValue); float xScale = scaleOnAxis(transform.matrix().getDouble(0, 0), transform.matrix().getDouble(1, 0), transform.matrix().getDouble(2, 0)); float yScale = scaleOnAxis(transform.matrix().getDouble(0, 1), transform.matrix().getDouble(1, 1), transform.matrix().getDouble(2, 1)); return gfx::Vector2dF(xScale, yScale); diff --git a/cc/math_util.h b/cc/math_util.h index e3ed2d3..d47c80a 100644 --- a/cc/math_util.h +++ b/cc/math_util.h @@ -106,7 +106,7 @@ public: static void flattenTransformTo2d(gfx::Transform&); - static gfx::Vector2dF computeTransform2dScaleComponents(const gfx::Transform&); + static gfx::Vector2dF computeTransform2dScaleComponents(const gfx::Transform&, float fallbackValue); // Returns the smallest angle between the given two vectors in degrees. Neither vector is // assumed to be normalized. |