Title: [117645] trunk/Source
Revision
117645
Author
shawnsi...@chromium.org
Date
2012-05-18 15:27:18 -0700 (Fri, 18 May 2012)

Log Message

[chromium] add back-face visibility check for renderSurfaces
https://bugs.webkit.org/show_bug.cgi?id=86870

Reviewed by Adrienne Walker.

Source/WebCore:

Test added CCLayerTreeHostCommonTest::verifyBackFaceCullingWithPreserves3dForFlatteningSurface

Chromium was not checking back-face visibility for renderSurfaces
that needed it. This patch adds that check and the appropriate
unit test.

* platform/graphics/chromium/cc/CCLayerTreeHostCommon.cpp:
(WebCore::layerIsInExisting3DRenderingContext):
(WebCore):
(WebCore::subtreeShouldRenderToSeparateSurface):
(WebCore::calculateDrawTransformsAndVisibilityInternal):

Source/WebKit/chromium:

* tests/CCLayerTreeHostCommonTest.cpp:
(WebKitTests::TEST):
(WebKitTests):

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (117644 => 117645)


--- trunk/Source/WebCore/ChangeLog	2012-05-18 22:24:00 UTC (rev 117644)
+++ trunk/Source/WebCore/ChangeLog	2012-05-18 22:27:18 UTC (rev 117645)
@@ -1,3 +1,22 @@
+2012-05-18  Shawn Singh  <shawnsi...@chromium.org>
+
+        [chromium] add back-face visibility check for renderSurfaces
+        https://bugs.webkit.org/show_bug.cgi?id=86870
+
+        Reviewed by Adrienne Walker.
+
+        Test added CCLayerTreeHostCommonTest::verifyBackFaceCullingWithPreserves3dForFlatteningSurface
+
+        Chromium was not checking back-face visibility for renderSurfaces
+        that needed it. This patch adds that check and the appropriate
+        unit test.
+
+        * platform/graphics/chromium/cc/CCLayerTreeHostCommon.cpp:
+        (WebCore::layerIsInExisting3DRenderingContext):
+        (WebCore):
+        (WebCore::subtreeShouldRenderToSeparateSurface):
+        (WebCore::calculateDrawTransformsAndVisibilityInternal):
+
 2012-05-18  Levi Weintraub  <le...@chromium.org>
 
         Standalone table-columns should be wrapped in anonymous tables

Modified: trunk/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHostCommon.cpp (117644 => 117645)


--- trunk/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHostCommon.cpp	2012-05-18 22:24:00 UTC (rev 117644)
+++ trunk/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHostCommon.cpp	2012-05-18 22:27:18 UTC (rev 117645)
@@ -66,6 +66,14 @@
 }
 
 template<typename LayerType>
+static inline bool layerIsInExisting3DRenderingContext(LayerType* layer)
+{
+    // According to current W3C spec on CSS transforms, a layer is part of an established
+    // 3d rendering context if its parent has transform-style of preserves-3d.
+    return layer->parent() && layer->parent()->preserves3D();
+}
+
+template<typename LayerType>
 static IntRect calculateVisibleLayerRect(LayerType* layer)
 {
     ASSERT(layer->targetRenderSurface());
@@ -211,7 +219,7 @@
 
     // If the layer flattens its subtree (i.e. the layer doesn't preserve-3d), but it is
     // treated as a 3D object by its parent (i.e. parent does preserve-3d).
-    if (layer->parent() && layer->parent()->preserves3D() && !layer->preserves3D() && descendantDrawsContent)
+    if (layerIsInExisting3DRenderingContext(layer) && !layer->preserves3D() && descendantDrawsContent)
         return true;
 
     // On the main thread side, animating transforms are unknown, and may cause a RenderSurface on the impl side.
@@ -382,6 +390,14 @@
     layer->setUsesLayerClipping(false);
 
     if (subtreeShouldRenderToSeparateSurface(layer, isScaleOrTranslation(combinedTransform))) {
+
+        // We need to check back-face visibility before continuing with this surface.
+        // We cannot early exit here, however, if the transform is animating and not known on the main thread.
+        // FIXME: Also compute back-face visibility for surfaces that are not in existing 3D rendering context, using
+        //        the layer's local transform. https://bugs.webkit.org/show_bug.cgi?id=84195
+        if (layerIsInExisting3DRenderingContext(layer) && transformToParentIsKnown(layer) && !layer->doubleSided() && combinedTransform.isBackFaceVisible())
+            return false;
+
         if (!layer->renderSurface())
             layer->createRenderSurface();
 

Modified: trunk/Source/WebKit/chromium/ChangeLog (117644 => 117645)


--- trunk/Source/WebKit/chromium/ChangeLog	2012-05-18 22:24:00 UTC (rev 117644)
+++ trunk/Source/WebKit/chromium/ChangeLog	2012-05-18 22:27:18 UTC (rev 117645)
@@ -1,3 +1,14 @@
+2012-05-18  Shawn Singh  <shawnsi...@chromium.org>
+
+        [chromium] add back-face visibility check for renderSurfaces
+        https://bugs.webkit.org/show_bug.cgi?id=86870
+
+        Reviewed by Adrienne Walker.
+
+        * tests/CCLayerTreeHostCommonTest.cpp:
+        (WebKitTests::TEST):
+        (WebKitTests):
+
 2012-05-18  Greg Billock  <gbill...@google.com>
 
         Enable web intents flag for chromium build

Modified: trunk/Source/WebKit/chromium/tests/CCLayerTreeHostCommonTest.cpp (117644 => 117645)


--- trunk/Source/WebKit/chromium/tests/CCLayerTreeHostCommonTest.cpp	2012-05-18 22:24:00 UTC (rev 117644)
+++ trunk/Source/WebKit/chromium/tests/CCLayerTreeHostCommonTest.cpp	2012-05-18 22:27:18 UTC (rev 117645)
@@ -1325,6 +1325,69 @@
     EXPECT_TRUE(childOfAnimatingSurface->visibleLayerRect().isEmpty());
 }
 
+TEST(CCLayerTreeHostCommonTest, verifyBackFaceCullingWithPreserves3dForFlatteningSurface)
+{
+    // Verify the behavior of back-face culling for a renderSurface that is created
+    // when it flattens its subtree, and its parent has preserves-3d.
+
+    const TransformationMatrix identityMatrix;
+    RefPtr<LayerChromium> parent = LayerChromium::create();
+    RefPtr<LayerChromiumWithForcedDrawsContent> frontFacingSurface = adoptRef(new LayerChromiumWithForcedDrawsContent());
+    RefPtr<LayerChromiumWithForcedDrawsContent> backFacingSurface = adoptRef(new LayerChromiumWithForcedDrawsContent());
+    RefPtr<LayerChromiumWithForcedDrawsContent> child1 = adoptRef(new LayerChromiumWithForcedDrawsContent());
+    RefPtr<LayerChromiumWithForcedDrawsContent> child2 = adoptRef(new LayerChromiumWithForcedDrawsContent());
+
+    parent->createRenderSurface();
+    parent->addChild(frontFacingSurface);
+    parent->addChild(backFacingSurface);
+    frontFacingSurface->addChild(child1);
+    backFacingSurface->addChild(child2);
+
+    // RenderSurfaces are not double-sided
+    frontFacingSurface->setDoubleSided(false);
+    backFacingSurface->setDoubleSided(false);
+
+    TransformationMatrix backfaceMatrix;
+    backfaceMatrix.translate(50, 50);
+    backfaceMatrix.rotate3d(0, 1, 0, 180);
+    backfaceMatrix.translate(-50, -50);
+
+    setLayerPropertiesForTesting(parent.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), true); // parent transform style is preserve3d.
+    setLayerPropertiesForTesting(frontFacingSurface.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false); // surface transform style is flat.
+    setLayerPropertiesForTesting(backFacingSurface.get(),  backfaceMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false); // surface transform style is flat.
+    setLayerPropertiesForTesting(child1.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false);
+    setLayerPropertiesForTesting(child2.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false);
+
+    Vector<RefPtr<LayerChromium> > renderSurfaceLayerList;
+    Vector<RefPtr<LayerChromium> > dummyLayerList;
+    int dummyMaxTextureSize = 512;
+    parent->renderSurface()->setContentRect(IntRect(IntPoint(), parent->bounds()));
+    parent->setClipRect(IntRect(IntPoint::zero(), parent->bounds()));
+    renderSurfaceLayerList.append(parent.get());
+
+    CCLayerTreeHostCommon::calculateDrawTransformsAndVisibility(parent.get(), parent.get(), identityMatrix, identityMatrix, renderSurfaceLayerList, dummyLayerList, dummyMaxTextureSize);
+
+    // Verify which renderSurfaces were created.
+    EXPECT_TRUE(frontFacingSurface->renderSurface());
+    EXPECT_FALSE(backFacingSurface->renderSurface()); // because it should be culled
+    EXPECT_FALSE(child1->renderSurface());
+    EXPECT_FALSE(child2->renderSurface());
+
+    // Verify the renderSurfaceLayerList. The back-facing surface should be culled.
+    ASSERT_EQ(2u, renderSurfaceLayerList.size());
+    EXPECT_EQ(parent->id(), renderSurfaceLayerList[0]->id());
+    EXPECT_EQ(frontFacingSurface->id(), renderSurfaceLayerList[1]->id());
+
+    // Verify root surface's layerList.
+    ASSERT_EQ(1u, renderSurfaceLayerList[0]->renderSurface()->layerList().size());
+    EXPECT_EQ(frontFacingSurface->id(), renderSurfaceLayerList[0]->renderSurface()->layerList()[0]->id());
+
+    // Verify frontFacingSurface's layerList.
+    ASSERT_EQ(2u, renderSurfaceLayerList[1]->renderSurface()->layerList().size());
+    EXPECT_EQ(frontFacingSurface->id(), renderSurfaceLayerList[1]->renderSurface()->layerList()[0]->id());
+    EXPECT_EQ(child1->id(), renderSurfaceLayerList[1]->renderSurface()->layerList()[1]->id());
+}
+
 // FIXME:
 // continue working on https://bugs.webkit.org/show_bug.cgi?id=68942
 //  - add a test to verify clipping that changes the "center point"
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to