Flutter Engine
The Flutter Engine
Classes | Public Types | Public Member Functions | Public Attributes | List of all members
impeller::ContentContextOptions Struct Reference

#include <content_context.h>

Classes

struct  Equal
 
struct  Hash
 

Public Types

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

Public Member Functions

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 254 of file content_context.h.

Member Enumeration Documentation

◆ StencilMode

enum class impeller::ContentContextOptions::StencilMode : uint8_t
strong
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 255 of file content_context.h.

255 : uint8_t {
256 /// Turn the stencil test off. Used when drawing without stencil-then-cover
257 /// or overdraw prevention.
258 kIgnore,
259
260 // Operations used for stencil-then-cover.
261
262 /// Draw the stencil for the NonZero fill path rule.
263 ///
264 /// The stencil ref should always be 0 on commands using this mode.
265 kStencilNonZeroFill,
266 /// Draw the stencil for the EvenOdd fill path rule.
267 ///
268 /// The stencil ref should always be 0 on commands using this mode.
269 kStencilEvenOddFill,
270 /// Used for draw calls which fill in the stenciled area. Intended to be
271 /// used after `kStencilNonZeroFill` or `kStencilEvenOddFill` is used to set
272 /// up the stencil buffer. Also cleans up the stencil buffer by resetting
273 /// everything to zero.
274 ///
275 /// The stencil ref should always be 0 on commands using this mode.
276 kCoverCompare,
277 /// The opposite of `kCoverCompare`. Used for draw calls which fill in the
278 /// non-stenciled area (intersection clips). Intended to be used after
279 /// `kStencilNonZeroFill` or `kStencilEvenOddFill` is used to set up the
280 /// stencil buffer. Also cleans up the stencil buffer by resetting
281 /// everything to zero.
282 ///
283 /// The stencil ref should always be 0 on commands using this mode.
284 kCoverCompareInverted,
285
286 // Operations used for the "overdraw prevention" mechanism. This is used for
287 // drawing strokes.
288
289 /// For each fragment, increment the stencil value if it's currently zero.
290 /// Discard fragments when the value is non-zero. This prevents
291 /// self-overlapping strokes from drawing over themselves.
292 ///
293 /// Note that this is done for rendering correctness, not performance. If a
294 /// stroke is drawn with a backdrop-reliant blend and self-intersects, then
295 /// the intersected geometry will render incorrectly when overdrawn because
296 /// we don't adjust the geometry prevent self-intersection.
297 ///
298 /// The stencil ref should always be 0 on commands using this mode.
299 kOverdrawPreventionIncrement,
300 /// Reset the stencil to a new maximum value specified by the ref (currently
301 /// always 0).
302 ///
303 /// The stencil ref should always be 0 on commands using this mode.
304 kOverdrawPreventionRestore,
305 };

Member Function Documentation

◆ ApplyToPipelineDescriptor()

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

Definition at line 28 of file content_context.cc.

29 {
30 auto pipeline_blend = blend_mode;
32 VALIDATION_LOG << "Cannot use blend mode " << static_cast<int>(blend_mode)
33 << " as a pipeline blend.";
34 pipeline_blend = BlendMode::kSourceOver;
35 }
36
37 desc.SetSampleCount(sample_count);
38
39 ColorAttachmentDescriptor color0 = *desc.GetColorAttachmentDescriptor(0u);
40 color0.format = color_attachment_pixel_format;
41 color0.alpha_blend_op = BlendOperation::kAdd;
42 color0.color_blend_op = BlendOperation::kAdd;
43 color0.write_mask = ColorWriteMaskBits::kAll;
44
45 switch (pipeline_blend) {
48 color0.alpha_blend_op = BlendOperation::kReverseSubtract;
49 color0.color_blend_op = BlendOperation::kReverseSubtract;
50 color0.dst_alpha_blend_factor = BlendFactor::kOne;
51 color0.dst_color_blend_factor = BlendFactor::kOne;
52 color0.src_alpha_blend_factor = BlendFactor::kDestinationColor;
53 color0.src_color_blend_factor = BlendFactor::kDestinationColor;
54 } else {
55 color0.dst_alpha_blend_factor = BlendFactor::kZero;
56 color0.dst_color_blend_factor = BlendFactor::kZero;
57 color0.src_alpha_blend_factor = BlendFactor::kZero;
58 color0.src_color_blend_factor = BlendFactor::kZero;
59 }
60 break;
62 color0.blending_enabled = false;
63 color0.dst_alpha_blend_factor = BlendFactor::kZero;
64 color0.dst_color_blend_factor = BlendFactor::kZero;
65 color0.src_alpha_blend_factor = BlendFactor::kOne;
66 color0.src_color_blend_factor = BlendFactor::kOne;
67 break;
69 color0.dst_alpha_blend_factor = BlendFactor::kOne;
70 color0.dst_color_blend_factor = BlendFactor::kOne;
71 color0.src_alpha_blend_factor = BlendFactor::kZero;
72 color0.src_color_blend_factor = BlendFactor::kZero;
73 color0.write_mask = ColorWriteMaskBits::kNone;
74 break;
76 color0.dst_alpha_blend_factor = BlendFactor::kOneMinusSourceAlpha;
77 color0.dst_color_blend_factor = BlendFactor::kOneMinusSourceAlpha;
78 color0.src_alpha_blend_factor = BlendFactor::kOne;
79 color0.src_color_blend_factor = BlendFactor::kOne;
80 break;
82 color0.dst_alpha_blend_factor = BlendFactor::kOne;
83 color0.dst_color_blend_factor = BlendFactor::kOne;
84 color0.src_alpha_blend_factor = BlendFactor::kOneMinusDestinationAlpha;
85 color0.src_color_blend_factor = BlendFactor::kOneMinusDestinationAlpha;
86 break;
88 color0.dst_alpha_blend_factor = BlendFactor::kZero;
89 color0.dst_color_blend_factor = BlendFactor::kZero;
90 color0.src_alpha_blend_factor = BlendFactor::kDestinationAlpha;
91 color0.src_color_blend_factor = BlendFactor::kDestinationAlpha;
92 break;
94 color0.dst_alpha_blend_factor = BlendFactor::kSourceAlpha;
95 color0.dst_color_blend_factor = BlendFactor::kSourceAlpha;
96 color0.src_alpha_blend_factor = BlendFactor::kZero;
97 color0.src_color_blend_factor = BlendFactor::kZero;
98 break;
100 color0.dst_alpha_blend_factor = BlendFactor::kZero;
101 color0.dst_color_blend_factor = BlendFactor::kZero;
102 color0.src_alpha_blend_factor = BlendFactor::kOneMinusDestinationAlpha;
103 color0.src_color_blend_factor = BlendFactor::kOneMinusDestinationAlpha;
104 break;
106 color0.dst_alpha_blend_factor = BlendFactor::kOneMinusSourceAlpha;
107 color0.dst_color_blend_factor = BlendFactor::kOneMinusSourceAlpha;
108 color0.src_alpha_blend_factor = BlendFactor::kZero;
109 color0.src_color_blend_factor = BlendFactor::kZero;
110 break;
112 color0.dst_alpha_blend_factor = BlendFactor::kOneMinusSourceAlpha;
113 color0.dst_color_blend_factor = BlendFactor::kOneMinusSourceAlpha;
114 color0.src_alpha_blend_factor = BlendFactor::kDestinationAlpha;
115 color0.src_color_blend_factor = BlendFactor::kDestinationAlpha;
116 break;
118 color0.dst_alpha_blend_factor = BlendFactor::kSourceAlpha;
119 color0.dst_color_blend_factor = BlendFactor::kSourceAlpha;
120 color0.src_alpha_blend_factor = BlendFactor::kOneMinusDestinationAlpha;
121 color0.src_color_blend_factor = BlendFactor::kOneMinusDestinationAlpha;
122 break;
123 case BlendMode::kXor:
124 color0.dst_alpha_blend_factor = BlendFactor::kOneMinusSourceAlpha;
125 color0.dst_color_blend_factor = BlendFactor::kOneMinusSourceAlpha;
126 color0.src_alpha_blend_factor = BlendFactor::kOneMinusDestinationAlpha;
127 color0.src_color_blend_factor = BlendFactor::kOneMinusDestinationAlpha;
128 break;
129 case BlendMode::kPlus:
130 color0.dst_alpha_blend_factor = BlendFactor::kOne;
131 color0.dst_color_blend_factor = BlendFactor::kOne;
132 color0.src_alpha_blend_factor = BlendFactor::kOne;
133 color0.src_color_blend_factor = BlendFactor::kOne;
134 break;
136 color0.dst_alpha_blend_factor = BlendFactor::kSourceAlpha;
137 color0.dst_color_blend_factor = BlendFactor::kSourceColor;
138 color0.src_alpha_blend_factor = BlendFactor::kZero;
139 color0.src_color_blend_factor = BlendFactor::kZero;
140 break;
141 default:
143 }
144 desc.SetColorAttachmentDescriptor(0u, color0);
145
147 desc.ClearDepthAttachment();
148 desc.ClearStencilAttachments();
149 }
150
151 auto maybe_stencil = desc.GetFrontStencilAttachmentDescriptor();
152 auto maybe_depth = desc.GetDepthStencilAttachmentDescriptor();
153 FML_DCHECK(has_depth_stencil_attachments == maybe_depth.has_value())
154 << "Depth attachment doesn't match expected pipeline state. "
155 "has_depth_stencil_attachments="
157 FML_DCHECK(has_depth_stencil_attachments == maybe_stencil.has_value())
158 << "Stencil attachment doesn't match expected pipeline state. "
159 "has_depth_stencil_attachments="
161 if (maybe_stencil.has_value()) {
162 StencilAttachmentDescriptor front_stencil = maybe_stencil.value();
163 StencilAttachmentDescriptor back_stencil = front_stencil;
164
165 switch (stencil_mode) {
167 front_stencil.stencil_compare = CompareFunction::kAlways;
168 front_stencil.depth_stencil_pass = StencilOperation::kKeep;
169 desc.SetStencilAttachmentDescriptors(front_stencil);
170 break;
172 // The stencil ref should be 0 on commands that use this mode.
173 front_stencil.stencil_compare = CompareFunction::kAlways;
174 front_stencil.depth_stencil_pass = StencilOperation::kIncrementWrap;
175 back_stencil.stencil_compare = CompareFunction::kAlways;
176 back_stencil.depth_stencil_pass = StencilOperation::kDecrementWrap;
177 desc.SetStencilAttachmentDescriptors(front_stencil, back_stencil);
178 break;
180 // The stencil ref should be 0 on commands that use this mode.
181 front_stencil.stencil_compare = CompareFunction::kEqual;
182 front_stencil.depth_stencil_pass = StencilOperation::kIncrementWrap;
183 front_stencil.stencil_failure = StencilOperation::kDecrementWrap;
184 desc.SetStencilAttachmentDescriptors(front_stencil);
185 break;
187 // The stencil ref should be 0 on commands that use this mode.
188 front_stencil.stencil_compare = CompareFunction::kNotEqual;
189 front_stencil.depth_stencil_pass =
191 desc.SetStencilAttachmentDescriptors(front_stencil);
192 break;
194 // The stencil ref should be 0 on commands that use this mode.
195 front_stencil.stencil_compare = CompareFunction::kEqual;
196 front_stencil.stencil_failure = StencilOperation::kSetToReferenceValue;
197 desc.SetStencilAttachmentDescriptors(front_stencil);
198 break;
200 front_stencil.stencil_compare = CompareFunction::kEqual;
201 front_stencil.depth_stencil_pass = StencilOperation::kIncrementClamp;
202 desc.SetStencilAttachmentDescriptors(front_stencil);
203 break;
205 front_stencil.stencil_compare = CompareFunction::kLess;
206 front_stencil.depth_stencil_pass =
208 desc.SetStencilAttachmentDescriptors(front_stencil);
209 break;
210 }
211 }
212 if (maybe_depth.has_value()) {
213 DepthAttachmentDescriptor depth = maybe_depth.value();
214 depth.depth_write_enabled = depth_write_enabled;
215 depth.depth_compare = depth_compare;
216 desc.SetDepthStencilAttachmentDescriptor(depth);
217 }
218
219 desc.SetPrimitiveType(primitive_type);
220
222}
static constexpr BlendMode kLastPipelineBlendMode
Definition: entity.h:22
#define FML_UNREACHABLE()
Definition: logging.h:109
#define FML_DCHECK(condition)
Definition: logging.h:103
@ 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:73

Member Data Documentation

◆ blend_mode

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

Definition at line 308 of file content_context.h.

◆ color_attachment_pixel_format

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

Definition at line 312 of file content_context.h.

◆ depth_compare

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

Definition at line 309 of file content_context.h.

◆ depth_write_enabled

bool impeller::ContentContextOptions::depth_write_enabled = false

Definition at line 314 of file content_context.h.

◆ has_depth_stencil_attachments

bool impeller::ContentContextOptions::has_depth_stencil_attachments = true

Definition at line 313 of file content_context.h.

◆ is_for_rrect_blur_clear

bool impeller::ContentContextOptions::is_for_rrect_blur_clear = false

Definition at line 316 of file content_context.h.

◆ primitive_type

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

Definition at line 311 of file content_context.h.

◆ sample_count

SampleCount impeller::ContentContextOptions::sample_count = SampleCount::kCount1

Definition at line 307 of file content_context.h.

◆ stencil_mode

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

Definition at line 310 of file content_context.h.

◆ wireframe

bool impeller::ContentContextOptions::wireframe = false

Definition at line 315 of file content_context.h.


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