REGRESSION (r245170): gmail.com header flickers when hovering over the animating buttons
https://bugs.webkit.org/show_bug.cgi?id=197975
<rdar://problem/50865946>

Reviewed by Antti Koivisto.

Source/WebCore:

When computeCompositingRequirements() determined that a layer could paint into shared backing, it
pushed an overlap container. If that layer then converted to normal composting, we'd push a second
overlap container, which left the overlap map in a bad state for the rest of the compositing
traversal, causing layers to not get composited when necessary.

Test: compositing/shared-backing/overlap-after-shared-to-composited.html

* rendering/RenderLayerCompositor.cpp:
(WebCore::RenderLayerCompositor::computeCompositingRequirements):

LayoutTests:

* compositing/shared-backing/overlap-after-shared-to-composited-expected.html: Added.
* compositing/shared-backing/overlap-after-shared-to-composited.html: Added.

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@245471 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog
index 26a7c71..ed2cbb4 100644
--- a/LayoutTests/ChangeLog
+++ b/LayoutTests/ChangeLog
@@ -1,3 +1,14 @@
+2019-05-17  Simon Fraser  <simon.fraser@apple.com>
+
+        REGRESSION (r245170): gmail.com header flickers when hovering over the animating buttons
+        https://bugs.webkit.org/show_bug.cgi?id=197975
+        <rdar://problem/50865946>
+
+        Reviewed by Antti Koivisto.
+
+        * compositing/shared-backing/overlap-after-shared-to-composited-expected.html: Added.
+        * compositing/shared-backing/overlap-after-shared-to-composited.html: Added.
+
 2019-05-16  Said Abou-Hallawa  <sabouhallawa@apple.com>
 
         SVGElement should detach itself from all its properties before it is deleted
diff --git a/LayoutTests/compositing/shared-backing/overlap-after-shared-to-composited-expected.html b/LayoutTests/compositing/shared-backing/overlap-after-shared-to-composited-expected.html
new file mode 100644
index 0000000..1415d4e
--- /dev/null
+++ b/LayoutTests/compositing/shared-backing/overlap-after-shared-to-composited-expected.html
@@ -0,0 +1,73 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <title>Tests that overlap testing continues to work after a layer converts from shared to composited</title>
+    <style>
+        .trigger {
+            position: absolute;
+            transform: translateZ(0);
+            background-color: silver;
+            width: 20px;
+            height: 400px;
+        }
+        
+        .provider {
+            position: absolute;
+            left: 20px;
+            top: 20px;
+            width: 400px;
+            height: 100px;
+            background-color: gray;
+        }
+
+        .box {
+            width: 100px;
+            height: 100px;
+            background-color: gray;
+        }
+        
+        .absolute {
+            position: absolute;
+            top: 200px;
+            left: 0px;
+            background-color: lightblue;
+        }
+        
+        .overlapper {
+            position: absolute;
+            top: 70px;
+            left: 150px;
+            width: 200px;
+            height: 100px;
+            padding: 10px;
+            background-color: green;
+        }
+        
+        .stacking {
+            position: relative;
+            z-index: 0;
+            padding: 10px;
+            height: 120px;
+            border: 1px solid black;
+            transform: translateZ(0);
+        }
+        
+        .negative {
+            position: relative;
+            z-index: -1;
+            background-color: orange;
+            transform: translateZ(0);
+        }
+    </style>
+</head>
+<body>
+    <div class="trigger"></div>
+    <div class="provider">
+        <div class="absolute box"></div>
+        <div class="stacking box">
+            <div class="negative box"></div>
+        </div>
+    </div>
+    <div class="overlapper"></div>
+</body>
+</html>
diff --git a/LayoutTests/compositing/shared-backing/overlap-after-shared-to-composited.html b/LayoutTests/compositing/shared-backing/overlap-after-shared-to-composited.html
new file mode 100644
index 0000000..8e99d63
--- /dev/null
+++ b/LayoutTests/compositing/shared-backing/overlap-after-shared-to-composited.html
@@ -0,0 +1,88 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <title>Tests that overlap testing continues to work after a layer converts from shared to composited</title>
+    <style>
+        .trigger {
+            position: absolute;
+            transform: translateZ(0);
+            background-color: silver;
+            width: 20px;
+            height: 400px;
+        }
+        
+        .provider {
+            position: absolute;
+            left: 20px;
+            top: 20px;
+            width: 400px;
+            height: 100px;
+            background-color: gray;
+        }
+
+        .box {
+            width: 100px;
+            height: 100px;
+            background-color: gray;
+        }
+        
+        .absolute {
+            position: absolute;
+            top: 200px;
+            left: 0px;
+            background-color: lightblue;
+        }
+        
+        .overlapper {
+            position: absolute;
+            top: 70px;
+            left: 150px;
+            width: 200px;
+            height: 100px;
+            padding: 10px;
+            background-color: green;
+        }
+        
+        .stacking {
+            position: relative;
+            z-index: 0;
+            padding: 10px;
+            height: 120px;
+            border: 1px solid black;
+        }
+        
+        .negative {
+            position: relative;
+            z-index: -1;
+            background-color: orange;
+        }
+        
+        .negative.changed {
+            transform: translateZ(0);
+        }
+        
+    </style>
+    <script>
+        if (window.testRunner)
+            testRunner.waitUntilDone();
+        
+        window.addEventListener('load', () => {
+            setTimeout(() => {
+                document.querySelector('.negative').classList.add('changed');
+                if (window.testRunner)
+                    testRunner.notifyDone();
+            }, 0);
+        }, false);
+    </script>
+</head>
+<body>
+    <div class="trigger"></div>
+    <div class="provider">
+        <div class="absolute box"></div>
+        <div class="stacking box">
+            <div class="negative box"></div>
+        </div>
+    </div>
+    <div class="overlapper"></div>
+</body>
+</html>
diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog
index 4234b17..e8c3abf 100644
--- a/Source/WebCore/ChangeLog
+++ b/Source/WebCore/ChangeLog
@@ -1,3 +1,21 @@
+2019-05-17  Simon Fraser  <simon.fraser@apple.com>
+
+        REGRESSION (r245170): gmail.com header flickers when hovering over the animating buttons
+        https://bugs.webkit.org/show_bug.cgi?id=197975
+        <rdar://problem/50865946>
+
+        Reviewed by Antti Koivisto.
+
+        When computeCompositingRequirements() determined that a layer could paint into shared backing, it
+        pushed an overlap container. If that layer then converted to normal composting, we'd push a second
+        overlap container, which left the overlap map in a bad state for the rest of the compositing
+        traversal, causing layers to not get composited when necessary.
+
+        Test: compositing/shared-backing/overlap-after-shared-to-composited.html
+
+        * rendering/RenderLayerCompositor.cpp:
+        (WebCore::RenderLayerCompositor::computeCompositingRequirements):
+
 2019-05-17  Commit Queue  <commit-queue@webkit.org>
 
         Unreviewed, rolling out r245401.
diff --git a/Source/WebCore/rendering/RenderLayerCompositor.cpp b/Source/WebCore/rendering/RenderLayerCompositor.cpp
index b5b8046..5897baa 100644
--- a/Source/WebCore/rendering/RenderLayerCompositor.cpp
+++ b/Source/WebCore/rendering/RenderLayerCompositor.cpp
@@ -910,8 +910,10 @@
         layer.setIndirectCompositingReason(compositingReason);
 
     // Check if the computed indirect reason will force the layer to become composited.
-    if (!willBeComposited && layer.mustCompositeForIndirectReasons() && canBeComposited(layer))
+    if (!willBeComposited && layer.mustCompositeForIndirectReasons() && canBeComposited(layer)) {
         willBeComposited = true;
+        layerPaintsIntoProvidedBacking = false;
+    }
 
     // The children of this layer don't need to composite, unless there is
     // a compositing layer among them, so start by inheriting the compositing
@@ -924,8 +926,11 @@
         currentState.testingOverlap = true;
         // This layer now acts as the ancestor for kids.
         currentState.compositingAncestor = &layer;
-        overlapMap.pushCompositingContainer();
-        LOG_WITH_STREAM(CompositingOverlap, stream << "layer " << &layer << " will composite, pushed container " << overlapMap);
+        
+        if (!layerPaintsIntoProvidedBacking) {
+            overlapMap.pushCompositingContainer();
+            LOG_WITH_STREAM(CompositingOverlap, stream << "layer " << &layer << " will composite, pushed container " << overlapMap);
+        }
 
         willBeComposited = true;
         layerPaintsIntoProvidedBacking = false;