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

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

Member Function Documentation

◆ ApplyToPipelineDescriptor()

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

Definition at line 320 of file content_context.cc.

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

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

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 79 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 84 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 80 of file content_context.h.

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


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