- Revision
- 260118
- Author
- [email protected]
- Date
- 2020-04-14 23:20:39 -0700 (Tue, 14 Apr 2020)
Log Message
[Async overflow scroll] Backgrounds missing on gmail sometimes
https://bugs.webkit.org/show_bug.cgi?id=210506
<rdar://problem/60523869>
Reviewed by Zalan Bujtas.
Source/WebCore:
When painting the scrolled contents layers of accelerated overflow:scroll, RenderBlock::paint()
needs to not short-circuit when the dirty rect is outside a clipping rect, because accelerated
overflow involves overdraw for tiles outside the visible area.
There were two code paths that made this mostly work: overflowRectForPaintRejection() tested for
usesCompositedScrolling(), and the #if PLATFORM(IOS_FAMILY) made it work on iOS.
For content involving flexbox, overflowRectForPaintRejection() gave the wrong answer because
flex layout would sometimes clear m_overflow, even on an overflow:scroll element.
So remove overflowRectForPaintRejection(), and instead revert to the simple visualOverflowRect(),
but first check a bit that's passed down from compositing code that indicates that
we're painting the contents of composited scroll
Test: compositing/scrolling/async-overflow-scrolling/mac/overflow-in-flex-empty-tiles.html
* rendering/PaintPhase.h:
* rendering/RenderBlock.cpp:
(WebCore::RenderBlock::paint):
* rendering/RenderBox.cpp:
(WebCore::RenderBox::overflowRectForPaintRejection const): Deleted.
* rendering/RenderBox.h:
* rendering/RenderLayer.cpp:
(WebCore::RenderLayer::paintLayerContents):
(WebCore::RenderLayer::paintForegroundForFragments):
LayoutTests:
Test with a scroller inside a flexbox; programmatically scrolls the scroller to the bottom,
then mouseWheels up to reveal new tiles.
* TestExpectations:
* compositing/scrolling/async-overflow-scrolling/mac/overflow-in-flex-empty-tiles-expected.html: Added.
* compositing/scrolling/async-overflow-scrolling/mac/overflow-in-flex-empty-tiles.html: Added.
* platform/mac/TestExpectations: Test is macOS-only because it uses wheel events.
Modified Paths
Added Paths
Diff
Modified: trunk/LayoutTests/ChangeLog (260117 => 260118)
--- trunk/LayoutTests/ChangeLog 2020-04-15 05:30:59 UTC (rev 260117)
+++ trunk/LayoutTests/ChangeLog 2020-04-15 06:20:39 UTC (rev 260118)
@@ -1,3 +1,19 @@
+2020-04-14 Simon Fraser <[email protected]>
+
+ [Async overflow scroll] Backgrounds missing on gmail sometimes
+ https://bugs.webkit.org/show_bug.cgi?id=210506
+ <rdar://problem/60523869>
+
+ Reviewed by Zalan Bujtas.
+
+ Test with a scroller inside a flexbox; programmatically scrolls the scroller to the bottom,
+ then mouseWheels up to reveal new tiles.
+
+ * TestExpectations:
+ * compositing/scrolling/async-overflow-scrolling/mac/overflow-in-flex-empty-tiles-expected.html: Added.
+ * compositing/scrolling/async-overflow-scrolling/mac/overflow-in-flex-empty-tiles.html: Added.
+ * platform/mac/TestExpectations: Test is macOS-only because it uses wheel events.
+
2020-04-14 Lauro Moura <[email protected]>
[GTK] Garden media/media-source/media-source-seek-back flaky crashes
Modified: trunk/LayoutTests/TestExpectations (260117 => 260118)
--- trunk/LayoutTests/TestExpectations 2020-04-15 05:30:59 UTC (rev 260117)
+++ trunk/LayoutTests/TestExpectations 2020-04-15 06:20:39 UTC (rev 260118)
@@ -9,6 +9,7 @@
compositing/ios [ Skip ]
compositing/contents-format/ipad [ Skip ]
compositing/contents-format/iphone-7 [ Skip ]
+compositing/scrolling/async-overflow-scrolling/mac [ Skip ]
css3/touch-action [ Skip ]
accessibility/ios-simulator [ Skip ]
accessibility/gtk [ Skip ]
Added: trunk/LayoutTests/compositing/scrolling/async-overflow-scrolling/mac/overflow-in-flex-empty-tiles-expected.html (0 => 260118)
--- trunk/LayoutTests/compositing/scrolling/async-overflow-scrolling/mac/overflow-in-flex-empty-tiles-expected.html (rev 0)
+++ trunk/LayoutTests/compositing/scrolling/async-overflow-scrolling/mac/overflow-in-flex-empty-tiles-expected.html 2020-04-15 06:20:39 UTC (rev 260118)
@@ -0,0 +1,42 @@
+<!DOCTYPE html> <!-- webkit-test-runner [ internal:AsyncOverflowScrollingEnabled=true ] -->
+<html>
+<head>
+ <style>
+ .scroller {
+ overflow-y: scroll;
+ width: 500px;
+ height: 500px;
+ border: 1px solid black;
+ background-color: red;
+ }
+ .contents {
+ height: 3000px;
+ width: 100%;
+ background-color: green;
+ }
+ </style>
+ <script src=""
+ <script>
+ if (window.testRunner)
+ testRunner.waitUntilDone();
+
+ window.addEventListener('load', async () => {
+ let scroller = document.querySelector('.scroller');
+
+ await UIHelper.delayFor(0);
+ scroller.scrollTop = 3000;
+ await UIHelper.delayFor(0);
+
+ await UIHelper.mouseWheelScrollAt(200, 200, 0, 1, 0, 100);
+
+ if (window.testRunner)
+ testRunner.notifyDone();
+ }, false);
+ </script>
+</head>
+<body>
+ <div class="scroller">
+ <div class="contents"> </div>
+ </div>
+</body>
+</html>
Added: trunk/LayoutTests/compositing/scrolling/async-overflow-scrolling/mac/overflow-in-flex-empty-tiles.html (0 => 260118)
--- trunk/LayoutTests/compositing/scrolling/async-overflow-scrolling/mac/overflow-in-flex-empty-tiles.html (rev 0)
+++ trunk/LayoutTests/compositing/scrolling/async-overflow-scrolling/mac/overflow-in-flex-empty-tiles.html 2020-04-15 06:20:39 UTC (rev 260118)
@@ -0,0 +1,59 @@
+<!DOCTYPE html> <!-- webkit-test-runner [ internal:AsyncOverflowScrollingEnabled=true ] -->
+<html>
+<head>
+ <style>
+ .flex {
+ display: flex;
+ width: 500px;
+ border: 1px solid black;
+ }
+ .clipped {
+ overflow: hidden;
+ width: 100%;
+ }
+ .relative {
+ position: relative;
+ }
+ .scroller {
+ overflow-y: scroll;
+ width: 100%;
+ height: 500px;
+ background-color: red;
+ }
+ .contents {
+ height: 3000px;
+ width: 100%;
+ background-color: green;
+ }
+ </style>
+ <script src=""
+ <script>
+ if (window.testRunner)
+ testRunner.waitUntilDone();
+
+ window.addEventListener('load', async () => {
+ let scroller = document.querySelector('.scroller');
+
+ await UIHelper.delayFor(0);
+ scroller.scrollTop = 3000;
+ await UIHelper.delayFor(0);
+
+ await UIHelper.mouseWheelScrollAt(200, 200, 0, 1, 0, 100);
+
+ if (window.testRunner)
+ testRunner.notifyDone();
+ }, false);
+ </script>
+</head>
+<body>
+ <div class="flex">
+ <div class="clipped">
+ <div class="relative">
+ <div class="scroller">
+ <div class="contents"> </div>
+ </div>
+ </div>
+ </div>
+ </div>
+</body>
+</html>
Modified: trunk/LayoutTests/platform/ios-wk2/TestExpectations (260117 => 260118)
--- trunk/LayoutTests/platform/ios-wk2/TestExpectations 2020-04-15 05:30:59 UTC (rev 260117)
+++ trunk/LayoutTests/platform/ios-wk2/TestExpectations 2020-04-15 06:20:39 UTC (rev 260118)
@@ -9,6 +9,7 @@
compositing/ios [ Pass ]
compositing/shared-backing/overflow-scroll [ Pass ]
compositing/scrolling/async-overflow-scrolling [ Pass ]
+compositing/scrolling/async-overflow-scrolling/mac [ Skip ]
compositing/layer-creation/clipping-scope [ Pass ]
fast/device-orientation [ Pass ]
fast/history/ios [ Pass ]
Modified: trunk/LayoutTests/platform/mac/TestExpectations (260117 => 260118)
--- trunk/LayoutTests/platform/mac/TestExpectations 2020-04-15 05:30:59 UTC (rev 260117)
+++ trunk/LayoutTests/platform/mac/TestExpectations 2020-04-15 06:20:39 UTC (rev 260118)
@@ -7,12 +7,13 @@
#//////////////////////////////////////////////////////////////////////////////////////////
accessibility/mac [ Pass ]
+compositing/scrolling/async-overflow-scrolling/mac [ Pass ]
displaylists [ Pass ]
editing/mac [ Pass ]
+editing/pasteboard/mac [ Pass ]
+fast/dom/Range/mac [ Pass ]
fast/scrolling/latching [ Pass ]
media/mac [ Pass ]
-editing/pasteboard/mac [ Pass ]
-fast/dom/Range/mac [ Pass ]
fast/forms/search/search-padding-cancel-results-buttons.html [ Pass ]
fast/forms/search/search-results-hidden-crash.html [ Pass ]
Modified: trunk/Source/WebCore/ChangeLog (260117 => 260118)
--- trunk/Source/WebCore/ChangeLog 2020-04-15 05:30:59 UTC (rev 260117)
+++ trunk/Source/WebCore/ChangeLog 2020-04-15 06:20:39 UTC (rev 260118)
@@ -1,3 +1,37 @@
+2020-04-14 Simon Fraser <[email protected]>
+
+ [Async overflow scroll] Backgrounds missing on gmail sometimes
+ https://bugs.webkit.org/show_bug.cgi?id=210506
+ <rdar://problem/60523869>
+
+ Reviewed by Zalan Bujtas.
+
+ When painting the scrolled contents layers of accelerated overflow:scroll, RenderBlock::paint()
+ needs to not short-circuit when the dirty rect is outside a clipping rect, because accelerated
+ overflow involves overdraw for tiles outside the visible area.
+
+ There were two code paths that made this mostly work: overflowRectForPaintRejection() tested for
+ usesCompositedScrolling(), and the #if PLATFORM(IOS_FAMILY) made it work on iOS.
+
+ For content involving flexbox, overflowRectForPaintRejection() gave the wrong answer because
+ flex layout would sometimes clear m_overflow, even on an overflow:scroll element.
+
+ So remove overflowRectForPaintRejection(), and instead revert to the simple visualOverflowRect(),
+ but first check a bit that's passed down from compositing code that indicates that
+ we're painting the contents of composited scroll
+
+ Test: compositing/scrolling/async-overflow-scrolling/mac/overflow-in-flex-empty-tiles.html
+
+ * rendering/PaintPhase.h:
+ * rendering/RenderBlock.cpp:
+ (WebCore::RenderBlock::paint):
+ * rendering/RenderBox.cpp:
+ (WebCore::RenderBox::overflowRectForPaintRejection const): Deleted.
+ * rendering/RenderBox.h:
+ * rendering/RenderLayer.cpp:
+ (WebCore::RenderLayer::paintLayerContents):
+ (WebCore::RenderLayer::paintForegroundForFragments):
+
2020-04-14 Zalan Bujtas <[email protected]>
Content expanding is broken on icourse163.org
Modified: trunk/Source/WebCore/rendering/PaintPhase.h (260117 => 260118)
--- trunk/Source/WebCore/rendering/PaintPhase.h 2020-04-15 05:30:59 UTC (rev 260117)
+++ trunk/Source/WebCore/rendering/PaintPhase.h 2020-04-15 06:20:39 UTC (rev 260118)
@@ -54,20 +54,21 @@
};
enum class PaintBehavior : uint16_t {
- Normal = 0,
- SelectionOnly = 1 << 0,
- SkipSelectionHighlight = 1 << 1,
- ForceBlackText = 1 << 2,
- ForceWhiteText = 1 << 3,
- RenderingSVGMask = 1 << 4,
- SkipRootBackground = 1 << 5,
- RootBackgroundOnly = 1 << 6,
- SelectionAndBackgroundsOnly = 1 << 7,
- ExcludeSelection = 1 << 8,
- FlattenCompositingLayers = 1 << 9, // Paint doesn't stop at compositing layer boundaries.
- Snapshotting = 1 << 10,
- TileFirstPaint = 1 << 11,
- AnnotateLinks = 1 << 12, // Collect all renderers with links to annotate their URLs (e.g. PDFs)
+ Normal = 0,
+ SelectionOnly = 1 << 0,
+ SkipSelectionHighlight = 1 << 1,
+ ForceBlackText = 1 << 2,
+ ForceWhiteText = 1 << 3,
+ RenderingSVGMask = 1 << 4,
+ SkipRootBackground = 1 << 5,
+ RootBackgroundOnly = 1 << 6,
+ SelectionAndBackgroundsOnly = 1 << 7,
+ ExcludeSelection = 1 << 8,
+ FlattenCompositingLayers = 1 << 9, // Paint doesn't stop at compositing layer boundaries.
+ Snapshotting = 1 << 10,
+ TileFirstPaint = 1 << 11,
+ CompositedOverflowScrollContent = 1 << 12,
+ AnnotateLinks = 1 << 13, // Collect all renderers with links to annotate their URLs (e.g. PDFs)
};
} // namespace WebCore
Modified: trunk/Source/WebCore/rendering/RenderBlock.cpp (260117 => 260118)
--- trunk/Source/WebCore/rendering/RenderBlock.cpp 2020-04-15 05:30:59 UTC (rev 260117)
+++ trunk/Source/WebCore/rendering/RenderBlock.cpp 2020-04-15 06:20:39 UTC (rev 260118)
@@ -1092,16 +1092,11 @@
// Check if we need to do anything at all.
// FIXME: Could eliminate the isDocumentElementRenderer() check if we fix background painting so that the RenderView
// paints the root's background.
- if (!isDocumentElementRenderer()) {
- LayoutRect overflowBox = overflowRectForPaintRejection();
+ if (!isDocumentElementRenderer() && !paintInfo.paintBehavior.contains(PaintBehavior::CompositedOverflowScrollContent)) {
+ LayoutRect overflowBox = visualOverflowRect();
flipForWritingMode(overflowBox);
overflowBox.moveBy(adjustedPaintOffset);
- if (!overflowBox.intersects(paintInfo.rect)
-#if PLATFORM(IOS_FAMILY)
- // FIXME: This may be applicable to non-iOS ports.
- && (!hasLayer() || !layer()->isComposited())
-#endif
- )
+ if (!overflowBox.intersects(paintInfo.rect))
return;
}
Modified: trunk/Source/WebCore/rendering/RenderBox.cpp (260117 => 260118)
--- trunk/Source/WebCore/rendering/RenderBox.cpp 2020-04-15 05:30:59 UTC (rev 260117)
+++ trunk/Source/WebCore/rendering/RenderBox.cpp 2020-04-15 06:20:39 UTC (rev 260118)
@@ -4848,18 +4848,6 @@
return rect;
}
-LayoutRect RenderBox::overflowRectForPaintRejection() const
-{
- LayoutRect overflowRect = visualOverflowRect();
-
- if (!m_overflow || !usesCompositedScrolling())
- return overflowRect;
-
- overflowRect.unite(layoutOverflowRect());
- overflowRect.moveBy(-scrollPosition());
- return overflowRect;
-}
-
LayoutUnit RenderBox::offsetLeft() const
{
return adjustedPositionRelativeToOffsetParent(topLeftLocation()).x();
Modified: trunk/Source/WebCore/rendering/RenderBox.h (260117 => 260118)
--- trunk/Source/WebCore/rendering/RenderBox.h 2020-04-15 05:30:59 UTC (rev 260117)
+++ trunk/Source/WebCore/rendering/RenderBox.h 2020-04-15 06:20:39 UTC (rev 260118)
@@ -195,8 +195,6 @@
LayoutUnit logicalLeftVisualOverflow() const { return style().isHorizontalWritingMode() ? visualOverflowRect().x() : visualOverflowRect().y(); }
LayoutUnit logicalRightVisualOverflow() const { return style().isHorizontalWritingMode() ? visualOverflowRect().maxX() : visualOverflowRect().maxY(); }
- LayoutRect overflowRectForPaintRejection() const;
-
void addLayoutOverflow(const LayoutRect&);
void addVisualOverflow(const LayoutRect&);
void clearOverflow();
Modified: trunk/Source/WebCore/rendering/RenderLayer.cpp (260117 => 260118)
--- trunk/Source/WebCore/rendering/RenderLayer.cpp 2020-04-15 05:30:59 UTC (rev 260117)
+++ trunk/Source/WebCore/rendering/RenderLayer.cpp 2020-04-15 06:20:39 UTC (rev 260118)
@@ -4684,6 +4684,9 @@
if (paintingInfo.paintBehavior & PaintBehavior::ExcludeSelection)
paintBehavior.add(PaintBehavior::ExcludeSelection);
+ if (isPaintingScrollingContent && isPaintingOverflowContents)
+ paintBehavior.add(PaintBehavior::CompositedOverflowScrollContent);
+
LayoutRect paintDirtyRect = localPaintingInfo.paintDirtyRect;
if (shouldPaintContent || shouldPaintOutline || isPaintingOverlayScrollbars || isCollectingEventRegion) {
// Collect the fragments. This will compute the clip rectangles and paint offsets for each layer fragment, as well as whether or not the content of each
@@ -4761,6 +4764,9 @@
if (paintingInfo.paintBehavior & PaintBehavior::TileFirstPaint)
paintBehavior.add(PaintBehavior::TileFirstPaint);
+ if (isPaintingScrollingContent && isPaintingOverflowContents)
+ paintBehavior.add(PaintBehavior::CompositedOverflowScrollContent);
+
if (shouldPaintMask(paintingInfo.paintBehavior, localPaintFlags)) {
// Paint the mask for the fragments.
paintMaskForFragments(layerFragments, context, paintingInfo, paintBehavior, subtreePaintRootForRenderer);
@@ -5092,6 +5098,7 @@
else
localPaintBehavior = paintBehavior;
+ // FIXME: It's unclear if this flag copying is necessary.
if (localPaintingInfo.paintBehavior & PaintBehavior::ExcludeSelection)
localPaintBehavior.add(PaintBehavior::ExcludeSelection);
@@ -5101,6 +5108,9 @@
if (localPaintingInfo.paintBehavior & PaintBehavior::TileFirstPaint)
localPaintBehavior.add(PaintBehavior::TileFirstPaint);
+ if (localPaintingInfo.paintBehavior & PaintBehavior::CompositedOverflowScrollContent)
+ localPaintBehavior.add(PaintBehavior::CompositedOverflowScrollContent);
+
// Optimize clipping for the single fragment case.
bool shouldClip = localPaintingInfo.clipToDirtyRect && layerFragments.size() == 1 && layerFragments[0].shouldPaintContent && !layerFragments[0].foregroundRect.isEmpty();
ClipRect clippedRect;