tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

WebGLFormats.h (10747B)


      1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
      2 /* This Source Code Form is subject to the terms of the Mozilla Public
      3 * License, v. 2.0. If a copy of the MPL was not distributed with this
      4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      5 
      6 #ifndef WEBGL_FORMATS_H_
      7 #define WEBGL_FORMATS_H_
      8 
      9 #include <map>
     10 #include <memory>
     11 #include <set>
     12 
     13 #include "WebGLTypes.h"
     14 
     15 namespace mozilla::webgl {
     16 
     17 using EffectiveFormatValueT = uint8_t;
     18 
     19 enum class EffectiveFormat : EffectiveFormatValueT {
     20  // GLES 3.0.4, p128-129, "Required Texture Formats"
     21  // "Texture and renderbuffer color formats"
     22  RGBA32I,
     23  RGBA32UI,
     24  RGBA16I,
     25  RGBA16UI,
     26  RGBA8,
     27  RGBA8I,
     28  RGBA8UI,
     29  SRGB8_ALPHA8,
     30  RGB10_A2,
     31  RGB10_A2UI,
     32  RGBA4,
     33  RGB5_A1,
     34 
     35  RGB8,
     36  RGB565,
     37 
     38  RG32I,
     39  RG32UI,
     40  RG16I,
     41  RG16UI,
     42  RG8,
     43  RG8I,
     44  RG8UI,
     45 
     46  R32I,
     47  R32UI,
     48  R16I,
     49  R16UI,
     50  R8,
     51  R8I,
     52  R8UI,
     53 
     54  // "Texture-only color formats"
     55  RGBA32F,
     56  RGBA16F,
     57  RGBA8_SNORM,
     58 
     59  RGB32F,
     60  RGB32I,
     61  RGB32UI,
     62 
     63  RGB16F,
     64  RGB16I,
     65  RGB16UI,
     66 
     67  RGB8_SNORM,
     68  RGB8I,
     69  RGB8UI,
     70  SRGB8,
     71 
     72  R11F_G11F_B10F,
     73  RGB9_E5,
     74 
     75  RG32F,
     76  RG16F,
     77  RG8_SNORM,
     78 
     79  R32F,
     80  R16F,
     81  R8_SNORM,
     82 
     83  // "Depth formats"
     84  DEPTH_COMPONENT32F,
     85  DEPTH_COMPONENT24,
     86  DEPTH_COMPONENT16,
     87 
     88  // "Combined depth+stencil formats"
     89  DEPTH32F_STENCIL8,
     90  DEPTH24_STENCIL8,
     91 
     92  // GLES 3.0.4, p205-206, "Required Renderbuffer Formats"
     93  STENCIL_INDEX8,
     94 
     95  ////////////////////////////////////
     96 
     97  // GLES 3.0.4, p147, table 3.19
     98  // GLES 3.0.4, p286+, $C.1 "ETC Compressed Texture Image Formats"
     99  COMPRESSED_R11_EAC,
    100  COMPRESSED_SIGNED_R11_EAC,
    101  COMPRESSED_RG11_EAC,
    102  COMPRESSED_SIGNED_RG11_EAC,
    103  COMPRESSED_RGB8_ETC2,
    104  COMPRESSED_SRGB8_ETC2,
    105  COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2,
    106  COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2,
    107  COMPRESSED_RGBA8_ETC2_EAC,
    108  COMPRESSED_SRGB8_ALPHA8_ETC2_EAC,
    109 
    110  // EXT_texture_compression_bptc
    111  COMPRESSED_RGBA_BPTC_UNORM,
    112  COMPRESSED_SRGB_ALPHA_BPTC_UNORM,
    113  COMPRESSED_RGB_BPTC_SIGNED_FLOAT,
    114  COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT,
    115 
    116  // EXT_texture_compression_rgtc
    117  COMPRESSED_RED_RGTC1,
    118  COMPRESSED_SIGNED_RED_RGTC1,
    119  COMPRESSED_RG_RGTC2,
    120  COMPRESSED_SIGNED_RG_RGTC2,
    121 
    122  // EXT_texture_compression_s3tc
    123  COMPRESSED_RGB_S3TC_DXT1_EXT,
    124  COMPRESSED_RGBA_S3TC_DXT1_EXT,
    125  COMPRESSED_RGBA_S3TC_DXT3_EXT,
    126  COMPRESSED_RGBA_S3TC_DXT5_EXT,
    127 
    128  // EXT_texture_sRGB
    129  COMPRESSED_SRGB_S3TC_DXT1_EXT,
    130  COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT,
    131  COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT,
    132  COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT,
    133 
    134  // KHR_texture_compression_astc_ldr
    135  COMPRESSED_RGBA_ASTC_4x4_KHR,
    136  COMPRESSED_RGBA_ASTC_5x4_KHR,
    137  COMPRESSED_RGBA_ASTC_5x5_KHR,
    138  COMPRESSED_RGBA_ASTC_6x5_KHR,
    139  COMPRESSED_RGBA_ASTC_6x6_KHR,
    140  COMPRESSED_RGBA_ASTC_8x5_KHR,
    141  COMPRESSED_RGBA_ASTC_8x6_KHR,
    142  COMPRESSED_RGBA_ASTC_8x8_KHR,
    143  COMPRESSED_RGBA_ASTC_10x5_KHR,
    144  COMPRESSED_RGBA_ASTC_10x6_KHR,
    145  COMPRESSED_RGBA_ASTC_10x8_KHR,
    146  COMPRESSED_RGBA_ASTC_10x10_KHR,
    147  COMPRESSED_RGBA_ASTC_12x10_KHR,
    148  COMPRESSED_RGBA_ASTC_12x12_KHR,
    149 
    150  COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR,
    151  COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR,
    152  COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR,
    153  COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR,
    154  COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR,
    155  COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR,
    156  COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR,
    157  COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR,
    158  COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR,
    159  COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR,
    160  COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR,
    161  COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR,
    162  COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR,
    163  COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR,
    164 
    165  // IMG_texture_compression_pvrtc
    166  COMPRESSED_RGB_PVRTC_4BPPV1,
    167  COMPRESSED_RGBA_PVRTC_4BPPV1,
    168  COMPRESSED_RGB_PVRTC_2BPPV1,
    169  COMPRESSED_RGBA_PVRTC_2BPPV1,
    170 
    171  // OES_compressed_ETC1_RGB8_texture
    172  ETC1_RGB8_OES,
    173 
    174  ////////////////////////////////////
    175 
    176  // GLES 3.0.4, p128, table 3.12.
    177  Luminance8Alpha8,
    178  Luminance8,
    179  Alpha8,
    180 
    181  // OES_texture_float
    182  Luminance32FAlpha32F,
    183  Luminance32F,
    184  Alpha32F,
    185 
    186  // OES_texture_half_float
    187  Luminance16FAlpha16F,
    188  Luminance16F,
    189  Alpha16F,
    190 
    191  // EXT_texture_norm16
    192  R16,
    193  RG16,
    194  RGB16,
    195  RGBA16,
    196  R16_SNORM,
    197  RG16_SNORM,
    198  RGB16_SNORM,
    199  RGBA16_SNORM,
    200 
    201  MAX,
    202 };
    203 
    204 enum class UnsizedFormat : uint8_t {
    205  R,
    206  RG,
    207  RGB,
    208  RGBA,
    209  LA,
    210  L,
    211  A,
    212  D,
    213  S,
    214  DEPTH_STENCIL,  // `DS` is a macro on Solaris. (regset.h)
    215 };
    216 
    217 // GLES 3.0.4 p114 Table 3.4, p240
    218 enum class ComponentType : uint8_t {
    219  Int,       // RGBA32I
    220  UInt,      // RGBA32UI
    221  NormInt,   // RGBA8_SNORM
    222  NormUInt,  // RGBA8
    223  Float,     // RGBA32F
    224 };
    225 const char* ToString(ComponentType);
    226 
    227 enum class TextureBaseType : uint8_t {
    228  Int = uint8_t(ComponentType::Int),
    229  UInt = uint8_t(ComponentType::UInt),
    230  Float = uint8_t(ComponentType::Float),  // Also includes NormU?Int and Depth
    231 };
    232 
    233 const char* ToString(TextureBaseType);
    234 
    235 enum class CompressionFamily : uint8_t {
    236  ASTC,
    237  BPTC,
    238  ES3,  // ETC2 or EAC
    239  ETC1,
    240  PVRTC,
    241  RGTC,
    242  S3TC,
    243 };
    244 
    245 ////////////////////////////////////////////////////////////////////////////////
    246 
    247 struct CompressedFormatInfo {
    248  const EffectiveFormat effectiveFormat;
    249  const uint8_t bytesPerBlock;
    250  const uint8_t blockWidth;
    251  const uint8_t blockHeight;
    252  const CompressionFamily family;
    253 };
    254 
    255 struct FormatInfo {
    256  const EffectiveFormat effectiveFormat;
    257  const char* const name;
    258  const GLenum sizedFormat;
    259  const UnsizedFormat unsizedFormat;
    260  const ComponentType componentType;
    261  const TextureBaseType baseType;
    262  const bool isSRGB;
    263 
    264  const CompressedFormatInfo* const compression;
    265 
    266  const uint8_t estimatedBytesPerPixel;  // 0 iff bool(compression).
    267 
    268  // In bits. Iff bool(compression), active channels are 1.
    269  const uint8_t r;
    270  const uint8_t g;
    271  const uint8_t b;
    272  const uint8_t a;
    273  const uint8_t d;
    274  const uint8_t s;
    275 
    276  //////
    277 
    278  std::map<UnsizedFormat, const FormatInfo*> copyDecayFormats;
    279 
    280  const FormatInfo* GetCopyDecayFormat(UnsizedFormat) const;
    281 
    282  bool IsColorFormat() const {
    283    // Alpha is a 'color format' since it's 'color-attachable'.
    284    return bool(compression) || bool(r | g | b | a);
    285  }
    286 };
    287 
    288 //////////////////////////////////////////////////////////////////////////////////////////
    289 
    290 struct PackingInfoInfo final {
    291  uint8_t bytesPerElement = 0;
    292  uint8_t elementsPerPixel = 0;  // E.g. 1 for LOCAL_GL_UNSIGNED_SHORT_4_4_4_4
    293  bool isPacked = false;
    294 
    295  static Maybe<PackingInfoInfo> For(const PackingInfo&);
    296 
    297  inline uint8_t BytesPerPixel() const {
    298    return bytesPerElement * elementsPerPixel;
    299  }
    300 };
    301 
    302 const FormatInfo* GetFormat(EffectiveFormat format);
    303 
    304 inline uint8_t BytesPerPixel(const PackingInfo& packing) {
    305  const auto pii = PackingInfoInfo::For(packing);
    306  if (MOZ_LIKELY(pii)) return pii->BytesPerPixel();
    307 
    308  gfxCriticalError() << "Bad BytesPerPixel(" << packing << ")";
    309  MOZ_CRASH("Bad `packing`.");
    310 }
    311 
    312 /*
    313 GLint ComponentSize(const FormatInfo* format, GLenum component);
    314 GLenum ComponentType(const FormatInfo* format);
    315 */
    316 ////////////////////////////////////////
    317 
    318 struct FormatRenderableState final {
    319 private:
    320  enum class RenderableState {
    321    Disabled,
    322    Implicit,
    323    Explicit,
    324  };
    325 
    326 public:
    327  RenderableState state = RenderableState::Disabled;
    328  WebGLExtensionID extid = WebGLExtensionID::Max;
    329 
    330  static FormatRenderableState Explicit() {
    331    return {RenderableState::Explicit};
    332  }
    333 
    334  static FormatRenderableState Implicit(WebGLExtensionID extid) {
    335    return {RenderableState::Implicit, extid};
    336  }
    337 
    338  bool IsRenderable() const { return state != RenderableState::Disabled; }
    339  bool IsExplicit() const { return state == RenderableState::Explicit; }
    340 };
    341 
    342 struct FormatUsageInfo {
    343  const FormatInfo* const format;
    344 
    345 private:
    346  FormatRenderableState renderableState;
    347 
    348 public:
    349  bool isFilterable = false;
    350 
    351  std::map<PackingInfo, DriverUnpackInfo> validUnpacks;
    352  const DriverUnpackInfo* idealUnpack = nullptr;
    353 
    354  // LOCAL_GL_IMPLEMENTATION_COLOR_READ_FORMAT/_TYPE:
    355  mutable std::optional<PackingInfo> implReadPiCache;
    356 
    357  const GLint* textureSwizzleRGBA = nullptr;
    358 
    359 private:
    360  mutable bool maxSamplesKnown = false;
    361  mutable uint32_t maxSamples = 0;
    362 
    363 public:
    364  static const GLint kLuminanceSwizzleRGBA[4];
    365  static const GLint kAlphaSwizzleRGBA[4];
    366  static const GLint kLumAlphaSwizzleRGBA[4];
    367 
    368  explicit FormatUsageInfo(const FormatInfo* const _format) : format(_format) {
    369    if (format->IsColorFormat() && format->baseType != TextureBaseType::Float) {
    370      maxSamplesKnown = true;
    371    }
    372  }
    373 
    374  bool IsRenderable() const { return renderableState.IsRenderable(); }
    375  void SetRenderable(
    376      const FormatRenderableState& state = FormatRenderableState::Explicit());
    377  bool IsExplicitlyRenderable() const { return renderableState.IsExplicit(); }
    378  WebGLExtensionID GetExtensionID() const {
    379    MOZ_ASSERT(renderableState.extid != WebGLExtensionID::Max);
    380    return renderableState.extid;
    381  }
    382 
    383  bool IsUnpackValid(const PackingInfo& key,
    384                     const DriverUnpackInfo** const out_value) const;
    385 
    386 private:
    387  void ResolveMaxSamples(gl::GLContext& gl) const;
    388 
    389 public:
    390  uint32_t MaxSamples(gl::GLContext& gl) const {
    391    if (!maxSamplesKnown) {
    392      ResolveMaxSamples(gl);
    393    }
    394    return maxSamples;
    395  }
    396 };
    397 
    398 class FormatUsageAuthority {
    399  std::map<EffectiveFormat, FormatUsageInfo> mUsageMap;
    400 
    401  std::map<GLenum, const FormatUsageInfo*> mRBFormatMap;
    402  std::map<GLenum, const FormatUsageInfo*> mSizedTexFormatMap;
    403  std::map<PackingInfo, const FormatUsageInfo*> mUnsizedTexFormatMap;
    404 
    405  std::set<GLenum> mValidTexInternalFormats;
    406  std::set<GLenum> mValidTexUnpackFormats;
    407  std::set<GLenum> mValidTexUnpackTypes;
    408 
    409 public:
    410  static std::unique_ptr<FormatUsageAuthority> CreateForWebGL1(
    411      gl::GLContext* gl);
    412  static std::unique_ptr<FormatUsageAuthority> CreateForWebGL2(
    413      gl::GLContext* gl);
    414 
    415 private:
    416  FormatUsageAuthority() = default;
    417 
    418 public:
    419  FormatUsageInfo* EditUsage(EffectiveFormat format);
    420  const FormatUsageInfo* GetUsage(EffectiveFormat format) const;
    421 
    422  void AddTexUnpack(FormatUsageInfo* usage, const PackingInfo& pi,
    423                    const DriverUnpackInfo& dui);
    424 
    425  bool IsInternalFormatEnumValid(GLenum internalFormat) const;
    426  bool AreUnpackEnumsValid(GLenum unpackFormat, GLenum unpackType) const;
    427 
    428  void AllowRBFormat(GLenum sizedFormat, const FormatUsageInfo* usage,
    429                     bool expectRenderable = true);
    430  void AllowSizedTexFormat(GLenum sizedFormat, const FormatUsageInfo* usage);
    431  void AllowUnsizedTexFormat(const PackingInfo& pi,
    432                             const FormatUsageInfo* usage);
    433 
    434  const FormatUsageInfo* GetRBUsage(GLenum sizedFormat) const;
    435  const FormatUsageInfo* GetSizedTexUsage(GLenum sizedFormat) const;
    436  const FormatUsageInfo* GetUnsizedTexUsage(const PackingInfo& pi) const;
    437 };
    438 
    439 }  // namespace mozilla::webgl
    440 
    441 #endif  // WEBGL_FORMATS_H_