Flutter Impeller
impeller::ContentContextOptions Struct Reference

#include <content_context.h>

Public Types

enum class  StencilMode : uint8_t {
  kIgnore ,
  kStencilNonZeroFill ,
  kStencilEvenOddFill ,
  kCoverCompare ,
  kCoverCompareInverted ,
  kOverdrawPreventionIncrement ,
  kOverdrawPreventionRestore
}
 

Public Member Functions

constexpr uint64_t ToKey () const
 
void ApplyToPipelineDescriptor (PipelineDescriptor &desc) const
 

Public Attributes

SampleCount sample_count = SampleCount::kCount1
 
BlendMode blend_mode = BlendMode::kSourceOver
 
CompareFunction depth_compare = CompareFunction::kAlways
 
StencilMode stencil_mode = ContentContextOptions::StencilMode::kIgnore
 
PrimitiveType primitive_type = PrimitiveType::kTriangle
 
PixelFormat color_attachment_pixel_format = PixelFormat::kUnknown
 
bool has_depth_stencil_attachments = true
 
bool depth_write_enabled = false
 
bool wireframe = false
 
bool is_for_rrect_blur_clear = false
 

Detailed Description

Pipeline state configuration.

Each unique combination of these options requires a different pipeline state object to be built. This struct is used as a key for the per-pipeline variant cache.

When adding fields to this key, reliant features should take care to limit the combinatorical explosion of variations. A sufficiently complicated Flutter application may easily require building hundreds of PSOs in total, but they shouldn't require e.g. 10s of thousands.

Definition at line 279 of file content_context.h.

Member Enumeration Documentation

◆ StencilMode

Enumerator
kIgnore 

Turn the stencil test off. Used when drawing without stencil-then-cover or overdraw prevention.

kStencilNonZeroFill 

Draw the stencil for the NonZero fill path rule.

The stencil ref should always be 0 on commands using this mode. 
kStencilEvenOddFill 

Draw the stencil for the EvenOdd fill path rule.

The stencil ref should always be 0 on commands using this mode. 
kCoverCompare 

Used for draw calls which fill in the stenciled area. Intended to be used after kStencilNonZeroFill or kStencilEvenOddFill is used to set up the stencil buffer. Also cleans up the stencil buffer by resetting everything to zero.

The stencil ref should always be 0 on commands using this mode.

kCoverCompareInverted 

The opposite of kCoverCompare. Used for draw calls which fill in the non-stenciled area (intersection clips). Intended to be used after kStencilNonZeroFill or kStencilEvenOddFill is used to set up the stencil buffer. Also cleans up the stencil buffer by resetting everything to zero.

The stencil ref should always be 0 on commands using this mode.

kOverdrawPreventionIncrement 

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.

kOverdrawPreventionRestore 

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.

Definition at line 280 of file content_context.h.

280  : uint8_t {
281  /// Turn the stencil test off. Used when drawing without stencil-then-cover
282  /// or overdraw prevention.
283  kIgnore,
284 
285  // Operations used for stencil-then-cover.
286 
287  /// Draw the stencil for the NonZero fill path rule.
288  ///
289  /// The stencil ref should always be 0 on commands using this mode.
290  kStencilNonZeroFill,
291  /// Draw the stencil for the EvenOdd fill path rule.
292  ///
293  /// The stencil ref should always be 0 on commands using this mode.
294  kStencilEvenOddFill,
295  /// Used for draw calls which fill in the stenciled area. Intended to be
296  /// used after `kStencilNonZeroFill` or `kStencilEvenOddFill` is used to set
297  /// up the stencil buffer. Also cleans up the stencil buffer by resetting
298  /// everything to zero.
299  ///
300  /// The stencil ref should always be 0 on commands using this mode.
301  kCoverCompare,
302  /// The opposite of `kCoverCompare`. Used for draw calls which fill in the
303  /// non-stenciled area (intersection clips). Intended to be used after
304  /// `kStencilNonZeroFill` or `kStencilEvenOddFill` is used to set up the
305  /// stencil buffer. Also cleans up the stencil buffer by resetting
306  /// everything to zero.
307  ///
308  /// The stencil ref should always be 0 on commands using this mode.
309  kCoverCompareInverted,
310 
311  // Operations used for the "overdraw prevention" mechanism. This is used for
312  // drawing strokes.
313 
314  /// For each fragment, increment the stencil value if it's currently zero.
315  /// Discard fragments when the value is non-zero. This prevents
316  /// self-overlapping strokes from drawing over themselves.
317  ///
318  /// Note that this is done for rendering correctness, not performance. If a
319  /// stroke is drawn with a backdrop-reliant blend and self-intersects, then
320  /// the intersected geometry will render incorrectly when overdrawn because
321  /// we don't adjust the geometry prevent self-intersection.
322  ///
323  /// The stencil ref should always be 0 on commands using this mode.
324  kOverdrawPreventionIncrement,
325  /// Reset the stencil to a new maximum value specified by the ref (currently
326  /// always 0).
327  ///
328  /// The stencil ref should always be 0 on commands using this mode.
329  kOverdrawPreventionRestore,
330  };

Member Function Documentation

◆ ApplyToPipelineDescriptor()

void impeller::ContentContextOptions::ApplyToPipelineDescriptor ( PipelineDescriptor desc) const

Definition at line 27 of file content_context.cc.

28  {
29  auto pipeline_blend = blend_mode;
31  VALIDATION_LOG << "Cannot use blend mode " << static_cast<int>(blend_mode)
32  << " as a pipeline blend.";
33  pipeline_blend = BlendMode::kSourceOver;
34  }
35 
36  desc.SetSampleCount(sample_count);
37 
38  ColorAttachmentDescriptor color0 = *desc.GetColorAttachmentDescriptor(0u);
39  color0.format = color_attachment_pixel_format;
40  color0.alpha_blend_op = BlendOperation::kAdd;
41  color0.color_blend_op = BlendOperation::kAdd;
42  color0.write_mask = ColorWriteMaskBits::kAll;
43 
44  switch (pipeline_blend) {
45  case BlendMode::kClear:
47  color0.alpha_blend_op = BlendOperation::kReverseSubtract;
48  color0.color_blend_op = BlendOperation::kReverseSubtract;
49  color0.dst_alpha_blend_factor = BlendFactor::kOne;
50  color0.dst_color_blend_factor = BlendFactor::kOne;
51  color0.src_alpha_blend_factor = BlendFactor::kDestinationColor;
52  color0.src_color_blend_factor = BlendFactor::kDestinationColor;
53  } else {
54  color0.dst_alpha_blend_factor = BlendFactor::kZero;
55  color0.dst_color_blend_factor = BlendFactor::kZero;
56  color0.src_alpha_blend_factor = BlendFactor::kZero;
57  color0.src_color_blend_factor = BlendFactor::kZero;
58  }
59  break;
60  case BlendMode::kSource:
61  color0.blending_enabled = false;
62  color0.dst_alpha_blend_factor = BlendFactor::kZero;
63  color0.dst_color_blend_factor = BlendFactor::kZero;
64  color0.src_alpha_blend_factor = BlendFactor::kOne;
65  color0.src_color_blend_factor = BlendFactor::kOne;
66  break;
68  color0.dst_alpha_blend_factor = BlendFactor::kOne;
69  color0.dst_color_blend_factor = BlendFactor::kOne;
70  color0.src_alpha_blend_factor = BlendFactor::kZero;
71  color0.src_color_blend_factor = BlendFactor::kZero;
72  color0.write_mask = ColorWriteMaskBits::kNone;
73  break;
75  color0.dst_alpha_blend_factor = BlendFactor::kOneMinusSourceAlpha;
76  color0.dst_color_blend_factor = BlendFactor::kOneMinusSourceAlpha;
77  color0.src_alpha_blend_factor = BlendFactor::kOne;
78  color0.src_color_blend_factor = BlendFactor::kOne;
79  break;
81  color0.dst_alpha_blend_factor = BlendFactor::kOne;
82  color0.dst_color_blend_factor = BlendFactor::kOne;
83  color0.src_alpha_blend_factor = BlendFactor::kOneMinusDestinationAlpha;
84  color0.src_color_blend_factor = BlendFactor::kOneMinusDestinationAlpha;
85  break;
87  color0.dst_alpha_blend_factor = BlendFactor::kZero;
88  color0.dst_color_blend_factor = BlendFactor::kZero;
89  color0.src_alpha_blend_factor = BlendFactor::kDestinationAlpha;
90  color0.src_color_blend_factor = BlendFactor::kDestinationAlpha;
91  break;
93  color0.dst_alpha_blend_factor = BlendFactor::kSourceAlpha;
94  color0.dst_color_blend_factor = BlendFactor::kSourceAlpha;
95  color0.src_alpha_blend_factor = BlendFactor::kZero;
96  color0.src_color_blend_factor = BlendFactor::kZero;
97  break;
99  color0.dst_alpha_blend_factor = BlendFactor::kZero;
100  color0.dst_color_blend_factor = BlendFactor::kZero;
101  color0.src_alpha_blend_factor = BlendFactor::kOneMinusDestinationAlpha;
102  color0.src_color_blend_factor = BlendFactor::kOneMinusDestinationAlpha;
103  break;
105  color0.dst_alpha_blend_factor = BlendFactor::kOneMinusSourceAlpha;
106  color0.dst_color_blend_factor = BlendFactor::kOneMinusSourceAlpha;
107  color0.src_alpha_blend_factor = BlendFactor::kZero;
108  color0.src_color_blend_factor = BlendFactor::kZero;
109  break;
111  color0.dst_alpha_blend_factor = BlendFactor::kOneMinusSourceAlpha;
112  color0.dst_color_blend_factor = BlendFactor::kOneMinusSourceAlpha;
113  color0.src_alpha_blend_factor = BlendFactor::kDestinationAlpha;
114  color0.src_color_blend_factor = BlendFactor::kDestinationAlpha;
115  break;
117  color0.dst_alpha_blend_factor = BlendFactor::kSourceAlpha;
118  color0.dst_color_blend_factor = BlendFactor::kSourceAlpha;
119  color0.src_alpha_blend_factor = BlendFactor::kOneMinusDestinationAlpha;
120  color0.src_color_blend_factor = BlendFactor::kOneMinusDestinationAlpha;
121  break;
122  case BlendMode::kXor:
123  color0.dst_alpha_blend_factor = BlendFactor::kOneMinusSourceAlpha;
124  color0.dst_color_blend_factor = BlendFactor::kOneMinusSourceAlpha;
125  color0.src_alpha_blend_factor = BlendFactor::kOneMinusDestinationAlpha;
126  color0.src_color_blend_factor = BlendFactor::kOneMinusDestinationAlpha;
127  break;
128  case BlendMode::kPlus:
129  color0.dst_alpha_blend_factor = BlendFactor::kOne;
130  color0.dst_color_blend_factor = BlendFactor::kOne;
131  color0.src_alpha_blend_factor = BlendFactor::kOne;
132  color0.src_color_blend_factor = BlendFactor::kOne;
133  break;
135  color0.dst_alpha_blend_factor = BlendFactor::kSourceAlpha;
136  color0.dst_color_blend_factor = BlendFactor::kSourceColor;
137  color0.src_alpha_blend_factor = BlendFactor::kZero;
138  color0.src_color_blend_factor = BlendFactor::kZero;
139  break;
140  default:
141  FML_UNREACHABLE();
142  }
143  desc.SetColorAttachmentDescriptor(0u, color0);
144 
146  desc.ClearDepthAttachment();
147  desc.ClearStencilAttachments();
148  }
149 
150  auto maybe_stencil = desc.GetFrontStencilAttachmentDescriptor();
151  auto maybe_depth = desc.GetDepthStencilAttachmentDescriptor();
152  FML_DCHECK(has_depth_stencil_attachments == maybe_depth.has_value())
153  << "Depth attachment doesn't match expected pipeline state. "
154  "has_depth_stencil_attachments="
156  FML_DCHECK(has_depth_stencil_attachments == maybe_stencil.has_value())
157  << "Stencil attachment doesn't match expected pipeline state. "
158  "has_depth_stencil_attachments="
160  if (maybe_stencil.has_value()) {
161  StencilAttachmentDescriptor front_stencil = maybe_stencil.value();
162  StencilAttachmentDescriptor back_stencil = front_stencil;
163 
164  switch (stencil_mode) {
166  front_stencil.stencil_compare = CompareFunction::kAlways;
167  front_stencil.depth_stencil_pass = StencilOperation::kKeep;
168  desc.SetStencilAttachmentDescriptors(front_stencil);
169  break;
171  // The stencil ref should be 0 on commands that use this mode.
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;
179  // The stencil ref should be 0 on commands that use this mode.
180  front_stencil.stencil_compare = CompareFunction::kEqual;
181  front_stencil.depth_stencil_pass = StencilOperation::kIncrementWrap;
182  front_stencil.stencil_failure = StencilOperation::kDecrementWrap;
183  desc.SetStencilAttachmentDescriptors(front_stencil);
184  break;
186  // The stencil ref should be 0 on commands that use this mode.
187  front_stencil.stencil_compare = CompareFunction::kNotEqual;
188  front_stencil.depth_stencil_pass =
190  desc.SetStencilAttachmentDescriptors(front_stencil);
191  break;
193  // The stencil ref should be 0 on commands that use this mode.
194  front_stencil.stencil_compare = CompareFunction::kEqual;
195  front_stencil.stencil_failure = StencilOperation::kSetToReferenceValue;
196  desc.SetStencilAttachmentDescriptors(front_stencil);
197  break;
199  front_stencil.stencil_compare = CompareFunction::kEqual;
200  front_stencil.depth_stencil_pass = StencilOperation::kIncrementClamp;
201  desc.SetStencilAttachmentDescriptors(front_stencil);
202  break;
204  front_stencil.stencil_compare = CompareFunction::kLess;
205  front_stencil.depth_stencil_pass =
207  desc.SetStencilAttachmentDescriptors(front_stencil);
208  break;
209  }
210  }
211  if (maybe_depth.has_value()) {
212  DepthAttachmentDescriptor depth = maybe_depth.value();
213  depth.depth_write_enabled = depth_write_enabled;
214  depth.depth_compare = depth_compare;
215  desc.SetDepthStencilAttachmentDescriptor(depth);
216  }
217 
218  desc.SetPrimitiveType(primitive_type);
219 
220  desc.SetPolygonMode(wireframe ? PolygonMode::kLine : PolygonMode::kFill);
221 }
static constexpr BlendMode kLastPipelineBlendMode
Definition: entity.h:22
@ kEqual
Comparison test passes if new_value == current_value.
@ kAlways
Comparison test passes always passes.
@ kLess
Comparison test passes if new_value < current_value.
@ kNotEqual
Comparison test passes if new_value != current_value.
@ kDecrementWrap
Decrement the current stencil value by 1. If at zero, set to maximum.
@ kSetToReferenceValue
Reset the stencil value to the reference value.
@ kIncrementClamp
Increment the current stencil value by 1. Clamp it to the maximum.
@ kIncrementWrap
Increment the current stencil value by 1. If at maximum, set to zero.
@ kKeep
Don't modify the current stencil value.
#define VALIDATION_LOG
Definition: validation.h:91

References impeller::ColorAttachmentDescriptor::alpha_blend_op, blend_mode, impeller::ColorAttachmentDescriptor::blending_enabled, impeller::PipelineDescriptor::ClearDepthAttachment(), impeller::PipelineDescriptor::ClearStencilAttachments(), color_attachment_pixel_format, impeller::ColorAttachmentDescriptor::color_blend_op, impeller::DepthAttachmentDescriptor::depth_compare, depth_compare, impeller::StencilAttachmentDescriptor::depth_stencil_pass, impeller::DepthAttachmentDescriptor::depth_write_enabled, depth_write_enabled, impeller::ColorAttachmentDescriptor::dst_alpha_blend_factor, impeller::ColorAttachmentDescriptor::dst_color_blend_factor, impeller::ColorAttachmentDescriptor::format, impeller::PipelineDescriptor::GetColorAttachmentDescriptor(), impeller::PipelineDescriptor::GetDepthStencilAttachmentDescriptor(), impeller::PipelineDescriptor::GetFrontStencilAttachmentDescriptor(), has_depth_stencil_attachments, is_for_rrect_blur_clear, impeller::kAdd, impeller::kAll, impeller::kAlways, impeller::kClear, kCoverCompare, kCoverCompareInverted, impeller::kDecrementWrap, impeller::kDestination, impeller::kDestinationAlpha, impeller::kDestinationATop, impeller::kDestinationColor, impeller::kDestinationIn, impeller::kDestinationOut, impeller::kDestinationOver, impeller::kEqual, impeller::kFill, kIgnore, impeller::kIncrementClamp, impeller::kIncrementWrap, impeller::kKeep, impeller::Entity::kLastPipelineBlendMode, impeller::kLess, impeller::kLine, impeller::kModulate, impeller::kNone, impeller::kNotEqual, impeller::kOne, impeller::kOneMinusDestinationAlpha, impeller::kOneMinusSourceAlpha, kOverdrawPreventionIncrement, kOverdrawPreventionRestore, impeller::kPlus, impeller::kReverseSubtract, impeller::kSetToReferenceValue, impeller::kSource, impeller::kSourceAlpha, impeller::kSourceATop, impeller::kSourceColor, impeller::kSourceIn, impeller::kSourceOut, impeller::kSourceOver, kStencilEvenOddFill, kStencilNonZeroFill, impeller::kXor, impeller::kZero, primitive_type, sample_count, impeller::PipelineDescriptor::SetColorAttachmentDescriptor(), impeller::PipelineDescriptor::SetDepthStencilAttachmentDescriptor(), impeller::PipelineDescriptor::SetPolygonMode(), impeller::PipelineDescriptor::SetPrimitiveType(), impeller::PipelineDescriptor::SetSampleCount(), impeller::PipelineDescriptor::SetStencilAttachmentDescriptors(), impeller::ColorAttachmentDescriptor::src_alpha_blend_factor, impeller::ColorAttachmentDescriptor::src_color_blend_factor, impeller::StencilAttachmentDescriptor::stencil_compare, impeller::StencilAttachmentDescriptor::stencil_failure, stencil_mode, VALIDATION_LOG, wireframe, and impeller::ColorAttachmentDescriptor::write_mask.

◆ ToKey()

constexpr uint64_t impeller::ContentContextOptions::ToKey ( ) const
inlineconstexpr

Definition at line 343 of file content_context.h.

343  {
344  static_assert(sizeof(sample_count) == 1);
345  static_assert(sizeof(blend_mode) == 1);
346  static_assert(sizeof(sample_count) == 1);
347  static_assert(sizeof(depth_compare) == 1);
348  static_assert(sizeof(stencil_mode) == 1);
349  static_assert(sizeof(primitive_type) == 1);
350  static_assert(sizeof(color_attachment_pixel_format) == 1);
351 
352  return (is_for_rrect_blur_clear ? 1llu : 0llu) << 0 |
353  (wireframe ? 1llu : 0llu) << 1 |
354  (has_depth_stencil_attachments ? 1llu : 0llu) << 2 |
355  (depth_write_enabled ? 1llu : 0llu) << 3 |
356  // enums
357  static_cast<uint64_t>(color_attachment_pixel_format) << 8 |
358  static_cast<uint64_t>(primitive_type) << 16 |
359  static_cast<uint64_t>(stencil_mode) << 24 |
360  static_cast<uint64_t>(depth_compare) << 32 |
361  static_cast<uint64_t>(blend_mode) << 40 |
362  static_cast<uint64_t>(sample_count) << 48;
363  }

References blend_mode, color_attachment_pixel_format, depth_compare, depth_write_enabled, has_depth_stencil_attachments, is_for_rrect_blur_clear, primitive_type, sample_count, stencil_mode, and wireframe.

Referenced by impeller::testing::TEST_P().

Member Data Documentation

◆ blend_mode

BlendMode impeller::ContentContextOptions::blend_mode = BlendMode::kSourceOver

◆ color_attachment_pixel_format

PixelFormat impeller::ContentContextOptions::color_attachment_pixel_format = PixelFormat::kUnknown

◆ depth_compare

CompareFunction impeller::ContentContextOptions::depth_compare = CompareFunction::kAlways

Definition at line 334 of file content_context.h.

Referenced by ApplyToPipelineDescriptor(), impeller::OptionsFromPass(), and ToKey().

◆ depth_write_enabled

bool impeller::ContentContextOptions::depth_write_enabled = false

Definition at line 339 of file content_context.h.

Referenced by ApplyToPipelineDescriptor(), and ToKey().

◆ has_depth_stencil_attachments

bool impeller::ContentContextOptions::has_depth_stencil_attachments = true

◆ is_for_rrect_blur_clear

bool impeller::ContentContextOptions::is_for_rrect_blur_clear = false

◆ primitive_type

PrimitiveType impeller::ContentContextOptions::primitive_type = PrimitiveType::kTriangle

◆ sample_count

◆ stencil_mode

StencilMode impeller::ContentContextOptions::stencil_mode = ContentContextOptions::StencilMode::kIgnore

Definition at line 335 of file content_context.h.

Referenced by ApplyToPipelineDescriptor(), impeller::OptionsFromPass(), and ToKey().

◆ wireframe

bool impeller::ContentContextOptions::wireframe = false

Definition at line 340 of file content_context.h.

Referenced by ApplyToPipelineDescriptor(), and ToKey().


The documentation for this struct was generated from the following files: