Skip to content

Commit c5f315a

Browse files
committed
[CoordinatedGraphics] Use Damage to track the dirty region of GraphicsLayer
https://bugs.webkit.org/show_bug.cgi?id=290385 Reviewed by Nikolas Zimmermann. We can use the Damage class to track the dirty rects in GraphicsLayer which should improve the performance. This patch adds a viewSize() method to GraphicsLayerClient since it's needed to create the Damage from GraphicsLayer. * Source/WebCore/platform/graphics/Damage.h: (WebCore::Damage::mode const): (WebCore::Damage::add): * Source/WebCore/platform/graphics/GraphicsLayerClient.h: (WebCore::GraphicsLayerClient::viewSize const): * Source/WebCore/platform/graphics/texmap/coordinated/CoordinatedPlatformLayer.cpp: (WebCore::CoordinatedPlatformLayer::setDirtyRegion): (WebCore::CoordinatedPlatformLayer::setDamage): Deleted. * Source/WebCore/platform/graphics/texmap/coordinated/CoordinatedPlatformLayer.h: * Source/WebCore/platform/graphics/texmap/coordinated/GraphicsLayerCoordinated.cpp: (WebCore::GraphicsLayerCoordinated::setNeedsDisplay): (WebCore::GraphicsLayerCoordinated::setNeedsDisplayInRect): (WebCore::GraphicsLayerCoordinated::commitLayerChanges): (WebCore::GraphicsLayerCoordinated::updateDamage): Deleted. (WebCore::GraphicsLayerCoordinated::updateDirtyRegion): Deleted. * Source/WebCore/platform/graphics/texmap/coordinated/GraphicsLayerCoordinated.h: * Source/WebCore/rendering/RenderLayerBacking.cpp: (WebCore::RenderLayerBacking::viewSize const): * Source/WebCore/rendering/RenderLayerBacking.h: * Source/WebCore/rendering/RenderLayerCompositor.cpp: (WebCore::RenderLayerCompositor::viewSize const): * Source/WebCore/rendering/RenderLayerCompositor.h: * Tools/TestWebKitAPI/Tests/WebCore/glib/Damage.cpp: (TestWebKitAPI::TEST(Damage, Mode)): (TestWebKitAPI::TEST(Damage, Move)): (TestWebKitAPI::TEST(Damage, AddRect)): (TestWebKitAPI::TEST(Damage, AddDamage)): (TestWebKitAPI::TEST(Damage, Unite)): (TestWebKitAPI::TEST(Damage, Resize)): Deleted. Canonical link: https://commits.webkit.org/292747@main
1 parent 6de2c97 commit c5f315a

11 files changed

Lines changed: 174 additions & 209 deletions

File tree

‎Source/WebCore/platform/graphics/Damage.h‎

Lines changed: 19 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525

2626
#pragma once
2727

28-
#if PLATFORM(GTK) || PLATFORM(WPE)
28+
#if USE(COORDINATED_GRAPHICS)
2929
#include "FloatRect.h"
3030
#include "Region.h"
3131
#include <wtf/ForbidHeapAllocation.h>
@@ -77,6 +77,7 @@ class Damage {
7777
// May return both empty and overlapping rects.
7878
ALWAYS_INLINE const Rects& rects() const { return m_rects; }
7979
ALWAYS_INLINE bool isEmpty() const { return m_rects.isEmpty(); }
80+
ALWAYS_INLINE Mode mode() const { return m_mode; }
8081

8182
// Removes empty and overlapping rects. May clip to grid.
8283
Rects rectsForPainting() const
@@ -126,68 +127,62 @@ class Damage {
126127
makeFull(m_rect);
127128
}
128129

129-
ALWAYS_INLINE void add(const Region& region)
130-
{
131-
if (region.isEmpty() || !shouldAdd())
132-
return;
133-
134-
for (const auto& rect : region.rects())
135-
add(rect);
136-
}
137-
138-
void add(const IntRect& rect)
130+
bool add(const IntRect& rect)
139131
{
140132
if (rect.isEmpty() || !shouldAdd())
141-
return;
133+
return false;
142134

143135
const auto rectsCount = m_rects.size();
144136
if (!rectsCount || rect.contains(m_minimumBoundingRectangle)) {
145137
m_rects.clear();
146138
m_rects.append(rect);
147139
m_minimumBoundingRectangle = rect;
148-
return;
140+
return true;
149141
}
150142

151143
if (rectsCount == 1 && m_minimumBoundingRectangle.contains(rect))
152-
return;
144+
return false;
153145

154146
m_minimumBoundingRectangle.unite(rect);
155147
if (m_mode == Mode::BoundingBox) {
156148
ASSERT(rectsCount == 1);
157149
m_rects[0] = m_minimumBoundingRectangle;
158-
return;
150+
return true;
159151
}
160152

161153
if (m_shouldUnite) {
162154
unite(rect);
163-
return;
155+
return true;
164156
}
165157

166158
if (rectsCount == m_gridCells.unclampedArea()) {
167159
m_shouldUnite = true;
168160
uniteExistingRects();
169161
unite(rect);
170-
return;
162+
return true;
171163
}
172164

173165
m_rects.append(rect);
166+
return true;
174167
}
175168

176-
ALWAYS_INLINE void add(const FloatRect& rect)
169+
ALWAYS_INLINE bool add(const FloatRect& rect)
177170
{
178171
if (rect.isEmpty() || !shouldAdd())
179-
return;
172+
return false;
180173

181-
add(enclosingIntRect(rect));
174+
return add(enclosingIntRect(rect));
182175
}
183176

184-
ALWAYS_INLINE void add(const Damage& other)
177+
ALWAYS_INLINE bool add(const Damage& other)
185178
{
186179
if (other.isEmpty() || !shouldAdd())
187-
return;
180+
return false;
188181

182+
bool returnValue = false;
189183
for (const auto& rect : other.rects())
190-
add(rect);
184+
returnValue |= add(rect);
185+
return returnValue;
191186
}
192187

193188
private:
@@ -278,4 +273,4 @@ static inline WTF::TextStream& operator<<(WTF::TextStream& ts, const Damage& dam
278273

279274
} // namespace WebCore
280275

281-
#endif // PLATFORM(GTK) || PLATFORM(WPE)
276+
#endif // USE(COORDINATED_GRAPHICS)

‎Source/WebCore/platform/graphics/GraphicsLayerClient.h‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,8 @@ class GraphicsLayerClient {
108108
virtual float pageScaleFactor() const { return 1; }
109109
virtual float zoomedOutPageScaleFactor() const { return 0; }
110110

111+
virtual FloatSize enclosingFrameViewVisibleSize() const { return { }; }
112+
111113
virtual std::optional<float> customContentsScale(const GraphicsLayer*) const { return { }; }
112114

113115
virtual float contentsScaleMultiplierForNewTiles(const GraphicsLayer*) const { return 1; }

‎Source/WebCore/platform/graphics/texmap/coordinated/CoordinatedPlatformLayer.cpp‎

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -548,28 +548,28 @@ void CoordinatedPlatformLayer::setContentsTilePhase(const FloatSize& contentsTil
548548
notifyCompositionRequired();
549549
}
550550

551-
void CoordinatedPlatformLayer::setDirtyRegion(Vector<IntRect, 1>&& dirtyRegion)
551+
void CoordinatedPlatformLayer::setDirtyRegion(Damage&& damage)
552552
{
553553
ASSERT(m_lock.isHeld());
554-
if (m_dirtyRegion == dirtyRegion)
555-
return;
556-
557-
m_dirtyRegion = WTFMove(dirtyRegion);
558-
notifyCompositionRequired();
559-
}
554+
// FIXME: add a way to remove the empty rects from Damage class.
555+
auto dirtyRegion = WTF::compactMap(damage.rects(), [](const auto& value) -> std::optional<IntRect> {
556+
if (value.isEmpty())
557+
return std::nullopt;
558+
return value;
559+
});
560+
if (m_dirtyRegion != dirtyRegion) {
561+
m_dirtyRegion = WTFMove(dirtyRegion);
562+
notifyCompositionRequired();
563+
}
560564

561565
#if ENABLE(DAMAGE_TRACKING)
562-
void CoordinatedPlatformLayer::setDamage(Damage&& damage)
563-
{
564-
ASSERT(m_lock.isHeld());
565-
566566
if (!m_damage)
567567
m_damage = WTFMove(damage);
568568
else
569569
m_damage->add(damage);
570570
m_pendingChanges.add(Change::Damage);
571-
}
572571
#endif
572+
}
573573

574574
void CoordinatedPlatformLayer::setFilters(const FilterOperations& filters)
575575
{

‎Source/WebCore/platform/graphics/texmap/coordinated/CoordinatedPlatformLayer.h‎

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -152,10 +152,7 @@ class CoordinatedPlatformLayer : public ThreadSafeRefCounted<CoordinatedPlatform
152152
void setContentsColor(const Color&);
153153
void setContentsTileSize(const FloatSize&);
154154
void setContentsTilePhase(const FloatSize&);
155-
void setDirtyRegion(Vector<IntRect, 1>&&);
156-
#if ENABLE(DAMAGE_TRACKING)
157-
void setDamage(Damage&&);
158-
#endif
155+
void setDirtyRegion(Damage&&);
159156

160157
void setFilters(const FilterOperations&);
161158
void setMask(CoordinatedPlatformLayer*);

‎Source/WebCore/platform/graphics/texmap/coordinated/GraphicsLayerCoordinated.cpp‎

Lines changed: 25 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -79,19 +79,27 @@ std::optional<PlatformLayerIdentifier> GraphicsLayerCoordinated::primaryLayerID(
7979

8080
void GraphicsLayerCoordinated::setNeedsDisplay()
8181
{
82-
if (!m_drawsContent || !m_contentsVisible || m_size.isEmpty() || m_dirtyRegion.fullRepaint)
82+
if (!m_drawsContent || !m_contentsVisible || m_size.isEmpty())
8383
return;
8484

85-
m_dirtyRegion.fullRepaint = true;
86-
m_dirtyRegion.rects.clear();
87-
noteLayerPropertyChanged(Change::DirtyRegion, ScheduleFlush::Yes);
85+
if (m_dirtyRegion) {
86+
if (m_dirtyRegion->mode() == Damage::Mode::Full)
87+
return;
88+
89+
m_dirtyRegion->makeFull(m_size);
90+
} else
91+
m_dirtyRegion = Damage(m_size, Damage::Mode::Full);
8892

93+
noteLayerPropertyChanged(Change::DirtyRegion, ScheduleFlush::Yes);
8994
addRepaintRect({ { }, m_size });
9095
}
9196

9297
void GraphicsLayerCoordinated::setNeedsDisplayInRect(const FloatRect& initialRect, ShouldClipToLayer shouldClip)
9398
{
94-
if (!m_drawsContent || !m_contentsVisible || m_size.isEmpty() || m_dirtyRegion.fullRepaint)
99+
if (!m_drawsContent || !m_contentsVisible || m_size.isEmpty())
100+
return;
101+
102+
if (m_dirtyRegion && m_dirtyRegion->mode() == Damage::Mode::Full)
95103
return;
96104

97105
auto rect = initialRect;
@@ -101,17 +109,16 @@ void GraphicsLayerCoordinated::setNeedsDisplayInRect(const FloatRect& initialRec
101109
if (rect.isEmpty())
102110
return;
103111

104-
auto& rects = m_dirtyRegion.rects;
105-
bool alreadyRecorded = std::any_of(rects.begin(), rects.end(), [&](auto& dirtyRect) {
106-
return dirtyRect.contains(rect);
107-
});
108-
if (alreadyRecorded)
109-
return;
112+
addRepaintRect(rect);
110113

111-
rects.append(rect);
112-
noteLayerPropertyChanged(Change::DirtyRegion, ScheduleFlush::Yes);
114+
if (!m_dirtyRegion) {
115+
static constexpr FloatSize minDamageSize = { 512, 512 };
116+
auto viewVisibleSize = client().enclosingFrameViewVisibleSize();
117+
m_dirtyRegion = Damage(m_size.constrainedBetween(minDamageSize, viewVisibleSize));
118+
}
113119

114-
addRepaintRect(rect);
120+
if (m_dirtyRegion->add(rect))
121+
noteLayerPropertyChanged(Change::DirtyRegion, ScheduleFlush::Yes);
115122
}
116123

117124
void GraphicsLayerCoordinated::setPosition(const FloatPoint& position)
@@ -891,48 +898,6 @@ void GraphicsLayerCoordinated::updateVisibleRect(const FloatRect& rect)
891898
m_platformLayer->setTransformedVisibleRect(WTFMove(visibleRect), WTFMove(visibleRectFuture));
892899
}
893900

894-
#if ENABLE(DAMAGE_TRACKING)
895-
void GraphicsLayerCoordinated::updateDamage(const FloatSize& visibleSize)
896-
{
897-
if (!m_platformLayer->damagePropagation())
898-
return;
899-
900-
if (m_dirtyRegion.fullRepaint) {
901-
m_platformLayer->setDamage(Damage(m_size, Damage::Mode::Full));
902-
return;
903-
}
904-
905-
static constexpr FloatSize minDamageSize = { 512, 512 };
906-
Damage damage(m_size.constrainedBetween(minDamageSize, visibleSize));
907-
for (const auto& rect : m_dirtyRegion.rects)
908-
damage.add(rect);
909-
m_platformLayer->setDamage(WTFMove(damage));
910-
}
911-
#endif
912-
913-
void GraphicsLayerCoordinated::updateDirtyRegion(const FloatSize& visibleSize)
914-
{
915-
#if ENABLE(DAMAGE_TRACKING)
916-
updateDamage(visibleSize);
917-
#else
918-
UNUSED_PARAM(visibleSize);
919-
#endif
920-
921-
IntRect contentsRect(IntPoint::zero(), IntSize(m_size));
922-
Vector<IntRect, 1> dirtyRegion;
923-
if (!m_dirtyRegion.fullRepaint) {
924-
dirtyRegion = m_dirtyRegion.rects.map<Vector<IntRect, 1>>([](const FloatRect& rect) {
925-
return enclosingIntRect(rect);
926-
});
927-
} else
928-
dirtyRegion = { contentsRect };
929-
930-
m_dirtyRegion.fullRepaint = false;
931-
m_dirtyRegion.rects.clear();
932-
933-
m_platformLayer->setDirtyRegion(WTFMove(dirtyRegion));
934-
}
935-
936901
void GraphicsLayerCoordinated::updateBackdropFilters()
937902
{
938903
bool canHaveBackdropFilters = needsBackdrop();
@@ -1092,8 +1057,10 @@ void GraphicsLayerCoordinated::commitLayerChanges(CommitState& commitState, floa
10921057
if (m_pendingChanges.contains(Change::ContentsColor))
10931058
m_platformLayer->setContentsColor(m_contentsColor);
10941059

1095-
if (m_pendingChanges.contains(Change::DirtyRegion))
1096-
updateDirtyRegion(commitState.visibleRect.size());
1060+
if (m_pendingChanges.contains(Change::DirtyRegion)) {
1061+
ASSERT(m_dirtyRegion.has_value());
1062+
m_platformLayer->setDirtyRegion(*std::exchange(m_dirtyRegion, std::nullopt));
1063+
}
10971064

10981065
if (m_pendingChanges.contains(Change::Filters))
10991066
m_platformLayer->setFilters(m_filters);

‎Source/WebCore/platform/graphics/texmap/coordinated/GraphicsLayerCoordinated.h‎

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
#pragma once
2727

2828
#if USE(COORDINATED_GRAPHICS)
29+
#include "Damage.h"
2930
#include "GraphicsLayer.h"
3031
#include "GraphicsLayerTransform.h"
3132
#include "TextureMapperAnimation.h"
@@ -171,10 +172,6 @@ class GraphicsLayerCoordinated final : public GraphicsLayer {
171172
IntRect transformedRect(const FloatRect&) const;
172173
IntRect transformedRectIncludingFuture(const FloatRect&) const;
173174
void updateGeometry(float pageScaleFactor, const FloatPoint&);
174-
#if ENABLE(DAMAGE_TRACKING)
175-
void updateDamage(const FloatSize&);
176-
#endif
177-
void updateDirtyRegion(const FloatSize&);
178175
void updateBackdropFilters();
179176
void updateBackdropFiltersRect();
180177
void updateAnimations();
@@ -201,10 +198,7 @@ class GraphicsLayerCoordinated final : public GraphicsLayer {
201198
bool m_hasDescendantsWithPendingTilesCreation { false };
202199
bool m_hasDescendantsWithRunningTransformAnimations { false };
203200
FloatSize m_pixelAlignmentOffset;
204-
struct {
205-
bool fullRepaint { false };
206-
Vector<FloatRect> rects;
207-
} m_dirtyRegion;
201+
std::optional<Damage> m_dirtyRegion;
208202
FloatRect m_visibleRect;
209203
struct {
210204
GraphicsLayerTransform current;

‎Source/WebCore/rendering/RenderLayerBacking.cpp‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4089,6 +4089,11 @@ float RenderLayerBacking::zoomedOutPageScaleFactor() const
40894089
return compositor().zoomedOutPageScaleFactor();
40904090
}
40914091

4092+
FloatSize RenderLayerBacking::enclosingFrameViewVisibleSize() const
4093+
{
4094+
return compositor().enclosingFrameViewVisibleSize();
4095+
}
4096+
40924097
float RenderLayerBacking::deviceScaleFactor() const
40934098
{
40944099
return compositor().deviceScaleFactor();

‎Source/WebCore/rendering/RenderLayerBacking.h‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -242,6 +242,8 @@ class RenderLayerBacking final : public GraphicsLayerClient {
242242
float pageScaleFactor() const override;
243243
float zoomedOutPageScaleFactor() const override;
244244

245+
FloatSize enclosingFrameViewVisibleSize() const override;
246+
245247
void didChangePlatformLayerForLayer(const GraphicsLayer*) override;
246248
bool getCurrentTransform(const GraphicsLayer*, TransformationMatrix&) const override;
247249

‎Source/WebCore/rendering/RenderLayerCompositor.cpp‎

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4503,6 +4503,17 @@ float RenderLayerCompositor::zoomedOutPageScaleFactor() const
45034503
return page().zoomedOutPageScaleFactor();
45044504
}
45054505

4506+
FloatSize RenderLayerCompositor::enclosingFrameViewVisibleSize() const
4507+
{
4508+
const Ref frameView = m_renderView.frameView();
4509+
#if PLATFORM(IOS_FAMILY)
4510+
return frameView->exposedContentRect().size();
4511+
#endif
4512+
if (m_scrolledContentsLayer)
4513+
return frameView->sizeForVisibleContent(scrollbarInclusionForVisibleRect());
4514+
return frameView->visibleContentRect().size();
4515+
}
4516+
45064517
float RenderLayerCompositor::contentsScaleMultiplierForNewTiles(const GraphicsLayer*) const
45074518
{
45084519
#if PLATFORM(IOS_FAMILY)

‎Source/WebCore/rendering/RenderLayerCompositor.h‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -345,6 +345,7 @@ class RenderLayerCompositor final : public GraphicsLayerClient, public CanMakeCh
345345
float contentsScaleMultiplierForNewTiles(const GraphicsLayer*) const override;
346346
float pageScaleFactor() const override;
347347
float zoomedOutPageScaleFactor() const override;
348+
FloatSize enclosingFrameViewVisibleSize() const override;
348349
void didChangePlatformLayerForLayer(const GraphicsLayer*) override { }
349350

350351
void layerTiledBackingUsageChanged(const GraphicsLayer*, bool /*usingTiledBacking*/);

0 commit comments

Comments
 (0)