REGRESSION (r233268): Elements animated in from offscreen sometimes don't display
authorsimon.fraser@apple.com <simon.fraser@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 17 Dec 2018 17:10:44 +0000 (17:10 +0000)
committersimon.fraser@apple.com <simon.fraser@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 17 Dec 2018 17:10:44 +0000 (17:10 +0000)
https://bugs.webkit.org/show_bug.cgi?id=192725
rdar://problem/46011418

Reviewed by Antoine Quint.

Source/WebCore:

There were two problems with backing store attachment and animation.

First, animations are an input into the "backing store attached" logic, so when they change
we should set the CoverageRectChanged bit on GraphicsLayerCA.

Secondly, when an ancestor has unknown animation extent, all its descendants need to
get backing store, so we need to set childCommitState.ancestorWithTransformAnimationIntersectsCoverageRect when
the current layer has no animation extent.

Tests: compositing/backing/animate-into-view-with-descendant.html
       compositing/backing/animate-into-view.html

* platform/graphics/ca/GraphicsLayerCA.cpp:
(WebCore::GraphicsLayerCA::addAnimation):
(WebCore::GraphicsLayerCA::removeAnimation):
(WebCore::GraphicsLayerCA::recursiveCommitChanges):

LayoutTests:

* compositing/backing/animate-into-view-expected.txt: Added.
* compositing/backing/animate-into-view-with-descendant-expected.txt: Added.
* compositing/backing/animate-into-view-with-descendant.html: Added.
* compositing/backing/animate-into-view.html: Added.
* platform/ios/compositing/backing/animate-into-view-expected.txt: Added.
* platform/ios/compositing/backing/animate-into-view-with-descendant-expected.txt: Added.

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

LayoutTests/ChangeLog
LayoutTests/compositing/backing/animate-into-view-expected.txt [new file with mode: 0644]
LayoutTests/compositing/backing/animate-into-view-with-descendant-expected.txt [new file with mode: 0644]
LayoutTests/compositing/backing/animate-into-view-with-descendant.html [new file with mode: 0644]
LayoutTests/compositing/backing/animate-into-view.html [new file with mode: 0644]
LayoutTests/platform/ios/compositing/backing/animate-into-view-expected.txt [new file with mode: 0644]
LayoutTests/platform/ios/compositing/backing/animate-into-view-with-descendant-expected.txt [new file with mode: 0644]
Source/WebCore/ChangeLog
Source/WebCore/platform/graphics/ca/GraphicsLayerCA.cpp

index 7cff414..754ab34 100644 (file)
@@ -1,3 +1,18 @@
+2018-12-17  Simon Fraser  <simon.fraser@apple.com>
+
+        REGRESSION (r233268): Elements animated in from offscreen sometimes don't display
+        https://bugs.webkit.org/show_bug.cgi?id=192725
+        rdar://problem/46011418
+
+        Reviewed by Antoine Quint.
+
+        * compositing/backing/animate-into-view-expected.txt: Added.
+        * compositing/backing/animate-into-view-with-descendant-expected.txt: Added.
+        * compositing/backing/animate-into-view-with-descendant.html: Added.
+        * compositing/backing/animate-into-view.html: Added.
+        * platform/ios/compositing/backing/animate-into-view-expected.txt: Added.
+        * platform/ios/compositing/backing/animate-into-view-with-descendant-expected.txt: Added.
+
 2018-12-17  Ms2ger  <Ms2ger@igalia.com>
 
         [GTK][WPE] Need a function to convert internal URI to display ("pretty") URI
diff --git a/LayoutTests/compositing/backing/animate-into-view-expected.txt b/LayoutTests/compositing/backing/animate-into-view-expected.txt
new file mode 100644 (file)
index 0000000..2b44a95
--- /dev/null
@@ -0,0 +1,24 @@
+T
+(GraphicsLayer
+  (anchor 0.00 0.00)
+  (bounds 912.00 585.00)
+  (backingStoreAttached 1)
+  (children 1
+    (GraphicsLayer
+      (bounds 912.00 585.00)
+      (contentsOpaque 1)
+      (backingStoreAttached 1)
+      (children 1
+        (GraphicsLayer
+          (position 503.00 26.00)
+          (anchor 0.50 0.52)
+          (bounds 10.00 31.00)
+          (drawsContent 1)
+          (backingStoreAttached 1)
+          (transform [1.50 -0.00 0.00 0.00] [0.00 0.50 0.00 0.00] [0.00 0.00 1.00 0.00] [-565.25 7.75 0.00 1.00])
+        )
+      )
+    )
+  )
+)
+
diff --git a/LayoutTests/compositing/backing/animate-into-view-with-descendant-expected.txt b/LayoutTests/compositing/backing/animate-into-view-with-descendant-expected.txt
new file mode 100644 (file)
index 0000000..4714009
--- /dev/null
@@ -0,0 +1,30 @@
+T
+(GraphicsLayer
+  (anchor 0.00 0.00)
+  (bounds 912.00 585.00)
+  (backingStoreAttached 1)
+  (children 1
+    (GraphicsLayer
+      (bounds 912.00 585.00)
+      (contentsOpaque 1)
+      (backingStoreAttached 1)
+      (children 1
+        (GraphicsLayer
+          (position 503.00 66.00)
+          (bounds 20.00 20.00)
+          (backingStoreAttached 1)
+          (transform [1.50 -0.00 0.00 0.00] [0.00 0.50 0.00 0.00] [0.00 0.00 1.00 0.00] [-565.25 7.75 0.00 1.00])
+          (children 1
+            (GraphicsLayer
+              (anchor 0.50 0.52)
+              (bounds 10.00 31.00)
+              (drawsContent 1)
+              (backingStoreAttached 1)
+            )
+          )
+        )
+      )
+    )
+  )
+)
+
diff --git a/LayoutTests/compositing/backing/animate-into-view-with-descendant.html b/LayoutTests/compositing/backing/animate-into-view-with-descendant.html
new file mode 100644 (file)
index 0000000..39ebdd7
--- /dev/null
@@ -0,0 +1,81 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <style>
+        .wrapper {
+            position: relative;
+            margin-top: 50px;
+            margin-left: -50px;
+            width: 952px;
+            height: 82px;
+            border: 1px solid black;
+            perspective: 2000px;
+        }
+        
+        .middle {
+            position: absolute;
+            top: 15px;
+            left: 544px;
+            padding: 10px;
+            animation-fill-mode: forwards;
+            animation-duration: 3s;
+            animation-name: bounce;
+        }
+        
+        .letter {
+            position: absolute;
+            top: 0px;
+            left: 0px;
+            width: 9px;
+            height: 31px;
+            position: absolute;
+            background-color: silver;
+            transform: translateZ(0);
+        }
+
+        @keyframes bounce {
+            0% { transform: matrix3d(1.5, 0, 0, 0, 0, 0.5, 0, 0, 0, 0, 1, 0, -565.25, 7.75, 0, 1); }
+            19% { transform: matrix3d(1.5, 0, 0, 0, 0, 0.5, 0, 0, 0, 0, 1, 0, -565.25, 7.75, 0, 1); }
+            25% { transform: matrix3d(1.1558, 0, 0, 0, -0.00666, 0.7771, 0, 0, 0, 0, 1, 0, -504.006, -41.6730, 0, 1); }
+            47% { transform: matrix3d(1.5, 0, 0, 0, 0, 0.5, 0, 0, 0, 0, 1, 0, -283.75, 7.75, 0, 1); }
+            60% { transform: matrix3d(1.3906, 0, 0, 0, 0.073394, 0.6825, 0, 0, 0, 0, 1, 0, -143.645, 4.920146, 0, 1); }
+            89% { transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); }
+            100% { transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); }
+        }
+    </style>
+    <script>
+        if (window.testRunner) {
+            testRunner.dumpAsText();
+            testRunner.waitUntilDone();
+        }
+
+        function dumpLayers()
+        {
+            var layersResult = document.getElementById('layers');
+            if (window.testRunner)
+                layersResult.innerText = window.internals.layerTreeAsText(document, internals.LAYER_TREE_INCLUDES_BACKING_STORE_ATTACHED);
+        }
+    </script>
+</head>
+<body>
+
+<div class="wrapper">
+    <div id="target" class="middle">
+        <div class="letter">T</div>
+    </div>
+</div>
+
+<pre id="layers">Layer tree goes here in DRT</pre>
+
+<script>
+    let animator = document.getElementById('target');
+    animator.addEventListener('animationstart', () => {
+        requestAnimationFrame(() => {
+            dumpLayers();
+            if (window.testRunner)
+                testRunner.notifyDone();
+        });
+    });
+</script>
+</body>
+</html>
diff --git a/LayoutTests/compositing/backing/animate-into-view.html b/LayoutTests/compositing/backing/animate-into-view.html
new file mode 100644 (file)
index 0000000..2b669a1
--- /dev/null
@@ -0,0 +1,88 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <style>
+        .wrapper {
+            position: relative;
+            margin-top: 10px;
+            margin-left: -50px;
+            width: 952px;
+            height: 82px;
+            border: 1px solid black;
+            perspective: 2000px;
+        }
+        
+        .middle {
+            position: absolute;
+            top: 15px;
+            left: 544px;
+            width: 9px;
+            height: 31px;
+        }
+        
+        .letter {
+            top: 0px;
+            left: 0px;
+            width: 9px;
+            height: 31px;
+            position: absolute;
+            background-color: blue;
+            animation-fill-mode: forwards;
+            animation-duration: 3s;
+            animation-name: bounce;
+        }
+        
+        .animating {
+            animation-name: bounce;
+        }
+
+        @keyframes bounce {
+            0% { transform: matrix3d(1.5, 0, 0, 0, 0, 0.5, 0, 0, 0, 0, 1, 0, -565.25, 7.75, 0, 1); }
+            19% { transform: matrix3d(1.5, 0, 0, 0, 0, 0.5, 0, 0, 0, 0, 1, 0, -565.25, 7.75, 0, 1); }
+            25% { transform: matrix3d(1.1558, 0, 0, 0, -0.00666, 0.7771, 0, 0, 0, 0, 1, 0, -504.006, -41.6730, 0, 1); }
+            47% { transform: matrix3d(1.5, 0, 0, 0, 0, 0.5, 0, 0, 0, 0, 1, 0, -283.75, 7.75, 0, 1); }
+            60% { transform: matrix3d(1.3906, 0, 0, 0, 0.073394, 0.6825, 0, 0, 0, 0, 1, 0, -143.645, 4.920146, 0, 1); }
+            89% { transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); }
+            100% { transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); }
+        }
+    </style>
+    <script>
+        if (window.testRunner) {
+            testRunner.dumpAsText();
+            testRunner.waitUntilDone();
+        }
+
+        function dumpLayers()
+        {
+            var layersResult = document.getElementById('layers');
+            if (window.testRunner)
+                layersResult.innerText = window.internals.layerTreeAsText(document, internals.LAYER_TREE_INCLUDES_BACKING_STORE_ATTACHED);
+        }
+
+        window.addEventListener('load', () => {
+            requestAnimationFrame(() => {
+                let animator = document.getElementById('target');
+                animator.addEventListener('animationstart', () => {
+                    requestAnimationFrame(() => {
+                        dumpLayers();
+                        if (window.testRunner)
+                            testRunner.notifyDone();
+                    });
+                });
+                animator.classList.add('animating');
+            });
+        }, false);
+    </script>
+</head>
+<body>
+
+<div class="wrapper">
+    <div class="middle">
+        <div id="target" class="letter">T</div>
+    </div>
+</div>
+
+<pre id="layers">Layer tree goes here in DRT</pre>
+
+</body>
+</html>
diff --git a/LayoutTests/platform/ios/compositing/backing/animate-into-view-expected.txt b/LayoutTests/platform/ios/compositing/backing/animate-into-view-expected.txt
new file mode 100644 (file)
index 0000000..d4dea64
--- /dev/null
@@ -0,0 +1,24 @@
+T
+(GraphicsLayer
+  (anchor 0.00 0.00)
+  (bounds 912.00 600.00)
+  (backingStoreAttached 1)
+  (children 1
+    (GraphicsLayer
+      (bounds 912.00 600.00)
+      (contentsOpaque 1)
+      (backingStoreAttached 1)
+      (children 1
+        (GraphicsLayer
+          (position 503.00 26.00)
+          (anchor 0.45 0.50)
+          (bounds 10.00 31.00)
+          (drawsContent 1)
+          (backingStoreAttached 1)
+          (transform [1.50 -0.00 0.00 0.00] [0.00 0.50 0.00 0.00] [0.00 0.00 1.00 0.00] [-565.25 7.75 0.00 1.00])
+        )
+      )
+    )
+  )
+)
+
diff --git a/LayoutTests/platform/ios/compositing/backing/animate-into-view-with-descendant-expected.txt b/LayoutTests/platform/ios/compositing/backing/animate-into-view-with-descendant-expected.txt
new file mode 100644 (file)
index 0000000..e92d19b
--- /dev/null
@@ -0,0 +1,30 @@
+T
+(GraphicsLayer
+  (anchor 0.00 0.00)
+  (bounds 912.00 600.00)
+  (backingStoreAttached 1)
+  (children 1
+    (GraphicsLayer
+      (bounds 912.00 600.00)
+      (contentsOpaque 1)
+      (backingStoreAttached 1)
+      (children 1
+        (GraphicsLayer
+          (position 503.00 66.00)
+          (bounds 20.00 20.00)
+          (backingStoreAttached 1)
+          (transform [1.50 -0.00 0.00 0.00] [0.00 0.50 0.00 0.00] [0.00 0.00 1.00 0.00] [-565.25 7.75 0.00 1.00])
+          (children 1
+            (GraphicsLayer
+              (anchor 0.45 0.50)
+              (bounds 10.00 31.00)
+              (drawsContent 1)
+              (backingStoreAttached 1)
+            )
+          )
+        )
+      )
+    )
+  )
+)
+
index 600180d..be9e4c1 100644 (file)
@@ -1,3 +1,28 @@
+2018-12-17  Simon Fraser  <simon.fraser@apple.com>
+
+        REGRESSION (r233268): Elements animated in from offscreen sometimes don't display
+        https://bugs.webkit.org/show_bug.cgi?id=192725
+        rdar://problem/46011418
+
+        Reviewed by Antoine Quint.
+
+        There were two problems with backing store attachment and animation.
+        
+        First, animations are an input into the "backing store attached" logic, so when they change
+        we should set the CoverageRectChanged bit on GraphicsLayerCA.
+        
+        Secondly, when an ancestor has unknown animation extent, all its descendants need to
+        get backing store, so we need to set childCommitState.ancestorWithTransformAnimationIntersectsCoverageRect when
+        the current layer has no animation extent.
+
+        Tests: compositing/backing/animate-into-view-with-descendant.html
+               compositing/backing/animate-into-view.html
+
+        * platform/graphics/ca/GraphicsLayerCA.cpp:
+        (WebCore::GraphicsLayerCA::addAnimation):
+        (WebCore::GraphicsLayerCA::removeAnimation):
+        (WebCore::GraphicsLayerCA::recursiveCommitChanges):
+
 2018-12-17  Zalan Bujtas  <zalan@apple.com>
 
         [LFC][BFC][MarginCollapsing] Unify margin collapse function naming
index fd76c79..d8aa373 100644 (file)
@@ -1039,7 +1039,7 @@ bool GraphicsLayerCA::addAnimation(const KeyframeValueList& valueList, const Flo
         createdAnimations = createAnimationFromKeyframes(valueList, anim, animationName, Seconds { timeOffset });
 
     if (createdAnimations)
-        noteLayerPropertyChanged(AnimationChanged);
+        noteLayerPropertyChanged(AnimationChanged | CoverageRectChanged);
 
     return createdAnimations;
 }
@@ -1072,7 +1072,7 @@ void GraphicsLayerCA::removeAnimation(const String& animationName)
         return;
 
     addProcessingActionForAnimation(animationName, AnimationProcessingAction(Remove));
-    noteLayerPropertyChanged(AnimationChanged);
+    noteLayerPropertyChanged(AnimationChanged | CoverageRectChanged);
 }
 
 void GraphicsLayerCA::platformCALayerAnimationStarted(const String& animationKey, MonotonicTime startTime)
@@ -1577,7 +1577,7 @@ void GraphicsLayerCA::recursiveCommitChanges(CommitState& commitState, const Tra
 
     if (nowRunningTransformAnimation) {
         childCommitState.ancestorHasTransformAnimation = true;
-        if (m_intersectsCoverageRect)
+        if (m_intersectsCoverageRect || !animationExtent())
             childCommitState.ancestorWithTransformAnimationIntersectsCoverageRect = true;
         affectedByTransformAnimation = true;
     }