Flutter Impeller
impeller::ContentContextOptions Struct Reference

#include <content_context.h>

Public Types

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

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

Member Enumeration Documentation

◆ StencilMode

Enumerator
kIgnore 

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

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. 
kStencilIncrementAll 

Draw a stencil which always increments once for everything in the vertex coverage regardless of triangle overlap.

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.

Definition at line 42 of file content_context.h.

42  : uint8_t {
43  /// Turn the stencil test off. Used when drawing without stencil-then-cover.
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.
51  kStencilNonZeroFill,
52  /// Draw the stencil for the EvenOdd fill path rule.
53  ///
54  /// The stencil ref should always be 0 on commands using this mode.
55  kStencilEvenOddFill,
56  /// Draw a stencil which always increments once for everything in the vertex
57  /// coverage regardless of triangle overlap.
58  ///
59  /// The stencil ref should always be 0 on commands using this mode.
60  kStencilIncrementAll,
61  /// Used for draw calls which fill in the stenciled area. Intended to be
62  /// used after `kStencilNonZeroFill` or `kStencilEvenOddFill` is used to set
63  /// up the stencil buffer. Also cleans up the stencil buffer by resetting
64  /// everything to zero.
65  ///
66  /// The stencil ref should always be 0 on commands using this mode.
67  kCoverCompare,
68  /// The opposite of `kCoverCompare`. Used for draw calls which fill in the
69  /// non-stenciled area (intersection clips). Intended to be used after
70  /// `kStencilNonZeroFill` or `kStencilEvenOddFill` is used to set up the
71  /// stencil buffer. Also cleans up the stencil buffer by resetting
72  /// everything to zero.
73  ///
74  /// The stencil ref should always be 0 on commands using this mode.
75  kCoverCompareInverted,
76  };

Member Function Documentation

◆ ApplyToPipelineDescriptor()

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

Definition at line 323 of file content_context.cc.

324  {
325  auto pipeline_blend = blend_mode;
327  VALIDATION_LOG << "Cannot use blend mode " << static_cast<int>(blend_mode)
328  << " as a pipeline blend.";
329  pipeline_blend = BlendMode::kSrcOver;
330  }
331 
332  desc.SetSampleCount(sample_count);
333 
334  ColorAttachmentDescriptor color0 = *desc.GetColorAttachmentDescriptor(0u);
335  color0.format = color_attachment_pixel_format;
336  color0.alpha_blend_op = BlendOperation::kAdd;
337  color0.color_blend_op = BlendOperation::kAdd;
338  color0.write_mask = ColorWriteMaskBits::kAll;
339 
340  switch (pipeline_blend) {
341  case BlendMode::kClear:
343  color0.alpha_blend_op = BlendOperation::kReverseSubtract;
344  color0.color_blend_op = BlendOperation::kReverseSubtract;
345  color0.dst_alpha_blend_factor = BlendFactor::kOne;
346  color0.dst_color_blend_factor = BlendFactor::kOne;
347  color0.src_alpha_blend_factor = BlendFactor::kDestinationColor;
348  color0.src_color_blend_factor = BlendFactor::kDestinationColor;
349  } else {
350  color0.dst_alpha_blend_factor = BlendFactor::kZero;
351  color0.dst_color_blend_factor = BlendFactor::kZero;
352  color0.src_alpha_blend_factor = BlendFactor::kZero;
353  color0.src_color_blend_factor = BlendFactor::kZero;
354  }
355  break;
356  case BlendMode::kSrc:
357  color0.blending_enabled = false;
358  color0.dst_alpha_blend_factor = BlendFactor::kZero;
359  color0.dst_color_blend_factor = BlendFactor::kZero;
360  color0.src_alpha_blend_factor = BlendFactor::kOne;
361  color0.src_color_blend_factor = BlendFactor::kOne;
362  break;
363  case BlendMode::kDst:
364  color0.dst_alpha_blend_factor = BlendFactor::kOne;
365  color0.dst_color_blend_factor = BlendFactor::kOne;
366  color0.src_alpha_blend_factor = BlendFactor::kZero;
367  color0.src_color_blend_factor = BlendFactor::kZero;
368  color0.write_mask = ColorWriteMaskBits::kNone;
369  break;
370  case BlendMode::kSrcOver:
371  color0.dst_alpha_blend_factor = BlendFactor::kOneMinusSourceAlpha;
372  color0.dst_color_blend_factor = BlendFactor::kOneMinusSourceAlpha;
373  color0.src_alpha_blend_factor = BlendFactor::kOne;
374  color0.src_color_blend_factor = BlendFactor::kOne;
375  break;
376  case BlendMode::kDstOver:
377  color0.dst_alpha_blend_factor = BlendFactor::kOne;
378  color0.dst_color_blend_factor = BlendFactor::kOne;
379  color0.src_alpha_blend_factor = BlendFactor::kOneMinusDestinationAlpha;
380  color0.src_color_blend_factor = BlendFactor::kOneMinusDestinationAlpha;
381  break;
382  case BlendMode::kSrcIn:
383  color0.dst_alpha_blend_factor = BlendFactor::kZero;
384  color0.dst_color_blend_factor = BlendFactor::kZero;
385  color0.src_alpha_blend_factor = BlendFactor::kDestinationAlpha;
386  color0.src_color_blend_factor = BlendFactor::kDestinationAlpha;
387  break;
388  case BlendMode::kDstIn:
389  color0.dst_alpha_blend_factor = BlendFactor::kSourceAlpha;
390  color0.dst_color_blend_factor = BlendFactor::kSourceAlpha;
391  color0.src_alpha_blend_factor = BlendFactor::kZero;
392  color0.src_color_blend_factor = BlendFactor::kZero;
393  break;
394  case BlendMode::kSrcOut:
395  color0.dst_alpha_blend_factor = BlendFactor::kZero;
396  color0.dst_color_blend_factor = BlendFactor::kZero;
397  color0.src_alpha_blend_factor = BlendFactor::kOneMinusDestinationAlpha;
398  color0.src_color_blend_factor = BlendFactor::kOneMinusDestinationAlpha;
399  break;
400  case BlendMode::kDstOut:
401  color0.dst_alpha_blend_factor = BlendFactor::kOneMinusSourceAlpha;
402  color0.dst_color_blend_factor = BlendFactor::kOneMinusSourceAlpha;
403  color0.src_alpha_blend_factor = BlendFactor::kZero;
404  color0.src_color_blend_factor = BlendFactor::kZero;
405  break;
406  case BlendMode::kSrcATop:
407  color0.dst_alpha_blend_factor = BlendFactor::kOneMinusSourceAlpha;
408  color0.dst_color_blend_factor = BlendFactor::kOneMinusSourceAlpha;
409  color0.src_alpha_blend_factor = BlendFactor::kDestinationAlpha;
410  color0.src_color_blend_factor = BlendFactor::kDestinationAlpha;
411  break;
412  case BlendMode::kDstATop:
413  color0.dst_alpha_blend_factor = BlendFactor::kSourceAlpha;
414  color0.dst_color_blend_factor = BlendFactor::kSourceAlpha;
415  color0.src_alpha_blend_factor = BlendFactor::kOneMinusDestinationAlpha;
416  color0.src_color_blend_factor = BlendFactor::kOneMinusDestinationAlpha;
417  break;
418  case BlendMode::kXor:
419  color0.dst_alpha_blend_factor = BlendFactor::kOneMinusSourceAlpha;
420  color0.dst_color_blend_factor = BlendFactor::kOneMinusSourceAlpha;
421  color0.src_alpha_blend_factor = BlendFactor::kOneMinusDestinationAlpha;
422  color0.src_color_blend_factor = BlendFactor::kOneMinusDestinationAlpha;
423  break;
424  case BlendMode::kPlus:
425  color0.dst_alpha_blend_factor = BlendFactor::kOne;
426  color0.dst_color_blend_factor = BlendFactor::kOne;
427  color0.src_alpha_blend_factor = BlendFactor::kOne;
428  color0.src_color_blend_factor = BlendFactor::kOne;
429  break;
431  color0.dst_alpha_blend_factor = BlendFactor::kSourceAlpha;
432  color0.dst_color_blend_factor = BlendFactor::kSourceColor;
433  color0.src_alpha_blend_factor = BlendFactor::kZero;
434  color0.src_color_blend_factor = BlendFactor::kZero;
435  break;
436  default:
437  FML_UNREACHABLE();
438  }
439  desc.SetColorAttachmentDescriptor(0u, color0);
440 
442  desc.ClearDepthAttachment();
443  desc.ClearStencilAttachments();
444  }
445 
446  auto maybe_stencil = desc.GetFrontStencilAttachmentDescriptor();
447  auto maybe_depth = desc.GetDepthStencilAttachmentDescriptor();
448  FML_DCHECK(has_depth_stencil_attachments == maybe_depth.has_value())
449  << "Depth attachment doesn't match expected pipeline state. "
450  "has_depth_stencil_attachments="
452  FML_DCHECK(has_depth_stencil_attachments == maybe_stencil.has_value())
453  << "Stencil attachment doesn't match expected pipeline state. "
454  "has_depth_stencil_attachments="
456  if (maybe_stencil.has_value()) {
457  StencilAttachmentDescriptor front_stencil = maybe_stencil.value();
458  StencilAttachmentDescriptor back_stencil = front_stencil;
459 
460  switch (stencil_mode) {
462  front_stencil.stencil_compare = CompareFunction::kAlways;
463  front_stencil.depth_stencil_pass = StencilOperation::kKeep;
464  desc.SetStencilAttachmentDescriptors(front_stencil);
465  break;
467  // The stencil ref should be 0 on commands that use this mode.
468  front_stencil.stencil_compare = CompareFunction::kAlways;
469  front_stencil.depth_stencil_pass = StencilOperation::kIncrementWrap;
470  back_stencil.stencil_compare = CompareFunction::kAlways;
471  back_stencil.depth_stencil_pass = StencilOperation::kDecrementWrap;
472  desc.SetStencilAttachmentDescriptors(front_stencil, back_stencil);
473  break;
475  // The stencil ref should be 0 on commands that use this mode.
476  front_stencil.stencil_compare = CompareFunction::kEqual;
477  front_stencil.depth_stencil_pass = StencilOperation::kIncrementWrap;
478  front_stencil.stencil_failure = StencilOperation::kDecrementWrap;
479  desc.SetStencilAttachmentDescriptors(front_stencil);
480  break;
482  // The stencil ref should be 0 on commands that use this mode.
483  front_stencil.stencil_compare = CompareFunction::kEqual;
484  front_stencil.depth_stencil_pass = StencilOperation::kIncrementWrap;
485  desc.SetStencilAttachmentDescriptors(front_stencil);
486  break;
488  // The stencil ref should be 0 on commands that use this mode.
489  front_stencil.stencil_compare = CompareFunction::kNotEqual;
490  front_stencil.depth_stencil_pass =
492  desc.SetStencilAttachmentDescriptors(front_stencil);
493  break;
495  // The stencil ref should be 0 on commands that use this mode.
496  front_stencil.stencil_compare = CompareFunction::kEqual;
497  front_stencil.stencil_failure = StencilOperation::kSetToReferenceValue;
498  desc.SetStencilAttachmentDescriptors(front_stencil);
499  break;
500  }
501  }
502  if (maybe_depth.has_value()) {
503  DepthAttachmentDescriptor depth = maybe_depth.value();
504  depth.depth_write_enabled = depth_write_enabled;
505  depth.depth_compare = depth_compare;
506  desc.SetDepthStencilAttachmentDescriptor(depth);
507  }
508 
509  desc.SetPrimitiveType(primitive_type);
510  desc.SetPolygonMode(PolygonMode::kFill);
511 }
static constexpr BlendMode kLastPipelineBlendMode
Definition: entity.h:28
@ kEqual
Comparison test passes if new_value == current_value.
@ kAlways
Comparison test passes always passes.
@ 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.
@ kIncrementWrap
Increment the current stencil value by 1. If at maximum, set to zero.
@ kKeep
Don't modify the current stencil value.
@ kIgnore
Turn the stencil test off. Used when drawing without stencil-then-cover.
#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::kDestinationAlpha, impeller::kDestinationColor, impeller::kDst, impeller::kDstATop, impeller::kDstIn, impeller::kDstOut, impeller::kDstOver, impeller::kEqual, impeller::kFill, kIgnore, impeller::kIncrementWrap, impeller::kKeep, impeller::Entity::kLastPipelineBlendMode, impeller::kModulate, impeller::kNone, impeller::kNotEqual, impeller::kOne, impeller::kOneMinusDestinationAlpha, impeller::kOneMinusSourceAlpha, impeller::kPlus, impeller::kReverseSubtract, impeller::kSetToReferenceValue, impeller::kSourceAlpha, impeller::kSourceColor, impeller::kSrc, impeller::kSrcATop, impeller::kSrcIn, impeller::kSrcOut, impeller::kSrcOver, kStencilEvenOddFill, kStencilIncrementAll, 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 88 of file content_context.h.

88  {
89  static_assert(sizeof(sample_count) == 1);
90  static_assert(sizeof(blend_mode) == 1);
91  static_assert(sizeof(sample_count) == 1);
92  static_assert(sizeof(depth_compare) == 1);
93  static_assert(sizeof(stencil_mode) == 1);
94  static_assert(sizeof(primitive_type) == 1);
95  static_assert(sizeof(color_attachment_pixel_format) == 1);
96 
97  return (is_for_rrect_blur_clear ? 1llu : 0llu) << 0 |
98  (0) << 1 | // // Unused, previously wireframe.
99  (has_depth_stencil_attachments ? 1llu : 0llu) << 2 |
100  (depth_write_enabled ? 1llu : 0llu) << 3 |
101  // enums
102  static_cast<uint64_t>(color_attachment_pixel_format) << 8 |
103  static_cast<uint64_t>(primitive_type) << 16 |
104  static_cast<uint64_t>(stencil_mode) << 24 |
105  static_cast<uint64_t>(depth_compare) << 32 |
106  static_cast<uint64_t>(blend_mode) << 40 |
107  static_cast<uint64_t>(sample_count) << 48;
108  }

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 80 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 85 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 81 of file content_context.h.

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


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