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

Commit aab6fb4

Browse files
committed
[Impeller] Add StC stencil ops.
1 parent c3a7f59 commit aab6fb4

13 files changed

+133
-54
lines changed

impeller/entity/contents/checkerboard_contents.cc

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,7 @@ bool CheckerboardContents::Render(const ContentContext& renderer,
2525

2626
auto options = OptionsFromPass(pass);
2727
options.blend_mode = BlendMode::kSourceOver;
28-
options.stencil_compare = CompareFunction::kAlways; // Ignore all clips.
29-
options.stencil_operation = StencilOperation::kKeep;
28+
options.stencil_mode = ContentContextOptions::StencilMode::kIgnore;
3029
options.primitive_type = PrimitiveType::kTriangleStrip;
3130

3231
VertexBufferBuilder<typename VS::PerVertexData> vtx_builder;

impeller/entity/contents/clip_contents.cc

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -89,8 +89,8 @@ bool ClipContents::Render(const ContentContext& renderer,
8989
{
9090
pass.SetCommandLabel("Difference Clip (Increment)");
9191

92-
options.stencil_compare = CompareFunction::kEqual;
93-
options.stencil_operation = StencilOperation::kIncrementClamp;
92+
options.stencil_mode =
93+
ContentContextOptions::StencilMode::kLegacyClipIncrement;
9494

9595
auto points = Rect::MakeSize(pass.GetRenderTargetSize()).GetPoints();
9696
auto vertices =
@@ -113,14 +113,14 @@ bool ClipContents::Render(const ContentContext& renderer,
113113
pass.SetCommandLabel("Difference Clip (Punch)");
114114
pass.SetStencilReference(entity.GetClipDepth() + 1);
115115

116-
options.stencil_compare = CompareFunction::kEqual;
117-
options.stencil_operation = StencilOperation::kDecrementClamp;
116+
options.stencil_mode =
117+
ContentContextOptions::StencilMode::kLegacyClipDecrement;
118118
}
119119
} else {
120120
pass.SetCommandLabel("Intersect Clip");
121121

122-
options.stencil_compare = CompareFunction::kEqual;
123-
options.stencil_operation = StencilOperation::kIncrementClamp;
122+
options.stencil_mode =
123+
ContentContextOptions::StencilMode::kLegacyClipIncrement;
124124
}
125125

126126
auto geometry_result = geometry_->GetPositionBuffer(renderer, entity, pass);
@@ -179,8 +179,7 @@ bool ClipRestoreContents::Render(const ContentContext& renderer,
179179
pass.SetCommandLabel("Restore Clip");
180180
auto options = OptionsFromPass(pass);
181181
options.blend_mode = BlendMode::kDestination;
182-
options.stencil_compare = CompareFunction::kLess;
183-
options.stencil_operation = StencilOperation::kSetToReferenceValue;
182+
options.stencil_mode = ContentContextOptions::StencilMode::kLegacyClipRestore;
184183
options.primitive_type = PrimitiveType::kTriangleStrip;
185184
pass.SetPipeline(renderer.GetClipPipeline(options));
186185
pass.SetStencilReference(entity.GetClipDepth());

impeller/entity/contents/conical_gradient_contents.cc

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -95,8 +95,8 @@ bool ConicalGradientContents::RenderSSBO(const ContentContext& renderer,
9595
GetGeometry()->GetPositionBuffer(renderer, entity, pass);
9696
auto options = OptionsFromPassAndEntity(pass, entity);
9797
if (geometry_result.prevent_overdraw) {
98-
options.stencil_compare = CompareFunction::kEqual;
99-
options.stencil_operation = StencilOperation::kIncrementClamp;
98+
options.stencil_mode =
99+
ContentContextOptions::StencilMode::kLegacyClipIncrement;
100100
}
101101
options.primitive_type = geometry_result.type;
102102

@@ -165,8 +165,8 @@ bool ConicalGradientContents::RenderTexture(const ContentContext& renderer,
165165

166166
auto options = OptionsFromPassAndEntity(pass, entity);
167167
if (geometry_result.prevent_overdraw) {
168-
options.stencil_compare = CompareFunction::kEqual;
169-
options.stencil_operation = StencilOperation::kIncrementClamp;
168+
options.stencil_mode =
169+
ContentContextOptions::StencilMode::kLegacyClipIncrement;
170170
}
171171
options.primitive_type = geometry_result.type;
172172
pass.SetPipeline(renderer.GetConicalGradientFillPipeline(options));

impeller/entity/contents/content_context.cc

Lines changed: 55 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -153,10 +153,61 @@ void ContentContextOptions::ApplyToPipelineDescriptor(
153153
"has_depth_stencil_attachments="
154154
<< has_depth_stencil_attachments;
155155
if (maybe_stencil.has_value()) {
156-
StencilAttachmentDescriptor stencil = maybe_stencil.value();
157-
stencil.stencil_compare = stencil_compare;
158-
stencil.depth_stencil_pass = stencil_operation;
159-
desc.SetStencilAttachmentDescriptors(stencil);
156+
StencilAttachmentDescriptor front_stencil = maybe_stencil.value();
157+
StencilAttachmentDescriptor back_stencil = front_stencil;
158+
159+
switch (stencil_mode) {
160+
case StencilMode::kIgnore:
161+
front_stencil.stencil_compare = CompareFunction::kAlways;
162+
front_stencil.depth_stencil_pass = StencilOperation::kKeep;
163+
desc.SetStencilAttachmentDescriptors(front_stencil);
164+
break;
165+
case StencilMode::kSetToRef:
166+
front_stencil.stencil_compare = CompareFunction::kEqual;
167+
front_stencil.depth_stencil_pass = StencilOperation::kKeep;
168+
front_stencil.stencil_failure = StencilOperation::kSetToReferenceValue;
169+
desc.SetStencilAttachmentDescriptors(front_stencil);
170+
break;
171+
case StencilMode::kNonZeroWrite:
172+
front_stencil.stencil_compare = CompareFunction::kAlways;
173+
front_stencil.depth_stencil_pass = StencilOperation::kIncrementWrap;
174+
back_stencil.stencil_compare = CompareFunction::kAlways;
175+
back_stencil.depth_stencil_pass = StencilOperation::kDecrementWrap;
176+
desc.SetStencilAttachmentDescriptors(front_stencil, back_stencil);
177+
break;
178+
case StencilMode::kEvenOddWrite:
179+
front_stencil.stencil_compare = CompareFunction::kEqual;
180+
front_stencil.depth_stencil_pass = StencilOperation::kIncrementWrap;
181+
front_stencil.stencil_failure = StencilOperation::kDecrementWrap;
182+
desc.SetStencilAttachmentDescriptors(front_stencil);
183+
break;
184+
case StencilMode::kCoverCompare:
185+
front_stencil.stencil_compare = CompareFunction::kNotEqual;
186+
front_stencil.depth_stencil_pass = StencilOperation::kKeep;
187+
desc.SetStencilAttachmentDescriptors(front_stencil);
188+
break;
189+
case StencilMode::kLegacyClipRestore:
190+
front_stencil.stencil_compare = CompareFunction::kLess;
191+
front_stencil.depth_stencil_pass =
192+
StencilOperation::kSetToReferenceValue;
193+
desc.SetStencilAttachmentDescriptors(front_stencil);
194+
break;
195+
case StencilMode::kLegacyClipIncrement:
196+
front_stencil.stencil_compare = CompareFunction::kEqual;
197+
front_stencil.depth_stencil_pass = StencilOperation::kIncrementClamp;
198+
desc.SetStencilAttachmentDescriptors(front_stencil);
199+
break;
200+
case StencilMode::kLegacyClipDecrement:
201+
front_stencil.stencil_compare = CompareFunction::kEqual;
202+
front_stencil.depth_stencil_pass = StencilOperation::kDecrementClamp;
203+
desc.SetStencilAttachmentDescriptors(front_stencil);
204+
break;
205+
case StencilMode::kLegacyClipCompare:
206+
front_stencil.stencil_compare = CompareFunction::kEqual;
207+
front_stencil.depth_stencil_pass = StencilOperation::kKeep;
208+
desc.SetStencilAttachmentDescriptors(front_stencil);
209+
break;
210+
}
160211
}
161212
if (maybe_depth.has_value()) {
162213
DepthAttachmentDescriptor depth = maybe_depth.value();

impeller/entity/contents/content_context.h

Lines changed: 38 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -286,11 +286,41 @@ struct PendingCommandBuffers {
286286
/// Flutter application may easily require building hundreds of PSOs in total,
287287
/// but they shouldn't require e.g. 10s of thousands.
288288
struct ContentContextOptions {
289+
enum class StencilMode : uint8_t {
290+
// Operations used for stencil-then-cover
291+
292+
/// Turn the stencil test off. Used when drawing without stencil-then-cover.
293+
kIgnore,
294+
/// Overwrite the stencil content to the ref value. Used for resetting the
295+
/// stencil buffer after a stencil-then-cover operation.
296+
kSetToRef,
297+
/// Draw the stencil for the nonzero fill path rule.
298+
kNonZeroWrite,
299+
/// Draw the stencil for the evenoff fill path rule.
300+
kEvenOddWrite,
301+
/// Used for draw calls which fill in the stenciled area. Intended to be
302+
/// used after `kNonZeroWrite` or `kEvenOddWrite` is used to set up the
303+
/// stencil buffer.
304+
kCoverCompare,
305+
306+
// Operations to control the legacy clip implementation, which forms a
307+
// heightmap on the stencil buffer.
308+
309+
/// Slice the clip heightmap to a new maximum height.
310+
kLegacyClipRestore,
311+
/// Increment the stencil heightmap.
312+
kLegacyClipIncrement,
313+
/// Decrement the stencil heightmap (used for difference clipping only).
314+
kLegacyClipDecrement,
315+
/// Used for applying clips to all non-clip draw calls.
316+
kLegacyClipCompare,
317+
};
318+
289319
SampleCount sample_count = SampleCount::kCount1;
290320
BlendMode blend_mode = BlendMode::kSourceOver;
291321
CompareFunction depth_compare = CompareFunction::kAlways;
292-
CompareFunction stencil_compare = CompareFunction::kEqual;
293-
StencilOperation stencil_operation = StencilOperation::kKeep;
322+
StencilMode stencil_mode =
323+
ContentContextOptions::StencilMode::kLegacyClipCompare;
294324
PrimitiveType primitive_type = PrimitiveType::kTriangle;
295325
PixelFormat color_attachment_pixel_format = PixelFormat::kUnknown;
296326
bool has_depth_stencil_attachments = true;
@@ -304,8 +334,7 @@ struct ContentContextOptions {
304334
static_assert(sizeof(o.blend_mode) == 1);
305335
static_assert(sizeof(o.sample_count) == 1);
306336
static_assert(sizeof(o.depth_compare) == 1);
307-
static_assert(sizeof(o.stencil_compare) == 1);
308-
static_assert(sizeof(o.stencil_operation) == 1);
337+
static_assert(sizeof(o.stencil_mode) == 1);
309338
static_assert(sizeof(o.primitive_type) == 1);
310339
static_assert(sizeof(o.color_attachment_pixel_format) == 1);
311340

@@ -316,11 +345,10 @@ struct ContentContextOptions {
316345
// enums
317346
static_cast<uint64_t>(o.color_attachment_pixel_format) << 8 |
318347
static_cast<uint64_t>(o.primitive_type) << 16 |
319-
static_cast<uint64_t>(o.stencil_operation) << 24 |
320-
static_cast<uint64_t>(o.stencil_compare) << 32 |
321-
static_cast<uint64_t>(o.depth_compare) << 40 |
322-
static_cast<uint64_t>(o.blend_mode) << 48 |
323-
static_cast<uint64_t>(o.sample_count) << 56;
348+
static_cast<uint64_t>(o.stencil_mode) << 24 |
349+
static_cast<uint64_t>(o.depth_compare) << 32 |
350+
static_cast<uint64_t>(o.blend_mode) << 40 |
351+
static_cast<uint64_t>(o.sample_count) << 48;
324352
}
325353
};
326354

@@ -331,8 +359,7 @@ struct ContentContextOptions {
331359
lhs.blend_mode == rhs.blend_mode &&
332360
lhs.depth_write_enabled == rhs.depth_write_enabled &&
333361
lhs.depth_compare == rhs.depth_compare &&
334-
lhs.stencil_compare == rhs.stencil_compare &&
335-
lhs.stencil_operation == rhs.stencil_operation &&
362+
lhs.stencil_mode == rhs.stencil_mode &&
336363
lhs.primitive_type == rhs.primitive_type &&
337364
lhs.color_attachment_pixel_format ==
338365
rhs.color_attachment_pixel_format &&

impeller/entity/contents/linear_gradient_contents.cc

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -96,8 +96,8 @@ bool LinearGradientContents::RenderTexture(const ContentContext& renderer,
9696

9797
auto options = OptionsFromPassAndEntity(pass, entity);
9898
if (geometry_result.prevent_overdraw) {
99-
options.stencil_compare = CompareFunction::kEqual;
100-
options.stencil_operation = StencilOperation::kIncrementClamp;
99+
options.stencil_mode =
100+
ContentContextOptions::StencilMode::kLegacyClipIncrement;
101101
}
102102
options.primitive_type = geometry_result.type;
103103

@@ -159,8 +159,8 @@ bool LinearGradientContents::RenderSSBO(const ContentContext& renderer,
159159
GetGeometry()->GetPositionBuffer(renderer, entity, pass);
160160
auto options = OptionsFromPassAndEntity(pass, entity);
161161
if (geometry_result.prevent_overdraw) {
162-
options.stencil_compare = CompareFunction::kEqual;
163-
options.stencil_operation = StencilOperation::kIncrementClamp;
162+
options.stencil_mode =
163+
ContentContextOptions::StencilMode::kLegacyClipIncrement;
164164
}
165165
options.primitive_type = geometry_result.type;
166166

impeller/entity/contents/radial_gradient_contents.cc

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -94,8 +94,8 @@ bool RadialGradientContents::RenderSSBO(const ContentContext& renderer,
9494
GetGeometry()->GetPositionBuffer(renderer, entity, pass);
9595
auto options = OptionsFromPassAndEntity(pass, entity);
9696
if (geometry_result.prevent_overdraw) {
97-
options.stencil_compare = CompareFunction::kEqual;
98-
options.stencil_operation = StencilOperation::kIncrementClamp;
97+
options.stencil_mode =
98+
ContentContextOptions::StencilMode::kLegacyClipIncrement;
9999
}
100100
options.primitive_type = geometry_result.type;
101101

@@ -154,8 +154,8 @@ bool RadialGradientContents::RenderTexture(const ContentContext& renderer,
154154

155155
auto options = OptionsFromPassAndEntity(pass, entity);
156156
if (geometry_result.prevent_overdraw) {
157-
options.stencil_compare = CompareFunction::kEqual;
158-
options.stencil_operation = StencilOperation::kIncrementClamp;
157+
options.stencil_mode =
158+
ContentContextOptions::StencilMode::kLegacyClipIncrement;
159159
}
160160
options.primitive_type = geometry_result.type;
161161

impeller/entity/contents/runtime_effect_contents.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -89,8 +89,8 @@ bool RuntimeEffectContents::Render(const ContentContext& renderer,
8989
GetGeometry()->GetPositionBuffer(renderer, entity, pass);
9090
auto options = OptionsFromPassAndEntity(pass, entity);
9191
if (geometry_result.prevent_overdraw) {
92-
options.stencil_compare = CompareFunction::kEqual;
93-
options.stencil_operation = StencilOperation::kIncrementClamp;
92+
options.stencil_mode =
93+
ContentContextOptions::StencilMode::kLegacyClipIncrement;
9494
}
9595
options.primitive_type = geometry_result.type;
9696

impeller/entity/contents/solid_color_contents.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,8 +57,8 @@ bool SolidColorContents::Render(const ContentContext& renderer,
5757

5858
auto options = OptionsFromPassAndEntity(pass, entity);
5959
if (geometry_result.prevent_overdraw) {
60-
options.stencil_compare = CompareFunction::kEqual;
61-
options.stencil_operation = StencilOperation::kIncrementClamp;
60+
options.stencil_mode =
61+
ContentContextOptions::StencilMode::kLegacyClipIncrement;
6262
}
6363

6464
options.primitive_type = geometry_result.type;

impeller/entity/contents/sweep_gradient_contents.cc

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -102,8 +102,8 @@ bool SweepGradientContents::RenderSSBO(const ContentContext& renderer,
102102

103103
auto options = OptionsFromPassAndEntity(pass, entity);
104104
if (geometry_result.prevent_overdraw) {
105-
options.stencil_compare = CompareFunction::kEqual;
106-
options.stencil_operation = StencilOperation::kIncrementClamp;
105+
options.stencil_mode =
106+
ContentContextOptions::StencilMode::kLegacyClipIncrement;
107107
}
108108
options.primitive_type = geometry_result.type;
109109

@@ -163,8 +163,8 @@ bool SweepGradientContents::RenderTexture(const ContentContext& renderer,
163163

164164
auto options = OptionsFromPassAndEntity(pass, entity);
165165
if (geometry_result.prevent_overdraw) {
166-
options.stencil_compare = CompareFunction::kEqual;
167-
options.stencil_operation = StencilOperation::kIncrementClamp;
166+
options.stencil_mode =
167+
ContentContextOptions::StencilMode::kLegacyClipIncrement;
168168
}
169169
options.primitive_type = geometry_result.type;
170170

impeller/entity/contents/texture_contents.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,7 @@ bool TextureContents::Render(const ContentContext& renderer,
158158

159159
auto pipeline_options = OptionsFromPassAndEntity(pass, entity);
160160
if (!stencil_enabled_) {
161-
pipeline_options.stencil_compare = CompareFunction::kAlways;
161+
pipeline_options.stencil_mode = ContentContextOptions::StencilMode::kIgnore;
162162
}
163163
pipeline_options.primitive_type = PrimitiveType::kTriangleStrip;
164164

impeller/entity/contents/tiled_texture_contents.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -153,8 +153,8 @@ bool TiledTextureContents::Render(const ContentContext& renderer,
153153

154154
auto options = OptionsFromPassAndEntity(pass, entity);
155155
if (geometry_result.prevent_overdraw) {
156-
options.stencil_compare = CompareFunction::kEqual;
157-
options.stencil_operation = StencilOperation::kIncrementClamp;
156+
options.stencil_mode =
157+
ContentContextOptions::StencilMode::kLegacyClipIncrement;
158158
}
159159
options.primitive_type = geometry_result.type;
160160

impeller/renderer/compute_subgroup_unittests.cc

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -143,8 +143,9 @@ TEST_P(ComputeSubgroupTest, PathPlayground) {
143143
pass.GetRenderTarget().GetStencilAttachment().has_value();
144144
options.blend_mode = BlendMode::kSourceIn;
145145
options.primitive_type = PrimitiveType::kTriangleStrip;
146-
options.stencil_compare = CompareFunction::kEqual;
147-
options.stencil_operation = StencilOperation::kIncrementClamp;
146+
147+
options.stencil_mode =
148+
ContentContextOptions::StencilMode::kLegacyClipIncrement;
148149

149150
pass.SetPipeline(renderer.GetSolidFillPipeline(options));
150151

@@ -340,8 +341,9 @@ TEST_P(ComputeSubgroupTest, LargePath) {
340341
pass.GetRenderTarget().GetStencilAttachment().has_value();
341342
options.blend_mode = BlendMode::kSourceIn;
342343
options.primitive_type = PrimitiveType::kTriangleStrip;
343-
options.stencil_compare = CompareFunction::kEqual;
344-
options.stencil_operation = StencilOperation::kIncrementClamp;
344+
345+
options.stencil_mode =
346+
ContentContextOptions::StencilMode::kLegacyClipIncrement;
345347

346348
pass.SetPipeline(renderer.GetSolidFillPipeline(options));
347349

@@ -418,8 +420,9 @@ TEST_P(ComputeSubgroupTest, QuadAndCubicInOnePath) {
418420
pass.GetRenderTarget().GetStencilAttachment().has_value();
419421
options.blend_mode = BlendMode::kSourceIn;
420422
options.primitive_type = PrimitiveType::kTriangleStrip;
421-
options.stencil_compare = CompareFunction::kEqual;
422-
options.stencil_operation = StencilOperation::kIncrementClamp;
423+
424+
options.stencil_mode =
425+
ContentContextOptions::StencilMode::kLegacyClipIncrement;
423426

424427
pass.SetPipeline(renderer.GetSolidFillPipeline(options));
425428

0 commit comments

Comments
 (0)