Title: [124782] trunk/Source
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();
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to