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  // Depth and stencil formats.
114  kS8UInt,
117 };
118 
119 constexpr bool IsDepthWritable(PixelFormat format) {
120  switch (format) {
123  return true;
124  default:
125  return false;
126  }
127 }
128 
129 constexpr bool IsStencilWritable(PixelFormat format) {
130  switch (format) {
134  return true;
135  default:
136  return false;
137  }
138 }
139 
140 constexpr const char* PixelFormatToString(PixelFormat format) {
141  switch (format) {
143  return "Unknown";
145  return "A8UNormInt";
147  return "R8UNormInt";
149  return "R8G8UNormInt";
151  return "R8G8B8A8UNormInt";
153  return "R8G8B8A8UNormIntSRGB";
155  return "B8G8R8A8UNormInt";
157  return "B8G8R8A8UNormIntSRGB";
159  return "R32G32B32A32Float";
161  return "R16G16B16A16Float";
163  return "B10G10R10XR";
165  return "B10G10R10XRSRGB";
167  return "B10G10R10A10XR";
169  return "S8UInt";
171  return "D24UnormS8Uint";
173  return "D32FloatS8UInt";
174  }
175  FML_UNREACHABLE();
176 }
177 
178 enum class BlendFactor {
179  kZero,
180  kOne,
181  kSourceColor,
183  kSourceAlpha,
190  kBlendColor,
192  kBlendAlpha,
194 };
195 
196 enum class BlendOperation {
197  kAdd,
198  kSubtract,
200 };
201 
202 enum class LoadAction {
203  kDontCare,
204  kLoad,
205  kClear,
206 };
207 
208 enum class StoreAction {
209  kDontCare,
210  kStore,
213 };
214 
215 constexpr const char* LoadActionToString(LoadAction action) {
216  switch (action) {
218  return "DontCare";
219  case LoadAction::kLoad:
220  return "Load";
221  case LoadAction::kClear:
222  return "Clear";
223  }
224 }
225 
226 constexpr const char* StoreActionToString(StoreAction action) {
227  switch (action) {
229  return "DontCare";
230  case StoreAction::kStore:
231  return "Store";
233  return "MultisampleResolve";
235  return "StoreAndMultisampleResolve";
236  }
237 }
238 
239 constexpr bool CanClearAttachment(LoadAction action) {
240  switch (action) {
241  case LoadAction::kLoad:
242  return false;
244  case LoadAction::kClear:
245  return true;
246  }
247  FML_UNREACHABLE();
248 }
249 
251  switch (action) {
252  case StoreAction::kStore:
254  return false;
257  return true;
258  }
259  FML_UNREACHABLE();
260 }
261 
262 enum class TextureType {
263  kTexture2D,
265  kTextureCube,
267 };
268 
269 constexpr const char* TextureTypeToString(TextureType type) {
270  switch (type) {
272  return "Texture2D";
274  return "Texture2DMultisample";
276  return "TextureCube";
278  return "TextureExternalOES";
279  }
280  FML_UNREACHABLE();
281 }
282 
284  switch (type) {
288  return false;
290  return true;
291  }
292  return false;
293 }
294 
295 enum class SampleCount : uint8_t {
296  kCount1 = 1,
297  kCount4 = 4,
298 };
299 
300 enum class TextureUsage {
301  kUnknown = 0,
302  kShaderRead = 1 << 0,
303  kShaderWrite = 1 << 1,
304  kRenderTarget = 1 << 2,
305 };
307 
309 
310 constexpr const char* TextureUsageToString(TextureUsage usage) {
311  switch (usage) {
313  return "Unknown";
315  return "ShaderRead";
317  return "ShaderWrite";
319  return "RenderTarget";
320  }
321  FML_UNREACHABLE();
322 }
323 
325 
326 // Texture coordinate system.
328  // Alternative coordinate system used when uploading texture data from the
329  // host.
330  // (0, 0) is the bottom-left of the image with +Y going up.
332  // Default coordinate system.
333  // (0, 0) is the top-left of the image with +Y going down.
335 };
336 
337 enum class CullMode {
338  kNone,
339  kFrontFace,
340  kBackFace,
341 };
342 
343 enum class IndexType {
344  kUnknown,
345  k16bit,
346  k32bit,
347  /// Does not use the index buffer.
348  kNone,
349 };
350 
351 /// Decides how backend draws pixels based on input vertices.
352 enum class PrimitiveType : uint8_t {
353  /// Draws a triangle for each separate set of three vertices.
354  ///
355  /// Vertices [A, B, C, D, E, F] will produce triangles
356  /// [ABC, DEF].
357  kTriangle,
358 
359  /// Draws a triangle for every adjacent three vertices.
360  ///
361  /// Vertices [A, B, C, D, E, F] will produce triangles
362  /// [ABC, BCD, CDE, DEF].
364 
365  /// Draws a line for each separate set of two vertices.
366  ///
367  /// Vertices [A, B, C] will produce discontinued line
368  /// [AB, BC].
369  kLine,
370 
371  /// Draws a continuous line that connect every input vertices
372  ///
373  /// Vertices [A, B, C] will produce one continuous line
374  /// [ABC].
375  kLineStrip,
376 
377  /// Draws a point at each input vertex.
378  kPoint,
379 
380  /// Draws a triangle for every two vertices, after the first.
381  ///
382  /// The first vertex acts as the hub, all following vertices connect with
383  /// this hub to "fan" out from the first vertex.
384  ///
385  /// Triangle fans are not supported in Metal and need a capability check.
386  kTriangleFan,
387 };
388 
389 enum class PolygonMode {
390  kFill,
391  kLine,
392 };
393 
394 struct DepthRange {
395  Scalar z_near = 0.0;
396  Scalar z_far = 1.0;
397 
398  constexpr bool operator==(const DepthRange& other) const {
399  return z_near == other.z_near && z_far == other.z_far;
400  }
401 };
402 
403 struct Viewport {
406 
407  constexpr bool operator==(const Viewport& other) const {
408  return rect == other.rect && depth_range == other.depth_range;
409  }
410 };
411 
412 /// @brief Describes how the texture should be sampled when the texture
413 /// is being shrunk (minified) or expanded (magnified) to fit to
414 /// the sample point.
415 enum class MinMagFilter : uint8_t {
416  /// Select nearest to the sample point. Most widely supported.
417  kNearest,
418 
419  /// Select two points and linearly interpolate between them. Some formats
420  /// may not support this.
421  kLinear,
422 };
423 
424 /// @brief Options for selecting and filtering between mipmap levels.
425 enum class MipFilter : uint8_t {
426  /// @brief The texture is sampled as if it only had a single mipmap level.
427  ///
428  /// All samples are read from level 0.
429  kBase,
430 
431  /// @brief The nearst mipmap level is selected.
432  kNearest,
433 
434  /// @brief Sample from the two nearest mip levels and linearly interpolate.
435  ///
436  /// If the filter falls between levels, both levels are sampled, and
437  /// their results linearly interpolated between levels.
438  kLinear,
439 };
440 
441 enum class SamplerAddressMode : uint8_t {
442  kClampToEdge,
443  kRepeat,
444  kMirror,
445  // More modes are almost always supported but they are usually behind
446  // extensions checks. The ones current in these structs are safe (always
447  // supported) defaults.
448 
449  /// @brief decal sampling mode is only supported on devices that pass
450  /// the `Capabilities.SupportsDecalSamplerAddressMode` check.
451  kDecal,
452 };
453 
454 enum class ColorWriteMaskBits : uint64_t {
455  kNone = 0,
456  kRed = 1 << 0,
457  kGreen = 1 << 1,
458  kBlue = 1 << 2,
459  kAlpha = 1 << 3,
460  kAll = kRed | kGreen | kBlue | kAlpha,
461 };
463 
465 
466 constexpr size_t BytesPerPixelForPixelFormat(PixelFormat format) {
467  switch (format) {
469  return 0u;
473  return 1u;
475  return 2u;
482  return 4u;
484  return 4u;
486  return 5u;
489  return 8u;
491  return 16u;
492  }
493  return 0u;
494 }
495 
496 //------------------------------------------------------------------------------
497 /// @brief Describe the color attachment that will be used with this
498 /// pipeline.
499 ///
500 /// Blending at specific color attachments follows the pseudo-code:
501 /// ```
502 /// if (blending_enabled) {
503 /// final_color.rgb = (src_color_blend_factor * new_color.rgb)
504 /// <color_blend_op>
505 /// (dst_color_blend_factor * old_color.rgb);
506 /// final_color.a = (src_alpha_blend_factor * new_color.a)
507 /// <alpha_blend_op>
508 /// (dst_alpha_blend_factor * old_color.a);
509 /// } else {
510 /// final_color = new_color;
511 /// }
512 /// // IMPORTANT: The write mask is applied irrespective of whether
513 /// // blending_enabled is set.
514 /// final_color = final_color & write_mask;
515 /// ```
516 ///
517 /// The default blend mode is 1 - source alpha.
520  bool blending_enabled = false;
521 
525 
529 
531 
532  constexpr bool operator==(const ColorAttachmentDescriptor& o) const {
533  return format == o.format && //
536  color_blend_op == o.color_blend_op && //
539  alpha_blend_op == o.alpha_blend_op && //
541  write_mask == o.write_mask;
542  }
543 
544  constexpr size_t Hash() const {
545  return fml::HashCombine(
548  dst_alpha_blend_factor, static_cast<uint64_t>(write_mask));
549  }
550 };
551 
552 enum class CompareFunction : uint8_t {
553  /// Comparison test never passes.
554  kNever,
555  /// Comparison test passes always passes.
556  kAlways,
557  /// Comparison test passes if new_value < current_value.
558  kLess,
559  /// Comparison test passes if new_value == current_value.
560  kEqual,
561  /// Comparison test passes if new_value <= current_value.
562  kLessEqual,
563  /// Comparison test passes if new_value > current_value.
564  kGreater,
565  /// Comparison test passes if new_value != current_value.
566  kNotEqual,
567  /// Comparison test passes if new_value >= current_value.
569 };
570 
571 enum class StencilOperation : uint8_t {
572  /// Don't modify the current stencil value.
573  kKeep,
574  /// Reset the stencil value to zero.
575  kZero,
576  /// Reset the stencil value to the reference value.
578  /// Increment the current stencil value by 1. Clamp it to the maximum.
580  /// Decrement the current stencil value by 1. Clamp it to zero.
582  /// Perform a logical bitwise invert on the current stencil value.
583  kInvert,
584  /// Increment the current stencil value by 1. If at maximum, set to zero.
586  /// Decrement the current stencil value by 1. If at zero, set to maximum.
588 };
589 
591  //----------------------------------------------------------------------------
592  /// Indicates how to compare the value with that in the depth buffer.
593  ///
595  //----------------------------------------------------------------------------
596  /// Indicates when writes must be performed to the depth buffer.
597  ///
598  bool depth_write_enabled = false;
599 
600  constexpr bool operator==(const DepthAttachmentDescriptor& o) const {
601  return depth_compare == o.depth_compare &&
603  }
604 
605  constexpr size_t GetHash() const {
606  return fml::HashCombine(depth_compare, depth_write_enabled);
607  }
608 };
609 
611  //----------------------------------------------------------------------------
612  /// Indicates the operation to perform between the reference value and the
613  /// value in the stencil buffer. Both values have the read_mask applied to
614  /// them before performing this operation.
615  ///
617  //----------------------------------------------------------------------------
618  /// Indicates what to do when the stencil test has failed.
619  ///
621  //----------------------------------------------------------------------------
622  /// Indicates what to do when the stencil test passes but the depth test
623  /// fails.
624  ///
626  //----------------------------------------------------------------------------
627  /// Indicates what to do when both the stencil and depth tests pass.
628  ///
630 
631  //----------------------------------------------------------------------------
632  /// The mask applied to the reference and stencil buffer values before
633  /// performing the stencil_compare operation.
634  ///
635  uint32_t read_mask = ~0;
636  //----------------------------------------------------------------------------
637  /// The mask applied to the new stencil value before it is written into the
638  /// stencil buffer.
639  ///
640  uint32_t write_mask = ~0;
641 
642  constexpr bool operator==(const StencilAttachmentDescriptor& o) const {
643  return stencil_compare == o.stencil_compare &&
648  }
649 
650  constexpr size_t GetHash() const {
651  return fml::HashCombine(stencil_compare, stencil_failure, depth_failure,
653  }
654 };
655 
656 struct Attachment {
657  std::shared_ptr<Texture> texture;
658  std::shared_ptr<Texture> resolve_texture;
661 
662  bool IsValid() const;
663 };
664 
665 struct ColorAttachment : public Attachment {
667 };
668 
669 struct DepthAttachment : public Attachment {
670  double clear_depth = 0.0;
671 };
672 
673 struct StencilAttachment : public Attachment {
674  uint32_t clear_stencil = 0;
675 };
676 
677 std::string AttachmentToString(const Attachment& attachment);
678 
679 std::string ColorAttachmentToString(const ColorAttachment& color);
680 
681 std::string DepthAttachmentToString(const DepthAttachment& depth);
682 
683 std::string StencilAttachmentToString(const StencilAttachment& stencil);
684 
685 } // namespace impeller
686 
687 namespace std {
688 
689 template <>
690 struct hash<impeller::DepthAttachmentDescriptor> {
691  constexpr std::size_t operator()(
692  const impeller::DepthAttachmentDescriptor& des) const {
693  return des.GetHash();
694  }
695 };
696 
697 template <>
698 struct hash<impeller::StencilAttachmentDescriptor> {
699  constexpr std::size_t operator()(
700  const impeller::StencilAttachmentDescriptor& des) const {
701  return des.GetHash();
702  }
703 };
704 
705 } // namespace std
706 
707 #endif // FLUTTER_IMPELLER_CORE_FORMATS_H_
GLenum type
constexpr size_t BytesPerPixelForPixelFormat(PixelFormat format)
Definition: formats.h:466
@ kNone
Does not use the index buffer.
constexpr bool CanClearAttachment(LoadAction action)
Definition: formats.h:239
std::string DepthAttachmentToString(const DepthAttachment &depth)
Definition: formats.cc:130
std::string ColorAttachmentToString(const ColorAttachment &color)
Definition: formats.cc:123
BlendFactor
Definition: formats.h:178
constexpr const char * LoadActionToString(LoadAction action)
Definition: formats.h:215
PrimitiveType
Decides how backend draws pixels based on input vertices.
Definition: formats.h:352
@ kPoint
Draws a point at each input vertex.
float Scalar
Definition: scalar.h:19
SamplerAddressMode
Definition: formats.h:441
@ kDecal
decal sampling mode is only supported on devices that pass the Capabilities.SupportsDecalSamplerAddre...
constexpr bool IsDepthWritable(PixelFormat format)
Definition: formats.h:119
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:269
CompareFunction
Definition: formats.h:552
@ 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:310
MipFilter
Options for selecting and filtering between mipmap levels.
Definition: formats.h:425
@ 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:571
@ 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:262
TextureCoordinateSystem
Definition: formats.h:327
WindingOrder
Definition: formats.h:22
IMPELLER_ENUM_IS_MASK(MyMaskBits)
LoadAction
Definition: formats.h:202
StoreAction
Definition: formats.h:208
constexpr bool IsStencilWritable(PixelFormat format)
Definition: formats.h:129
PolygonMode
Definition: formats.h:389
constexpr const char * StoreActionToString(StoreAction action)
Definition: formats.h:226
constexpr const char * PixelFormatToString(PixelFormat format)
Definition: formats.h:140
constexpr const char * StorageModeToString(StorageMode mode)
Definition: formats.h:60
constexpr bool IsMultisampleCapable(TextureType type)
Definition: formats.h:283
MinMagFilter
Describes how the texture should be sampled when the texture is being shrunk (minified) or expanded (...
Definition: formats.h:415
@ kNearest
Select nearest to the sample point. Most widely supported.
ColorWriteMaskBits
Definition: formats.h:454
Mask< TextureUsage > TextureUsageMask
Definition: formats.h:308
BlendOperation
Definition: formats.h:196
TextureUsage
Definition: formats.h:300
SampleCount
Definition: formats.h:295
constexpr bool CanDiscardAttachmentWhenDone(StoreAction action)
Definition: formats.h:250
Definition: comparable.h:95
std::shared_ptr< Texture > resolve_texture
Definition: formats.h:658
bool IsValid() const
Definition: formats.cc:26
LoadAction load_action
Definition: formats.h:659
std::shared_ptr< Texture > texture
Definition: formats.h:657
StoreAction store_action
Definition: formats.h:660
Describe the color attachment that will be used with this pipeline.
Definition: formats.h:518
constexpr size_t Hash() const
Definition: formats.h:544
constexpr bool operator==(const ColorAttachmentDescriptor &o) const
Definition: formats.h:532
static constexpr Color BlackTransparent()
Definition: color.h:270
constexpr bool operator==(const DepthAttachmentDescriptor &o) const
Definition: formats.h:600
constexpr size_t GetHash() const
Definition: formats.h:605
constexpr bool operator==(const DepthRange &other) const
Definition: formats.h:398
constexpr bool operator==(const StencilAttachmentDescriptor &o) const
Definition: formats.h:642
constexpr size_t GetHash() const
Definition: formats.h:650
StencilOperation depth_stencil_pass
Definition: formats.h:629
constexpr bool operator==(const Viewport &other) const
Definition: formats.h:407
DepthRange depth_range
Definition: formats.h:405
constexpr std::size_t operator()(const impeller::DepthAttachmentDescriptor &des) const
Definition: formats.h:691
constexpr std::size_t operator()(const impeller::StencilAttachmentDescriptor &des) const
Definition: formats.h:699