Bug 1539846. Ensure building rect changes cause invalidations. r=mstange a=pascalc
authorJeff Muizelaar <jmuizelaar@mozilla.com>
Fri, 03 May 2019 20:46:07 +0000
changeset 526534 f293cecba8fd77bcf3395b6e66449f48851b66fa
parent 526533 4649dbd1d133e1900e3232724aec002ce3dd2655
child 526535 d7e6f0c8a9db25034d5c2766b04be20e47cf4fe1
push id2032
push userffxbld-merge
push dateMon, 13 May 2019 09:36:57 +0000
treeherdermozilla-release@455c1065dcbe [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmstange, pascalc
bugs1539846
milestone67.0
Bug 1539846. Ensure building rect changes cause invalidations. r=mstange a=pascalc Typically this would be handled by the visible region of the layer changing. However, since we build the container layer for the filter item directly the visible region doesn't get set or checked. As a shortcut to using more of FLB we just ensure the building rect hasn't changed. The situations under which this bugs shows up are somewhat rare: - The filtered item needs to be in transform so that it's bounds are not changed by scrolling. - The filtered item needs to contain items that change their drawing depending on the building rect. In this case an image with downscale on decode. - The filter needs to be unsupported by WebRender. Differential Revision: https://phabricator.services.mozilla.com/D29879
gfx/layers/wr/WebRenderCommandBuilder.cpp
gfx/layers/wr/WebRenderUserData.h
layout/reftests/invalidation/jetstream-scroll-ref.html
layout/reftests/invalidation/jetstream-scroll.html
layout/reftests/invalidation/reftest.list
--- a/gfx/layers/wr/WebRenderCommandBuilder.cpp
+++ b/gfx/layers/wr/WebRenderCommandBuilder.cpp
@@ -2161,16 +2161,23 @@ WebRenderCommandBuilder::GenerateFallbac
           recorder, dummyDt, dtSize.ToUnknownSize());
       if (!fallbackData->mBasicLayerManager) {
         fallbackData->mBasicLayerManager =
             new BasicLayerManager(BasicLayerManager::BLM_INACTIVE);
       }
       bool isInvalidated = PaintItemByDrawTarget(
           aItem, dt, offset, aDisplayListBuilder,
           fallbackData->mBasicLayerManager, scale, highlight);
+      if (!isInvalidated) {
+        if (!aItem->GetBuildingRect().IsEqualInterior(fallbackData->mBuildingRect)) {
+          // The building rect has changed but we didn't see any invalidations.
+          // We should still consider this an invalidation.
+          isInvalidated = true;
+        }
+      }
       recorder->FlushItem(IntRect({0, 0}, dtSize.ToUnknownSize()));
       TakeExternalSurfaces(recorder, fallbackData->mExternalSurfaces,
                            mManager->GetRenderRootStateManager(), aResources);
       recorder->Finish();
 
       if (!validFonts) {
         gfxCriticalNote << "Failed serializing fonts for blob image";
         return nullptr;
@@ -2250,16 +2257,17 @@ WebRenderCommandBuilder::GenerateFallbac
     }
 
     fallbackData->mScale = scale;
     fallbackData->SetInvalid(false);
   }
 
   // Update current bounds to fallback data
   fallbackData->mBounds = paintBounds;
+  fallbackData->mBuildingRect = aItem->GetBuildingRect();
 
   MOZ_ASSERT(fallbackData->GetImageKey());
 
   return fallbackData.forget();
 }
 
 class WebRenderMaskData : public WebRenderUserData {
  public:
--- a/gfx/layers/wr/WebRenderUserData.h
+++ b/gfx/layers/wr/WebRenderUserData.h
@@ -196,16 +196,17 @@ class WebRenderFallbackData : public Web
   /// Create a WebRenderImageData to manage the image we are about to render
   /// into.
   WebRenderImageData* PaintIntoImage();
 
   std::vector<RefPtr<gfx::SourceSurface>> mExternalSurfaces;
   RefPtr<BasicLayerManager> mBasicLayerManager;
   nsAutoPtr<nsDisplayItemGeometry> mGeometry;
   nsRect mBounds;
+  nsRect mBuildingRect;
   gfx::Size mScale;
 
  protected:
   void ClearImageKey();
 
   std::vector<RefPtr<gfx::ScaledFont>> mFonts;
   Maybe<wr::BlobImageKey> mBlobKey;
   // When rendering into a blob image, mImageData is null. It is non-null only
new file mode 100644
--- /dev/null
+++ b/layout/reftests/invalidation/jetstream-scroll-ref.html
@@ -0,0 +1,70 @@
+<!DOCTYPE html>
+<html class="reftest-wait" reftest-async-scroll><head>
+<meta http-equiv="content-type" content="text/html; charset=UTF-8"><meta charset="utf-8">
+<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=yes, viewport-fit=cover">
+<style>
+    figure {
+        position: relative;
+        width: 100vw;
+        left: 50%;
+        transform: translate(-50%);
+    }
+
+    figure img {
+        filter: url(#invertLightness)
+    }
+
+    main { scrollbar-width: none; width: 400px; height: 500px; overflow: auto; border: 1px solid black; }
+</style>
+
+</head>
+
+<body>
+
+    <svg xmlns="http://www.w3.org/2000/svg"> <style>svg{display:block;width:0;height:0}</style>
+        <filter id="invertLightness" x="0" y="0" style="color-interpolation-filters:sRGB">
+            <feColorMatrix type="matrix" in="SourceGraphic" result="red" values="1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 1">
+            </feColorMatrix>
+            <feColorMatrix type="matrix" in="SourceGraphic" result="green" values="0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 1">
+            </feColorMatrix>
+            <feColorMatrix type="matrix" in="SourceGraphic" result="blue" values="0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 1">
+            </feColorMatrix>
+            <feBlend in="red" in2="green" mode="lighten" result="maxyellow"></feBlend>
+            <feBlend in="maxyellow" in2="blue" mode="lighten" result="max"></feBlend>
+            <feBlend in="red" in2="green" mode="darken" result="minyellow"></feBlend>
+            <feBlend in="minyellow" in2="blue" mode="darken" result="min"></feBlend>
+            <feComponentTransfer result="adjustment" in="min">
+                <feFuncR type="linear" intercept="1" slope="-1"></feFuncR>
+                <feFuncG type="linear" intercept="1" slope="-1"></feFuncG>
+                <feFuncB type="linear" intercept="1" slope="-1"></feFuncB>
+            </feComponentTransfer>
+            <feComposite operator="arithmetic" in="SourceGraphic" in2="adjustment" k1="0" k2="1" k3="1" k4="-1" result="channelAdjustment"></feComposite>
+            <feComposite operator="arithmetic" in="channelAdjustment" in2="max" k1="0" k2="1" k3="-1" k4="1" result="finalColors">
+            </feComposite>
+            <feComposite operator="in" in="finalColors" in2="SourceAlpha"></feComposite>
+        </filter>
+    </svg>
+    <main id="content"
+          reftest-displayport-x="0"
+          reftest-displayport-y="0"
+          reftest-displayport-w="400"
+          reftest-displayport-h="500">
+    <div>
+      <article>
+        <div>
+          <div style="height: 1000px"></div>
+          <figure>
+            <img id=telement src="data:image/webp;base64,UklGRugAAABXRUJQVlA4TNsAAAAvOEuOAQfQxhK3sf8BBW3bMOUPvzuO6H+G//znP//5z3/+85///Oc///nPf/7zn//85z//+c9//vOf//znP//5z3/+85///Oc///nPf/7zn//85z//+c9//vOf//znP//5z3/+85///Oc///nPf/7zn//85z//+c9//vOf//znP//5z3/+85///Oc///nPf/7zn//85z//+c9//vOf//znP//5z3/+85///Oc///nPf/7zn//85z//+c9//vOf//znP//5z3/+85///Oc///nPf/7zn//85z//qwEA" alt="JetStream 2 Scores. Bigger is Better.">
+          </figure>
+        </div>
+      </article>
+    </div>
+    </main>
+</body>
+<script>
+
+    document.getElementById("content").scrollTop = 1100;
+    document.documentElement.removeAttribute("class");
+</script>
+
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/invalidation/jetstream-scroll.html
@@ -0,0 +1,73 @@
+<!DOCTYPE html>
+<html class="reftest-wait" reftest-async-scroll><head>
+<meta http-equiv="content-type" content="text/html; charset=UTF-8"><meta charset="utf-8">
+<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=yes, viewport-fit=cover">
+<style>
+    figure {
+        position: relative;
+        width: 100vw;
+        left: 50%;
+        transform: translate(-50%);
+    }
+
+    figure img {
+        filter: url(#invertLightness)
+    }
+
+    main { scrollbar-width: none; width: 400px; height: 500px; overflow: auto; border: 1px solid black; }
+</style>
+
+</head>
+
+<body>
+
+    <svg xmlns="http://www.w3.org/2000/svg"> <style>svg{display:block;width:0;height:0}</style>
+        <filter id="invertLightness" x="0" y="0" style="color-interpolation-filters:sRGB">
+            <feColorMatrix type="matrix" in="SourceGraphic" result="red" values="1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 1">
+            </feColorMatrix>
+            <feColorMatrix type="matrix" in="SourceGraphic" result="green" values="0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 1">
+            </feColorMatrix>
+            <feColorMatrix type="matrix" in="SourceGraphic" result="blue" values="0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 1">
+            </feColorMatrix>
+            <feBlend in="red" in2="green" mode="lighten" result="maxyellow"></feBlend>
+            <feBlend in="maxyellow" in2="blue" mode="lighten" result="max"></feBlend>
+            <feBlend in="red" in2="green" mode="darken" result="minyellow"></feBlend>
+            <feBlend in="minyellow" in2="blue" mode="darken" result="min"></feBlend>
+            <feComponentTransfer result="adjustment" in="min">
+                <feFuncR type="linear" intercept="1" slope="-1"></feFuncR>
+                <feFuncG type="linear" intercept="1" slope="-1"></feFuncG>
+                <feFuncB type="linear" intercept="1" slope="-1"></feFuncB>
+            </feComponentTransfer>
+            <feComposite operator="arithmetic" in="SourceGraphic" in2="adjustment" k1="0" k2="1" k3="1" k4="-1" result="channelAdjustment"></feComposite>
+            <feComposite operator="arithmetic" in="channelAdjustment" in2="max" k1="0" k2="1" k3="-1" k4="1" result="finalColors">
+            </feComposite>
+            <feComposite operator="in" in="finalColors" in2="SourceAlpha"></feComposite>
+        </filter>
+    </svg>
+    <main id="content"
+          reftest-displayport-x="0"
+          reftest-displayport-y="0"
+          reftest-displayport-w="400"
+          reftest-displayport-h="500">
+    <div>
+      <article>
+        <div>
+          <div style="height: 1000px"></div>
+          <figure>
+            <img id=telement src="data:image/webp;base64,UklGRugAAABXRUJQVlA4TNsAAAAvOEuOAQfQxhK3sf8BBW3bMOUPvzuO6H+G//znP//5z3/+85///Oc///nPf/7zn//85z//+c9//vOf//znP//5z3/+85///Oc///nPf/7zn//85z//+c9//vOf//znP//5z3/+85///Oc///nPf/7zn//85z//+c9//vOf//znP//5z3/+85///Oc///nPf/7zn//85z//+c9//vOf//znP//5z3/+85///Oc///nPf/7zn//85z//+c9//vOf//znP//5z3/+85///Oc///nPf/7zn//85z//qwEA" alt="JetStream 2 Scores. Bigger is Better.">
+          </figure>
+        </div>
+      </article>
+    </div>
+    </main>
+</body>
+<script>
+
+  document.getElementById("content").scrollTop = 800;
+  document.addEventListener("MozReftestInvalidate", function() {
+    document.getElementById("content").scrollTop = 1100;
+    document.documentElement.removeAttribute("class");
+  });
+</script>
+
+</html>
--- a/layout/reftests/invalidation/reftest.list
+++ b/layout/reftests/invalidation/reftest.list
@@ -98,8 +98,9 @@ pref(layers.single-tile.enabled,false) !
 
 != fractional-transform-1.html about:blank
 skip-if(/^Windows\x20NT\x2010\.0/.test(http.oscpu)) != fractional-transform-2.html about:blank
 != fractional-transform-3.html about:blank
 
 == partially-scrolled-svg-group.html partially-scrolled-svg-group-ref.html
 
 == paintedlayer-recycling-8.html paintedlayer-recycling-8-ref.html
+pref(image.downscale-during-decode.enabled,true) == jetstream-scroll.html jetstream-scroll-ref.html