Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit 67d3526

Browse files
authored
[Impeller] Use minimal coverage for stencil restores after overdraw prevention (#39358)
1 parent 655530e commit 67d3526

8 files changed

+49
-17
lines changed

impeller/entity/contents/clip_contents.cc

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,11 @@ ClipRestoreContents::ClipRestoreContents() = default;
136136

137137
ClipRestoreContents::~ClipRestoreContents() = default;
138138

139+
void ClipRestoreContents::SetRestoreCoverage(
140+
std::optional<Rect> restore_coverage) {
141+
restore_coverage_ = restore_coverage;
142+
}
143+
139144
std::optional<Rect> ClipRestoreContents::GetCoverage(
140145
const Entity& entity) const {
141146
return std::nullopt;
@@ -164,19 +169,20 @@ bool ClipRestoreContents::Render(const ContentContext& renderer,
164169
auto options = OptionsFromPassAndEntity(pass, entity);
165170
options.stencil_compare = CompareFunction::kLess;
166171
options.stencil_operation = StencilOperation::kSetToReferenceValue;
172+
options.primitive_type = PrimitiveType::kTriangleStrip;
167173
cmd.pipeline = renderer.GetClipPipeline(options);
168174
cmd.stencil_reference = entity.GetStencilDepth();
169175

170-
// Create a rect that covers the whole render target.
171-
auto size = pass.GetRenderTargetSize();
176+
// Create a rect that covers either the given restore area, or the whole
177+
// render target texture.
178+
auto ltrb = restore_coverage_.value_or(Rect(Size(pass.GetRenderTargetSize())))
179+
.GetLTRB();
172180
VertexBufferBuilder<VS::PerVertexData> vtx_builder;
173181
vtx_builder.AddVertices({
174-
{Point(0.0, 0.0)},
175-
{Point(size.width, 0.0)},
176-
{Point(size.width, size.height)},
177-
{Point(0.0, 0.0)},
178-
{Point(size.width, size.height)},
179-
{Point(0.0, size.height)},
182+
{Point(ltrb[0], ltrb[1])},
183+
{Point(ltrb[2], ltrb[1])},
184+
{Point(ltrb[0], ltrb[3])},
185+
{Point(ltrb[2], ltrb[3])},
180186
});
181187
cmd.BindVertices(vtx_builder.CreateVertexBuffer(pass.GetTransientsBuffer()));
182188

impeller/entity/contents/clip_contents.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,12 @@ class ClipRestoreContents final : public Contents {
5555

5656
~ClipRestoreContents();
5757

58+
/// @brief The area on the pass texture where this clip restore will be
59+
/// applied. If unset, the entire pass texture will be restored.
60+
///
61+
/// @note This rectangle is not transformed by the entity's transformation.
62+
void SetRestoreCoverage(std::optional<Rect> coverage);
63+
5864
// |Contents|
5965
std::optional<Rect> GetCoverage(const Entity& entity) const override;
6066

@@ -73,6 +79,8 @@ class ClipRestoreContents final : public Contents {
7379
RenderPass& pass) const override;
7480

7581
private:
82+
std::optional<Rect> restore_coverage_;
83+
7684
FML_DISALLOW_COPY_AND_ASSIGN(ClipRestoreContents);
7785
};
7886

impeller/entity/contents/linear_gradient_contents.cc

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,9 @@ bool LinearGradientContents::RenderTexture(const ContentContext& renderer,
111111
}
112112

113113
if (geometry_result.prevent_overdraw) {
114-
return ClipRestoreContents().Render(renderer, entity, pass);
114+
auto restore = ClipRestoreContents();
115+
restore.SetRestoreCoverage(GetCoverage(entity));
116+
return restore.Render(renderer, entity, pass);
115117
}
116118
return true;
117119
}
@@ -165,7 +167,9 @@ bool LinearGradientContents::RenderSSBO(const ContentContext& renderer,
165167
}
166168

167169
if (geometry_result.prevent_overdraw) {
168-
return ClipRestoreContents().Render(renderer, entity, pass);
170+
auto restore = ClipRestoreContents();
171+
restore.SetRestoreCoverage(GetCoverage(entity));
172+
return restore.Render(renderer, entity, pass);
169173
}
170174
return true;
171175
}

impeller/entity/contents/radial_gradient_contents.cc

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,9 @@ bool RadialGradientContents::RenderSSBO(const ContentContext& renderer,
103103
}
104104

105105
if (geometry_result.prevent_overdraw) {
106-
return ClipRestoreContents().Render(renderer, entity, pass);
106+
auto restore = ClipRestoreContents();
107+
restore.SetRestoreCoverage(GetCoverage(entity));
108+
return restore.Render(renderer, entity, pass);
107109
}
108110
return true;
109111
}
@@ -166,7 +168,9 @@ bool RadialGradientContents::RenderTexture(const ContentContext& renderer,
166168
}
167169

168170
if (geometry_result.prevent_overdraw) {
169-
return ClipRestoreContents().Render(renderer, entity, pass);
171+
auto restore = ClipRestoreContents();
172+
restore.SetRestoreCoverage(GetCoverage(entity));
173+
return restore.Render(renderer, entity, pass);
170174
}
171175
return true;
172176
}

impeller/entity/contents/runtime_effect_contents.cc

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -238,7 +238,9 @@ bool RuntimeEffectContents::Render(const ContentContext& renderer,
238238
pass.AddCommand(std::move(cmd));
239239

240240
if (geometry_result.prevent_overdraw) {
241-
return ClipRestoreContents().Render(renderer, entity, pass);
241+
auto restore = ClipRestoreContents();
242+
restore.SetRestoreCoverage(GetCoverage(entity));
243+
return restore.Render(renderer, entity, pass);
242244
}
243245
return true;
244246
}

impeller/entity/contents/solid_color_contents.cc

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,9 @@ bool SolidColorContents::Render(const ContentContext& renderer,
8383
}
8484

8585
if (geometry_result.prevent_overdraw) {
86-
return ClipRestoreContents().Render(renderer, entity, pass);
86+
auto restore = ClipRestoreContents();
87+
restore.SetRestoreCoverage(GetCoverage(entity));
88+
return restore.Render(renderer, entity, pass);
8789
}
8890
return true;
8991
}

impeller/entity/contents/sweep_gradient_contents.cc

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,9 @@ bool SweepGradientContents::RenderSSBO(const ContentContext& renderer,
109109
}
110110

111111
if (geometry_result.prevent_overdraw) {
112-
return ClipRestoreContents().Render(renderer, entity, pass);
112+
auto restore = ClipRestoreContents();
113+
restore.SetRestoreCoverage(GetCoverage(entity));
114+
return restore.Render(renderer, entity, pass);
113115
}
114116
return true;
115117
}
@@ -173,7 +175,9 @@ bool SweepGradientContents::RenderTexture(const ContentContext& renderer,
173175
}
174176

175177
if (geometry_result.prevent_overdraw) {
176-
return ClipRestoreContents().Render(renderer, entity, pass);
178+
auto restore = ClipRestoreContents();
179+
restore.SetRestoreCoverage(GetCoverage(entity));
180+
return restore.Render(renderer, entity, pass);
177181
}
178182
return true;
179183
}

impeller/entity/contents/tiled_texture_contents.cc

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,9 @@ bool TiledTextureContents::Render(const ContentContext& renderer,
9696
}
9797

9898
if (geometry_result.prevent_overdraw) {
99-
return ClipRestoreContents().Render(renderer, entity, pass);
99+
auto restore = ClipRestoreContents();
100+
restore.SetRestoreCoverage(GetCoverage(entity));
101+
return restore.Render(renderer, entity, pass);
100102
}
101103
return true;
102104
}

0 commit comments

Comments
 (0)