Source/WebCore: [CoordGfx] Regression from r135212: big layers with transform animati...
authorallan.jensen@digia.com <allan.jensen@digia.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 15 Feb 2013 12:09:08 +0000 (12:09 +0000)
committerallan.jensen@digia.com <allan.jensen@digia.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 15 Feb 2013 12:09:08 +0000 (12:09 +0000)
https://bugs.webkit.org/show_bug.cgi?id=109179

Reviewed by Jocelyn Turcotte.

Fix adjustForContentsRect logic for AC layers that are higher or wider than the visible rect.

Force updates of the visible rect while it is animating, and until we have done one last update after
it stops animating.

Test: compositing/transitions/transform-on-large-layer.html

* platform/graphics/TiledBackingStore.cpp:
(WebCore::TiledBackingStore::adjustForContentsRect):
(WebCore::TiledBackingStore::computeCoverAndKeepRect):
* platform/graphics/texmap/coordinated/CoordinatedGraphicsLayer.cpp:
(WebCore::CoordinatedGraphicsLayer::CoordinatedGraphicsLayer):
(WebCore::CoordinatedGraphicsLayer::flushCompositingStateForThisLayerOnly):
(WebCore::CoordinatedGraphicsLayer::computePixelAlignment):
(WebCore::CoordinatedGraphicsLayer::computeTransformedVisibleRect):
* platform/graphics/texmap/coordinated/CoordinatedGraphicsLayer.h:
(CoordinatedGraphicsLayer):

LayoutTests: [CoordGfx] Regression from r135212: big layers with transform animations sometime fail to render tiles.
https://bugs.webkit.org/show_bug.cgi?id=109179

Reviewed by Jocelyn Turcotte.

Test of a large layer with an animated transform. Skipped on WK1 due to resize event not firing in DRT.

* compositing/transitions/transform-on-large-layer-expected.html: Added.
* compositing/transitions/transform-on-large-layer.html: Added.
* platform/mac/TestExpectations:
* platform/qt-5.0-wk1/TestExpectations:

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

LayoutTests/ChangeLog
LayoutTests/compositing/transitions/transform-on-large-layer-expected.html [new file with mode: 0644]
LayoutTests/compositing/transitions/transform-on-large-layer.html [new file with mode: 0644]
LayoutTests/platform/mac/TestExpectations
LayoutTests/platform/qt-5.0-wk1/TestExpectations
Source/WebCore/ChangeLog
Source/WebCore/platform/graphics/TiledBackingStore.cpp
Source/WebCore/platform/graphics/texmap/coordinated/CoordinatedGraphicsLayer.cpp
Source/WebCore/platform/graphics/texmap/coordinated/CoordinatedGraphicsLayer.h

index 0a34ba3..db9b23d 100644 (file)
@@ -1,3 +1,17 @@
+2013-02-13  Allan Sandfeld Jensen  <allan.jensen@digia.com>
+
+        [CoordGfx] Regression from r135212: big layers with transform animations sometime fail to render tiles.
+        https://bugs.webkit.org/show_bug.cgi?id=109179
+
+        Reviewed by Jocelyn Turcotte.
+
+        Test of a large layer with an animated transform. Skipped on WK1 due to resize event not firing in DRT.
+
+        * compositing/transitions/transform-on-large-layer-expected.html: Added.
+        * compositing/transitions/transform-on-large-layer.html: Added.
+        * platform/mac/TestExpectations:
+        * platform/qt-5.0-wk1/TestExpectations:
+
 2013-02-14  Alexander Pavlov  <apavlov@chromium.org>
 
         Web Inspector: Implement tracking of active stylesheets in the frontend
diff --git a/LayoutTests/compositing/transitions/transform-on-large-layer-expected.html b/LayoutTests/compositing/transitions/transform-on-large-layer-expected.html
new file mode 100644 (file)
index 0000000..4f8eb8e
--- /dev/null
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <title>Animating transform on large tiled layer.</title>
+    <style type="text/css">
+        #box {
+            display: block;
+            width: 1000px;
+            height: 2000px;
+            background-color: green;
+        }
+
+        #sandbox {
+            height: 1000px;
+            width: 1000px;
+            background-color: red;
+            overflow: hidden;
+        }
+    </style>
+</head>
+<script>
+    window.resizeTo(1600,1200);
+</script>
+<body>
+    <div id=description> 
+        The test passes if the box below turns green.
+    </div>
+    <div id=sandbox> 
+        <div id="box"><font style="opacity:0">ABC</font></div>
+    </div>
+</body>
+</html>
\ No newline at end of file
diff --git a/LayoutTests/compositing/transitions/transform-on-large-layer.html b/LayoutTests/compositing/transitions/transform-on-large-layer.html
new file mode 100644 (file)
index 0000000..716be30
--- /dev/null
@@ -0,0 +1,56 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <title>Animating transform on large tiled layer.</title>
+    <style type="text/css">
+        #box {
+            -webkit-transition: -webkit-transform 1s step-end;
+            display: block;
+            width: 1000px;
+            height: 2000px;
+            background-color: green;
+        }
+
+        #sandbox {
+            height: 1000px;
+            width: 1000px;
+            background-color: red;
+            overflow: hidden;
+        }
+
+        .end {
+            -webkit-transform: translate3d(0, -1000px, 0);
+        }
+
+        .start {
+            -webkit-transform: translate3d(0, 100%, 0);
+        }
+    </style>
+    <script type="text/javascript">
+        function run()
+        {
+            if (window.testRunner) {
+                testRunner.waitUntilDone();
+                window.setTimeout(notifyDone, 1200);
+            }
+            window.onresize = function() {
+                var box = document.getElementById("box");
+                box.className = "end";
+            }
+            window.resizeTo(1600,1200);
+        }
+        function notifyDone()
+        {
+            testRunner.notifyDone();
+        }
+    </script>
+</head>
+<body onload="run()">
+    <div id=description>
+        The test passes if the box below turns green.
+    </div>
+    <div id=sandbox> 
+        <div id="box" class="start"><font style="opacity:0">ABC</font></div>
+    </div>
+</body>
+</html>
\ No newline at end of file
index 9b8b9b8..1f47c21 100644 (file)
@@ -1417,3 +1417,6 @@ webkit.org/b/109209 fast/text/international/bidi-ignored-for-first-child-inline.
 webkit.org/b/109232 [ Debug ] inspector/debugger/debugger-reload-on-pause.html [ Crash ]
 
 webkit.org/b/109869 media/media-captions.html [ Crash ]
+
+# New test failing, needs investigation.
+webkit.org/b/109179 compositing/transitions/transform-on-large-layer.html [ Failure ]
index f6099a2..7efb374 100644 (file)
@@ -188,3 +188,6 @@ webkit.org/b/95507 http/tests/notifications/events.html [ Failure ]
 webkit.org/b/95507 http/tests/notifications/window-show-on-click.html [ Failure ]
 webkit.org/b/95507 http/tests/notifications/legacy/events.html [ Failure ]
 webkit.org/b/95507 http/tests/notifications/legacy/window-show-on-click.html [ Failure ]
+
+# New test fails due to resizeTo not firing an event.
+webkit.org/b/109179 compositing/transitions/transform-on-large-layer.html [ Failure ]
index 2a2abb4..419f106 100644 (file)
@@ -1,3 +1,28 @@
+2013-02-13  Allan Sandfeld Jensen  <allan.jensen@digia.com>
+
+        [CoordGfx] Regression from r135212: big layers with transform animations sometime fail to render tiles
+        https://bugs.webkit.org/show_bug.cgi?id=109179
+
+        Reviewed by Jocelyn Turcotte.
+
+        Fix adjustForContentsRect logic for AC layers that are higher or wider than the visible rect.
+
+        Force updates of the visible rect while it is animating, and until we have done one last update after
+        it stops animating.
+
+        Test: compositing/transitions/transform-on-large-layer.html
+
+        * platform/graphics/TiledBackingStore.cpp:
+        (WebCore::TiledBackingStore::adjustForContentsRect):
+        (WebCore::TiledBackingStore::computeCoverAndKeepRect):
+        * platform/graphics/texmap/coordinated/CoordinatedGraphicsLayer.cpp:
+        (WebCore::CoordinatedGraphicsLayer::CoordinatedGraphicsLayer):
+        (WebCore::CoordinatedGraphicsLayer::flushCompositingStateForThisLayerOnly):
+        (WebCore::CoordinatedGraphicsLayer::computePixelAlignment):
+        (WebCore::CoordinatedGraphicsLayer::computeTransformedVisibleRect):
+        * platform/graphics/texmap/coordinated/CoordinatedGraphicsLayer.h:
+        (CoordinatedGraphicsLayer):
+
 2013-02-15  Sheriff Bot  <webkit.review.bot@gmail.com>
 
         Unreviewed, rolling out r142876.
index d902adb..790945b 100644 (file)
@@ -344,26 +344,13 @@ void TiledBackingStore::adjustForContentsRect(IntRect& rect) const
     IntRect bounds = m_rect;
     IntSize candidateSize = rect.size();
 
-    // If candidateSize is bigger than bounds (i.e. TBS is used as a backing store of GraphicsLayer), we skip the below adjusting logic which expects bounds to cover the given rect.
-    if (candidateSize.width() > bounds.width() && candidateSize.height() > bounds.height()) {
-        rect.intersect(bounds);
-        return;
-    }
-
-    // We will try to keep the cover and keep rect the same size at all time, which
-    // might not be the case when at the content edges.
-
-    // We start by moving when at the edges.
-    rect.move(std::max(0, bounds.x() - rect.x()), std::max(0, bounds.y() - rect.y()));
-    rect.move(std::min(0, bounds.maxX() - rect.maxX()), std::min(0, bounds.maxY() - rect.maxY()));
-
     rect.intersect(bounds);
 
     if (rect.size() == candidateSize)
         return;
 
     /*
-     * In the following case, there is no intersection of the contents rect and the cover/keep rect.
+     * In the following case, there is no intersection of the contents rect and the cover rect.
      * Thus the latter should not be inflated.
      *
      *  +---------------+
@@ -371,7 +358,7 @@ void TiledBackingStore::adjustForContentsRect(IntRect& rect) const
      *  +---------------+
      *
      *          +-------------------------------+
-     *          |      cover or keep rect       |
+     *          |          cover rect           |
      *          |         +---------+           |
      *          |         | visible |           |
      *          |         |  rect   |           |
@@ -381,13 +368,12 @@ void TiledBackingStore::adjustForContentsRect(IntRect& rect) const
     if (rect.isEmpty())
         return;
 
-    // Even now we might cover more than the content area so let's inflate in the
-    // opposite directions.
+    // Try to create a cover rect of the same size as the candidate, but within content bounds.
     int pixelsCovered = candidateSize.width() * candidateSize.height();
 
-    if (rect.width() != candidateSize.width())
+    if (rect.width() < candidateSize.width())
         rect.inflateY(((pixelsCovered / rect.width()) - rect.height()) / 2);
-    if (rect.height() != candidateSize.height())
+    if (rect.height() < candidateSize.height())
         rect.inflateX(((pixelsCovered / rect.height()) - rect.width()) / 2);
 
     rect.intersect(bounds);
@@ -425,16 +411,18 @@ void TiledBackingStore::computeCoverAndKeepRect(const IntRect& visibleRect, IntR
 
             coverRect.unite(visibleRect);
         }
+        ASSERT(keepRect.contains(coverRect));
     }
 
-    ASSERT(keepRect.contains(coverRect));
+    adjustForContentsRect(coverRect);
 
     // The keep rect is an inflated version of the cover rect, inflated in tile dimensions.
+    keepRect.unite(coverRect);
     keepRect.inflateX(m_tileSize.width() / 2);
     keepRect.inflateY(m_tileSize.height() / 2);
+    keepRect.intersect(m_rect);
 
-    adjustForContentsRect(coverRect);
-    adjustForContentsRect(keepRect);
+    ASSERT(coverRect.isEmpty() || keepRect.contains(coverRect));
 }
 
 bool TiledBackingStore::isBackingStoreUpdatesSuspended() const
index 0ee97cd..4c43aa7 100644 (file)
@@ -111,6 +111,7 @@ CoordinatedGraphicsLayer::CoordinatedGraphicsLayer(GraphicsLayerClient* client)
     , m_shouldSyncImageBacking(true)
     , m_shouldSyncAnimations(true)
     , m_fixedToViewport(false)
+    , m_movingVisibleRect(false)
     , m_pendingContentsScaleAdjustment(false)
     , m_pendingVisibleRectAdjustment(false)
 #if USE(GRAPHICS_SURFACE)
@@ -646,6 +647,11 @@ void CoordinatedGraphicsLayer::flushCompositingStateForThisLayerOnly()
 {
     ASSERT(m_coordinator->isFlushingLayerChanges());
 
+    // When we have a transform animation, we need to update visible rect every frame to adjust the visible rect of a backing store.
+    bool hasActiveTransformAnimation = selfOrAncestorHasActiveTransformAnimation();
+    if (hasActiveTransformAnimation)
+        m_movingVisibleRect = true;
+
     // Sets the values.
     computePixelAlignment(m_adjustedPosition, m_adjustedSize, m_adjustedAnchorPoint, m_pixelAlignmentOffset);
 
@@ -661,6 +667,9 @@ void CoordinatedGraphicsLayer::flushCompositingStateForThisLayerOnly()
 #if USE(GRAPHICS_SURFACE)
     syncCanvas();
 #endif
+    // Only unset m_movingVisibleRect after we have updated the visible rect after the animation stopped.
+    if (!hasActiveTransformAnimation)
+        m_movingVisibleRect = false;
 }
 
 bool CoordinatedGraphicsLayer::imageBackingVisible()
@@ -956,14 +965,12 @@ void CoordinatedGraphicsLayer::computePixelAlignment(FloatPoint& position, Float
 
 void CoordinatedGraphicsLayer::computeTransformedVisibleRect()
 {
-    // When we have a transform animation, we need to update visible rect every frame to adjust the visible rect of a backing store.
-    bool hasActiveTransformAnimation = selfOrAncestorHasActiveTransformAnimation();
-    if (!m_shouldUpdateVisibleRect && !hasActiveTransformAnimation)
+    if (!m_shouldUpdateVisibleRect && !m_movingVisibleRect)
         return;
 
     m_shouldUpdateVisibleRect = false;
     TransformationMatrix currentTransform = transform();
-    if (hasActiveTransformAnimation)
+    if (m_movingVisibleRect)
         client()->getCurrentTransform(this, currentTransform);
     m_layerTransform.setLocalTransform(currentTransform);
 
index a3f0a08..e5aa47a 100644 (file)
@@ -234,6 +234,7 @@ private:
     bool m_shouldSyncImageBacking: 1;
     bool m_shouldSyncAnimations: 1;
     bool m_fixedToViewport : 1;
+    bool m_movingVisibleRect : 1;
     bool m_pendingContentsScaleAdjustment : 1;
     bool m_pendingVisibleRectAdjustment : 1;
 #if USE(GRAPHICS_SURFACE)