Branch: refs/heads/main
Home: https://github.com/WebKit/WebKit
Commit: ea01c03eb4ed9183cc36b479fc29ed3ec1bce18f
https://github.com/WebKit/WebKit/commit/ea01c03eb4ed9183cc36b479fc29ed3ec1bce18f
Author: Nikolas Zimmermann <[email protected]>
Date: 2026-07-16 (Thu, 16 Jul 2026)
Changed paths:
A LayoutTests/platform/glib/damage/layer-addition-expected.txt
A LayoutTests/platform/glib/damage/layer-addition.html
A
LayoutTests/platform/glib/damage/layer-backdrop-filter-above-backdrop-expected.txt
A LayoutTests/platform/glib/damage/layer-backdrop-filter-above-backdrop.html
A
LayoutTests/platform/glib/damage/layer-backdrop-filter-damage-underneath-expected.txt
A
LayoutTests/platform/glib/damage/layer-backdrop-filter-damage-underneath.html
A
LayoutTests/platform/glib/damage/layer-backdrop-filter-layer-moves-away-expected.txt
A
LayoutTests/platform/glib/damage/layer-backdrop-filter-layer-moves-away.html
A
LayoutTests/platform/glib/damage/layer-backdrop-filter-unrelated-change-expected.txt
A
LayoutTests/platform/glib/damage/layer-backdrop-filter-unrelated-change.html
A
LayoutTests/platform/glib/damage/layer-clip-to-bounds-child-fully-outside-expected.txt
A
LayoutTests/platform/glib/damage/layer-clip-to-bounds-child-fully-outside.html
A LayoutTests/platform/glib/damage/layer-clip-to-bounds-expected.txt
A LayoutTests/platform/glib/damage/layer-clip-to-bounds.html
A LayoutTests/platform/glib/damage/layer-filter-removal-expected.txt
A LayoutTests/platform/glib/damage/layer-filter-removal.html
A LayoutTests/platform/glib/damage/layer-mask-change-expected.txt
A LayoutTests/platform/glib/damage/layer-mask-change.html
A LayoutTests/platform/glib/damage/layer-mask-on-moving-layer-expected.txt
A LayoutTests/platform/glib/damage/layer-mask-on-moving-layer.html
A LayoutTests/platform/glib/damage/layer-mask-removal-expected.txt
A LayoutTests/platform/glib/damage/layer-mask-removal.html
A
LayoutTests/platform/glib/damage/layer-mask-with-overflowing-child-expected.txt
A LayoutTests/platform/glib/damage/layer-mask-with-overflowing-child.html
A LayoutTests/platform/glib/damage/layer-multiple-movement-expected.txt
A LayoutTests/platform/glib/damage/layer-multiple-movement.html
A LayoutTests/platform/glib/damage/layer-nested-clip-expected.txt
A LayoutTests/platform/glib/damage/layer-nested-clip.html
A LayoutTests/platform/glib/damage/layer-recomposition-expected.txt
A LayoutTests/platform/glib/damage/layer-recomposition.html
A LayoutTests/platform/glib/damage/layer-removal-expected.txt
A LayoutTests/platform/glib/damage/layer-removal.html
A LayoutTests/platform/glib/damage/layer-replica-color-change-expected.txt
A LayoutTests/platform/glib/damage/layer-replica-color-change.html
A LayoutTests/platform/glib/damage/layer-replica-movement-expected.txt
A LayoutTests/platform/glib/damage/layer-replica-movement.html
A LayoutTests/platform/glib/damage/layer-replica-removal-expected.txt
A LayoutTests/platform/glib/damage/layer-replica-removal.html
A LayoutTests/platform/glib/damage/layer-replica-with-mask-expected.txt
A LayoutTests/platform/glib/damage/layer-replica-with-mask.html
A LayoutTests/platform/glib/damage/layer-size-to-empty-expected.txt
A LayoutTests/platform/glib/damage/layer-size-to-empty.html
A LayoutTests/platform/glib/damage/layer-subtree-hidden-expected.txt
A LayoutTests/platform/glib/damage/layer-subtree-hidden.html
A LayoutTests/platform/glib/damage/layer-transform-with-replica-expected.txt
A LayoutTests/platform/glib/damage/layer-transform-with-replica.html
M Source/WebCore/platform/graphics/skia/SkiaCompositingLayer.cpp
M Source/WebCore/platform/graphics/skia/SkiaCompositingLayer.h
M
Source/WebCore/platform/graphics/texmap/coordinated/CoordinatedPlatformLayer.cpp
M Tools/TestWebKitAPI/PlatformGTK.cmake
M Tools/TestWebKitAPI/PlatformWPE.cmake
A Tools/TestWebKitAPI/Tests/WebCore/glib/SkiaCompositingLayerDamage.cpp
Log Message:
-----------
[Damage][Skia] Make the collected frame damage cover every pixel the frame
changes
https://bugs.webkit.org/show_bug.cgi?id=319568
Reviewed by Alejandro G. Castro.
The damage-collecting walk is meant to end up with every pixel that changes
from one frame to the
next. It missed a good few of them, which wasn't noticed so far, because we had
damage-restriction
in the composition turned off by default. Since we want to change that we have
to ensure the damage
collection algorithm doesn't miss a single case - otherwise we'll end up with
rendering artifacts.
Each layer used to keep the rect it had painted, and handed that rect to a
Damage shared by the
whole tree the moment it changed: when it was resized, when its transform
changed, ..., when it was
detached, which walked the subtree and handed over every rect in it. That only
works if the layer is
still around to hand anything over. A hidden layer never did, and a destroyed
one took its rect with
it, so whatever it had painted was left on screen.
The root layer now keeps those rects instead, one per layer, under an id the
layer is given the first
time it paints, and nothing is handed over anymore. Every layer the walk
reaches writes down where it
is painting, and once the walk is done the root looks at what it got. A layer
whose rect changed has
moved, so both the old place and the new one are repainted. A layer the walk
never reached is
hidden, detached or destroyed, so the place it used to paint is repainted and
its rect is dropped.
The root asks every frame rather than waiting to be told, so a layer no longer
has to be alive, or
to notice anything, for the place it left behind to be repainted.
Some damage is not accessible via a simple tree walk: A mask is not part of the
tree walk, so a
changed mask is picked up where the mask is applied, and it damages the whole
masked subtree, since
the mask applies to descendants that need not paint within the layer's bounds.
A backdrop filter paints
nothing of its own, and changes as a whole whenever anything under it does,
including the place a
layer moved away from, which is only known once the walk has finished. A
contents rect may reach
outside the layer bounds, and a filter such as a blur paints outside them too,
so what the layer
really paints is damaged rather than its bounds...
Covered by new glib-specific damage tests and specific API tests, where
constructing a layout test
was hard.
* LayoutTests/platform/glib/damage/layer-addition-expected.txt: Added.
* LayoutTests/platform/glib/damage/layer-addition.html: Added.
*
LayoutTests/platform/glib/damage/layer-backdrop-filter-above-backdrop-expected.txt:
Added.
* LayoutTests/platform/glib/damage/layer-backdrop-filter-above-backdrop.html:
Added.
*
LayoutTests/platform/glib/damage/layer-backdrop-filter-damage-underneath-expected.txt:
Added.
*
LayoutTests/platform/glib/damage/layer-backdrop-filter-damage-underneath.html:
Added.
*
LayoutTests/platform/glib/damage/layer-backdrop-filter-layer-moves-away-expected.txt:
Added.
* LayoutTests/platform/glib/damage/layer-backdrop-filter-layer-moves-away.html:
Added.
*
LayoutTests/platform/glib/damage/layer-backdrop-filter-unrelated-change-expected.txt:
Added.
* LayoutTests/platform/glib/damage/layer-backdrop-filter-unrelated-change.html:
Added.
*
LayoutTests/platform/glib/damage/layer-clip-to-bounds-child-fully-outside-expected.txt:
Added.
*
LayoutTests/platform/glib/damage/layer-clip-to-bounds-child-fully-outside.html:
Added.
* LayoutTests/platform/glib/damage/layer-clip-to-bounds-expected.txt: Added.
* LayoutTests/platform/glib/damage/layer-clip-to-bounds.html: Added.
* LayoutTests/platform/glib/damage/layer-filter-removal-expected.txt: Added.
* LayoutTests/platform/glib/damage/layer-filter-removal.html: Added.
* LayoutTests/platform/glib/damage/layer-mask-change-expected.txt: Added.
* LayoutTests/platform/glib/damage/layer-mask-change.html: Added.
* LayoutTests/platform/glib/damage/layer-mask-on-moving-layer-expected.txt:
Added.
* LayoutTests/platform/glib/damage/layer-mask-on-moving-layer.html: Added.
* LayoutTests/platform/glib/damage/layer-mask-removal-expected.txt: Added.
* LayoutTests/platform/glib/damage/layer-mask-removal.html: Added.
*
LayoutTests/platform/glib/damage/layer-mask-with-overflowing-child-expected.txt:
Added.
* LayoutTests/platform/glib/damage/layer-mask-with-overflowing-child.html:
Added.
* LayoutTests/platform/glib/damage/layer-multiple-movement-expected.txt: Added.
* LayoutTests/platform/glib/damage/layer-multiple-movement.html: Added.
* LayoutTests/platform/glib/damage/layer-nested-clip-expected.txt: Added.
* LayoutTests/platform/glib/damage/layer-nested-clip.html: Added.
* LayoutTests/platform/glib/damage/layer-recomposition-expected.txt: Added.
* LayoutTests/platform/glib/damage/layer-recomposition.html: Added.
* LayoutTests/platform/glib/damage/layer-removal-expected.txt: Added.
* LayoutTests/platform/glib/damage/layer-removal.html: Added.
* LayoutTests/platform/glib/damage/layer-replica-color-change-expected.txt:
Added.
* LayoutTests/platform/glib/damage/layer-replica-color-change.html: Added.
* LayoutTests/platform/glib/damage/layer-replica-movement-expected.txt: Added.
* LayoutTests/platform/glib/damage/layer-replica-movement.html: Added.
* LayoutTests/platform/glib/damage/layer-replica-removal-expected.txt: Added.
* LayoutTests/platform/glib/damage/layer-replica-removal.html: Added.
* LayoutTests/platform/glib/damage/layer-replica-with-mask-expected.txt: Added.
* LayoutTests/platform/glib/damage/layer-replica-with-mask.html: Added.
* LayoutTests/platform/glib/damage/layer-size-to-empty-expected.txt: Added.
* LayoutTests/platform/glib/damage/layer-size-to-empty.html: Added.
* LayoutTests/platform/glib/damage/layer-subtree-hidden-expected.txt: Added.
* LayoutTests/platform/glib/damage/layer-subtree-hidden.html: Added.
* LayoutTests/platform/glib/damage/layer-transform-with-replica-expected.txt:
Added.
* LayoutTests/platform/glib/damage/layer-transform-with-replica.html: Added.
* Source/WebCore/platform/graphics/skia/SkiaCompositingLayer.cpp:
(WebCore::SkiaCompositingLayer::setSize):
(WebCore::SkiaCompositingLayer::setOpacity):
(WebCore::SkiaCompositingLayer::removeFromParent):
(WebCore::SkiaCompositingLayer::setContentsSolidColor):
(WebCore::SkiaCompositingLayer::setMask):
(WebCore::SkiaCompositingLayer::paintedLayerRect const):
(WebCore::SkiaCompositingLayer::LayerRectTracker::recordVisit):
(WebCore::SkiaCompositingLayer::LayerRectTracker::damageStaleLayerRectsAndAdvanceEntries):
(WebCore::SkiaCompositingLayer::trackLayerRect):
(WebCore::SkiaCompositingLayer::resolveBackdropDamage):
(WebCore::SkiaCompositingLayer::syncAnimations):
(WebCore::SkiaCompositingLayer::computeTransformsAndAnimations):
(WebCore::SkiaCompositingLayer::paint):
(WebCore::SkiaCompositingLayer::paintSelf):
(WebCore::SkiaCompositingLayer::collectFrameDamage):
(WebCore::SkiaCompositingLayer::collectBackdropDamage):
(WebCore::SkiaCompositingLayer::collectMaskDamage):
(WebCore::SkiaCompositingLayer::paintWithIntermediateSurface):
(WebCore::SkiaCompositingLayer::paintBackdrop):
(WebCore::SkiaCompositingLayer::paintWithMaskAndBackdrop):
(WebCore::SkiaCompositingLayer::paintWithFilterAndMask):
(WebCore::SkiaCompositingLayer::recursivePaint):
(WebCore::SkiaCompositingLayer::paintWithOpacity):
(WebCore::SkiaCompositingLayer::paintWithBlendMode):
(WebCore::SkiaCompositingLayer::recursiveCleanUpAfterPaint):
(WebCore::SkiaCompositingLayer::addPreviousRectToSharedFrameDamage): Deleted.
(WebCore::SkiaCompositingLayer::recursiveAddPreviousRectToSharedFrameDamage):
Deleted.
* Source/WebCore/platform/graphics/skia/SkiaCompositingLayer.h:
*
Source/WebCore/platform/graphics/texmap/coordinated/CoordinatedPlatformLayer.cpp:
(WebCore::CoordinatedPlatformLayer::ensureSkiaTarget):
* Tools/TestWebKitAPI/PlatformGTK.cmake:
* Tools/TestWebKitAPI/PlatformWPE.cmake:
* Tools/TestWebKitAPI/Tests/WebCore/glib/SkiaCompositingLayerDamage.cpp: Added.
(TestWebKitAPI::TEST(SkiaCompositingLayerDamage,
CollectsDamageBeyondTheRootLayerSize)):
(TestWebKitAPI::createMaskedTree):
(TestWebKitAPI::paintAndCollect):
(TestWebKitAPI::TEST(SkiaCompositingLayerDamage,
MovedMaskDamagesTheMaskedLayer)):
(TestWebKitAPI::TEST(SkiaCompositingLayerDamage,
ChangedMaskDamagesChildrenOutsideTheLayerBounds)):
(TestWebKitAPI::TEST(SkiaCompositingLayerDamage,
RemovedMaskDamagesChildrenOutsideTheLayerBounds)):
(TestWebKitAPI::createSolidColorLayer):
(TestWebKitAPI::createSettledTree):
(TestWebKitAPI::TEST(SkiaCompositingLayerDamage, RemovedLayerIsDamagedOnce)):
(TestWebKitAPI::TEST(SkiaCompositingLayerDamage,
DestroyedLayerIsDamagedWhereItPainted)):
(TestWebKitAPI::TEST(SkiaCompositingLayerDamage,
HiddenLayerComingBackIsDamagedWhereItPaintsNow)):
(TestWebKitAPI::TEST(SkiaCompositingLayerDamage,
MovedLayerIsDamagedInBothPlaces)):
(TestWebKitAPI::TEST(SkiaCompositingLayerDamage,
ReplicatedLayerIsDamagedWithItsReplica)):
Canonical link: https://commits.webkit.org/317343@main
To unsubscribe from these emails, change your notification settings at
https://github.com/WebKit/WebKit/settings/notifications