Skip to content

Commit

Permalink
Cherry-pick 126e5bd39128. rdar://120666136
Browse files Browse the repository at this point in the history
    Cherry-pick 272394@main (5ce41d8). rdar://120666136

        Wikipedia video control icon backgrounds flicker.
        https://bugs.webkit.org/show_bug.cgi?id=266726
        <rdar://119868478>

        Reviewed by Simon Fraser.

        The previous code always required a full repaint of the layer whenever a buffer was allocated,
        so the copy-forward code didn't run on the second paint of a layer. This meant the copy-forward
        code, and the 'buffer is already clear' optimization were mutually exclusive.

        The new code uses copy-forward and partial repaints whenever possible, even if the front buffer
        was newly allocated (or existing, but purged).

        The copy-forward code tries to only copy pixels that won't be re-drawn this frame, but is rounded
        out to a single rectangle, not a complex region.

        If the copy-forwards ends up copying pixels that we'll also drawn this frame, we can no longer
        consider the buffer to be 'clear' and have to manually clear the paint region.

        * LayoutTests/compositing/repaint/copy-forward-clear-rect-expected.html: Added.
        * LayoutTests/compositing/repaint/copy-forward-clear-rect.html: Added.
        * Source/WebKit/GPUProcess/graphics/RemoteImageBufferSet.cpp:
        (WebKit::RemoteImageBufferSet::prepareBufferForDisplay):

        Canonical link: https://commits.webkit.org/272394@main

Canonical link: https://commits.webkit.org/271831.79@safari-7619.0.1-branch
  • Loading branch information
Dan Robson committed Jan 10, 2024
1 parent 809cefc commit 0abaf26
Show file tree
Hide file tree
Showing 3 changed files with 77 additions and 1 deletion.
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<!DOCTYPE html>

<html>
<head>
<style>
#first {
width: 500px;
height: 500px;
transform: translate3d(0, 0, 0);
background: rgba(222, 0, 0, 0.4);
}
#inner {
left: 50px;
top: 50px;
width: 50px;
height: 50px;
position: absolute;
background: rgba(0, 40, 40, 0.5);
}
</style>
</head>
<body>
<div id="first"><div id="inner"></div></div>
</body>
</html>
45 changes: 45 additions & 0 deletions LayoutTests/compositing/repaint/copy-forward-clear-rect.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
<!DOCTYPE html>

<html>
<head>
<script src="../../resources/ui-helper.js"></script>
<style>
#first {
width: 500px;
height: 500px;
transform: translate3d(0, 0, 0);
background: rgba(222, 0, 0, 0.4);
}
#inner {
width: 50px;
height: 50px;
position: absolute;
background: rgba(0, 40, 40, 0.5);
}
</style>
<script>
if (window.testRunner) {
testRunner.waitUntilDone();
if (testRunner.dontForceRepaint)
testRunner.dontForceRepaint();
}
async function doTest()
{
await UIHelper.renderingUpdate();

inner.style.left = "50px";
inner.style.top = "50px";

await UIHelper.renderingUpdate();
await UIHelper.renderingUpdate();

if (window.testRunner)
testRunner.notifyDone();
}
window.addEventListener('load', doTest, false);
</script>
</head>
<body>
<div id="first"><div id="inner"></div></div>
</body>
</html>
8 changes: 7 additions & 1 deletion Source/WebKit/GPUProcess/graphics/RemoteImageBufferSet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -188,10 +188,11 @@ void RemoteImageBufferSet::prepareBufferForDisplay(const WebCore::Region& dirtyR
GraphicsContext& context = m_frontBuffer->context();
context.resetClip();

IntRect copyRect;
if (m_previousFrontBuffer && m_frontBuffer != m_previousFrontBuffer && !dirtyRegion.contains(layerBounds)) {
Region copyRegion(m_previouslyPaintedRect ? *m_previouslyPaintedRect : layerBounds);
copyRegion.subtract(dirtyRegion);
IntRect copyRect = copyRegion.bounds();
copyRect = copyRegion.bounds();
if (!copyRect.isEmpty())
m_frontBuffer->context().drawImageBuffer(*m_previousFrontBuffer, copyRect, copyRect, { CompositeOperator::Copy });
}
Expand All @@ -212,6 +213,11 @@ void RemoteImageBufferSet::prepareBufferForDisplay(const WebCore::Region& dirtyR
scaledRect = enclosingIntRect(scaledRect);
scaledRect.scale(1 / m_resolutionScale);
paintingRects.append(scaledRect);

// If the copy-forward touched pixels that are about to be painted, then they
// won't be 'clear' any more.
if (copyRect.intersects(scaledRect))
m_frontBufferIsCleared = false;
}

if (paintingRects.size() == 1)
Expand Down

0 comments on commit 0abaf26

Please sign in to comment.