Flutter Engine
 
Loading...
Searching...
No Matches
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::kSrcOver
 
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 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 40 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 41 of file content_context.h.

41 : uint8_t {
42 /// Turn the stencil test off. Used when drawing without stencil-then-cover
43 /// or overdraw prevention.
44 kIgnore,
45
46 // Operations used for stencil-then-cover.
47
48 /// Draw the stencil for the NonZero fill path rule.
49 ///
50 /// The stencil ref should always be 0 on commands using this mode.
52 /// Draw the stencil for the EvenOdd fill path rule.
53 ///
54 /// The stencil ref should always be 0 on commands using this mode.
56 /// Used for draw calls which fill in the stenciled area. Intended to be
57 /// used after `kStencilNonZeroFill` or `kStencilEvenOddFill` is used to set
58 /// up the stencil buffer. Also cleans up the stencil buffer by resetting
59 /// everything to zero.
60 ///
61 /// The stencil ref should always be 0 on commands using this mode.
63 /// The opposite of `kCoverCompare`. Used for draw calls which fill in the
64 /// non-stenciled area (intersection clips). Intended to be used after
65 /// `kStencilNonZeroFill` or `kStencilEvenOddFill` is used to set up the
66 /// stencil buffer. Also cleans up the stencil buffer by resetting
67 /// everything to zero.
68 ///
69 /// The stencil ref should always be 0 on commands using this mode.
71
72 // Operations used for the "overdraw prevention" mechanism. This is used for
73 // drawing strokes.
74
75 /// For each fragment, increment the stencil value if it's currently zero.
76 /// Discard fragments when the value is non-zero. This prevents
77 /// self-overlapping strokes from drawing over themselves.
78 ///
79 /// Note that this is done for rendering correctness, not performance. If a
80 /// stroke is drawn with a backdrop-reliant blend and self-intersects, then
81 /// the intersected geometry will render incorrectly when overdrawn because
82 /// we don't adjust the geometry prevent self-intersection.
83 ///
84 /// The stencil ref should always be 0 on commands using this mode.
86 /// Reset the stencil to a new maximum value specified by the ref (currently
87 /// always 0).
88 ///
89 /// The stencil ref should always be 0 on commands using this mode.
91 };

Member Function Documentation

◆ ApplyToPipelineDescriptor()

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

Definition at line 313 of file content_context.cc.

314 {
315 auto pipeline_blend = blend_mode;
317 VALIDATION_LOG << "Cannot use blend mode " << static_cast<int>(blend_mode)
318 << " as a pipeline blend.";
319 pipeline_blend = BlendMode::kSrcOver;
320 }
321
322 desc.SetSampleCount(sample_count);
323
324 ColorAttachmentDescriptor color0 = *desc.GetColorAttachmentDescriptor(0u);
325 color0.format = color_attachment_pixel_format;
326 color0.alpha_blend_op = BlendOperation::kAdd;
327 color0.color_blend_op = BlendOperation::kAdd;
328 color0.write_mask = ColorWriteMaskBits::kAll;
329
330 switch (pipeline_blend) {
333 color0.alpha_blend_op = BlendOperation::kReverseSubtract;
334 color0.color_blend_op = BlendOperation::kReverseSubtract;
335 color0.dst_alpha_blend_factor = BlendFactor::kOne;
336 color0.dst_color_blend_factor = BlendFactor::kOne;
337 color0.src_alpha_blend_factor = BlendFactor::kDestinationColor;
338 color0.src_color_blend_factor = BlendFactor::kDestinationColor;
339 } else {
340 color0.dst_alpha_blend_factor = BlendFactor::kZero;
341 color0.dst_color_blend_factor = BlendFactor::kZero;
342 color0.src_alpha_blend_factor = BlendFactor::kZero;
343 color0.src_color_blend_factor = BlendFactor::kZero;
344 }
345 break;
346 case BlendMode::kSrc:
347 color0.blending_enabled = false;
348 color0.dst_alpha_blend_factor = BlendFactor::kZero;
349 color0.dst_color_blend_factor = BlendFactor::kZero;
350 color0.src_alpha_blend_factor = BlendFactor::kOne;
351 color0.src_color_blend_factor = BlendFactor::kOne;
352 break;
353 case BlendMode::kDst:
354 color0.dst_alpha_blend_factor = BlendFactor::kOne;
355 color0.dst_color_blend_factor = BlendFactor::kOne;
356 color0.src_alpha_blend_factor = BlendFactor::kZero;
357 color0.src_color_blend_factor = BlendFactor::kZero;
358 color0.write_mask = ColorWriteMaskBits::kNone;
359 break;
361 color0.dst_alpha_blend_factor = BlendFactor::kOneMinusSourceAlpha;
362 color0.dst_color_blend_factor = BlendFactor::kOneMinusSourceAlpha;
363 color0.src_alpha_blend_factor = BlendFactor::kOne;
364 color0.src_color_blend_factor = BlendFactor::kOne;
365 break;
367 color0.dst_alpha_blend_factor = BlendFactor::kOne;
368 color0.dst_color_blend_factor = BlendFactor::kOne;
369 color0.src_alpha_blend_factor = BlendFactor::kOneMinusDestinationAlpha;
370 color0.src_color_blend_factor = BlendFactor::kOneMinusDestinationAlpha;
371 break;
373 color0.dst_alpha_blend_factor = BlendFactor::kZero;
374 color0.dst_color_blend_factor = BlendFactor::kZero;
375 color0.src_alpha_blend_factor = BlendFactor::kDestinationAlpha;
376 color0.src_color_blend_factor = BlendFactor::kDestinationAlpha;
377 break;
379 color0.dst_alpha_blend_factor = BlendFactor::kSourceAlpha;
380 color0.dst_color_blend_factor = BlendFactor::kSourceAlpha;
381 color0.src_alpha_blend_factor = BlendFactor::kZero;
382 color0.src_color_blend_factor = BlendFactor::kZero;
383 break;
385 color0.dst_alpha_blend_factor = BlendFactor::kZero;
386 color0.dst_color_blend_factor = BlendFactor::kZero;
387 color0.src_alpha_blend_factor = BlendFactor::kOneMinusDestinationAlpha;
388 color0.src_color_blend_factor = BlendFactor::kOneMinusDestinationAlpha;
389 break;
391 color0.dst_alpha_blend_factor = BlendFactor::kOneMinusSourceAlpha;
392 color0.dst_color_blend_factor = BlendFactor::kOneMinusSourceAlpha;
393 color0.src_alpha_blend_factor = BlendFactor::kZero;
394 color0.src_color_blend_factor = BlendFactor::kZero;
395 break;
397 color0.dst_alpha_blend_factor = BlendFactor::kOneMinusSourceAlpha;
398 color0.dst_color_blend_factor = BlendFactor::kOneMinusSourceAlpha;
399 color0.src_alpha_blend_factor = BlendFactor::kDestinationAlpha;
400 color0.src_color_blend_factor = BlendFactor::kDestinationAlpha;
401 break;
403 color0.dst_alpha_blend_factor = BlendFactor::kSourceAlpha;
404 color0.dst_color_blend_factor = BlendFactor::kSourceAlpha;
405 color0.src_alpha_blend_factor = BlendFactor::kOneMinusDestinationAlpha;
406 color0.src_color_blend_factor = BlendFactor::kOneMinusDestinationAlpha;
407 break;
408 case BlendMode::kXor:
409 color0.dst_alpha_blend_factor = BlendFactor::kOneMinusSourceAlpha;
410 color0.dst_color_blend_factor = BlendFactor::kOneMinusSourceAlpha;
411 color0.src_alpha_blend_factor = BlendFactor::kOneMinusDestinationAlpha;
412 color0.src_color_blend_factor = BlendFactor::kOneMinusDestinationAlpha;
413 break;
414 case BlendMode::kPlus:
415 color0.dst_alpha_blend_factor = BlendFactor::kOne;
416 color0.dst_color_blend_factor = BlendFactor::kOne;
417 color0.src_alpha_blend_factor = BlendFactor::kOne;
418 color0.src_color_blend_factor = BlendFactor::kOne;
419 break;
421 color0.dst_alpha_blend_factor = BlendFactor::kSourceAlpha;
422 color0.dst_color_blend_factor = BlendFactor::kSourceColor;
423 color0.src_alpha_blend_factor = BlendFactor::kZero;
424 color0.src_color_blend_factor = BlendFactor::kZero;
425 break;
426 default:
428 }
429 desc.SetColorAttachmentDescriptor(0u, color0);
430
432 desc.ClearDepthAttachment();
433 desc.ClearStencilAttachments();
434 }
435
436 auto maybe_stencil = desc.GetFrontStencilAttachmentDescriptor();
437 auto maybe_depth = desc.GetDepthStencilAttachmentDescriptor();
438 FML_DCHECK(has_depth_stencil_attachments == maybe_depth.has_value())
439 << "Depth attachment doesn't match expected pipeline state. "
440 "has_depth_stencil_attachments="
442 FML_DCHECK(has_depth_stencil_attachments == maybe_stencil.has_value())
443 << "Stencil attachment doesn't match expected pipeline state. "
444 "has_depth_stencil_attachments="
446 if (maybe_stencil.has_value()) {
447 StencilAttachmentDescriptor front_stencil = maybe_stencil.value();
448 StencilAttachmentDescriptor back_stencil = front_stencil;
449
450 switch (stencil_mode) {
452 front_stencil.stencil_compare = CompareFunction::kAlways;
453 front_stencil.depth_stencil_pass = StencilOperation::kKeep;
454 desc.SetStencilAttachmentDescriptors(front_stencil);
455 break;
457 // The stencil ref should be 0 on commands that use this mode.
458 front_stencil.stencil_compare = CompareFunction::kAlways;
459 front_stencil.depth_stencil_pass = StencilOperation::kIncrementWrap;
460 back_stencil.stencil_compare = CompareFunction::kAlways;
461 back_stencil.depth_stencil_pass = StencilOperation::kDecrementWrap;
462 desc.SetStencilAttachmentDescriptors(front_stencil, back_stencil);
463 break;
465 // The stencil ref should be 0 on commands that use this mode.
466 front_stencil.stencil_compare = CompareFunction::kEqual;
467 front_stencil.depth_stencil_pass = StencilOperation::kIncrementWrap;
468 front_stencil.stencil_failure = StencilOperation::kDecrementWrap;
469 desc.SetStencilAttachmentDescriptors(front_stencil);
470 break;
472 // The stencil ref should be 0 on commands that use this mode.
473 front_stencil.stencil_compare = CompareFunction::kNotEqual;
474 front_stencil.depth_stencil_pass =
476 desc.SetStencilAttachmentDescriptors(front_stencil);
477 break;
479 // The stencil ref should be 0 on commands that use this mode.
480 front_stencil.stencil_compare = CompareFunction::kEqual;
481 front_stencil.stencil_failure = StencilOperation::kSetToReferenceValue;
482 desc.SetStencilAttachmentDescriptors(front_stencil);
483 break;
485 front_stencil.stencil_compare = CompareFunction::kEqual;
486 front_stencil.depth_stencil_pass = StencilOperation::kIncrementClamp;
487 desc.SetStencilAttachmentDescriptors(front_stencil);
488 break;
490 front_stencil.stencil_compare = CompareFunction::kLess;
491 front_stencil.depth_stencil_pass =
493 desc.SetStencilAttachmentDescriptors(front_stencil);
494 break;
495 }
496 }
497 if (maybe_depth.has_value()) {
498 DepthAttachmentDescriptor depth = maybe_depth.value();
499 depth.depth_write_enabled = depth_write_enabled;
500 depth.depth_compare = depth_compare;
501 desc.SetDepthStencilAttachmentDescriptor(depth);
502 }
503
504 desc.SetPrimitiveType(primitive_type);
505 desc.SetPolygonMode(PolygonMode::kFill);
506}
static constexpr BlendMode kLastPipelineBlendMode
Definition entity.h:28
#define FML_UNREACHABLE()
Definition logging.h:128
#define FML_DCHECK(condition)
Definition logging.h:122
@ 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, FML_DCHECK, FML_UNREACHABLE, 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::kDestinationAlpha, impeller::kDestinationColor, impeller::kDst, impeller::kDstATop, impeller::kDstIn, impeller::kDstOut, impeller::kDstOver, impeller::kEqual, impeller::kFill, kIgnore, impeller::kIncrementClamp, impeller::kIncrementWrap, impeller::kKeep, impeller::Entity::kLastPipelineBlendMode, impeller::kLess, impeller::kModulate, impeller::kNone, impeller::kNotEqual, impeller::kOne, impeller::kOneMinusDestinationAlpha, impeller::kOneMinusSourceAlpha, kOverdrawPreventionIncrement, kOverdrawPreventionRestore, impeller::kPlus, impeller::kReverseSubtract, impeller::kSetToReferenceValue, impeller::kSourceAlpha, impeller::kSourceColor, impeller::kSrc, impeller::kSrcATop, impeller::kSrcIn, impeller::kSrcOut, impeller::kSrcOver, 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, and impeller::ColorAttachmentDescriptor::write_mask.

◆ ToKey()

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

Definition at line 103 of file content_context.h.

103 {
104 static_assert(sizeof(sample_count) == 1);
105 static_assert(sizeof(blend_mode) == 1);
106 static_assert(sizeof(sample_count) == 1);
107 static_assert(sizeof(depth_compare) == 1);
108 static_assert(sizeof(stencil_mode) == 1);
109 static_assert(sizeof(primitive_type) == 1);
110 static_assert(sizeof(color_attachment_pixel_format) == 1);
111
112 return (is_for_rrect_blur_clear ? 1llu : 0llu) << 0 |
113 (0) << 1 | // // Unused, previously wireframe.
114 (has_depth_stencil_attachments ? 1llu : 0llu) << 2 |
115 (depth_write_enabled ? 1llu : 0llu) << 3 |
116 // enums
117 static_cast<uint64_t>(color_attachment_pixel_format) << 8 |
118 static_cast<uint64_t>(primitive_type) << 16 |
119 static_cast<uint64_t>(stencil_mode) << 24 |
120 static_cast<uint64_t>(depth_compare) << 32 |
121 static_cast<uint64_t>(blend_mode) << 40 |
122 static_cast<uint64_t>(sample_count) << 48;
123 }

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, and stencil_mode.

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

Member Data Documentation

◆ blend_mode

BlendMode impeller::ContentContextOptions::blend_mode = BlendMode::kSrcOver

◆ 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 95 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 100 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

◆ sample_count

◆ stencil_mode

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

Definition at line 96 of file content_context.h.

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


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