Repaint issues when the login field collapses on music.apple.com
authorzalan@apple.com <zalan@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 21 May 2020 01:44:12 +0000 (01:44 +0000)
committerzalan@apple.com <zalan@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 21 May 2020 01:44:12 +0000 (01:44 +0000)
https://bugs.webkit.org/show_bug.cgi?id=212101
<rdar://problem/62874369>

Reviewed by Simon Fraser.

Source/WebCore:

RenderWidgets (e.g iframe) are painted on integral pixel boundaries. When we issue the repaints on such renderers, we need to
make sure that the repaint rectangles are also snapped to integral pixel values.
Currently trunk only covers the case when the renderer itself is positioned on a subpixel position (e.g when the containing block's content box has a non-integral position value).
This patch ensures that we repaint the RenderWidgets properly when a non-direct ancestor puts the renderer on a subpixel position.

Test: fast/repaint/iframe-on-subpixel-position.html

* page/FrameView.h:
* rendering/RenderBox.cpp:
(WebCore::RenderBox::computeVisibleRectInContainer const):
* rendering/RenderLayerBacking.cpp:
(WebCore::RenderLayerBacking::setContentsNeedDisplay):
(WebCore::RenderLayerBacking::setContentsNeedDisplayInRect):
* rendering/RenderObject.h:
* testing/Internals.cpp:
(WebCore::Internals::enableSubframeRepaintTracking): add subframe repaint tracking
(WebCore::Internals::disableSubframeRepaintTracking):
* testing/Internals.h:
* testing/Internals.idl:

LayoutTests:

* fast/repaint/iframe-on-subpixel-position-expected.txt: Added.
* fast/repaint/iframe-on-subpixel-position.html: Added.

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

LayoutTests/ChangeLog
LayoutTests/fast/repaint/iframe-on-subpixel-position-expected.txt [new file with mode: 0644]
LayoutTests/fast/repaint/iframe-on-subpixel-position.html [new file with mode: 0644]
Source/WebCore/ChangeLog
Source/WebCore/rendering/RenderBox.cpp
Source/WebCore/rendering/RenderObject.h

index 2f2b66c..6e03748 100644 (file)
@@ -1,3 +1,14 @@
+2020-05-20  Zalan Bujtas  <zalan@apple.com>
+
+        Repaint issues when the login field collapses on music.apple.com
+        https://bugs.webkit.org/show_bug.cgi?id=212101
+        <rdar://problem/62874369>
+
+        Reviewed by Simon Fraser.
+
+        * fast/repaint/iframe-on-subpixel-position-expected.txt: Added.
+        * fast/repaint/iframe-on-subpixel-position.html: Added.
+
 2020-05-20  Kenneth Russell  <kbr@chromium.org>
 
         OES_texture_half_float_linear unavailable on WebGL 1.0 on iOS with ANGLE
diff --git a/LayoutTests/fast/repaint/iframe-on-subpixel-position-expected.txt b/LayoutTests/fast/repaint/iframe-on-subpixel-position-expected.txt
new file mode 100644 (file)
index 0000000..9feca6f
--- /dev/null
@@ -0,0 +1,23 @@
+
+(GraphicsLayer
+  (anchor 0.00 0.00)
+  (bounds 800.00 600.00)
+  (children 1
+    (GraphicsLayer
+      (bounds 800.00 600.00)
+      (contentsOpaque 1)
+      (children 1
+        (GraphicsLayer
+          (bounds 301.00 151.00)
+          (drawsContent 1)
+          (repaint rects
+            (rect 0.00 0.00 101.00 101.00)
+            (rect 0.00 0.00 301.00 101.00)
+            (rect 0.00 0.00 301.00 101.00)
+          )
+        )
+      )
+    )
+  )
+)
+
diff --git a/LayoutTests/fast/repaint/iframe-on-subpixel-position.html b/LayoutTests/fast/repaint/iframe-on-subpixel-position.html
new file mode 100644 (file)
index 0000000..0262f3e
--- /dev/null
@@ -0,0 +1,53 @@
+<script>
+function runRepaintTest() {
+
+if (window.testRunner)
+    testRunner.waitUntilDone();
+
+setTimeout(function() {
+    let shrink = document.getElementById("subpixel_iframe").contentDocument.getElementById("shrink");
+    if (!window.testRunner) {
+        setTimeout('shrink.style.height = "0px"', 100);
+        return;
+    }
+
+    testRunner.dumpAsText();
+    document.body.offsetTop;
+    internals.startTrackingRepaints();
+
+    shrink.style.height = "0px";
+    document.getElementById("subpixel_iframe").contentDocument.body.offsetHeight;
+
+    let layerTreeAsText = window.internals.layerTreeAsText(document, internals.LAYER_TREE_INCLUDES_REPAINT_RECTS);
+    internals.stopTrackingRepaints();
+
+    let pre = document.createElement('pre');
+    document.body.appendChild(pre);
+    pre.innerHTML = layerTreeAsText;
+    testRunner.notifyDone();
+}, 0);
+
+}
+</script>
+<style>
+.container {
+  position: fixed;
+  left: 0px;
+  top: 0px;
+  padding: 0.5px;
+}
+</style>
+<body>
+<div class=container><div><iframe onload="runRepaintTest()" id=subpixel_iframe frameborder=no srcdoc="
+<style>
+body {
+  margin:0px;
+}
+div {
+  background-color: green;
+  height: 100px;
+  width: 100px;
+}
+</style>
+<div id=shrink></div>">
+</body>
index bab9836..40b93e7 100644 (file)
@@ -1,3 +1,31 @@
+2020-05-20  Zalan Bujtas  <zalan@apple.com>
+
+        Repaint issues when the login field collapses on music.apple.com
+        https://bugs.webkit.org/show_bug.cgi?id=212101
+        <rdar://problem/62874369>
+
+        Reviewed by Simon Fraser.
+
+        RenderWidgets (e.g iframe) are painted on integral pixel boundaries. When we issue the repaints on such renderers, we need to
+        make sure that the repaint rectangles are also snapped to integral pixel values.
+        Currently trunk only covers the case when the renderer itself is positioned on a subpixel position (e.g when the containing block's content box has a non-integral position value).
+        This patch ensures that we repaint the RenderWidgets properly when a non-direct ancestor puts the renderer on a subpixel position.
+
+        Test: fast/repaint/iframe-on-subpixel-position.html
+
+        * page/FrameView.h:
+        * rendering/RenderBox.cpp:
+        (WebCore::RenderBox::computeVisibleRectInContainer const):
+        * rendering/RenderLayerBacking.cpp:
+        (WebCore::RenderLayerBacking::setContentsNeedDisplay):
+        (WebCore::RenderLayerBacking::setContentsNeedDisplayInRect):
+        * rendering/RenderObject.h:
+        * testing/Internals.cpp:
+        (WebCore::Internals::enableSubframeRepaintTracking): add subframe repaint tracking 
+        (WebCore::Internals::disableSubframeRepaintTracking):
+        * testing/Internals.h:
+        * testing/Internals.idl:
+
 2020-05-20  Oriol Brufau  <obrufau@igalia.com>
 
         Computed min-width/height for auto depends on box
index 7a10117..8cd92c0 100644 (file)
@@ -2277,6 +2277,8 @@ Optional<LayoutRect> RenderBox::computeVisibleRectInContainer(const LayoutRect&
     if (container == this) {
         if (container->style().isFlippedBlocksWritingMode())
             flipForWritingMode(adjustedRect);
+        if (context.descendantNeedsEnclosingIntRect)
+            adjustedRect = enclosingIntRect(adjustedRect);
         return adjustedRect;
     }
 
@@ -2313,6 +2315,7 @@ Optional<LayoutRect> RenderBox::computeVisibleRectInContainer(const LayoutRect&
         LayoutSize flooredLocationOffset = toIntSize(flooredIntPoint(locationOffset));
         adjustedRect.expand(locationOffset - flooredLocationOffset);
         locationOffset = flooredLocationOffset;
+        context.descendantNeedsEnclosingIntRect = true;
     }
 
     if (is<RenderMultiColumnFlow>(this)) {
index b3ecbb8..228fa60 100644 (file)
@@ -624,8 +624,9 @@ public:
             , options(options)
             {
             }
-        bool hasPositionFixedDescendant;
-        bool dirtyRectIsFlipped;
+        bool hasPositionFixedDescendant { false };
+        bool dirtyRectIsFlipped { false };
+        bool descendantNeedsEnclosingIntRect { false };
         OptionSet<VisibleRectContextOption> options;
     };
     virtual Optional<LayoutRect> computeVisibleRectInContainer(const LayoutRect&, const RenderLayerModelObject* repaintContainer, VisibleRectContext) const;