[Impeller] Cleanup legacy StencilModes and document overdraw prevention. (flutter/engine#52372)

We don't need `kLegacyClipDecrement` or `kLegacyClipCompare` anymore, but we still need `kLegacyClipRestore` and `kLegacyClipIncrement`. So I renamed these to `kOverdrawPreventionRestore` and `kOverdrawPreventionIncrement` respectively and documented how they're used.
This commit is contained in:
Brandon DeRosier 2024-04-24 14:58:59 -07:00 committed by GitHub
parent 71f41387b7
commit 524fc9e31b
5 changed files with 36 additions and 38 deletions

View File

@ -133,7 +133,7 @@ bool ClipContents::Render(const ContentContext& renderer,
case GeometryResult::Mode::kPreventOverdraw:
pass.SetCommandLabel("Clip stencil preparation (Increment)");
options.stencil_mode =
ContentContextOptions::StencilMode::kLegacyClipIncrement;
ContentContextOptions::StencilMode::kOverdrawPreventionIncrement;
break;
}
pass.SetPipeline(renderer.GetClipPipeline(options));
@ -235,7 +235,8 @@ bool ClipRestoreContents::Render(const ContentContext& renderer,
pass.SetCommandLabel("Restore Clip");
auto options = OptionsFromPass(pass);
options.blend_mode = BlendMode::kDestination;
options.stencil_mode = ContentContextOptions::StencilMode::kLegacyClipRestore;
options.stencil_mode =
ContentContextOptions::StencilMode::kOverdrawPreventionRestore;
options.primitive_type = PrimitiveType::kTriangleStrip;
pass.SetPipeline(renderer.GetClipPipeline(options));
pass.SetStencilReference(0);

View File

@ -195,7 +195,7 @@ class ColorSourceContents : public Contents {
// the stencil buffer (happens below in this method).
if (geometry_result.mode == GeometryResult::Mode::kPreventOverdraw) {
options.stencil_mode =
ContentContextOptions::StencilMode::kLegacyClipIncrement;
ContentContextOptions::StencilMode::kOverdrawPreventionIncrement;
}
pass.SetStencilReference(0);

View File

@ -193,25 +193,15 @@ void ContentContextOptions::ApplyToPipelineDescriptor(
front_stencil.stencil_failure = StencilOperation::kSetToReferenceValue;
desc.SetStencilAttachmentDescriptors(front_stencil);
break;
case StencilMode::kLegacyClipRestore:
front_stencil.stencil_compare = CompareFunction::kLess;
front_stencil.depth_stencil_pass =
StencilOperation::kSetToReferenceValue;
desc.SetStencilAttachmentDescriptors(front_stencil);
break;
case StencilMode::kLegacyClipIncrement:
case StencilMode::kOverdrawPreventionIncrement:
front_stencil.stencil_compare = CompareFunction::kEqual;
front_stencil.depth_stencil_pass = StencilOperation::kIncrementClamp;
desc.SetStencilAttachmentDescriptors(front_stencil);
break;
case StencilMode::kLegacyClipDecrement:
front_stencil.stencil_compare = CompareFunction::kEqual;
front_stencil.depth_stencil_pass = StencilOperation::kDecrementClamp;
desc.SetStencilAttachmentDescriptors(front_stencil);
break;
case StencilMode::kLegacyClipCompare:
front_stencil.stencil_compare = CompareFunction::kEqual;
front_stencil.depth_stencil_pass = StencilOperation::kKeep;
case StencilMode::kOverdrawPreventionRestore:
front_stencil.stencil_compare = CompareFunction::kLess;
front_stencil.depth_stencil_pass =
StencilOperation::kSetToReferenceValue;
desc.SetStencilAttachmentDescriptors(front_stencil);
break;
}
@ -617,9 +607,8 @@ void ContentContext::InitializeCommonlyUsedShadersIfNeeded() const {
options.blend_mode = BlendMode::kDestination;
options.primitive_type = PrimitiveType::kTriangleStrip;
for (const auto stencil_mode :
{ContentContextOptions::StencilMode::kLegacyClipIncrement,
ContentContextOptions::StencilMode::kLegacyClipDecrement,
ContentContextOptions::StencilMode::kLegacyClipRestore}) {
{ContentContextOptions::StencilMode::kOverdrawPreventionIncrement,
ContentContextOptions::StencilMode::kOverdrawPreventionRestore}) {
options.stencil_mode = stencil_mode;
CreateIfNeeded(clip_pipelines_, options);
}

View File

@ -269,10 +269,11 @@ using TiledTextureExternalPipeline =
/// but they shouldn't require e.g. 10s of thousands.
struct ContentContextOptions {
enum class StencilMode : uint8_t {
/// Turn the stencil test off. Used when drawing without stencil-then-cover.
/// Turn the stencil test off. Used when drawing without stencil-then-cover
/// or overdraw prevention.
kIgnore,
// Operations used for stencil-then-cover
// Operations used for stencil-then-cover.
/// Draw the stencil for the NonZero fill path rule.
///
@ -298,24 +299,31 @@ struct ContentContextOptions {
/// The stencil ref should always be 0 on commands using this mode.
kCoverCompareInverted,
// Operations to control the legacy clip implementation, which forms a
// heightmap on the stencil buffer.
// Operations used for the "overdraw prevention" mechanism. This is used for
// drawing strokes.
/// Slice the clip heightmap to a new maximum height.
kLegacyClipRestore,
/// Increment the stencil heightmap.
kLegacyClipIncrement,
/// Decrement the stencil heightmap (used for difference clipping only).
kLegacyClipDecrement,
/// Used for applying clips to all non-clip draw calls.
kLegacyClipCompare,
/// For each fragment, increment the stencil value if it's currently zero.
/// Discard fragments when the value is non-zero. This prevents
/// self-overlapping strokes from drawing over themselves.
///
/// Note that this is done for rendering correctness, not performance. If a
/// stroke is drawn with a backdrop-reliant blend and self-intersects, then
/// the intersected geometry will render incorrectly when overdrawn because
/// we don't adjust the geometry prevent self-intersection.
///
/// The stencil ref should always be 0 on commands using this mode.
kOverdrawPreventionIncrement,
/// Reset the stencil to a new maximum value specified by the ref (currently
/// always 0).
///
/// The stencil ref should always be 0 on commands using this mode.
kOverdrawPreventionRestore,
};
SampleCount sample_count = SampleCount::kCount1;
BlendMode blend_mode = BlendMode::kSourceOver;
CompareFunction depth_compare = CompareFunction::kAlways;
StencilMode stencil_mode =
ContentContextOptions::StencilMode::kLegacyClipCompare;
StencilMode stencil_mode = ContentContextOptions::StencilMode::kIgnore;
PrimitiveType primitive_type = PrimitiveType::kTriangle;
PixelFormat color_attachment_pixel_format = PixelFormat::kUnknown;
bool has_depth_stencil_attachments = true;

View File

@ -145,7 +145,7 @@ TEST_P(ComputeSubgroupTest, PathPlayground) {
options.primitive_type = PrimitiveType::kTriangleStrip;
options.stencil_mode =
ContentContextOptions::StencilMode::kLegacyClipIncrement;
ContentContextOptions::StencilMode::kOverdrawPreventionIncrement;
pass.SetPipeline(renderer.GetSolidFillPipeline(options));
@ -343,7 +343,7 @@ TEST_P(ComputeSubgroupTest, LargePath) {
options.primitive_type = PrimitiveType::kTriangleStrip;
options.stencil_mode =
ContentContextOptions::StencilMode::kLegacyClipIncrement;
ContentContextOptions::StencilMode::kOverdrawPreventionIncrement;
pass.SetPipeline(renderer.GetSolidFillPipeline(options));
@ -422,7 +422,7 @@ TEST_P(ComputeSubgroupTest, QuadAndCubicInOnePath) {
options.primitive_type = PrimitiveType::kTriangleStrip;
options.stencil_mode =
ContentContextOptions::StencilMode::kLegacyClipIncrement;
ContentContextOptions::StencilMode::kOverdrawPreventionIncrement;
pass.SetPipeline(renderer.GetSolidFillPipeline(options));