Skip to content

Commit ac177a3

Browse files
committed
[GTK][WPE] Add a mode enum to Damage
https://bugs.webkit.org/show_bug.cgi?id=290108 Reviewed by Alejandro G. Castro. With 3 different modes: - Rectangles: that's the default where rectangles are added. - BoundingBox: added rectangles are always united in bounding box. - Full: always reports the whole area as the damage. * Source/WebCore/platform/graphics/Damage.h: (WebCore::Damage::Damage): (WebCore::Damage::resize): (WebCore::Damage::setMode): (WebCore::Damage::add): (WebCore::Damage::shouldAdd const): * Source/WebCore/platform/graphics/texmap/TextureMapperLayer.cpp: (WebCore::TextureMapperLayer::damageWholeLayer): * Source/WebCore/platform/graphics/texmap/coordinated/GraphicsLayerCoordinated.cpp: (WebCore::GraphicsLayerCoordinated::updateDamage): * Source/WebKit/WebProcess/WebPage/CoordinatedGraphics/ThreadedCompositor.cpp: (WebKit::ThreadedCompositor::paintToCurrentGLContext): * Tools/TestWebKitAPI/Tests/WebCore/glib/Damage.cpp: (TestWebKitAPI::TEST(Damage, Mode)): (TestWebKitAPI::TEST(Damage, Unite)): Canonical link: https://commits.webkit.org/292581@main
1 parent 530b6fd commit ac177a3

5 files changed

Lines changed: 154 additions & 20 deletions

File tree

Source/WebCore/platform/graphics/Damage.h

Lines changed: 53 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ class Damage {
5050
: m_tileSize(s_tileSize, s_tileSize)
5151
{
5252
// FIXME: Add a constructor to pass the size.
53-
resize({ 2048, 1024 });
53+
resize(IntSize { 2048, 1024 });
5454
}
5555

5656
Damage(Damage&&) = default;
@@ -72,12 +72,47 @@ class Damage {
7272
m_size = size;
7373
m_gridSize = { std::max(1, m_size.width() / m_tileSize.width()), std::max(1, m_size.height() / m_tileSize.height()) };
7474
m_rects.clear();
75+
m_minimumBoundingRectangle = { };
7576
m_shouldUnite = m_gridSize.width() == 1 && m_gridSize.height() == 1;
7677
}
7778

79+
void resize(const FloatSize& size)
80+
{
81+
resize(ceiledIntSize(LayoutSize(size)));
82+
}
83+
84+
enum class Mode : uint8_t {
85+
Rectangles, // Tracks dirty regions as rectangles, only unifying when maximum is reached.
86+
BoundingBox, // Dirty region is always the minimum bounding box of all added rectangles.
87+
Full, // All area is always dirty.
88+
};
89+
90+
void setMode(Mode mode)
91+
{
92+
if (m_mode == mode)
93+
return;
94+
95+
switch (mode) {
96+
case Mode::Rectangles:
97+
break;
98+
case Mode::BoundingBox:
99+
m_rects.clear();
100+
if (!m_minimumBoundingRectangle.isEmpty())
101+
m_rects.append(m_minimumBoundingRectangle);
102+
break;
103+
case Mode::Full:
104+
m_minimumBoundingRectangle = { { }, m_size };
105+
m_rects.clear();
106+
m_rects.append(m_minimumBoundingRectangle);
107+
break;
108+
}
109+
110+
m_mode = mode;
111+
}
112+
78113
ALWAYS_INLINE void add(const Region& region)
79114
{
80-
if (region.isEmpty())
115+
if (region.isEmpty() || !shouldAdd())
81116
return;
82117

83118
for (const auto& rect : region.rects())
@@ -86,7 +121,7 @@ class Damage {
86121

87122
void add(const IntRect& rect)
88123
{
89-
if (rect.isEmpty())
124+
if (rect.isEmpty() || !shouldAdd())
90125
return;
91126

92127
const auto rectsCount = m_rects.size();
@@ -101,6 +136,11 @@ class Damage {
101136
return;
102137

103138
m_minimumBoundingRectangle.unite(rect);
139+
if (m_mode == Mode::BoundingBox) {
140+
ASSERT(rectsCount == 1);
141+
m_rects[0] = m_minimumBoundingRectangle;
142+
return;
143+
}
104144

105145
if (m_shouldUnite) {
106146
unite(rect);
@@ -119,19 +159,27 @@ class Damage {
119159

120160
ALWAYS_INLINE void add(const FloatRect& rect)
121161
{
122-
if (rect.isEmpty())
162+
if (rect.isEmpty() || !shouldAdd())
123163
return;
124164

125165
add(enclosingIntRect(rect));
126166
}
127167

128168
ALWAYS_INLINE void add(const Damage& other)
129169
{
170+
if (other.isEmpty() || !shouldAdd())
171+
return;
172+
130173
for (const auto& rect : other.rects())
131174
add(rect);
132175
}
133176

134177
private:
178+
ALWAYS_INLINE bool shouldAdd() const
179+
{
180+
return !m_size.isEmpty() && m_mode != Mode::Full;
181+
}
182+
135183
void uniteExistingRects()
136184
{
137185
Rects rectsCopy(m_rects.size());
@@ -161,6 +209,7 @@ class Damage {
161209
m_rects[index].unite(rect);
162210
}
163211

212+
Mode m_mode { Mode::Rectangles };
164213
IntSize m_size;
165214
bool m_shouldUnite { false };
166215
IntSize m_tileSize;

Source/WebCore/platform/graphics/texmap/TextureMapperLayer.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -552,7 +552,10 @@ void TextureMapperLayer::collectDamageSelfChildrenFilterAndMask(TextureMapperPai
552552

553553
void TextureMapperLayer::damageWholeLayer()
554554
{
555-
ensureDamageInLayerCoordinateSpace().add(layerRect());
555+
// FIXME: this will be simply changing the mode when we create damage with the layer size.
556+
auto& damage = ensureDamageInLayerCoordinateSpace();
557+
damage.resize(layerRect().size());
558+
damage.setMode(Damage::Mode::Full);
556559
}
557560

558561
void TextureMapperLayer::damageWholeLayerIncludingItsRectFromPreviousFrame()

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

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -898,9 +898,12 @@ void GraphicsLayerCoordinated::updateDamage()
898898
return;
899899

900900
Damage damage;
901-
if (m_dirtyRegion.fullRepaint)
901+
if (m_dirtyRegion.fullRepaint) {
902+
// FIXME: this will be simply changing the mode when we create damage with the layer size.
903+
damage.resize(m_size);
904+
damage.setMode(Damage::Mode::Full);
902905
damage.add(FloatRect({ }, m_size));
903-
else {
906+
} else {
904907
for (const auto& rect : m_dirtyRegion.rects)
905908
damage.add(rect);
906909
}

Source/WebKit/WebProcess/WebPage/CoordinatedGraphics/ThreadedCompositor.cpp

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -264,16 +264,13 @@ void ThreadedCompositor::paintToCurrentGLContext(const TransformationMatrix& mat
264264
currentRootLayer.prepareForPainting(*m_textureMapper);
265265
if (m_damagePropagation != Damage::Propagation::None) {
266266
Damage frameDamage;
267+
if (m_damagePropagation == Damage::Propagation::Unified)
268+
frameDamage.setMode(Damage::Mode::BoundingBox);
269+
267270
WTFBeginSignpost(this, CollectDamage);
268271
currentRootLayer.collectDamage(*m_textureMapper, frameDamage);
269272
WTFEndSignpost(this, CollectDamage);
270273

271-
if (m_damagePropagation == Damage::Propagation::Unified) {
272-
Damage boundsDamage;
273-
boundsDamage.add(frameDamage.bounds());
274-
frameDamage = WTFMove(boundsDamage);
275-
}
276-
277274
if (m_frameDamageHistory)
278275
m_frameDamageHistory->addDamage(frameDamage);
279276

Tools/TestWebKitAPI/Tests/WebCore/glib/Damage.cpp

Lines changed: 89 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,88 @@ TEST(Damage, Basics)
3939
EXPECT_EQ(damage.rects().size(), 0);
4040
}
4141

42+
TEST(Damage, Mode)
43+
{
44+
// Rectangles is the default mode.
45+
Damage rectsDamage;
46+
rectsDamage.resize(IntSize { 1024, 768 });
47+
rectsDamage.add(IntRect { 100, 100, 200, 200 });
48+
rectsDamage.add(IntRect { 300, 300, 200, 200 });
49+
EXPECT_FALSE(rectsDamage.isEmpty());
50+
EXPECT_EQ(rectsDamage.rects().size(), 2);
51+
EXPECT_EQ(rectsDamage.bounds().x(), 100);
52+
EXPECT_EQ(rectsDamage.bounds().y(), 100);
53+
EXPECT_EQ(rectsDamage.bounds().width(), 400);
54+
EXPECT_EQ(rectsDamage.bounds().height(), 400);
55+
56+
// BoundingBox always unite damage in bounds.
57+
Damage bboxDamage;
58+
bboxDamage.resize(IntSize { 1024, 768 });
59+
bboxDamage.setMode(Damage::Mode::BoundingBox);
60+
bboxDamage.add(IntRect { 100, 100, 200, 200 });
61+
bboxDamage.add(IntRect { 300, 300, 200, 200 });
62+
EXPECT_FALSE(bboxDamage.isEmpty());
63+
EXPECT_EQ(bboxDamage.rects().size(), 1);
64+
EXPECT_EQ(bboxDamage.rects()[0], bboxDamage.bounds());
65+
EXPECT_EQ(bboxDamage.bounds().x(), 100);
66+
EXPECT_EQ(bboxDamage.bounds().y(), 100);
67+
EXPECT_EQ(bboxDamage.bounds().width(), 400);
68+
EXPECT_EQ(bboxDamage.bounds().height(), 400);
69+
70+
// Full ignores any adds and always reports the whole area.
71+
Damage fullDamage;
72+
fullDamage.resize(IntSize { 1024, 768 });
73+
fullDamage.setMode(Damage::Mode::Full);
74+
fullDamage.add(IntRect { 100, 100, 200, 200 });
75+
fullDamage.add(IntRect { 300, 300, 200, 200 });
76+
EXPECT_FALSE(fullDamage.isEmpty());
77+
EXPECT_EQ(fullDamage.rects().size(), 1);
78+
EXPECT_EQ(fullDamage.rects()[0], fullDamage.bounds());
79+
EXPECT_EQ(fullDamage.bounds().x(), 0);
80+
EXPECT_EQ(fullDamage.bounds().y(), 0);
81+
EXPECT_EQ(fullDamage.bounds().width(), 1024);
82+
EXPECT_EQ(fullDamage.bounds().height(), 768);
83+
84+
// We can change the existing mode.
85+
Damage bboxDamage2 = rectsDamage;
86+
bboxDamage2.setMode(Damage::Mode::BoundingBox);
87+
EXPECT_FALSE(bboxDamage2.isEmpty());
88+
EXPECT_EQ(bboxDamage2.rects().size(), 1);
89+
EXPECT_EQ(bboxDamage2.rects()[0], bboxDamage.bounds());
90+
EXPECT_EQ(bboxDamage2.bounds().x(), 100);
91+
EXPECT_EQ(bboxDamage2.bounds().y(), 100);
92+
EXPECT_EQ(bboxDamage2.bounds().width(), 400);
93+
EXPECT_EQ(bboxDamage2.bounds().height(), 400);
94+
95+
Damage fullDamage2 = rectsDamage;
96+
fullDamage2.setMode(Damage::Mode::Full);
97+
EXPECT_FALSE(fullDamage2.isEmpty());
98+
EXPECT_EQ(fullDamage2.rects().size(), 1);
99+
EXPECT_EQ(fullDamage2.rects()[0], fullDamage.bounds());
100+
EXPECT_EQ(fullDamage2.bounds().x(), 0);
101+
EXPECT_EQ(fullDamage2.bounds().y(), 0);
102+
EXPECT_EQ(fullDamage2.bounds().width(), 1024);
103+
EXPECT_EQ(fullDamage2.bounds().height(), 768);
104+
105+
Damage rectsDamage2 = bboxDamage;
106+
rectsDamage2.setMode(Damage::Mode::Rectangles);
107+
EXPECT_FALSE(rectsDamage2.isEmpty());
108+
EXPECT_EQ(rectsDamage2.rects().size(), 1);
109+
EXPECT_EQ(rectsDamage2.bounds().x(), 100);
110+
EXPECT_EQ(rectsDamage2.bounds().y(), 100);
111+
EXPECT_EQ(rectsDamage2.bounds().width(), 400);
112+
EXPECT_EQ(rectsDamage2.bounds().height(), 400);
113+
114+
Damage rectsDamage3 = fullDamage;
115+
rectsDamage3.setMode(Damage::Mode::Rectangles);
116+
EXPECT_FALSE(rectsDamage3.isEmpty());
117+
EXPECT_EQ(rectsDamage3.rects().size(), 1);
118+
EXPECT_EQ(rectsDamage3.bounds().x(), 0);
119+
EXPECT_EQ(rectsDamage3.bounds().y(), 0);
120+
EXPECT_EQ(rectsDamage3.bounds().width(), 1024);
121+
EXPECT_EQ(rectsDamage3.bounds().height(), 768);
122+
}
123+
42124
TEST(Damage, Move)
43125
{
44126
Damage damage;
@@ -143,7 +225,7 @@ TEST(Damage, AddDamage)
143225
TEST(Damage, Unite)
144226
{
145227
Damage damage;
146-
damage.resize({ 512, 512 });
228+
damage.resize(IntSize { 512, 512 });
147229

148230
// Add several rects to the first tile.
149231
damage.add(IntRect { 0, 0, 4, 4 });
@@ -163,7 +245,7 @@ TEST(Damage, Unite)
163245
EXPECT_EQ(damage.rects()[0], damage.bounds());
164246

165247
damage = { };
166-
damage.resize({ 512, 512 });
248+
damage.resize(IntSize { 512, 512 });
167249

168250
// Add several rects to the second tile.
169251
damage.add(IntRect { 300, 0, 4, 4 });
@@ -184,7 +266,7 @@ TEST(Damage, Unite)
184266

185267

186268
damage = { };
187-
damage.resize({ 512, 512 });
269+
damage.resize(IntSize { 512, 512 });
188270

189271
// Add several rects to the third tile.
190272
damage.add(IntRect { 0, 300, 4, 4 });
@@ -204,7 +286,7 @@ TEST(Damage, Unite)
204286
EXPECT_EQ(damage.rects()[2], damage.bounds());
205287

206288
damage = { };
207-
damage.resize({ 512, 512 });
289+
damage.resize(IntSize { 512, 512 });
208290

209291
// Add several rects to the fourth tile.
210292
damage.add(IntRect { 300, 300, 4, 4 });
@@ -225,7 +307,7 @@ TEST(Damage, Unite)
225307

226308

227309
damage = { };
228-
damage.resize({ 512, 512 });
310+
damage.resize(IntSize { 512, 512 });
229311

230312
// Add one rect per tile.
231313
damage.add(IntRect { 0, 0, 4, 4 });
@@ -258,7 +340,7 @@ TEST(Damage, Unite)
258340
EXPECT_EQ(damage.rects()[3].height(), 4);
259341

260342
damage = { };
261-
damage.resize({ 512, 512 });
343+
damage.resize(IntSize { 512, 512 });
262344

263345
// Add rects with points off the grid area.
264346
damage.add(IntRect { -2, 0, 4, 4 });
@@ -299,7 +381,7 @@ TEST(Damage, Unite)
299381
EXPECT_EQ(damage.rects()[3].height(), 254);
300382

301383
damage = { };
302-
damage.resize({ 128, 128 });
384+
damage.resize(IntSize { 128, 128 });
303385

304386
// Add several rects and check that unite works for single tile grid.
305387
damage.add(IntRect { 10, 10, 4, 4 });

0 commit comments

Comments
 (0)