Flutter Impeller
formats.h
Go to the documentation of this file.
1 // Copyright 2013 The Flutter Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef FLUTTER_IMPELLER_CORE_FORMATS_H_
6 #define FLUTTER_IMPELLER_CORE_FORMATS_H_
7 
8 #include <cstdint>
9 #include <functional>
10 #include <memory>
11 #include <string>
12 
13 #include "flutter/fml/hash_combine.h"
14 #include "flutter/fml/logging.h"
15 #include "impeller/base/mask.h"
17 #include "impeller/geometry/rect.h"
19 
20 namespace impeller {
21 
22 enum class WindingOrder {
23  kClockwise,
25 };
26 
27 class Texture;
28 
29 //------------------------------------------------------------------------------
30 /// @brief Specified where the allocation resides and how it is used.
31 ///
32 enum class StorageMode {
33  //----------------------------------------------------------------------------
34  /// Allocations can be mapped onto the hosts address space and also be used by
35  /// the device.
36  ///
38  //----------------------------------------------------------------------------
39  /// Allocations can only be used by the device. This location is optimal for
40  /// use by the device. If the host needs to access these allocations, the
41  /// transfer queue must be used to transfer this allocation onto the a host
42  /// visible buffer.
43  ///
45  //----------------------------------------------------------------------------
46  /// Used by the device for temporary render targets. These allocations cannot
47  /// be transferred from and to other allocations using the transfer queue.
48  /// Render pass cannot initialize the contents of these buffers using load and
49  /// store actions.
50  ///
51  /// These allocations reside in tile memory which has higher bandwidth, lower
52  /// latency and lower power consumption. The total device memory usage is
53  /// also lower as a separate allocation does not need to be created in
54  /// device memory. Prefer using these allocations for intermediates like depth
55  /// and stencil buffers.
56  ///
58 };
59 
60 constexpr const char* StorageModeToString(StorageMode mode) {
61  switch (mode) {
63  return "HostVisible";
65  return "DevicePrivate";
67  return "DeviceTransient";
68  }
69  FML_UNREACHABLE();
70 }
71 
72 //------------------------------------------------------------------------------
73 /// @brief The Pixel formats supported by Impeller. The naming convention
74 /// denotes the usage of the component, the bit width of that
75 /// component, and then one or more qualifiers to its
76 /// interpretation.
77 ///
78 /// For instance, `kR8G8B8A8UNormIntSRGB` is a 32 bits-per-pixel
79 /// format ordered in RGBA with 8 bits per component with each
80 /// component expressed as an unsigned normalized integer and a
81 /// conversion from sRGB to linear color space.
82 ///
83 /// Key:
84 /// R -> Red Component
85 /// G -> Green Component
86 /// B -> Blue Component
87 /// D -> Depth Component
88 /// S -> Stencil Component
89 /// U -> Unsigned (Lack of this denotes a signed component)
90 /// Norm -> Normalized
91 /// SRGB -> sRGB to linear interpretation
92 ///
93 /// While the effective bit width of the pixel can be determined by
94 /// adding up the widths of each component, only the non-esoteric
95 /// formats are tightly packed. Do not assume tight packing for the
96 /// esoteric formats and use blit passes to convert to a
97 /// non-esoteric pass.
98 ///
99 enum class PixelFormat : uint8_t {
100  kUnknown,
101  kA8UNormInt,
102  kR8UNormInt,
110  kB10G10R10XR,
113  kR32Float,
114  // Depth and stencil formats.
115  kS8UInt,
118 };
119 
120 constexpr bool IsDepthWritable(PixelFormat format) {
121  switch (format) {
124  return true;
125  default:
126  return false;
127  }
128 }
129 
130 constexpr bool IsStencilWritable(PixelFormat format) {
131  switch (format) {
135  return true;
136  default:
137  return false;
138  }
139 }
140 
141 constexpr const char* PixelFormatToString(PixelFormat format) {
142  switch (format) {
144  return "Unknown";
146  return "A8UNormInt";
148  return "R8UNormInt";
150  return "R8G8UNormInt";
152  return "R8G8B8A8UNormInt";
154  return "R8G8B8A8UNormIntSRGB";
156  return "B8G8R8A8UNormInt";
158  return "B8G8R8A8UNormIntSRGB";
160  return "R32G32B32A32Float";
162  return "R16G16B16A16Float";
164  return "B10G10R10XR";
166  return "B10G10R10XRSRGB";
168  return "B10G10R10A10XR";
170  return "S8UInt";
172  return "D24UnormS8Uint";
174  return "D32FloatS8UInt";
176  return "R32Float";
177  }
178  FML_UNREACHABLE();
179 }
180 
181 enum class BlendFactor {
182  kZero,
183  kOne,
184  kSourceColor,
186  kSourceAlpha,
193  kBlendColor,
195  kBlendAlpha,
197 };
198 
199 enum class BlendOperation {
200  kAdd,
201  kSubtract,
203 };
204 
205 enum class LoadAction {
206  kDontCare,
207  kLoad,
208  kClear,
209 };
210 
211 enum class StoreAction {
212  kDontCare,
213  kStore,
216 };
217 
218 constexpr const char* LoadActionToString(LoadAction action) {
219  switch (action) {
221  return "DontCare";
222  case LoadAction::kLoad:
223  return "Load";
224  case LoadAction::kClear:
225  return "Clear";
226  }
227 }
228 
229 constexpr const char* StoreActionToString(StoreAction action) {
230  switch (action) {
232  return "DontCare";
233  case StoreAction::kStore:
234  return "Store";
236  return "MultisampleResolve";
238  return "StoreAndMultisampleResolve";
239  }
240 }
241 
242 constexpr bool CanClearAttachment(LoadAction action) {
243  switch (action) {
244  case LoadAction::kLoad:
245  return false;
247  case LoadAction::kClear:
248  return true;
249  }
250  FML_UNREACHABLE();
251 }
252 
254  switch (action) {
255  case StoreAction::kStore:
257  return false;
260  return true;
261  }
262  FML_UNREACHABLE();
263 }
264 
265 enum class TextureType {
266  kTexture2D,
268  kTextureCube,
270 };
271 
272 constexpr const char* TextureTypeToString(TextureType type) {
273  switch (type) {
275  return "Texture2D";
277  return "Texture2DMultisample";
279  return "TextureCube";
281  return "TextureExternalOES";
282  }
283  FML_UNREACHABLE();
284 }
285 
287  switch (type) {
291  return false;
293  return true;
294  }
295  return false;
296 }
297 
298 enum class SampleCount : uint8_t {
299  kCount1 = 1,
300  kCount4 = 4,
301 };
302 
303 enum class TextureUsage {
304  kUnknown = 0,
305  kShaderRead = 1 << 0,
306  kShaderWrite = 1 << 1,
307  kRenderTarget = 1 << 2,
308 };
310 
312 
313 constexpr const char* TextureUsageToString(TextureUsage usage) {
314  switch (usage) {
316  return "Unknown";
318  return "ShaderRead";
320  return "ShaderWrite";
322  return "RenderTarget";
323  }
324  FML_UNREACHABLE();
325 }
326 
328 
329 // Texture coordinate system.
331  // Alternative coordinate system used when uploading texture data from the
332  // host.
333  // (0, 0) is the bottom-left of the image with +Y going up.
335  // Default coordinate system.
336  // (0, 0) is the top-left of the image with +Y going down.
338 };
339 
340 enum class CullMode {
341  kNone,
342  kFrontFace,
343  kBackFace,
344 };
345 
346 enum class IndexType : uint8_t {
347  kUnknown,
348  k16bit,
349  k32bit,
350  /// Does not use the index buffer.
351  kNone,
352 };
353 
354 /// Decides how backend draws pixels based on input vertices.
355 enum class PrimitiveType : uint8_t {
356  /// Draws a triangle for each separate set of three vertices.
357  ///
358  /// Vertices [A, B, C, D, E, F] will produce triangles
359  /// [ABC, DEF].
360  kTriangle,
361 
362  /// Draws a triangle for every adjacent three vertices.
363  ///
364  /// Vertices [A, B, C, D, E, F] will produce triangles
365  /// [ABC, BCD, CDE, DEF].
367 
368  /// Draws a line for each separate set of two vertices.
369  ///
370  /// Vertices [A, B, C] will produce discontinued line
371  /// [AB, BC].
372  kLine,
373 
374  /// Draws a continuous line that connect every input vertices
375  ///
376  /// Vertices [A, B, C] will produce one continuous line
377  /// [ABC].
378  kLineStrip,
379 
380  /// Draws a point at each input vertex.
381  kPoint,
382 
383  /// Draws a triangle for every two vertices, after the first.
384  ///
385  /// The first vertex acts as the hub, all following vertices connect with
386  /// this hub to "fan" out from the first vertex.
387  ///
388  /// Triangle fans are not supported in Metal and need a capability check.
389  kTriangleFan,
390 };
391 
392 enum class PolygonMode {
393  kFill,
394  kLine,
395 };
396 
397 struct DepthRange {
398  Scalar z_near = 0.0;
399  Scalar z_far = 1.0;
400 
401  constexpr bool operator==(const DepthRange& other) const {
402  return z_near == other.z_near && z_far == other.z_far;
403  }
404 };
405 
406 struct Viewport {
409 
410  constexpr bool operator==(const Viewport& other) const {
411  return rect == other.rect && depth_range == other.depth_range;
412  }
413 };
414 
415 /// @brief Describes how the texture should be sampled when the texture
416 /// is being shrunk (minified) or expanded (magnified) to fit to
417 /// the sample point.
418 enum class MinMagFilter : uint8_t {
419  /// Select nearest to the sample point. Most widely supported.
420  kNearest,
421 
422  /// Select two points and linearly interpolate between them. Some formats
423  /// may not support this.
424  kLinear,
425 };
426 
427 /// @brief Options for selecting and filtering between mipmap levels.
428 enum class MipFilter : uint8_t {
429  /// @brief The texture is sampled as if it only had a single mipmap level.
430  ///
431  /// All samples are read from level 0.
432  kBase,
433 
434  /// @brief The nearst mipmap level is selected.
435  kNearest,
436 
437  /// @brief Sample from the two nearest mip levels and linearly interpolate.
438  ///
439  /// If the filter falls between levels, both levels are sampled, and
440  /// their results linearly interpolated between levels.
441  kLinear,
442 };
443 
444 enum class SamplerAddressMode : uint8_t {
445  kClampToEdge,
446  kRepeat,
447  kMirror,
448  // More modes are almost always supported but they are usually behind
449  // extensions checks. The ones current in these structs are safe (always
450  // supported) defaults.
451 
452  /// @brief decal sampling mode is only supported on devices that pass
453  /// the `Capabilities.SupportsDecalSamplerAddressMode` check.
454  kDecal,
455 };
456 
457 enum class ColorWriteMaskBits : uint64_t {
458  kNone = 0,
459  kRed = 1 << 0,
460  kGreen = 1 << 1,
461  kBlue = 1 << 2,
462  kAlpha = 1 << 3,
463  kAll = kRed | kGreen | kBlue | kAlpha,
464 };
466 
468 
469 constexpr size_t BytesPerPixelForPixelFormat(PixelFormat format) {
470  switch (format) {
472  return 0u;
476  return 1u;
478  return 2u;
486  return 4u;
488  return 4u;
490  return 5u;
493  return 8u;
495  return 16u;
496  }
497  return 0u;
498 }
499 
500 //------------------------------------------------------------------------------
501 /// @brief Describe the color attachment that will be used with this
502 /// pipeline.
503 ///
504 /// Blending at specific color attachments follows the pseudo-code:
505 /// ```
506 /// if (blending_enabled) {
507 /// final_color.rgb = (src_color_blend_factor * new_color.rgb)
508 /// <color_blend_op>
509 /// (dst_color_blend_factor * old_color.rgb);
510 /// final_color.a = (src_alpha_blend_factor * new_color.a)
511 /// <alpha_blend_op>
512 /// (dst_alpha_blend_factor * old_color.a);
513 /// } else {
514 /// final_color = new_color;
515 /// }
516 /// // IMPORTANT: The write mask is applied irrespective of whether
517 /// // blending_enabled is set.
518 /// final_color = final_color & write_mask;
519 /// ```
520 ///
521 /// The default blend mode is 1 - source alpha.
524  bool blending_enabled = false;
525 
529 
533 
535 
536  constexpr bool operator==(const ColorAttachmentDescriptor& o) const {
537  return format == o.format && //
540  color_blend_op == o.color_blend_op && //
543  alpha_blend_op == o.alpha_blend_op && //
545  write_mask == o.write_mask;
546  }
547 
548  constexpr size_t Hash() const {
549  return fml::HashCombine(
552  dst_alpha_blend_factor, static_cast<uint64_t>(write_mask));
553  }
554 };
555 
556 enum class CompareFunction : uint8_t {
557  /// Comparison test never passes.
558  kNever,
559  /// Comparison test passes always passes.
560  kAlways,
561  /// Comparison test passes if new_value < current_value.
562  kLess,
563  /// Comparison test passes if new_value == current_value.
564  kEqual,
565  /// Comparison test passes if new_value <= current_value.
566  kLessEqual,
567  /// Comparison test passes if new_value > current_value.
568  kGreater,
569  /// Comparison test passes if new_value != current_value.
570  kNotEqual,
571  /// Comparison test passes if new_value >= current_value.
573 };
574 
575 enum class StencilOperation : uint8_t {
576  /// Don't modify the current stencil value.
577  kKeep,
578  /// Reset the stencil value to zero.
579  kZero,
580  /// Reset the stencil value to the reference value.
582  /// Increment the current stencil value by 1. Clamp it to the maximum.
584  /// Decrement the current stencil value by 1. Clamp it to zero.
586  /// Perform a logical bitwise invert on the current stencil value.
587  kInvert,
588  /// Increment the current stencil value by 1. If at maximum, set to zero.
590  /// Decrement the current stencil value by 1. If at zero, set to maximum.
592 };
593 
595  //----------------------------------------------------------------------------
596  /// Indicates how to compare the value with that in the depth buffer.
597  ///
599  //----------------------------------------------------------------------------
600  /// Indicates when writes must be performed to the depth buffer.
601  ///
602  bool depth_write_enabled = false;
603 
604  constexpr bool operator==(const DepthAttachmentDescriptor& o) const {
605  return depth_compare == o.depth_compare &&
607  }
608 
609  constexpr size_t GetHash() const {
610  return fml::HashCombine(depth_compare, depth_write_enabled);
611  }
612 };
613 
615  //----------------------------------------------------------------------------
616  /// Indicates the operation to perform between the reference value and the
617  /// value in the stencil buffer. Both values have the read_mask applied to
618  /// them before performing this operation.
619  ///
621  //----------------------------------------------------------------------------
622  /// Indicates what to do when the stencil test has failed.
623  ///
625  //----------------------------------------------------------------------------
626  /// Indicates what to do when the stencil test passes but the depth test
627  /// fails.
628  ///
630  //----------------------------------------------------------------------------
631  /// Indicates what to do when both the stencil and depth tests pass.
632  ///
634 
635  //----------------------------------------------------------------------------
636  /// The mask applied to the reference and stencil buffer values before
637  /// performing the stencil_compare operation.
638  ///
639  uint32_t read_mask = ~0;
640  //----------------------------------------------------------------------------
641  /// The mask applied to the new stencil value before it is written into the
642  /// stencil buffer.
643  ///
644  uint32_t write_mask = ~0;
645 
646  constexpr bool operator==(const StencilAttachmentDescriptor& o) const {
647  return stencil_compare == o.stencil_compare &&
652  }
653 
654  constexpr size_t GetHash() const {
655  return fml::HashCombine(stencil_compare, stencil_failure, depth_failure,
657  }
658 };
659 
660 struct Attachment {
661  std::shared_ptr<Texture> texture;
662  std::shared_ptr<Texture> resolve_texture;
665 
666  bool IsValid() const;
667 };
668 
669 struct ColorAttachment : public Attachment {
671 };
672 
673 struct DepthAttachment : public Attachment {
674  double clear_depth = 0.0;
675 };
676 
677 struct StencilAttachment : public Attachment {
678  uint32_t clear_stencil = 0;
679 };
680 
681 std::string AttachmentToString(const Attachment& attachment);
682 
683 std::string ColorAttachmentToString(const ColorAttachment& color);
684 
685 std::string DepthAttachmentToString(const DepthAttachment& depth);
686 
687 std::string StencilAttachmentToString(const StencilAttachment& stencil);
688 
689 } // namespace impeller
690 
691 namespace std {
692 
693 template <>
694 struct hash<impeller::DepthAttachmentDescriptor> {
695  constexpr std::size_t operator()(
696  const impeller::DepthAttachmentDescriptor& des) const {
697  return des.GetHash();
698  }
699 };
700 
701 template <>
702 struct hash<impeller::StencilAttachmentDescriptor> {
703  constexpr std::size_t operator()(
704  const impeller::StencilAttachmentDescriptor& des) const {
705  return des.GetHash();
706  }
707 };
708 
709 } // namespace std
710 
711 #endif // FLUTTER_IMPELLER_CORE_FORMATS_H_
GLenum type
constexpr size_t BytesPerPixelForPixelFormat(PixelFormat format)
Definition: formats.h:469
constexpr bool CanClearAttachment(LoadAction action)
Definition: formats.h:242
std::string DepthAttachmentToString(const DepthAttachment &depth)
Definition: formats.cc:130
std::string ColorAttachmentToString(const ColorAttachment &color)
Definition: formats.cc:123
BlendFactor
Definition: formats.h:181
constexpr const char * LoadActionToString(LoadAction action)
Definition: formats.h:218
PrimitiveType
Decides how backend draws pixels based on input vertices.
Definition: formats.h:355
@ kPoint
Draws a point at each input vertex.
float Scalar
Definition: scalar.h:19
@ kNone
Does not use the index buffer.
SamplerAddressMode
Definition: formats.h:444
@ kDecal
decal sampling mode is only supported on devices that pass the Capabilities.SupportsDecalSamplerAddre...
constexpr bool IsDepthWritable(PixelFormat format)
Definition: formats.h:120
std::string StencilAttachmentToString(const StencilAttachment &stencil)
Definition: formats.cc:137
std::string TextureUsageMaskToString(TextureUsageMask mask)
Definition: formats.cc:81
StorageMode
Specified where the allocation resides and how it is used.
Definition: formats.h:32
std::string AttachmentToString(const Attachment &attachment)
Definition: formats.cc:104
PixelFormat
The Pixel formats supported by Impeller. The naming convention denotes the usage of the component,...
Definition: formats.h:99
constexpr const char * TextureTypeToString(TextureType type)
Definition: formats.h:272
CompareFunction
Definition: formats.h:556
@ kEqual
Comparison test passes if new_value == current_value.
@ kLessEqual
Comparison test passes if new_value <= current_value.
@ kGreaterEqual
Comparison test passes if new_value >= current_value.
@ kAlways
Comparison test passes always passes.
@ kLess
Comparison test passes if new_value < current_value.
@ kGreater
Comparison test passes if new_value > current_value.
@ kNotEqual
Comparison test passes if new_value != current_value.
@ kNever
Comparison test never passes.
constexpr const char * TextureUsageToString(TextureUsage usage)
Definition: formats.h:313
MipFilter
Options for selecting and filtering between mipmap levels.
Definition: formats.h:428
@ kLinear
Sample from the two nearest mip levels and linearly interpolate.
@ kBase
The texture is sampled as if it only had a single mipmap level.
@ kNearest
The nearst mipmap level is selected.
StencilOperation
Definition: formats.h:575
@ kDecrementWrap
Decrement the current stencil value by 1. If at zero, set to maximum.
@ kSetToReferenceValue
Reset the stencil value to the reference value.
@ kDecrementClamp
Decrement the current stencil value by 1. Clamp it to zero.
@ kZero
Reset the stencil value to zero.
@ 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.
@ kInvert
Perform a logical bitwise invert on the current stencil value.
@ kKeep
Don't modify the current stencil value.
TextureType
Definition: formats.h:265
TextureCoordinateSystem
Definition: formats.h:330
WindingOrder
Definition: formats.h:22
IMPELLER_ENUM_IS_MASK(MyMaskBits)
LoadAction
Definition: formats.h:205
StoreAction
Definition: formats.h:211
constexpr bool IsStencilWritable(PixelFormat format)
Definition: formats.h:130
PolygonMode
Definition: formats.h:392
constexpr const char * StoreActionToString(StoreAction action)
Definition: formats.h:229
constexpr const char * PixelFormatToString(PixelFormat format)
Definition: formats.h:141
constexpr const char * StorageModeToString(StorageMode mode)
Definition: formats.h:60
constexpr bool IsMultisampleCapable(TextureType type)
Definition: formats.h:286
MinMagFilter
Describes how the texture should be sampled when the texture is being shrunk (minified) or expanded (...
Definition: formats.h:418
@ kNearest
Select nearest to the sample point. Most widely supported.
ColorWriteMaskBits
Definition: formats.h:457
Mask< TextureUsage > TextureUsageMask
Definition: formats.h:311
BlendOperation
Definition: formats.h:199
TextureUsage
Definition: formats.h:303
SampleCount
Definition: formats.h:298
constexpr bool CanDiscardAttachmentWhenDone(StoreAction action)
Definition: formats.h:253
Definition: comparable.h:95
std::shared_ptr< Texture > resolve_texture
Definition: formats.h:662
bool IsValid() const
Definition: formats.cc:26
LoadAction load_action
Definition: formats.h:663
std::shared_ptr< Texture > texture
Definition: formats.h:661
StoreAction store_action
Definition: formats.h:664
Describe the color attachment that will be used with this pipeline.
Definition: formats.h:522
constexpr size_t Hash() const
Definition: formats.h:548
constexpr bool operator==(const ColorAttachmentDescriptor &o) const
Definition: formats.h:536
static constexpr Color BlackTransparent()
Definition: color.h:270
constexpr bool operator==(const DepthAttachmentDescriptor &o) const
Definition: formats.h:604
constexpr size_t GetHash() const
Definition: formats.h:609
constexpr bool operator==(const DepthRange &other) const
Definition: formats.h:401
constexpr bool operator==(const StencilAttachmentDescriptor &o) const
Definition: formats.h:646
constexpr size_t GetHash() const
Definition: formats.h:654
StencilOperation depth_stencil_pass
Definition: formats.h:633
constexpr bool operator==(const Viewport &other) const
Definition: formats.h:410
DepthRange depth_range
Definition: formats.h:408
constexpr std::size_t operator()(const impeller::DepthAttachmentDescriptor &des) const
Definition: formats.h:695
constexpr std::size_t operator()(const impeller::StencilAttachmentDescriptor &des) const
Definition: formats.h:703