- Revision
- 124782
- Author
- [email protected]
- Date
- 2012-08-06 10:43:02 -0700 (Mon, 06 Aug 2012)
Log Message
[chromium] Non-preserves-3d requires explicit flattening of screen-space transform.
https://bugs.webkit.org/show_bug.cgi?id=85808
Reviewed by Adrienne Walker.
Source/WebCore:
When computing the screen-space transforms, z values were not
being flattened when they should be. This caused incorrect
clipping due to occlusion tracking that relied on the screen-space
transform. The fix is to flatten the screen-space transform just
like the "sublayerMatrix" is flattened, when the layer does not
preserve-3d.
In addition to making the simple fix, it was convenient to make a
helper function for the flattening code.
Additional unit test added to exercise that flattening code:
CCLayerTreeHostCommonTest.verifyTransformsForFlatteningLayer
* platform/graphics/chromium/cc/CCLayerTreeHostCommon.cpp:
(WebCore::calculateDrawTransformsInternal):
* platform/graphics/chromium/cc/CCMathUtil.cpp:
(WebCore::CCMathUtil::flattenTransformTo2d):
(WebCore):
* platform/graphics/chromium/cc/CCMathUtil.h:
(CCMathUtil):
Source/WebKit/chromium:
* tests/CCLayerTreeHostCommonTest.cpp:
Modified Paths
Diff
Modified: trunk/Source/WebCore/ChangeLog (124781 => 124782)
--- trunk/Source/WebCore/ChangeLog 2012-08-06 17:37:12 UTC (rev 124781)
+++ trunk/Source/WebCore/ChangeLog 2012-08-06 17:43:02 UTC (rev 124782)
@@ -1,3 +1,31 @@
+2012-08-06 Shawn Singh <[email protected]>
+
+ [chromium] Non-preserves-3d requires explicit flattening of screen-space transform.
+ https://bugs.webkit.org/show_bug.cgi?id=85808
+
+ Reviewed by Adrienne Walker.
+
+ When computing the screen-space transforms, z values were not
+ being flattened when they should be. This caused incorrect
+ clipping due to occlusion tracking that relied on the screen-space
+ transform. The fix is to flatten the screen-space transform just
+ like the "sublayerMatrix" is flattened, when the layer does not
+ preserve-3d.
+
+ In addition to making the simple fix, it was convenient to make a
+ helper function for the flattening code.
+
+ Additional unit test added to exercise that flattening code:
+ CCLayerTreeHostCommonTest.verifyTransformsForFlatteningLayer
+
+ * platform/graphics/chromium/cc/CCLayerTreeHostCommon.cpp:
+ (WebCore::calculateDrawTransformsInternal):
+ * platform/graphics/chromium/cc/CCMathUtil.cpp:
+ (WebCore::CCMathUtil::flattenTransformTo2d):
+ (WebCore):
+ * platform/graphics/chromium/cc/CCMathUtil.h:
+ (CCMathUtil):
+
2012-08-06 Anna Cavender <[email protected]>
Create a MediaSource object.
Modified: trunk/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHostCommon.cpp (124781 => 124782)
--- trunk/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHostCommon.cpp 2012-08-06 17:37:12 UTC (rev 124781)
+++ trunk/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHostCommon.cpp 2012-08-06 17:43:02 UTC (rev 124782)
@@ -556,6 +556,8 @@
// layerScreenSpaceTransform represents the transform between root layer's "screen space" and local content space.
WebTransformationMatrix layerScreenSpaceTransform = fullHierarchyMatrix;
+ if (!layer->preserves3D())
+ CCMathUtil::flattenTransformTo2d(layerScreenSpaceTransform);
layerScreenSpaceTransform.multiply(drawTransform);
layer->setScreenSpaceTransform(layerScreenSpaceTransform);
@@ -679,15 +681,8 @@
}
// Flatten to 2D if the layer doesn't preserve 3D.
- if (!layer->preserves3D()) {
- sublayerMatrix.setM13(0);
- sublayerMatrix.setM23(0);
- sublayerMatrix.setM31(0);
- sublayerMatrix.setM32(0);
- sublayerMatrix.setM33(1);
- sublayerMatrix.setM34(0);
- sublayerMatrix.setM43(0);
- }
+ if (!layer->preserves3D())
+ CCMathUtil::flattenTransformTo2d(sublayerMatrix);
// Apply the sublayer transform at the center of the layer.
sublayerMatrix.multiply(layer->sublayerTransform());
Modified: trunk/Source/WebCore/platform/graphics/chromium/cc/CCMathUtil.cpp (124781 => 124782)
--- trunk/Source/WebCore/platform/graphics/chromium/cc/CCMathUtil.cpp 2012-08-06 17:37:12 UTC (rev 124781)
+++ trunk/Source/WebCore/platform/graphics/chromium/cc/CCMathUtil.cpp 2012-08-06 17:43:02 UTC (rev 124782)
@@ -360,4 +360,25 @@
return h.cartesianPoint2d();
}
+void CCMathUtil::flattenTransformTo2d(WebTransformationMatrix& transform)
+{
+ // Set both the 3rd row and 3rd column to (0, 0, 1, 0).
+ //
+ // One useful interpretation of doing this operation:
+ // - For x and y values, the new transform behaves effectively like an orthographic
+ // projection was added to the matrix sequence.
+ // - For z values, the new transform overrides any effect that the transform had on
+ // z, and instead it preserves the z value for any points that are transformed.
+ // - Because of linearity of transforms, this flattened transform also preserves the
+ // effect that any subsequent (post-multiplied) transforms would have on z values.
+ //
+ transform.setM13(0);
+ transform.setM23(0);
+ transform.setM31(0);
+ transform.setM32(0);
+ transform.setM33(1);
+ transform.setM34(0);
+ transform.setM43(0);
+}
+
} // namespace WebCore
Modified: trunk/Source/WebCore/platform/graphics/chromium/cc/CCMathUtil.h (124781 => 124782)
--- trunk/Source/WebCore/platform/graphics/chromium/cc/CCMathUtil.h 2012-08-06 17:37:12 UTC (rev 124781)
+++ trunk/Source/WebCore/platform/graphics/chromium/cc/CCMathUtil.h 2012-08-06 17:43:02 UTC (rev 124782)
@@ -113,6 +113,8 @@
static FloatPoint3D mapPoint(const WebKit::WebTransformationMatrix&, const FloatPoint3D&, bool& clipped);
static FloatQuad projectQuad(const WebKit::WebTransformationMatrix&, const FloatQuad&, bool& clipped);
static FloatPoint projectPoint(const WebKit::WebTransformationMatrix&, const FloatPoint&, bool& clipped);
+
+ static void flattenTransformTo2d(WebKit::WebTransformationMatrix&);
};
} // namespace WebCore
Modified: trunk/Source/WebKit/chromium/ChangeLog (124781 => 124782)
--- trunk/Source/WebKit/chromium/ChangeLog 2012-08-06 17:37:12 UTC (rev 124781)
+++ trunk/Source/WebKit/chromium/ChangeLog 2012-08-06 17:43:02 UTC (rev 124782)
@@ -1,3 +1,12 @@
+2012-08-06 Shawn Singh <[email protected]>
+
+ [chromium] Non-preserves-3d requires explicit flattening of screen-space transform.
+ https://bugs.webkit.org/show_bug.cgi?id=85808
+
+ Reviewed by Adrienne Walker.
+
+ * tests/CCLayerTreeHostCommonTest.cpp:
+
2012-08-06 Yury Semikhatsky <[email protected]>
Web Inspector: rename WorkerAgent.setWorkerInspectionEnabled to WorkerAgent.enable and make it return error
Modified: trunk/Source/WebKit/chromium/tests/CCLayerTreeHostCommonTest.cpp (124781 => 124782)
--- trunk/Source/WebKit/chromium/tests/CCLayerTreeHostCommonTest.cpp 2012-08-06 17:37:12 UTC (rev 124781)
+++ trunk/Source/WebKit/chromium/tests/CCLayerTreeHostCommonTest.cpp 2012-08-06 17:43:02 UTC (rev 124782)
@@ -903,6 +903,51 @@
EXPECT_FLOAT_EQ(5, grandChildOfRS2->screenSpaceTransform().m42());
}
+TEST(CCLayerTreeHostCommonTest, verifyTransformsForFlatteningLayer)
+{
+ // For layers that flatten their subtree, there should be an orthographic projection
+ // (for x and y values) in the middle of the transform sequence. Note that the way the
+ // code is currently implemented, it is not expected to use a canonical orthographic
+ // projection.
+
+ RefPtr<LayerChromium> root = LayerChromium::create();
+ RefPtr<LayerChromium> child = LayerChromium::create();
+ RefPtr<LayerChromiumWithForcedDrawsContent> grandChild = adoptRef(new LayerChromiumWithForcedDrawsContent());
+
+ WebTransformationMatrix rotationAboutYAxis;
+ rotationAboutYAxis.rotate3d(0, 30, 0);
+
+ const WebTransformationMatrix identityMatrix;
+ setLayerPropertiesForTesting(root.get(), identityMatrix, identityMatrix, FloatPoint::zero(), FloatPoint::zero(), IntSize(100, 100), false);
+ setLayerPropertiesForTesting(child.get(), rotationAboutYAxis, identityMatrix, FloatPoint::zero(), FloatPoint::zero(), IntSize(10, 10), false);
+ setLayerPropertiesForTesting(grandChild.get(), rotationAboutYAxis, identityMatrix, FloatPoint::zero(), FloatPoint::zero(), IntSize(10, 10), false);
+
+ root->addChild(child);
+ child->addChild(grandChild);
+ child->setForceRenderSurface(true);
+
+ // No layers in this test should preserve 3d.
+ ASSERT_FALSE(root->preserves3D());
+ ASSERT_FALSE(child->preserves3D());
+ ASSERT_FALSE(grandChild->preserves3D());
+
+ WebTransformationMatrix expectedChildDrawTransform = rotationAboutYAxis;
+ WebTransformationMatrix expectedChildScreenSpaceTransform = rotationAboutYAxis;
+ WebTransformationMatrix expectedGrandChildDrawTransform = rotationAboutYAxis; // draws onto child's renderSurface
+ WebTransformationMatrix expectedGrandChildScreenSpaceTransform = rotationAboutYAxis.to2dTransform() * rotationAboutYAxis;
+
+ executeCalculateDrawTransformsAndVisibility(root.get());
+
+ // The child's drawTransform should have been taken by its surface.
+ ASSERT_TRUE(child->renderSurface());
+ EXPECT_TRANSFORMATION_MATRIX_EQ(expectedChildDrawTransform, child->renderSurface()->drawTransform());
+ EXPECT_TRANSFORMATION_MATRIX_EQ(expectedChildScreenSpaceTransform, child->renderSurface()->screenSpaceTransform());
+ EXPECT_TRANSFORMATION_MATRIX_EQ(identityMatrix, child->drawTransform());
+ EXPECT_TRANSFORMATION_MATRIX_EQ(expectedChildScreenSpaceTransform, child->screenSpaceTransform());
+ EXPECT_TRANSFORMATION_MATRIX_EQ(expectedGrandChildDrawTransform, grandChild->drawTransform());
+ EXPECT_TRANSFORMATION_MATRIX_EQ(expectedGrandChildScreenSpaceTransform, grandChild->screenSpaceTransform());
+}
+
TEST(CCLayerTreeHostCommonTest, verifyRenderSurfaceListForRenderSurfaceWithClippedLayer)
{
RefPtr<LayerChromium> parent = LayerChromium::create();