Bug 1414033 - Recursively invalidate any cached ContainerLayer surfaces for new attached Layers, since they might have been moved and we don't track invalid areas within them. r=mstange
☠☠ backed out by b035b8bb0f64 ☠ ☠
authorMatt Woodrow <mwoodrow@mozilla.com>
Thu, 02 May 2019 01:14:46 +0000
changeset 472226 10a025aed3d426ac976d8dbd98cffc15a33cfb5f
parent 472225 f446fb2da3fb1b6e30f6de6b0f6ed1b5cfcda071
child 472227 b49cd2b191aef78a47b2eda16d9a6f023c5778b8
push id84529
push usermwoodrow@mozilla.com
push dateThu, 02 May 2019 01:16:16 +0000
treeherderautoland@10a025aed3d4 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmstange
bugs1414033
milestone68.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1414033 - Recursively invalidate any cached ContainerLayer surfaces for new attached Layers, since they might have been moved and we don't track invalid areas within them. r=mstange Differential Revision: https://phabricator.services.mozilla.com/D29452
gfx/layers/LayerTreeInvalidation.cpp
layout/reftests/layers/opacity-keep-intermediate-surface-too-long-ref.html
layout/reftests/layers/opacity-keep-intermediate-surface-too-long.html
layout/reftests/layers/reftest.list
--- a/gfx/layers/LayerTreeInvalidation.cpp
+++ b/gfx/layers/LayerTreeInvalidation.cpp
@@ -135,16 +135,27 @@ static void NotifySubdocumentInvalidatio
         if (container) {
           nsIntRegion region =
               container->GetLocalVisibleRegion().ToUnknownRegion();
           aCallback(container, &region);
         }
       });
 }
 
+static void SetChildrenChangedRecursive(Layer* aLayer) {
+  ForEachNode<ForwardIterator>(
+      aLayer,
+      [](Layer* layer) {
+        ContainerLayer* container = layer->AsContainerLayer();
+        if (container) {
+          container->SetChildrenChanged(true);
+        }
+      });
+}
+
 struct LayerPropertiesBase : public LayerProperties {
   explicit LayerPropertiesBase(Layer* aLayer)
       : mLayer(aLayer),
         mMaskLayer(nullptr),
         mVisibleRegion(mLayer->GetLocalVisibleRegion().ToUnknownRegion()),
         mPostXScale(aLayer->GetPostXScale()),
         mPostYScale(aLayer->GetPostYScale()),
         mOpacity(aLayer->GetLocalOpacity()),
@@ -442,20 +453,24 @@ struct ContainerLayerProperties : public
             // We've already seen this child in mChildren (which means it must
             // have been reordered) and invalidated its old area. We need to
             // invalidate its new area too:
             invalidateChildsCurrentArea = true;
           }
         } else {
           // |child| is new
           invalidateChildsCurrentArea = true;
+          SetChildrenChangedRecursive(child);
         }
       } else {
         // |child| is new, or was reordered to a higher index
         invalidateChildsCurrentArea = true;
+        if (!oldIndexMap.Contains(child)) {
+          SetChildrenChangedRecursive(child);
+        }
       }
       if (invalidateChildsCurrentArea) {
         LTI_DUMP(child->GetLocalVisibleRegion().ToUnknownRegion(),
                  "invalidateChildsCurrentArea");
         AddTransformedRegion(result,
                              child->GetLocalVisibleRegion().ToUnknownRegion(),
                              GetTransformForInvalidation(child));
         if (aCallback) {
new file mode 100644
--- /dev/null
+++ b/layout/reftests/layers/opacity-keep-intermediate-surface-too-long-ref.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<html lang="en"><head>
+<meta http-equiv="content-type" content="text/html; charset=UTF-8"><meta charset="utf-8">
+<title>Clicking the canvas should turn it green (and shift it slighly)</title>
+
+<style>
+
+canvas {
+  border: 10px solid black;
+}
+
+.opacity {
+  opacity: 0.8;
+}
+
+</style>
+
+</head><body><div style="transform: translateX(1px)">
+  <div class="wrapper" style="transform: translateX(1px);">
+    <div class="opacity">
+      <div class="border">
+        <canvas id="canvas" width="200" height="200"></canvas>
+      </div>
+    </div>
+  </div>
+</div>
+
+<script>
+
+var canvas = document.getElementById('canvas');
+canvas.width = 200;
+canvas.height = 200;
+var ctx = canvas.getContext('2d');
+ctx.fillStyle = 'lime';
+ctx.fillRect(0, 0, 200, 200);
+</script>
+</body></html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/layers/opacity-keep-intermediate-surface-too-long.html
@@ -0,0 +1,47 @@
+<!DOCTYPE html>
+<html lang="en" class="reftest-wait"><head>
+<meta http-equiv="content-type" content="text/html; charset=UTF-8"><meta charset="utf-8">
+<title>Clicking the canvas should turn it green (and shift it slighly)</title>
+
+<style>
+
+canvas {
+  border: 10px solid black;
+}
+
+.opacity {
+  opacity: 0.8;
+}
+
+</style>
+
+</head><body><div style="transform: translateX(1px)"><!-- create reference frame -->
+  <div class="wrapper"><!-- this starts out without a transform but later gets transformed -->
+    <div class="opacity"><!-- this creates a ContainerLayer with an intermediate surface for group opacity -->
+      <div class="border"><!-- this adds another visual element into the group opacity -->
+        <canvas id="canvas" width="200" height="200"></canvas><!-- this causes all ancestor effects to become active ContainerLayers -->
+      </div>
+    </div>
+  </div>
+</div>
+
+<script>
+
+var canvas = document.getElementById('canvas');
+var wrapper = document.querySelector('.wrapper');
+canvas.width = 200;
+canvas.height = 200;
+var ctx = canvas.getContext('2d');
+ctx.fillStyle = 'red';
+ctx.fillRect(0, 0, 200, 200);
+
+function doTest() {
+  ctx.fillStyle = 'lime';
+  ctx.fillRect(0, 0, 200, 200);
+  wrapper.style.transform = 'translateX(1px)';
+  document.documentElement.removeAttribute("class");
+}
+document.addEventListener("MozReftestInvalidate", doTest);
+
+</script>
+</body></html>
--- a/layout/reftests/layers/reftest.list
+++ b/layout/reftests/layers/reftest.list
@@ -35,8 +35,10 @@ skip-if(!asyncPan) == fixed-pos-scrolled
 #   Direct2D 1.1 works (as a proxy for Windows 7 SP1 + Platform Update or higher), OR
 #   The GPU process has been forced on.
 # If these conditions are met, but the GPU process is not on, these tests will turn on
 # and compare false.
 skip-if(!browserIsRemote||!d2d||gpuProcess) == data:text/plain,FAIL about:blank
 skip-if(!gpuProcessForceEnabled||gpuProcess) == data:text/plain,FAIL about:blank
 
 fuzzy-if(webrender,0-1,0-8033) == opacity-background-1.html opacity-background-1-ref.html
+
+== opacity-keep-intermediate-surface-too-long.html opacity-keep-intermediate-surface-too-long-ref.html