[chromium] Use projectQuad to apply inverse mapRect
authorcommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 13 Mar 2012 15:43:45 +0000 (15:43 +0000)
committercommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 13 Mar 2012 15:43:45 +0000 (15:43 +0000)
https://bugs.webkit.org/show_bug.cgi?id=80741

Patch by Dana Jansens <danakj@chromium.org> on 2012-03-13
Reviewed by Adrienne Walker.

Source/WebCore:

Unit test: CCOcclusionTrackerTest3dTransform
           CCOcclusionTrackerTestPerspectiveTransform
           CCOcclusionTrackerTestPerspectiveTransformBehindCamera

* platform/graphics/chromium/cc/CCOcclusionTracker.cpp:
(WebCore::projectQuad):
(WebCore):
(WebCore::computeUnoccludedContentRect):

Source/WebKit/chromium:

* tests/CCOcclusionTrackerTest.cpp:
(WebCore):
(CCOcclusionTrackerTest3dTransform):
(WebCore::CCOcclusionTrackerTest3dTransform::runMyTest):
(CCOcclusionTrackerTestPerspectiveTransform):
(WebCore::CCOcclusionTrackerTestPerspectiveTransform::runMyTest):
(CCOcclusionTrackerTestPerspectiveTransformBehindCamera):
(WebCore::CCOcclusionTrackerTestPerspectiveTransformBehindCamera::runMyTest):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@110569 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/WebCore/ChangeLog
Source/WebCore/platform/graphics/chromium/cc/CCOcclusionTracker.cpp
Source/WebKit/chromium/ChangeLog
Source/WebKit/chromium/tests/CCOcclusionTrackerTest.cpp

index 1ddc276..2acc1ea 100644 (file)
@@ -1,3 +1,19 @@
+2012-03-13  Dana Jansens  <danakj@chromium.org>
+
+        [chromium] Use projectQuad to apply inverse mapRect
+        https://bugs.webkit.org/show_bug.cgi?id=80741
+
+        Reviewed by Adrienne Walker.
+
+        Unit test: CCOcclusionTrackerTest3dTransform
+                   CCOcclusionTrackerTestPerspectiveTransform
+                   CCOcclusionTrackerTestPerspectiveTransformBehindCamera
+
+        * platform/graphics/chromium/cc/CCOcclusionTracker.cpp:
+        (WebCore::projectQuad):
+        (WebCore):
+        (WebCore::computeUnoccludedContentRect):
+
 2012-03-13  Gavin Peters  <gavinp@chromium.org>
 
         New PageCache histogram which counts failures ignoring Settings.
index 9e49772..b2dfcb5 100644 (file)
@@ -270,12 +270,34 @@ static inline IntRect rectSubtractRegion(const IntRect& rect, const Region& regi
     return boundsRect;
 }
 
+static FloatQuad projectQuad(const TransformationMatrix& transform, const FloatQuad& q, bool& clamped)
+{
+    FloatQuad projectedQuad;
+    bool clampedPoint;
+    projectedQuad.setP1(transform.projectPoint(q.p1(), &clampedPoint));
+    clamped = clampedPoint;
+    projectedQuad.setP2(transform.projectPoint(q.p2(), &clampedPoint));
+    clamped |= clampedPoint;
+    projectedQuad.setP3(transform.projectPoint(q.p3(), &clampedPoint));
+    clamped |= clampedPoint;
+    projectedQuad.setP4(transform.projectPoint(q.p4(), &clampedPoint));
+    clamped |= clampedPoint;
+
+    return projectedQuad;
+}
+
 static inline IntRect computeUnoccludedContentRect(const IntRect& contentRect, const TransformationMatrix& contentSpaceTransform, const IntRect& scissorRect, const Region& occlusion)
 {
+    if (!contentSpaceTransform.isInvertible())
+        return contentRect;
+
     FloatRect transformedRect = contentSpaceTransform.mapRect(FloatRect(contentRect));
     // Take the enclosingIntRect at each step, as we want to contain any unoccluded partial pixels in the resulting IntRect.
     IntRect shrunkRect = rectSubtractRegion(intersection(enclosingIntRect(transformedRect), scissorRect), occlusion);
-    IntRect unoccludedRect = enclosingIntRect(contentSpaceTransform.inverse().mapRect(FloatRect(shrunkRect)));
+    bool clamped; // FIXME: projectQuad returns invalid results when a point gets clamped. To be fixed in bug https://bugs.webkit.org/show_bug.cgi?id=80806.
+    IntRect unoccludedRect = enclosingIntRect(projectQuad(contentSpaceTransform.inverse(), FloatQuad(FloatRect(shrunkRect)), clamped).boundingBox());
+    if (clamped)
+        return contentRect;
     // The rect back in content space is a bounding box and may extend outside of the original contentRect, so clamp it to the contentRectBounds.
     return intersection(unoccludedRect, contentRect);
 }
index 2c58bd2..b824800 100644 (file)
@@ -1,3 +1,19 @@
+2012-03-13  Dana Jansens  <danakj@chromium.org>
+
+        [chromium] Use projectQuad to apply inverse mapRect
+        https://bugs.webkit.org/show_bug.cgi?id=80741
+
+        Reviewed by Adrienne Walker.
+
+        * tests/CCOcclusionTrackerTest.cpp:
+        (WebCore):
+        (CCOcclusionTrackerTest3dTransform):
+        (WebCore::CCOcclusionTrackerTest3dTransform::runMyTest):
+        (CCOcclusionTrackerTestPerspectiveTransform):
+        (WebCore::CCOcclusionTrackerTestPerspectiveTransform::runMyTest):
+        (CCOcclusionTrackerTestPerspectiveTransformBehindCamera):
+        (WebCore::CCOcclusionTrackerTestPerspectiveTransformBehindCamera::runMyTest):
+
 2012-03-13  Gavin Peters  <gavinp@chromium.org>
 
         Make ApplicationCacheHost::canCacheInPageCache() non-const.
index 25151c5..254414d 100644 (file)
@@ -314,6 +314,9 @@ private:
     RUN_TEST_IMPL_THREAD_OPAQUE_LAYERS(ClassName) \
     RUN_TEST_IMPL_THREAD_OPAQUE_PAINTS(ClassName)
 
+#define MAIN_THREAD_TEST(ClassName) \
+    RUN_TEST_MAIN_THREAD_OPAQUE_LAYERS(ClassName)
+
 #define MAIN_AND_IMPL_THREAD_TEST(ClassName) \
     RUN_TEST_MAIN_THREAD_OPAQUE_LAYERS(ClassName) \
     RUN_TEST_IMPL_THREAD_OPAQUE_LAYERS(ClassName)
@@ -1712,4 +1715,83 @@ protected:
 
 MAIN_AND_IMPL_THREAD_TEST(CCOcclusionTrackerTestOpaqueContentsRegionNonEmpty);
 
+template<class Types, bool opaqueLayers>
+class CCOcclusionTrackerTest3dTransform : public CCOcclusionTrackerTest<Types, opaqueLayers> {
+protected:
+    void runMyTest()
+    {
+        TransformationMatrix transform;
+        transform.rotate3d(0, 30, 0);
+
+        typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(300, 300));
+        typename Types::LayerType* container = this->createLayer(parent, this->identityMatrix, FloatPoint(0, 0), IntSize(300, 300));
+        typename Types::ContentLayerType* layer = this->createDrawingSurface(container, transform, FloatPoint(100, 100), IntSize(200, 200), true);
+        this->calcDrawEtc(parent);
+
+        TestCCOcclusionTrackerBase<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
+        occlusion.enterTargetRenderSurface(parent->renderSurface());
+
+        EXPECT_EQ_RECT(IntRect(0, 0, 200, 200), occlusion.unoccludedContentRect(layer, IntRect(0, 0, 200, 200)));
+    }
+};
+
+MAIN_AND_IMPL_THREAD_TEST(CCOcclusionTrackerTest3dTransform);
+
+template<class Types, bool opaqueLayers>
+class CCOcclusionTrackerTestPerspectiveTransform : public CCOcclusionTrackerTest<Types, opaqueLayers> {
+protected:
+    void runMyTest()
+    {
+        TransformationMatrix transform;
+        transform.translate(150, 150);
+        transform.applyPerspective(400);
+        transform.rotate3d(1, 0, 0, -30);
+        transform.translate(-150, -150);
+
+        typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(300, 300));
+        typename Types::LayerType* container = this->createLayer(parent, this->identityMatrix, FloatPoint(0, 0), IntSize(300, 300));
+        typename Types::ContentLayerType* layer = this->createDrawingSurface(container, transform, FloatPoint(100, 100), IntSize(200, 200), true);
+        container->setPreserves3D(true);
+        this->calcDrawEtc(parent);
+
+        TestCCOcclusionTrackerBase<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
+        occlusion.enterTargetRenderSurface(parent->renderSurface());
+
+        EXPECT_EQ_RECT(IntRect(0, 0, 200, 200), occlusion.unoccludedContentRect(layer, IntRect(0, 0, 200, 200)));
+    }
+};
+
+MAIN_THREAD_TEST(CCOcclusionTrackerTestPerspectiveTransform);
+
+template<class Types, bool opaqueLayers>
+class CCOcclusionTrackerTestPerspectiveTransformBehindCamera : public CCOcclusionTrackerTest<Types, opaqueLayers> {
+protected:
+    void runMyTest()
+    {
+        // This test is based on the platform/chromium/compositing/3d-corners.html layout test.
+        TransformationMatrix transform;
+        transform.translate(250, 50);
+        transform.applyPerspective(10);
+        transform.translate(-250, -50);
+        transform.translate(250, 50);
+        transform.rotate3d(1, 0, 0, -167);
+        transform.translate(-250, -50);
+
+        typename Types::ContentLayerType* parent = this->createRoot(this->identityMatrix, FloatPoint(0, 0), IntSize(500, 100));
+        typename Types::LayerType* container = this->createLayer(parent, this->identityMatrix, FloatPoint(0, 0), IntSize(500, 500));
+        typename Types::ContentLayerType* layer = this->createDrawingLayer(container, transform, FloatPoint(0, 0), IntSize(500, 500), true);
+        container->setPreserves3D(true);
+        this->calcDrawEtc(parent);
+
+        TestCCOcclusionTrackerBase<typename Types::LayerType, typename Types::RenderSurfaceType> occlusion(IntRect(0, 0, 1000, 1000));
+        occlusion.enterTargetRenderSurface(parent->renderSurface());
+
+        // The bottom 11 pixel rows of this layer remain visible inside the container, after translation to the target surface. When translated back,
+        // this will include many more pixels but must include at least the bottom 11 rows.
+        EXPECT_TRUE(occlusion.unoccludedContentRect(layer, IntRect(0, 0, 500, 500)).contains(IntRect(0, 489, 500, 11)));
+    }
+};
+
+MAIN_THREAD_TEST(CCOcclusionTrackerTestPerspectiveTransformBehindCamera);
+
 } // namespace