LCOV - code coverage report
Current view: top level - dom/canvas - WebGLFormats.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 3 631 0.5 %
Date: 2017-07-14 16:53:18 Functions: 0 47 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       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             : #include "WebGLFormats.h"
       7             : 
       8             : #include "gfxPrefs.h"
       9             : #include "GLContext.h"
      10             : #include "GLDefs.h"
      11             : #include "mozilla/gfx/Logging.h"
      12             : #include "mozilla/StaticMutex.h"
      13             : 
      14             : #ifdef FOO
      15             : #error FOO is already defined! We use FOO() macros to keep things succinct in this file.
      16             : #endif
      17             : 
      18             : namespace mozilla {
      19             : namespace webgl {
      20             : 
      21             : template<typename K, typename V, typename K2, typename V2>
      22             : static inline void
      23           0 : AlwaysInsert(std::map<K,V>& dest, const K2& key, const V2& val)
      24             : {
      25           0 :     auto res = dest.insert({ key, val });
      26           0 :     bool didInsert = res.second;
      27           0 :     MOZ_ALWAYS_TRUE(didInsert);
      28           0 : }
      29             : 
      30             : template<typename K, typename V, typename K2>
      31             : static inline V*
      32           0 : FindOrNull(const std::map<K,V*>& dest, const K2& key)
      33             : {
      34           0 :     auto itr = dest.find(key);
      35           0 :     if (itr == dest.end())
      36           0 :         return nullptr;
      37             : 
      38           0 :     return itr->second;
      39             : }
      40             : 
      41             : // Returns a pointer to the in-place value for `key`.
      42             : template<typename K, typename V, typename K2>
      43             : static inline V*
      44           0 : FindPtrOrNull(std::map<K,V>& dest, const K2& key)
      45             : {
      46           0 :     auto itr = dest.find(key);
      47           0 :     if (itr == dest.end())
      48           0 :         return nullptr;
      49             : 
      50           0 :     return &(itr->second);
      51             : }
      52             : 
      53             : //////////////////////////////////////////////////////////////////////////////////////////
      54             : 
      55           3 : std::map<EffectiveFormat, const CompressedFormatInfo> gCompressedFormatInfoMap;
      56           3 : std::map<EffectiveFormat, FormatInfo> gFormatInfoMap;
      57             : 
      58             : static inline const CompressedFormatInfo*
      59           0 : GetCompressedFormatInfo(EffectiveFormat format)
      60             : {
      61           0 :     MOZ_ASSERT(!gCompressedFormatInfoMap.empty());
      62           0 :     return FindPtrOrNull(gCompressedFormatInfoMap, format);
      63             : }
      64             : 
      65             : static inline FormatInfo*
      66           0 : GetFormatInfo_NoLock(EffectiveFormat format)
      67             : {
      68           0 :     MOZ_ASSERT(!gFormatInfoMap.empty());
      69           0 :     return FindPtrOrNull(gFormatInfoMap, format);
      70             : }
      71             : 
      72             : //////////////////////////////////////////////////////////////////////////////////////////
      73             : 
      74             : static void
      75           0 : AddCompressedFormatInfo(EffectiveFormat format, uint16_t bitsPerBlock, uint8_t blockWidth,
      76             :                         uint8_t blockHeight, CompressionFamily family)
      77             : {
      78           0 :     MOZ_ASSERT(bitsPerBlock % 8 == 0);
      79           0 :     uint16_t bytesPerBlock = bitsPerBlock / 8; // The specs always state these in bits,
      80             :                                                // but it's only ever useful to us as
      81             :                                                // bytes.
      82           0 :     MOZ_ASSERT(bytesPerBlock <= 255);
      83             : 
      84             :     const CompressedFormatInfo info = { format, uint8_t(bytesPerBlock), blockWidth,
      85           0 :                                         blockHeight, family };
      86           0 :     AlwaysInsert(gCompressedFormatInfoMap, format, info);
      87           0 : }
      88             : 
      89             : static void
      90           0 : InitCompressedFormatInfo()
      91             : {
      92             :     // GLES 3.0.4, p147, table 3.19
      93             :     // GLES 3.0.4, p286+, $C.1 "ETC Compressed Texture Image Formats"
      94           0 :     AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_RGB8_ETC2                     ,  64, 4, 4, CompressionFamily::ES3);
      95           0 :     AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_SRGB8_ETC2                    ,  64, 4, 4, CompressionFamily::ES3);
      96           0 :     AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_RGBA8_ETC2_EAC                , 128, 4, 4, CompressionFamily::ES3);
      97           0 :     AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_SRGB8_ALPHA8_ETC2_EAC         , 128, 4, 4, CompressionFamily::ES3);
      98           0 :     AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_R11_EAC                       ,  64, 4, 4, CompressionFamily::ES3);
      99           0 :     AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_RG11_EAC                      , 128, 4, 4, CompressionFamily::ES3);
     100           0 :     AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_SIGNED_R11_EAC                ,  64, 4, 4, CompressionFamily::ES3);
     101           0 :     AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_SIGNED_RG11_EAC               , 128, 4, 4, CompressionFamily::ES3);
     102           0 :     AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2 ,  64, 4, 4, CompressionFamily::ES3);
     103           0 :     AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2,  64, 4, 4, CompressionFamily::ES3);
     104             : 
     105             :     // AMD_compressed_ATC_texture
     106           0 :     AddCompressedFormatInfo(EffectiveFormat::ATC_RGB_AMD                    ,  64, 4, 4, CompressionFamily::ATC);
     107           0 :     AddCompressedFormatInfo(EffectiveFormat::ATC_RGBA_EXPLICIT_ALPHA_AMD    , 128, 4, 4, CompressionFamily::ATC);
     108           0 :     AddCompressedFormatInfo(EffectiveFormat::ATC_RGBA_INTERPOLATED_ALPHA_AMD, 128, 4, 4, CompressionFamily::ATC);
     109             : 
     110             :     // EXT_texture_compression_s3tc
     111           0 :     AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_RGB_S3TC_DXT1_EXT ,  64, 4, 4, CompressionFamily::S3TC);
     112           0 :     AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_RGBA_S3TC_DXT1_EXT,  64, 4, 4, CompressionFamily::S3TC);
     113           0 :     AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_RGBA_S3TC_DXT3_EXT, 128, 4, 4, CompressionFamily::S3TC);
     114           0 :     AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_RGBA_S3TC_DXT5_EXT, 128, 4, 4, CompressionFamily::S3TC);
     115             : 
     116             :     // EXT_texture_compression_s3tc_srgb
     117           0 :     AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_SRGB_S3TC_DXT1_EXT ,       64, 4, 4, CompressionFamily::S3TC);
     118           0 :     AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT,  64, 4, 4, CompressionFamily::S3TC);
     119           0 :     AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT, 128, 4, 4, CompressionFamily::S3TC);
     120           0 :     AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT, 128, 4, 4, CompressionFamily::S3TC);
     121             : 
     122             :     // KHR_texture_compression_astc_ldr
     123           0 :     AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_RGBA_ASTC_4x4_KHR          , 128,  4,  4, CompressionFamily::ASTC);
     124           0 :     AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_RGBA_ASTC_5x4_KHR          , 128,  5,  4, CompressionFamily::ASTC);
     125           0 :     AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_RGBA_ASTC_5x5_KHR          , 128,  5,  5, CompressionFamily::ASTC);
     126           0 :     AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_RGBA_ASTC_6x5_KHR          , 128,  6,  5, CompressionFamily::ASTC);
     127           0 :     AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_RGBA_ASTC_6x6_KHR          , 128,  6,  6, CompressionFamily::ASTC);
     128           0 :     AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_RGBA_ASTC_8x5_KHR          , 128,  8,  5, CompressionFamily::ASTC);
     129           0 :     AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_RGBA_ASTC_8x6_KHR          , 128,  8,  6, CompressionFamily::ASTC);
     130           0 :     AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_RGBA_ASTC_8x8_KHR          , 128,  8,  8, CompressionFamily::ASTC);
     131           0 :     AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_RGBA_ASTC_10x5_KHR         , 128, 10,  5, CompressionFamily::ASTC);
     132           0 :     AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_RGBA_ASTC_10x6_KHR         , 128, 10,  6, CompressionFamily::ASTC);
     133           0 :     AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_RGBA_ASTC_10x8_KHR         , 128, 10,  8, CompressionFamily::ASTC);
     134           0 :     AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_RGBA_ASTC_10x10_KHR        , 128, 10, 10, CompressionFamily::ASTC);
     135           0 :     AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_RGBA_ASTC_12x10_KHR        , 128, 12, 10, CompressionFamily::ASTC);
     136           0 :     AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_RGBA_ASTC_12x12_KHR        , 128, 12, 12, CompressionFamily::ASTC);
     137             : 
     138           0 :     AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR  , 128,  4,  4, CompressionFamily::ASTC);
     139           0 :     AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR  , 128,  5,  4, CompressionFamily::ASTC);
     140           0 :     AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR  , 128,  5,  5, CompressionFamily::ASTC);
     141           0 :     AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR  , 128,  6,  5, CompressionFamily::ASTC);
     142           0 :     AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR  , 128,  6,  6, CompressionFamily::ASTC);
     143           0 :     AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR  , 128,  8,  5, CompressionFamily::ASTC);
     144           0 :     AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR  , 128,  8,  6, CompressionFamily::ASTC);
     145           0 :     AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR  , 128,  8,  8, CompressionFamily::ASTC);
     146           0 :     AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR , 128, 10,  5, CompressionFamily::ASTC);
     147           0 :     AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR , 128, 10,  6, CompressionFamily::ASTC);
     148           0 :     AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR , 128, 10,  8, CompressionFamily::ASTC);
     149           0 :     AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR, 128, 10, 10, CompressionFamily::ASTC);
     150           0 :     AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR, 128, 12, 10, CompressionFamily::ASTC);
     151           0 :     AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR, 128, 12, 12, CompressionFamily::ASTC);
     152             : 
     153             :     // IMG_texture_compression_pvrtc
     154           0 :     AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_RGB_PVRTC_4BPPV1 , 256,  8, 8, CompressionFamily::PVRTC);
     155           0 :     AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_RGBA_PVRTC_4BPPV1, 256,  8, 8, CompressionFamily::PVRTC);
     156           0 :     AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_RGB_PVRTC_2BPPV1 , 256, 16, 8, CompressionFamily::PVRTC);
     157           0 :     AddCompressedFormatInfo(EffectiveFormat::COMPRESSED_RGBA_PVRTC_2BPPV1, 256, 16, 8, CompressionFamily::PVRTC);
     158             : 
     159             :     // OES_compressed_ETC1_RGB8_texture
     160           0 :     AddCompressedFormatInfo(EffectiveFormat::ETC1_RGB8_OES, 64, 4, 4, CompressionFamily::ETC1);
     161           0 : }
     162             : 
     163             : //////////////////////////////////////////////////////////////////////////////////////////
     164             : 
     165             : static void
     166           0 : AddFormatInfo(EffectiveFormat format, const char* name, GLenum sizedFormat,
     167             :               uint8_t bytesPerPixel, uint8_t r, uint8_t g, uint8_t b, uint8_t a,
     168             :               uint8_t d, uint8_t s, UnsizedFormat unsizedFormat, bool isSRGB,
     169             :               ComponentType componentType)
     170             : {
     171           0 :     switch (unsizedFormat) {
     172             :     case UnsizedFormat::R:
     173           0 :         MOZ_ASSERT(r && !g && !b && !a && !d && !s);
     174           0 :         break;
     175             : 
     176             :     case UnsizedFormat::RG:
     177           0 :         MOZ_ASSERT(r && g && !b && !a && !d && !s);
     178           0 :         break;
     179             : 
     180             :     case UnsizedFormat::RGB:
     181           0 :         MOZ_ASSERT(r && g && b && !a && !d && !s);
     182           0 :         break;
     183             : 
     184             :     case UnsizedFormat::RGBA:
     185           0 :         MOZ_ASSERT(r && g && b && a && !d && !s);
     186           0 :         break;
     187             : 
     188             :     case UnsizedFormat::L:
     189           0 :         MOZ_ASSERT(r && !g && !b && !a && !d && !s);
     190           0 :         break;
     191             : 
     192             :     case UnsizedFormat::A:
     193           0 :         MOZ_ASSERT(!r && !g && !b && a && !d && !s);
     194           0 :         break;
     195             : 
     196             :     case UnsizedFormat::LA:
     197           0 :         MOZ_ASSERT(r && !g && !b && a && !d && !s);
     198           0 :         break;
     199             : 
     200             :     case UnsizedFormat::D:
     201           0 :         MOZ_ASSERT(!r && !g && !b && !a && d && !s);
     202           0 :         break;
     203             : 
     204             :     case UnsizedFormat::S:
     205           0 :         MOZ_ASSERT(!r && !g && !b && !a && !d && s);
     206           0 :         break;
     207             : 
     208             :     case UnsizedFormat::DEPTH_STENCIL:
     209           0 :         MOZ_ASSERT(!r && !g && !b && !a && d && s);
     210           0 :         break;
     211             :     }
     212             : 
     213           0 :     const CompressedFormatInfo* compressedFormatInfo = GetCompressedFormatInfo(format);
     214           0 :     MOZ_ASSERT(!bytesPerPixel == bool(compressedFormatInfo));
     215             : 
     216             : #ifdef DEBUG
     217           0 :     uint8_t totalBits = r + g + b + a + d + s;
     218           0 :     if (format == EffectiveFormat::RGB9_E5) {
     219           0 :         totalBits = 9 + 9 + 9 + 5;
     220             :     }
     221             : 
     222           0 :     if (compressedFormatInfo) {
     223           0 :         MOZ_ASSERT(totalBits);
     224           0 :         MOZ_ASSERT(!bytesPerPixel);
     225             :     } else {
     226           0 :         MOZ_ASSERT(totalBits == bytesPerPixel*8);
     227             :     }
     228             : #endif
     229             : 
     230             :     const FormatInfo info = { format, name, sizedFormat, unsizedFormat, componentType,
     231           0 :                               isSRGB, compressedFormatInfo, bytesPerPixel, r,g,b,a,d,s };
     232           0 :     AlwaysInsert(gFormatInfoMap, format, info);
     233           0 : }
     234             : 
     235             : static void
     236           0 : InitFormatInfo()
     237             : {
     238             : #define FOO(x) EffectiveFormat::x, #x, LOCAL_GL_ ## x
     239             : 
     240             :     // GLES 3.0.4, p130-132, table 3.13
     241           0 :     AddFormatInfo(FOO(R8            ),  1,  8, 0, 0, 0,  0,0, UnsizedFormat::R   , false, ComponentType::NormUInt);
     242           0 :     AddFormatInfo(FOO(R8_SNORM      ),  1,  8, 0, 0, 0,  0,0, UnsizedFormat::R   , false, ComponentType::NormInt );
     243           0 :     AddFormatInfo(FOO(RG8           ),  2,  8, 8, 0, 0,  0,0, UnsizedFormat::RG  , false, ComponentType::NormUInt);
     244           0 :     AddFormatInfo(FOO(RG8_SNORM     ),  2,  8, 8, 0, 0,  0,0, UnsizedFormat::RG  , false, ComponentType::NormInt );
     245           0 :     AddFormatInfo(FOO(RGB8          ),  3,  8, 8, 8, 0,  0,0, UnsizedFormat::RGB , false, ComponentType::NormUInt);
     246           0 :     AddFormatInfo(FOO(RGB8_SNORM    ),  3,  8, 8, 8, 0,  0,0, UnsizedFormat::RGB , false, ComponentType::NormInt );
     247           0 :     AddFormatInfo(FOO(RGB565        ),  2,  5, 6, 5, 0,  0,0, UnsizedFormat::RGB , false, ComponentType::NormUInt);
     248           0 :     AddFormatInfo(FOO(RGBA4         ),  2,  4, 4, 4, 4,  0,0, UnsizedFormat::RGBA, false, ComponentType::NormUInt);
     249           0 :     AddFormatInfo(FOO(RGB5_A1       ),  2,  5, 5, 5, 1,  0,0, UnsizedFormat::RGBA, false, ComponentType::NormUInt);
     250           0 :     AddFormatInfo(FOO(RGBA8         ),  4,  8, 8, 8, 8,  0,0, UnsizedFormat::RGBA, false, ComponentType::NormUInt);
     251           0 :     AddFormatInfo(FOO(RGBA8_SNORM   ),  4,  8, 8, 8, 8,  0,0, UnsizedFormat::RGBA, false, ComponentType::NormInt );
     252           0 :     AddFormatInfo(FOO(RGB10_A2      ),  4, 10,10,10, 2,  0,0, UnsizedFormat::RGBA, false, ComponentType::NormUInt);
     253           0 :     AddFormatInfo(FOO(RGB10_A2UI    ),  4, 10,10,10, 2,  0,0, UnsizedFormat::RGBA, false, ComponentType::UInt    );
     254             : 
     255           0 :     AddFormatInfo(FOO(SRGB8         ),  3,  8, 8, 8, 0,  0,0, UnsizedFormat::RGB , true , ComponentType::NormUInt);
     256           0 :     AddFormatInfo(FOO(SRGB8_ALPHA8  ),  4,  8, 8, 8, 8,  0,0, UnsizedFormat::RGBA, true , ComponentType::NormUInt);
     257             : 
     258           0 :     AddFormatInfo(FOO(R16F          ),  2, 16, 0, 0, 0,  0,0, UnsizedFormat::R   , false, ComponentType::Float   );
     259           0 :     AddFormatInfo(FOO(RG16F         ),  4, 16,16, 0, 0,  0,0, UnsizedFormat::RG  , false, ComponentType::Float   );
     260           0 :     AddFormatInfo(FOO(RGB16F        ),  6, 16,16,16, 0,  0,0, UnsizedFormat::RGB , false, ComponentType::Float   );
     261           0 :     AddFormatInfo(FOO(RGBA16F       ),  8, 16,16,16,16,  0,0, UnsizedFormat::RGBA, false, ComponentType::Float   );
     262           0 :     AddFormatInfo(FOO(R32F          ),  4, 32, 0, 0, 0,  0,0, UnsizedFormat::R   , false, ComponentType::Float   );
     263           0 :     AddFormatInfo(FOO(RG32F         ),  8, 32,32, 0, 0,  0,0, UnsizedFormat::RG  , false, ComponentType::Float   );
     264           0 :     AddFormatInfo(FOO(RGB32F        ), 12, 32,32,32, 0,  0,0, UnsizedFormat::RGB , false, ComponentType::Float   );
     265           0 :     AddFormatInfo(FOO(RGBA32F       ), 16, 32,32,32,32,  0,0, UnsizedFormat::RGBA, false, ComponentType::Float   );
     266             : 
     267           0 :     AddFormatInfo(FOO(R11F_G11F_B10F),  4, 11,11,10, 0,  0,0, UnsizedFormat::RGB , false, ComponentType::Float   );
     268           0 :     AddFormatInfo(FOO(RGB9_E5       ),  4, 14,14,14, 0,  0,0, UnsizedFormat::RGB , false, ComponentType::Float   );
     269             : 
     270           0 :     AddFormatInfo(FOO(R8I           ),  1,  8, 0, 0, 0,  0,0, UnsizedFormat::R   , false, ComponentType::Int     );
     271           0 :     AddFormatInfo(FOO(R8UI          ),  1,  8, 0, 0, 0,  0,0, UnsizedFormat::R   , false, ComponentType::UInt    );
     272           0 :     AddFormatInfo(FOO(R16I          ),  2, 16, 0, 0, 0,  0,0, UnsizedFormat::R   , false, ComponentType::Int     );
     273           0 :     AddFormatInfo(FOO(R16UI         ),  2, 16, 0, 0, 0,  0,0, UnsizedFormat::R   , false, ComponentType::UInt    );
     274           0 :     AddFormatInfo(FOO(R32I          ),  4, 32, 0, 0, 0,  0,0, UnsizedFormat::R   , false, ComponentType::Int     );
     275           0 :     AddFormatInfo(FOO(R32UI         ),  4, 32, 0, 0, 0,  0,0, UnsizedFormat::R   , false, ComponentType::UInt    );
     276             : 
     277           0 :     AddFormatInfo(FOO(RG8I          ),  2,  8, 8, 0, 0,  0,0, UnsizedFormat::RG  , false, ComponentType::Int     );
     278           0 :     AddFormatInfo(FOO(RG8UI         ),  2,  8, 8, 0, 0,  0,0, UnsizedFormat::RG  , false, ComponentType::UInt    );
     279           0 :     AddFormatInfo(FOO(RG16I         ),  4, 16,16, 0, 0,  0,0, UnsizedFormat::RG  , false, ComponentType::Int     );
     280           0 :     AddFormatInfo(FOO(RG16UI        ),  4, 16,16, 0, 0,  0,0, UnsizedFormat::RG  , false, ComponentType::UInt    );
     281           0 :     AddFormatInfo(FOO(RG32I         ),  8, 32,32, 0, 0,  0,0, UnsizedFormat::RG  , false, ComponentType::Int     );
     282           0 :     AddFormatInfo(FOO(RG32UI        ),  8, 32,32, 0, 0,  0,0, UnsizedFormat::RG  , false, ComponentType::UInt    );
     283             : 
     284           0 :     AddFormatInfo(FOO(RGB8I         ),  3,  8, 8, 8, 0,  0,0, UnsizedFormat::RGB , false, ComponentType::Int     );
     285           0 :     AddFormatInfo(FOO(RGB8UI        ),  3,  8, 8, 8, 0,  0,0, UnsizedFormat::RGB , false, ComponentType::UInt    );
     286           0 :     AddFormatInfo(FOO(RGB16I        ),  6, 16,16,16, 0,  0,0, UnsizedFormat::RGB , false, ComponentType::Int     );
     287           0 :     AddFormatInfo(FOO(RGB16UI       ),  6, 16,16,16, 0,  0,0, UnsizedFormat::RGB , false, ComponentType::UInt    );
     288           0 :     AddFormatInfo(FOO(RGB32I        ), 12, 32,32,32, 0,  0,0, UnsizedFormat::RGB , false, ComponentType::Int     );
     289           0 :     AddFormatInfo(FOO(RGB32UI       ), 12, 32,32,32, 0,  0,0, UnsizedFormat::RGB , false, ComponentType::UInt    );
     290             : 
     291           0 :     AddFormatInfo(FOO(RGBA8I        ),  4,  8, 8, 8, 8,  0,0, UnsizedFormat::RGBA, false, ComponentType::Int     );
     292           0 :     AddFormatInfo(FOO(RGBA8UI       ),  4,  8, 8, 8, 8,  0,0, UnsizedFormat::RGBA, false, ComponentType::UInt    );
     293           0 :     AddFormatInfo(FOO(RGBA16I       ),  8, 16,16,16,16,  0,0, UnsizedFormat::RGBA, false, ComponentType::Int     );
     294           0 :     AddFormatInfo(FOO(RGBA16UI      ),  8, 16,16,16,16,  0,0, UnsizedFormat::RGBA, false, ComponentType::UInt    );
     295           0 :     AddFormatInfo(FOO(RGBA32I       ), 16, 32,32,32,32,  0,0, UnsizedFormat::RGBA, false, ComponentType::Int     );
     296           0 :     AddFormatInfo(FOO(RGBA32UI      ), 16, 32,32,32,32,  0,0, UnsizedFormat::RGBA, false, ComponentType::UInt    );
     297             : 
     298             :     // GLES 3.0.4, p133, table 3.14
     299           0 :     AddFormatInfo(FOO(DEPTH_COMPONENT16 ), 2, 0,0,0,0, 16,0, UnsizedFormat::D , false, ComponentType::NormUInt);
     300           0 :     AddFormatInfo(FOO(DEPTH_COMPONENT24 ), 3, 0,0,0,0, 24,0, UnsizedFormat::D , false, ComponentType::NormUInt);
     301           0 :     AddFormatInfo(FOO(DEPTH_COMPONENT32F), 4, 0,0,0,0, 32,0, UnsizedFormat::D , false, ComponentType::Float);
     302           0 :     AddFormatInfo(FOO(DEPTH24_STENCIL8  ), 4, 0,0,0,0, 24,8, UnsizedFormat::DEPTH_STENCIL, false, ComponentType::Special);
     303           0 :     AddFormatInfo(FOO(DEPTH32F_STENCIL8 ), 5, 0,0,0,0, 32,8, UnsizedFormat::DEPTH_STENCIL, false, ComponentType::Special);
     304             : 
     305             :     // GLES 3.0.4, p205-206, "Required Renderbuffer Formats"
     306           0 :     AddFormatInfo(FOO(STENCIL_INDEX8), 1, 0,0,0,0, 0,8, UnsizedFormat::S, false, ComponentType::UInt);
     307             : 
     308             :     // GLES 3.0.4, p147, table 3.19
     309             :     // GLES 3.0.4  p286+  $C.1 "ETC Compressed Texture Image Formats"
     310           0 :     AddFormatInfo(FOO(COMPRESSED_RGB8_ETC2                     ), 0, 1,1,1,0, 0,0, UnsizedFormat::RGB , false, ComponentType::NormUInt);
     311           0 :     AddFormatInfo(FOO(COMPRESSED_SRGB8_ETC2                    ), 0, 1,1,1,0, 0,0, UnsizedFormat::RGB , true , ComponentType::NormUInt);
     312           0 :     AddFormatInfo(FOO(COMPRESSED_RGBA8_ETC2_EAC                ), 0, 1,1,1,1, 0,0, UnsizedFormat::RGBA, false, ComponentType::NormUInt);
     313           0 :     AddFormatInfo(FOO(COMPRESSED_SRGB8_ALPHA8_ETC2_EAC         ), 0, 1,1,1,1, 0,0, UnsizedFormat::RGBA, true , ComponentType::NormUInt);
     314           0 :     AddFormatInfo(FOO(COMPRESSED_R11_EAC                       ), 0, 1,0,0,0, 0,0, UnsizedFormat::R   , false, ComponentType::NormUInt);
     315           0 :     AddFormatInfo(FOO(COMPRESSED_RG11_EAC                      ), 0, 1,1,0,0, 0,0, UnsizedFormat::RG  , false, ComponentType::NormUInt);
     316           0 :     AddFormatInfo(FOO(COMPRESSED_SIGNED_R11_EAC                ), 0, 1,0,0,0, 0,0, UnsizedFormat::R   , false, ComponentType::NormInt );
     317           0 :     AddFormatInfo(FOO(COMPRESSED_SIGNED_RG11_EAC               ), 0, 1,1,0,0, 0,0, UnsizedFormat::RG  , false, ComponentType::NormInt );
     318           0 :     AddFormatInfo(FOO(COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2 ), 0, 1,1,1,1, 0,0, UnsizedFormat::RGBA, false, ComponentType::NormUInt);
     319           0 :     AddFormatInfo(FOO(COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2), 0, 1,1,1,1, 0,0, UnsizedFormat::RGBA, true , ComponentType::NormUInt);
     320             : 
     321             :     // AMD_compressed_ATC_texture
     322           0 :     AddFormatInfo(FOO(ATC_RGB_AMD                    ), 0, 1,1,1,0, 0,0, UnsizedFormat::RGB , false, ComponentType::NormUInt);
     323           0 :     AddFormatInfo(FOO(ATC_RGBA_EXPLICIT_ALPHA_AMD    ), 0, 1,1,1,1, 0,0, UnsizedFormat::RGBA, false, ComponentType::NormUInt);
     324           0 :     AddFormatInfo(FOO(ATC_RGBA_INTERPOLATED_ALPHA_AMD), 0, 1,1,1,1, 0,0, UnsizedFormat::RGBA, false, ComponentType::NormUInt);
     325             : 
     326             :     // EXT_texture_compression_s3tc
     327           0 :     AddFormatInfo(FOO(COMPRESSED_RGB_S3TC_DXT1_EXT ), 0, 1,1,1,0, 0,0, UnsizedFormat::RGB , false, ComponentType::NormUInt);
     328           0 :     AddFormatInfo(FOO(COMPRESSED_RGBA_S3TC_DXT1_EXT), 0, 1,1,1,1, 0,0, UnsizedFormat::RGBA, false, ComponentType::NormUInt);
     329           0 :     AddFormatInfo(FOO(COMPRESSED_RGBA_S3TC_DXT3_EXT), 0, 1,1,1,1, 0,0, UnsizedFormat::RGBA, false, ComponentType::NormUInt);
     330           0 :     AddFormatInfo(FOO(COMPRESSED_RGBA_S3TC_DXT5_EXT), 0, 1,1,1,1, 0,0, UnsizedFormat::RGBA, false, ComponentType::NormUInt);
     331             : 
     332             :     // EXT_texture_compression_s3tc_srgb
     333           0 :     AddFormatInfo(FOO(COMPRESSED_SRGB_S3TC_DXT1_EXT ), 0, 1,1,1,0, 0,0, UnsizedFormat::RGB , true, ComponentType::NormUInt);
     334           0 :     AddFormatInfo(FOO(COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT), 0, 1,1,1,1, 0,0, UnsizedFormat::RGBA, true, ComponentType::NormUInt);
     335           0 :     AddFormatInfo(FOO(COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT), 0, 1,1,1,1, 0,0, UnsizedFormat::RGBA, true, ComponentType::NormUInt);
     336           0 :     AddFormatInfo(FOO(COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT), 0, 1,1,1,1, 0,0, UnsizedFormat::RGBA, true, ComponentType::NormUInt);
     337             : 
     338             :     // KHR_texture_compression_astc_ldr
     339           0 :     AddFormatInfo(FOO(COMPRESSED_RGBA_ASTC_4x4_KHR          ), 0, 1,1,1,1, 0,0, UnsizedFormat::RGBA, false, ComponentType::NormUInt);
     340           0 :     AddFormatInfo(FOO(COMPRESSED_RGBA_ASTC_5x4_KHR          ), 0, 1,1,1,1, 0,0, UnsizedFormat::RGBA, false, ComponentType::NormUInt);
     341           0 :     AddFormatInfo(FOO(COMPRESSED_RGBA_ASTC_5x5_KHR          ), 0, 1,1,1,1, 0,0, UnsizedFormat::RGBA, false, ComponentType::NormUInt);
     342           0 :     AddFormatInfo(FOO(COMPRESSED_RGBA_ASTC_6x5_KHR          ), 0, 1,1,1,1, 0,0, UnsizedFormat::RGBA, false, ComponentType::NormUInt);
     343           0 :     AddFormatInfo(FOO(COMPRESSED_RGBA_ASTC_6x6_KHR          ), 0, 1,1,1,1, 0,0, UnsizedFormat::RGBA, false, ComponentType::NormUInt);
     344           0 :     AddFormatInfo(FOO(COMPRESSED_RGBA_ASTC_8x5_KHR          ), 0, 1,1,1,1, 0,0, UnsizedFormat::RGBA, false, ComponentType::NormUInt);
     345           0 :     AddFormatInfo(FOO(COMPRESSED_RGBA_ASTC_8x6_KHR          ), 0, 1,1,1,1, 0,0, UnsizedFormat::RGBA, false, ComponentType::NormUInt);
     346           0 :     AddFormatInfo(FOO(COMPRESSED_RGBA_ASTC_8x8_KHR          ), 0, 1,1,1,1, 0,0, UnsizedFormat::RGBA, false, ComponentType::NormUInt);
     347           0 :     AddFormatInfo(FOO(COMPRESSED_RGBA_ASTC_10x5_KHR         ), 0, 1,1,1,1, 0,0, UnsizedFormat::RGBA, false, ComponentType::NormUInt);
     348           0 :     AddFormatInfo(FOO(COMPRESSED_RGBA_ASTC_10x6_KHR         ), 0, 1,1,1,1, 0,0, UnsizedFormat::RGBA, false, ComponentType::NormUInt);
     349           0 :     AddFormatInfo(FOO(COMPRESSED_RGBA_ASTC_10x8_KHR         ), 0, 1,1,1,1, 0,0, UnsizedFormat::RGBA, false, ComponentType::NormUInt);
     350           0 :     AddFormatInfo(FOO(COMPRESSED_RGBA_ASTC_10x10_KHR        ), 0, 1,1,1,1, 0,0, UnsizedFormat::RGBA, false, ComponentType::NormUInt);
     351           0 :     AddFormatInfo(FOO(COMPRESSED_RGBA_ASTC_12x10_KHR        ), 0, 1,1,1,1, 0,0, UnsizedFormat::RGBA, false, ComponentType::NormUInt);
     352           0 :     AddFormatInfo(FOO(COMPRESSED_RGBA_ASTC_12x12_KHR        ), 0, 1,1,1,1, 0,0, UnsizedFormat::RGBA, false, ComponentType::NormUInt);
     353             : 
     354           0 :     AddFormatInfo(FOO(COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR  ), 0, 1,1,1,1, 0,0, UnsizedFormat::RGBA, true , ComponentType::NormUInt);
     355           0 :     AddFormatInfo(FOO(COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR  ), 0, 1,1,1,1, 0,0, UnsizedFormat::RGBA, true , ComponentType::NormUInt);
     356           0 :     AddFormatInfo(FOO(COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR  ), 0, 1,1,1,1, 0,0, UnsizedFormat::RGBA, true , ComponentType::NormUInt);
     357           0 :     AddFormatInfo(FOO(COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR  ), 0, 1,1,1,1, 0,0, UnsizedFormat::RGBA, true , ComponentType::NormUInt);
     358           0 :     AddFormatInfo(FOO(COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR  ), 0, 1,1,1,1, 0,0, UnsizedFormat::RGBA, true , ComponentType::NormUInt);
     359           0 :     AddFormatInfo(FOO(COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR  ), 0, 1,1,1,1, 0,0, UnsizedFormat::RGBA, true , ComponentType::NormUInt);
     360           0 :     AddFormatInfo(FOO(COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR  ), 0, 1,1,1,1, 0,0, UnsizedFormat::RGBA, true , ComponentType::NormUInt);
     361           0 :     AddFormatInfo(FOO(COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR  ), 0, 1,1,1,1, 0,0, UnsizedFormat::RGBA, true , ComponentType::NormUInt);
     362           0 :     AddFormatInfo(FOO(COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR ), 0, 1,1,1,1, 0,0, UnsizedFormat::RGBA, true , ComponentType::NormUInt);
     363           0 :     AddFormatInfo(FOO(COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR ), 0, 1,1,1,1, 0,0, UnsizedFormat::RGBA, true , ComponentType::NormUInt);
     364           0 :     AddFormatInfo(FOO(COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR ), 0, 1,1,1,1, 0,0, UnsizedFormat::RGBA, true , ComponentType::NormUInt);
     365           0 :     AddFormatInfo(FOO(COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR), 0, 1,1,1,1, 0,0, UnsizedFormat::RGBA, true , ComponentType::NormUInt);
     366           0 :     AddFormatInfo(FOO(COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR), 0, 1,1,1,1, 0,0, UnsizedFormat::RGBA, true , ComponentType::NormUInt);
     367           0 :     AddFormatInfo(FOO(COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR), 0, 1,1,1,1, 0,0, UnsizedFormat::RGBA, true , ComponentType::NormUInt);
     368             : 
     369             :     // IMG_texture_compression_pvrtc
     370           0 :     AddFormatInfo(FOO(COMPRESSED_RGB_PVRTC_4BPPV1 ), 0, 1,1,1,0, 0,0, UnsizedFormat::RGB , false, ComponentType::NormUInt);
     371           0 :     AddFormatInfo(FOO(COMPRESSED_RGBA_PVRTC_4BPPV1), 0, 1,1,1,1, 0,0, UnsizedFormat::RGBA, false, ComponentType::NormUInt);
     372           0 :     AddFormatInfo(FOO(COMPRESSED_RGB_PVRTC_2BPPV1 ), 0, 1,1,1,0, 0,0, UnsizedFormat::RGB , false, ComponentType::NormUInt);
     373           0 :     AddFormatInfo(FOO(COMPRESSED_RGBA_PVRTC_2BPPV1), 0, 1,1,1,1, 0,0, UnsizedFormat::RGBA, false, ComponentType::NormUInt);
     374             : 
     375             :     // OES_compressed_ETC1_RGB8_texture
     376           0 :     AddFormatInfo(FOO(ETC1_RGB8_OES), 0, 1,1,1,0, 0,0, UnsizedFormat::RGB, false, ComponentType::NormUInt);
     377             : 
     378             : #undef FOO
     379             : 
     380             :     // 'Virtual' effective formats have no sizedFormat.
     381             : #define FOO(x) EffectiveFormat::x, #x, 0
     382             : 
     383             :     // GLES 3.0.4, p128, table 3.12.
     384           0 :     AddFormatInfo(FOO(Luminance8Alpha8), 2, 8,0,0,8, 0,0, UnsizedFormat::LA, false, ComponentType::NormUInt);
     385           0 :     AddFormatInfo(FOO(Luminance8      ), 1, 8,0,0,0, 0,0, UnsizedFormat::L , false, ComponentType::NormUInt);
     386           0 :     AddFormatInfo(FOO(Alpha8          ), 1, 0,0,0,8, 0,0, UnsizedFormat::A , false, ComponentType::NormUInt);
     387             : 
     388             :     // OES_texture_float
     389           0 :     AddFormatInfo(FOO(Luminance32FAlpha32F), 8, 32,0,0,32, 0,0, UnsizedFormat::LA, false, ComponentType::Float);
     390           0 :     AddFormatInfo(FOO(Luminance32F        ), 4, 32,0,0, 0, 0,0, UnsizedFormat::L , false, ComponentType::Float);
     391           0 :     AddFormatInfo(FOO(Alpha32F            ), 4,  0,0,0,32, 0,0, UnsizedFormat::A , false, ComponentType::Float);
     392             : 
     393             :     // OES_texture_half_float
     394           0 :     AddFormatInfo(FOO(Luminance16FAlpha16F), 4, 16,0,0,16, 0,0, UnsizedFormat::LA, false, ComponentType::Float);
     395           0 :     AddFormatInfo(FOO(Luminance16F        ), 2, 16,0,0, 0, 0,0, UnsizedFormat::L , false, ComponentType::Float);
     396           0 :     AddFormatInfo(FOO(Alpha16F            ), 2,  0,0,0,16, 0,0, UnsizedFormat::A , false, ComponentType::Float);
     397             : 
     398             : #undef FOO
     399             : 
     400             :     ////////////////////////////////////////////////////////////////////////////
     401             : 
     402             :     const auto fnSetCopyDecay = [](EffectiveFormat src, EffectiveFormat asR,
     403             :                                    EffectiveFormat asRG, EffectiveFormat asRGB,
     404             :                                    EffectiveFormat asRGBA, EffectiveFormat asL,
     405           0 :                                    EffectiveFormat asA, EffectiveFormat asLA)
     406             :     {
     407           0 :         auto& map = GetFormatInfo_NoLock(src)->copyDecayFormats;
     408             : 
     409           0 :         const auto fnSet = [&map](UnsizedFormat uf, EffectiveFormat ef) {
     410           0 :             if (ef == EffectiveFormat::MAX)
     411           0 :                 return;
     412             : 
     413           0 :             const auto* format = GetFormatInfo_NoLock(ef);
     414           0 :             MOZ_ASSERT(format->unsizedFormat == uf);
     415           0 :             AlwaysInsert(map, uf, format);
     416           0 :         };
     417             : 
     418           0 :         fnSet(UnsizedFormat::R   , asR);
     419           0 :         fnSet(UnsizedFormat::RG  , asRG);
     420           0 :         fnSet(UnsizedFormat::RGB , asRGB);
     421           0 :         fnSet(UnsizedFormat::RGBA, asRGBA);
     422           0 :         fnSet(UnsizedFormat::L   , asL);
     423           0 :         fnSet(UnsizedFormat::A   , asA);
     424           0 :         fnSet(UnsizedFormat::LA  , asLA);
     425           0 :     };
     426             : 
     427             : #define SET_COPY_DECAY(src,asR,asRG,asRGB,asRGBA,asL,asA,asLA) \
     428             :     fnSetCopyDecay(EffectiveFormat::src, EffectiveFormat::asR, EffectiveFormat::asRG,     \
     429             :                    EffectiveFormat::asRGB, EffectiveFormat::asRGBA, EffectiveFormat::asL, \
     430             :                    EffectiveFormat::asA, EffectiveFormat::asLA);
     431             : 
     432             :     //////
     433             : 
     434             : #define SET_BY_SUFFIX(X) \
     435             :         SET_COPY_DECAY(   R##X, R##X,   MAX,    MAX,     MAX, Luminance##X,      MAX,                    MAX) \
     436             :         SET_COPY_DECAY(  RG##X, R##X, RG##X,    MAX,     MAX, Luminance##X,      MAX,                    MAX) \
     437             :         SET_COPY_DECAY( RGB##X, R##X, RG##X, RGB##X,     MAX, Luminance##X,      MAX,                    MAX) \
     438             :         SET_COPY_DECAY(RGBA##X, R##X, RG##X, RGB##X, RGBA##X, Luminance##X, Alpha##X, Luminance##X##Alpha##X)
     439             : 
     440           0 :     SET_BY_SUFFIX(8)   // WebGL decided that RGB8 should be guaranteed renderable.
     441           0 :     SET_BY_SUFFIX(16F) // RGB16F is renderable in EXT_color_buffer_half_float, though not
     442             :                        // EXT_color_buffer_float.
     443           0 :     SET_BY_SUFFIX(32F) // Technically RGB32F is never renderable, but no harm here.
     444             : 
     445             : #undef SET_BY_SUFFIX
     446             : 
     447             :     //////
     448             : 
     449             : #define SET_BY_SUFFIX(X) \
     450             :         SET_COPY_DECAY(   R##X, R##X,   MAX,    MAX,     MAX, MAX, MAX, MAX) \
     451             :         SET_COPY_DECAY(  RG##X, R##X, RG##X,    MAX,     MAX, MAX, MAX, MAX) \
     452             :         SET_COPY_DECAY(RGBA##X, R##X, RG##X, RGB##X, RGBA##X, MAX, MAX, MAX)
     453             : 
     454           0 :     SET_BY_SUFFIX(8I)
     455           0 :     SET_BY_SUFFIX(8UI)
     456             : 
     457           0 :     SET_BY_SUFFIX(16I)
     458           0 :     SET_BY_SUFFIX(16UI)
     459             : 
     460           0 :     SET_BY_SUFFIX(32I)
     461           0 :     SET_BY_SUFFIX(32UI)
     462             : 
     463             : #undef SET_BY_SUFFIX
     464             : 
     465             :     //////
     466             : 
     467           0 :     SET_COPY_DECAY(    RGB565, R8, RG8, RGB565,      MAX, Luminance8,    MAX,              MAX)
     468           0 :     SET_COPY_DECAY(     RGBA4, R8, RG8, RGB565,    RGBA4, Luminance8, Alpha8, Luminance8Alpha8)
     469           0 :     SET_COPY_DECAY(   RGB5_A1, R8, RG8, RGB565,  RGB5_A1, Luminance8, Alpha8, Luminance8Alpha8)
     470           0 :     SET_COPY_DECAY(  RGB10_A2, R8, RG8,   RGB8, RGB10_A2, Luminance8, Alpha8,              MAX)
     471             : 
     472           0 :     SET_COPY_DECAY(RGB10_A2UI, R8UI, RG8UI, RGB8UI, RGB10_A2UI, MAX, MAX, MAX)
     473             : 
     474           0 :     SET_COPY_DECAY(SRGB8_ALPHA8, MAX, MAX, MAX, SRGB8_ALPHA8, MAX, Alpha8, MAX)
     475             : 
     476           0 :     SET_COPY_DECAY(R11F_G11F_B10F, R16F, RG16F, R11F_G11F_B10F, MAX, Luminance16F, MAX, MAX)
     477             : 
     478             : #undef SET_COPY_DECAY
     479           0 : }
     480             : 
     481             : //////////////////////////////////////////////////////////////////////////////////////////
     482             : 
     483             : bool gAreFormatTablesInitialized = false;
     484             : 
     485             : static void
     486           0 : EnsureInitFormatTables(const StaticMutexAutoLock&) // Prove that you locked it!
     487             : {
     488           0 :     if (MOZ_LIKELY(gAreFormatTablesInitialized))
     489           0 :         return;
     490             : 
     491           0 :     gAreFormatTablesInitialized = true;
     492             : 
     493           0 :     InitCompressedFormatInfo();
     494           0 :     InitFormatInfo();
     495             : }
     496             : 
     497             : //////////////////////////////////////////////////////////////////////////////////////////
     498             : // Public funcs
     499             : 
     500           3 : StaticMutex gFormatMapMutex;
     501             : 
     502             : const FormatInfo*
     503           0 : GetFormat(EffectiveFormat format)
     504             : {
     505           0 :     StaticMutexAutoLock lock(gFormatMapMutex);
     506           0 :     EnsureInitFormatTables(lock);
     507             : 
     508           0 :     return GetFormatInfo_NoLock(format);
     509             : }
     510             : 
     511             : //////////////////////////////////////////////////////////////////////////////////////////
     512             : 
     513             : const FormatInfo*
     514           0 : FormatInfo::GetCopyDecayFormat(UnsizedFormat uf) const
     515             : {
     516           0 :     return FindOrNull(this->copyDecayFormats, uf);
     517             : }
     518             : 
     519             : bool
     520           0 : GetBytesPerPixel(const PackingInfo& packing, uint8_t* const out_bytes)
     521             : {
     522             :     uint8_t bytesPerChannel;
     523             : 
     524           0 :     switch (packing.type) {
     525             :     case LOCAL_GL_UNSIGNED_SHORT_4_4_4_4:
     526             :     case LOCAL_GL_UNSIGNED_SHORT_5_5_5_1:
     527             :     case LOCAL_GL_UNSIGNED_SHORT_5_6_5:
     528           0 :         *out_bytes = 2;
     529           0 :         return true;
     530             : 
     531             :     case LOCAL_GL_UNSIGNED_INT_10F_11F_11F_REV:
     532             :     case LOCAL_GL_UNSIGNED_INT_2_10_10_10_REV:
     533             :     case LOCAL_GL_UNSIGNED_INT_24_8:
     534             :     case LOCAL_GL_UNSIGNED_INT_5_9_9_9_REV:
     535           0 :         *out_bytes = 4;
     536           0 :         return true;
     537             : 
     538             :     case LOCAL_GL_FLOAT_32_UNSIGNED_INT_24_8_REV:
     539           0 :         *out_bytes = 8;
     540           0 :         return true;
     541             : 
     542             :     // Alright, that's all the fixed-size unpackTypes.
     543             : 
     544             :     case LOCAL_GL_BYTE:
     545             :     case LOCAL_GL_UNSIGNED_BYTE:
     546           0 :         bytesPerChannel = 1;
     547           0 :         break;
     548             : 
     549             :     case LOCAL_GL_SHORT:
     550             :     case LOCAL_GL_UNSIGNED_SHORT:
     551             :     case LOCAL_GL_HALF_FLOAT:
     552             :     case LOCAL_GL_HALF_FLOAT_OES:
     553           0 :         bytesPerChannel = 2;
     554           0 :         break;
     555             : 
     556             :     case LOCAL_GL_INT:
     557             :     case LOCAL_GL_UNSIGNED_INT:
     558             :     case LOCAL_GL_FLOAT:
     559           0 :         bytesPerChannel = 4;
     560           0 :         break;
     561             : 
     562             :     default:
     563           0 :         return false;
     564             :     }
     565             : 
     566             :     uint8_t channels;
     567             : 
     568           0 :     switch (packing.format) {
     569             :     case LOCAL_GL_RED:
     570             :     case LOCAL_GL_RED_INTEGER:
     571             :     case LOCAL_GL_LUMINANCE:
     572             :     case LOCAL_GL_ALPHA:
     573             :     case LOCAL_GL_DEPTH_COMPONENT:
     574           0 :         channels = 1;
     575           0 :         break;
     576             : 
     577             :     case LOCAL_GL_RG:
     578             :     case LOCAL_GL_RG_INTEGER:
     579             :     case LOCAL_GL_LUMINANCE_ALPHA:
     580           0 :         channels = 2;
     581           0 :         break;
     582             : 
     583             :     case LOCAL_GL_RGB:
     584             :     case LOCAL_GL_RGB_INTEGER:
     585             :     case LOCAL_GL_SRGB:
     586           0 :         channels = 3;
     587           0 :         break;
     588             : 
     589             :     case LOCAL_GL_BGRA:
     590             :     case LOCAL_GL_RGBA:
     591             :     case LOCAL_GL_RGBA_INTEGER:
     592             :     case LOCAL_GL_SRGB_ALPHA:
     593           0 :         channels = 4;
     594           0 :         break;
     595             : 
     596             :     default:
     597           0 :         return false;
     598             :     }
     599             : 
     600           0 :     *out_bytes = bytesPerChannel * channels;
     601           0 :     return true;
     602             : }
     603             : 
     604             : uint8_t
     605           0 : BytesPerPixel(const PackingInfo& packing)
     606             : {
     607             :     uint8_t ret;
     608           0 :     if (MOZ_LIKELY(GetBytesPerPixel(packing, &ret)))
     609           0 :         return ret;
     610             : 
     611           0 :     gfxCriticalError() << "Bad `packing`: " << gfx::hexa(packing.format) << ", "
     612           0 :                        << gfx::hexa(packing.type);
     613           0 :     MOZ_CRASH("Bad `packing`.");
     614             : }
     615             : 
     616             : //////////////////////////////////////////////////////////////////////////////////////////
     617             : //////////////////////////////////////////////////////////////////////////////////////////
     618             : //////////////////////////////////////////////////////////////////////////////////////////
     619             : //////////////////////////////////////////////////////////////////////////////////////////
     620             : //////////////////////////////////////////////////////////////////////////////////////////
     621             : //////////////////////////////////////////////////////////////////////////////////////////
     622             : //////////////////////////////////////////////////////////////////////////////////////////
     623             : //////////////////////////////////////////////////////////////////////////////////////////
     624             : // FormatUsageAuthority
     625             : 
     626             : bool
     627           0 : FormatUsageInfo::IsUnpackValid(const PackingInfo& key,
     628             :                                const DriverUnpackInfo** const out_value) const
     629             : {
     630           0 :     auto itr = validUnpacks.find(key);
     631           0 :     if (itr == validUnpacks.end())
     632           0 :         return false;
     633             : 
     634           0 :     *out_value = &(itr->second);
     635           0 :     return true;
     636             : }
     637             : 
     638             : void
     639           0 : FormatUsageInfo::ResolveMaxSamples(gl::GLContext* gl)
     640             : {
     641           0 :     MOZ_ASSERT(!this->maxSamplesKnown);
     642           0 :     MOZ_ASSERT(this->maxSamples == 0);
     643           0 :     MOZ_ASSERT(gl->IsCurrent());
     644             : 
     645           0 :     this->maxSamplesKnown = true;
     646             : 
     647           0 :     const GLenum internalFormat = this->format->sizedFormat;
     648           0 :     if (!internalFormat)
     649           0 :         return;
     650             : 
     651           0 :     if (!gl->IsSupported(gl::GLFeature::internalformat_query))
     652           0 :         return; // Leave it at 0.
     653             : 
     654           0 :     GLint maxSamplesGL = 0;
     655             :     gl->fGetInternalformativ(LOCAL_GL_RENDERBUFFER, internalFormat, LOCAL_GL_SAMPLES, 1,
     656           0 :                              &maxSamplesGL);
     657             : 
     658           0 :     this->maxSamples = maxSamplesGL;
     659             : }
     660             : 
     661             : ////////////////////////////////////////
     662             : 
     663             : static void
     664           0 : AddSimpleUnsized(FormatUsageAuthority* fua, GLenum unpackFormat, GLenum unpackType,
     665             :                  EffectiveFormat effFormat)
     666             : {
     667           0 :     auto usage = fua->EditUsage(effFormat);
     668           0 :     usage->isFilterable = true;
     669             : 
     670           0 :     const PackingInfo pi = {unpackFormat, unpackType};
     671           0 :     const DriverUnpackInfo dui = {unpackFormat, unpackFormat, unpackType};
     672           0 :     fua->AddTexUnpack(usage, pi, dui);
     673             : 
     674           0 :     fua->AllowUnsizedTexFormat(pi, usage);
     675           0 : };
     676             : 
     677             : 
     678             : /*static*/ const GLint FormatUsageInfo::kLuminanceSwizzleRGBA[4] = { LOCAL_GL_RED,
     679             :                                                                      LOCAL_GL_RED,
     680             :                                                                      LOCAL_GL_RED,
     681             :                                                                      LOCAL_GL_ONE };
     682             : /*static*/ const GLint FormatUsageInfo::kAlphaSwizzleRGBA[4] = { LOCAL_GL_ZERO,
     683             :                                                                  LOCAL_GL_ZERO,
     684             :                                                                  LOCAL_GL_ZERO,
     685             :                                                                  LOCAL_GL_RED };
     686             : /*static*/ const GLint FormatUsageInfo::kLumAlphaSwizzleRGBA[4] = { LOCAL_GL_RED,
     687             :                                                                     LOCAL_GL_RED,
     688             :                                                                     LOCAL_GL_RED,
     689             :                                                                     LOCAL_GL_GREEN };
     690             : 
     691             : static bool
     692           0 : AddLegacyFormats_LA8(FormatUsageAuthority* fua, gl::GLContext* gl)
     693             : {
     694           0 :     if (gl->IsCoreProfile()) {
     695           0 :         if (!gl->IsSupported(gl::GLFeature::texture_swizzle))
     696           0 :             return false;
     697             : 
     698             :         PackingInfo pi;
     699             :         DriverUnpackInfo dui;
     700             : 
     701             :         const auto fnAdd = [fua, &pi, &dui](EffectiveFormat effFormat,
     702           0 :                                             const GLint* swizzle)
     703           0 :         {
     704           0 :             auto usage = fua->EditUsage(effFormat);
     705           0 :             usage->isFilterable = true;
     706           0 :             usage->textureSwizzleRGBA = swizzle;
     707             : 
     708           0 :             fua->AddTexUnpack(usage, pi, dui);
     709             : 
     710           0 :             fua->AllowUnsizedTexFormat(pi, usage);
     711           0 :         };
     712             : 
     713           0 :         pi = {LOCAL_GL_LUMINANCE, LOCAL_GL_UNSIGNED_BYTE};
     714           0 :         dui = {LOCAL_GL_R8, LOCAL_GL_RED, LOCAL_GL_UNSIGNED_BYTE};
     715           0 :         fnAdd(EffectiveFormat::Luminance8, FormatUsageInfo::kLuminanceSwizzleRGBA);
     716             : 
     717           0 :         pi = {LOCAL_GL_ALPHA, LOCAL_GL_UNSIGNED_BYTE};
     718           0 :         dui = {LOCAL_GL_R8, LOCAL_GL_RED, LOCAL_GL_UNSIGNED_BYTE};
     719           0 :         fnAdd(EffectiveFormat::Alpha8, FormatUsageInfo::kAlphaSwizzleRGBA);
     720             : 
     721           0 :         pi = {LOCAL_GL_LUMINANCE_ALPHA, LOCAL_GL_UNSIGNED_BYTE};
     722           0 :         dui = {LOCAL_GL_RG8, LOCAL_GL_RG, LOCAL_GL_UNSIGNED_BYTE};
     723           0 :         fnAdd(EffectiveFormat::Luminance8Alpha8, FormatUsageInfo::kLumAlphaSwizzleRGBA);
     724             :     } else {
     725           0 :         AddSimpleUnsized(fua, LOCAL_GL_LUMINANCE      , LOCAL_GL_UNSIGNED_BYTE, EffectiveFormat::Luminance8      );
     726           0 :         AddSimpleUnsized(fua, LOCAL_GL_ALPHA          , LOCAL_GL_UNSIGNED_BYTE, EffectiveFormat::Alpha8          );
     727           0 :         AddSimpleUnsized(fua, LOCAL_GL_LUMINANCE_ALPHA, LOCAL_GL_UNSIGNED_BYTE, EffectiveFormat::Luminance8Alpha8);
     728             :     }
     729             : 
     730           0 :     return true;
     731             : }
     732             : 
     733             : static bool
     734           0 : AddUnsizedFormats(FormatUsageAuthority* fua, gl::GLContext* gl)
     735             : {
     736             :     // GLES 2.0.25, p63, Table 3.4
     737           0 :     AddSimpleUnsized(fua, LOCAL_GL_RGBA, LOCAL_GL_UNSIGNED_BYTE         , EffectiveFormat::RGBA8  );
     738           0 :     AddSimpleUnsized(fua, LOCAL_GL_RGBA, LOCAL_GL_UNSIGNED_SHORT_4_4_4_4, EffectiveFormat::RGBA4  );
     739           0 :     AddSimpleUnsized(fua, LOCAL_GL_RGBA, LOCAL_GL_UNSIGNED_SHORT_5_5_5_1, EffectiveFormat::RGB5_A1);
     740           0 :     AddSimpleUnsized(fua, LOCAL_GL_RGB , LOCAL_GL_UNSIGNED_BYTE         , EffectiveFormat::RGB8   );
     741           0 :     AddSimpleUnsized(fua, LOCAL_GL_RGB , LOCAL_GL_UNSIGNED_SHORT_5_6_5  , EffectiveFormat::RGB565 );
     742             : 
     743             :     // L, A, LA
     744           0 :     return AddLegacyFormats_LA8(fua, gl);
     745             : }
     746             : 
     747             : void
     748           0 : FormatUsageInfo::SetRenderable()
     749             : {
     750           0 :     this->isRenderable = true;
     751             : 
     752             : #ifdef DEBUG
     753           0 :     const auto format = this->format;
     754           0 :     if (format->IsColorFormat()) {
     755           0 :         const auto& map = format->copyDecayFormats;
     756           0 :         const auto itr = map.find(format->unsizedFormat);
     757           0 :         MOZ_ASSERT(itr != map.end(), "Renderable formats must be in copyDecayFormats.");
     758           0 :         MOZ_ASSERT(itr->second == format);
     759             :     }
     760             : #endif
     761           0 : }
     762             : 
     763             : UniquePtr<FormatUsageAuthority>
     764           0 : FormatUsageAuthority::CreateForWebGL1(gl::GLContext* gl)
     765             : {
     766           0 :     UniquePtr<FormatUsageAuthority> ret(new FormatUsageAuthority);
     767           0 :     const auto ptr = ret.get();
     768             : 
     769             :     ////////////////////////////////////////////////////////////////////////////
     770             :     // Usages
     771             : 
     772             :     const auto fnSet = [ptr](EffectiveFormat effFormat, bool isRenderable,
     773           0 :                              bool isFilterable)
     774           0 :     {
     775           0 :         MOZ_ASSERT(!ptr->GetUsage(effFormat));
     776             : 
     777           0 :         auto usage = ptr->EditUsage(effFormat);
     778           0 :         usage->isFilterable = isFilterable;
     779             : 
     780           0 :         if (isRenderable) {
     781           0 :             usage->SetRenderable();
     782             :         }
     783           0 :     };
     784             : 
     785             :     // GLES 2.0.25, p117, Table 4.5
     786             :     // RGBA8 is made renderable in WebGL 1.0, "Framebuffer Object Attachments"
     787             :     //                              render filter
     788             :     //                              able   able
     789           0 :     fnSet(EffectiveFormat::RGBA8  , true, true);
     790           0 :     fnSet(EffectiveFormat::RGBA4  , true, true);
     791           0 :     fnSet(EffectiveFormat::RGB5_A1, true, true);
     792           0 :     fnSet(EffectiveFormat::RGB565 , true, true);
     793             : 
     794             :     // RGB8 is not guaranteed to be renderable, but we should allow it for web-compat.
     795             :     // Min-capability mode should mark this as non-renderable.
     796           0 :     fnSet(EffectiveFormat::RGB8, true, true);
     797             : 
     798           0 :     fnSet(EffectiveFormat::Luminance8Alpha8, false, true);
     799           0 :     fnSet(EffectiveFormat::Luminance8      , false, true);
     800           0 :     fnSet(EffectiveFormat::Alpha8          , false, true);
     801             : 
     802           0 :     fnSet(EffectiveFormat::DEPTH_COMPONENT16, true, false);
     803           0 :     fnSet(EffectiveFormat::STENCIL_INDEX8   , true, false);
     804             : 
     805             :     // Added in WebGL 1.0 spec:
     806           0 :     fnSet(EffectiveFormat::DEPTH24_STENCIL8, true, false);
     807             : 
     808             :     ////////////////////////////////////
     809             :     // RB formats
     810             : 
     811             : #define FOO(x) ptr->AllowRBFormat(LOCAL_GL_ ## x, ptr->GetUsage(EffectiveFormat::x))
     812             : 
     813           0 :     FOO(RGBA4            );
     814           0 :     FOO(RGB5_A1          );
     815           0 :     FOO(RGB565           );
     816           0 :     FOO(DEPTH_COMPONENT16);
     817           0 :     FOO(STENCIL_INDEX8   );
     818             :     //FOO(DEPTH24_STENCIL8 ); // WebGL 1 uses DEPTH_STENCIL instead of DEPTH24_STENCIL8.
     819             : 
     820             : #undef FOO
     821             : 
     822           0 :     ptr->AllowRBFormat(LOCAL_GL_DEPTH_STENCIL,
     823           0 :                        ptr->GetUsage(EffectiveFormat::DEPTH24_STENCIL8));
     824             : 
     825             :     ////////////////////////////////////////////////////////////////////////////
     826             : 
     827           0 :     if (!AddUnsizedFormats(ptr, gl))
     828           0 :         return nullptr;
     829             : 
     830           0 :     return Move(ret);
     831             : }
     832             : 
     833             : UniquePtr<FormatUsageAuthority>
     834           0 : FormatUsageAuthority::CreateForWebGL2(gl::GLContext* gl)
     835             : {
     836           0 :     UniquePtr<FormatUsageAuthority> ret(new FormatUsageAuthority);
     837           0 :     const auto ptr = ret.get();
     838             : 
     839             :     ////////////////////////////////////////////////////////////////////////////
     840             :     // GLES 3.0.4 p111-113
     841             : 
     842             :     const auto fnAddSizedUnpack = [ptr](EffectiveFormat effFormat, GLenum internalFormat,
     843           0 :                                         GLenum unpackFormat, GLenum unpackType)
     844           0 :     {
     845           0 :         auto usage = ptr->EditUsage(effFormat);
     846             : 
     847           0 :         const PackingInfo pi = {unpackFormat, unpackType};
     848           0 :         const DriverUnpackInfo dui = {internalFormat, unpackFormat, unpackType};
     849           0 :         ptr->AddTexUnpack(usage, pi, dui);
     850           0 :     };
     851             : 
     852             : #define FOO(x) EffectiveFormat::x, LOCAL_GL_ ## x
     853             : 
     854             :     // RGBA
     855           0 :     fnAddSizedUnpack(FOO(RGBA8       ), LOCAL_GL_RGBA, LOCAL_GL_UNSIGNED_BYTE              );
     856           0 :     fnAddSizedUnpack(FOO(RGBA4       ), LOCAL_GL_RGBA, LOCAL_GL_UNSIGNED_SHORT_4_4_4_4     );
     857           0 :     fnAddSizedUnpack(FOO(RGBA4       ), LOCAL_GL_RGBA, LOCAL_GL_UNSIGNED_BYTE              );
     858           0 :     fnAddSizedUnpack(FOO(RGB5_A1     ), LOCAL_GL_RGBA, LOCAL_GL_UNSIGNED_SHORT_5_5_5_1     );
     859           0 :     fnAddSizedUnpack(FOO(RGB5_A1     ), LOCAL_GL_RGBA, LOCAL_GL_UNSIGNED_BYTE              );
     860           0 :     fnAddSizedUnpack(FOO(RGB5_A1     ), LOCAL_GL_RGBA, LOCAL_GL_UNSIGNED_INT_2_10_10_10_REV);
     861           0 :     fnAddSizedUnpack(FOO(SRGB8_ALPHA8), LOCAL_GL_RGBA, LOCAL_GL_UNSIGNED_BYTE              );
     862           0 :     fnAddSizedUnpack(FOO(RGBA8_SNORM ), LOCAL_GL_RGBA, LOCAL_GL_BYTE                       );
     863           0 :     fnAddSizedUnpack(FOO(RGB10_A2    ), LOCAL_GL_RGBA, LOCAL_GL_UNSIGNED_INT_2_10_10_10_REV);
     864           0 :     fnAddSizedUnpack(FOO(RGBA16F     ), LOCAL_GL_RGBA, LOCAL_GL_HALF_FLOAT                 );
     865           0 :     fnAddSizedUnpack(FOO(RGBA16F     ), LOCAL_GL_RGBA, LOCAL_GL_FLOAT                      );
     866           0 :     fnAddSizedUnpack(FOO(RGBA32F     ), LOCAL_GL_RGBA, LOCAL_GL_FLOAT                      );
     867             : 
     868             :     // RGBA_INTEGER
     869           0 :     fnAddSizedUnpack(FOO(RGBA8UI   ), LOCAL_GL_RGBA_INTEGER, LOCAL_GL_UNSIGNED_BYTE              );
     870           0 :     fnAddSizedUnpack(FOO(RGBA8I    ), LOCAL_GL_RGBA_INTEGER, LOCAL_GL_BYTE                       );
     871           0 :     fnAddSizedUnpack(FOO(RGBA16UI  ), LOCAL_GL_RGBA_INTEGER, LOCAL_GL_UNSIGNED_SHORT             );
     872           0 :     fnAddSizedUnpack(FOO(RGBA16I   ), LOCAL_GL_RGBA_INTEGER, LOCAL_GL_SHORT                      );
     873           0 :     fnAddSizedUnpack(FOO(RGBA32UI  ), LOCAL_GL_RGBA_INTEGER, LOCAL_GL_UNSIGNED_INT               );
     874           0 :     fnAddSizedUnpack(FOO(RGBA32I   ), LOCAL_GL_RGBA_INTEGER, LOCAL_GL_INT                        );
     875           0 :     fnAddSizedUnpack(FOO(RGB10_A2UI), LOCAL_GL_RGBA_INTEGER, LOCAL_GL_UNSIGNED_INT_2_10_10_10_REV);
     876             : 
     877             :     // RGB
     878           0 :     fnAddSizedUnpack(FOO(RGB8          ), LOCAL_GL_RGB, LOCAL_GL_UNSIGNED_BYTE               );
     879           0 :     fnAddSizedUnpack(FOO(SRGB8         ), LOCAL_GL_RGB, LOCAL_GL_UNSIGNED_BYTE               );
     880           0 :     fnAddSizedUnpack(FOO(RGB565        ), LOCAL_GL_RGB, LOCAL_GL_UNSIGNED_SHORT_5_6_5        );
     881           0 :     fnAddSizedUnpack(FOO(RGB565        ), LOCAL_GL_RGB, LOCAL_GL_UNSIGNED_BYTE               );
     882           0 :     fnAddSizedUnpack(FOO(RGB8_SNORM    ), LOCAL_GL_RGB, LOCAL_GL_BYTE                        );
     883           0 :     fnAddSizedUnpack(FOO(R11F_G11F_B10F), LOCAL_GL_RGB, LOCAL_GL_UNSIGNED_INT_10F_11F_11F_REV);
     884           0 :     fnAddSizedUnpack(FOO(R11F_G11F_B10F), LOCAL_GL_RGB, LOCAL_GL_HALF_FLOAT                  );
     885           0 :     fnAddSizedUnpack(FOO(R11F_G11F_B10F), LOCAL_GL_RGB, LOCAL_GL_FLOAT                       );
     886           0 :     fnAddSizedUnpack(FOO(RGB16F        ), LOCAL_GL_RGB, LOCAL_GL_HALF_FLOAT                  );
     887           0 :     fnAddSizedUnpack(FOO(RGB16F        ), LOCAL_GL_RGB, LOCAL_GL_FLOAT                       );
     888           0 :     fnAddSizedUnpack(FOO(RGB9_E5       ), LOCAL_GL_RGB, LOCAL_GL_UNSIGNED_INT_5_9_9_9_REV    );
     889           0 :     fnAddSizedUnpack(FOO(RGB9_E5       ), LOCAL_GL_RGB, LOCAL_GL_HALF_FLOAT                  );
     890           0 :     fnAddSizedUnpack(FOO(RGB9_E5       ), LOCAL_GL_RGB, LOCAL_GL_FLOAT                       );
     891           0 :     fnAddSizedUnpack(FOO(RGB32F        ), LOCAL_GL_RGB, LOCAL_GL_FLOAT                       );
     892             : 
     893             :     // RGB_INTEGER
     894           0 :     fnAddSizedUnpack(FOO(RGB8UI ), LOCAL_GL_RGB_INTEGER, LOCAL_GL_UNSIGNED_BYTE );
     895           0 :     fnAddSizedUnpack(FOO(RGB8I  ), LOCAL_GL_RGB_INTEGER, LOCAL_GL_BYTE          );
     896           0 :     fnAddSizedUnpack(FOO(RGB16UI), LOCAL_GL_RGB_INTEGER, LOCAL_GL_UNSIGNED_SHORT);
     897           0 :     fnAddSizedUnpack(FOO(RGB16I ), LOCAL_GL_RGB_INTEGER, LOCAL_GL_SHORT         );
     898           0 :     fnAddSizedUnpack(FOO(RGB32UI), LOCAL_GL_RGB_INTEGER, LOCAL_GL_UNSIGNED_INT  );
     899           0 :     fnAddSizedUnpack(FOO(RGB32I ), LOCAL_GL_RGB_INTEGER, LOCAL_GL_INT           );
     900             : 
     901             :     // RG
     902           0 :     fnAddSizedUnpack(FOO(RG8      ), LOCAL_GL_RG, LOCAL_GL_UNSIGNED_BYTE);
     903           0 :     fnAddSizedUnpack(FOO(RG8_SNORM), LOCAL_GL_RG, LOCAL_GL_BYTE         );
     904           0 :     fnAddSizedUnpack(FOO(RG16F    ), LOCAL_GL_RG, LOCAL_GL_HALF_FLOAT   );
     905           0 :     fnAddSizedUnpack(FOO(RG16F    ), LOCAL_GL_RG, LOCAL_GL_FLOAT        );
     906           0 :     fnAddSizedUnpack(FOO(RG32F    ), LOCAL_GL_RG, LOCAL_GL_FLOAT        );
     907             : 
     908             :     // RG_INTEGER
     909           0 :     fnAddSizedUnpack(FOO(RG8UI ), LOCAL_GL_RG_INTEGER, LOCAL_GL_UNSIGNED_BYTE );
     910           0 :     fnAddSizedUnpack(FOO(RG8I  ), LOCAL_GL_RG_INTEGER, LOCAL_GL_BYTE          );
     911           0 :     fnAddSizedUnpack(FOO(RG16UI), LOCAL_GL_RG_INTEGER, LOCAL_GL_UNSIGNED_SHORT);
     912           0 :     fnAddSizedUnpack(FOO(RG16I ), LOCAL_GL_RG_INTEGER, LOCAL_GL_SHORT         );
     913           0 :     fnAddSizedUnpack(FOO(RG32UI), LOCAL_GL_RG_INTEGER, LOCAL_GL_UNSIGNED_INT  );
     914           0 :     fnAddSizedUnpack(FOO(RG32I ), LOCAL_GL_RG_INTEGER, LOCAL_GL_INT           );
     915             : 
     916             :     // RED
     917           0 :     fnAddSizedUnpack(FOO(R8      ), LOCAL_GL_RED, LOCAL_GL_UNSIGNED_BYTE);
     918           0 :     fnAddSizedUnpack(FOO(R8_SNORM), LOCAL_GL_RED, LOCAL_GL_BYTE         );
     919           0 :     fnAddSizedUnpack(FOO(R16F    ), LOCAL_GL_RED, LOCAL_GL_HALF_FLOAT   );
     920           0 :     fnAddSizedUnpack(FOO(R16F    ), LOCAL_GL_RED, LOCAL_GL_FLOAT        );
     921           0 :     fnAddSizedUnpack(FOO(R32F    ), LOCAL_GL_RED, LOCAL_GL_FLOAT        );
     922             : 
     923             :     // RED_INTEGER
     924           0 :     fnAddSizedUnpack(FOO(R8UI ), LOCAL_GL_RED_INTEGER, LOCAL_GL_UNSIGNED_BYTE );
     925           0 :     fnAddSizedUnpack(FOO(R8I  ), LOCAL_GL_RED_INTEGER, LOCAL_GL_BYTE          );
     926           0 :     fnAddSizedUnpack(FOO(R16UI), LOCAL_GL_RED_INTEGER, LOCAL_GL_UNSIGNED_SHORT);
     927           0 :     fnAddSizedUnpack(FOO(R16I ), LOCAL_GL_RED_INTEGER, LOCAL_GL_SHORT         );
     928           0 :     fnAddSizedUnpack(FOO(R32UI), LOCAL_GL_RED_INTEGER, LOCAL_GL_UNSIGNED_INT  );
     929           0 :     fnAddSizedUnpack(FOO(R32I ), LOCAL_GL_RED_INTEGER, LOCAL_GL_INT           );
     930             : 
     931             :     // DEPTH_COMPONENT
     932           0 :     fnAddSizedUnpack(FOO(DEPTH_COMPONENT16 ), LOCAL_GL_DEPTH_COMPONENT, LOCAL_GL_UNSIGNED_SHORT);
     933           0 :     fnAddSizedUnpack(FOO(DEPTH_COMPONENT16 ), LOCAL_GL_DEPTH_COMPONENT, LOCAL_GL_UNSIGNED_INT  );
     934           0 :     fnAddSizedUnpack(FOO(DEPTH_COMPONENT24 ), LOCAL_GL_DEPTH_COMPONENT, LOCAL_GL_UNSIGNED_INT  );
     935           0 :     fnAddSizedUnpack(FOO(DEPTH_COMPONENT32F), LOCAL_GL_DEPTH_COMPONENT, LOCAL_GL_FLOAT         );
     936             : 
     937             :     // DEPTH_STENCIL
     938           0 :     fnAddSizedUnpack(FOO(DEPTH24_STENCIL8 ), LOCAL_GL_DEPTH_STENCIL, LOCAL_GL_UNSIGNED_INT_24_8             );
     939           0 :     fnAddSizedUnpack(FOO(DEPTH32F_STENCIL8), LOCAL_GL_DEPTH_STENCIL, LOCAL_GL_FLOAT_32_UNSIGNED_INT_24_8_REV);
     940             : 
     941             : #undef FOO
     942             : 
     943             :     ////////////////////////////////////////////////////////////////////////////
     944             : 
     945             :     // For renderable, see GLES 3.0.4, p212 "Framebuffer Completeness"
     946             :     // For filterable, see GLES 3.0.4, p161 "...a texture is complete unless..."
     947             : 
     948             :     const auto fnAllowES3TexFormat = [ptr](GLenum sizedFormat, EffectiveFormat effFormat,
     949           0 :                                            bool isRenderable, bool isFilterable)
     950           0 :     {
     951           0 :         auto usage = ptr->EditUsage(effFormat);
     952           0 :         usage->isFilterable = isFilterable;
     953             : 
     954           0 :         if (isRenderable) {
     955           0 :             usage->SetRenderable();
     956             :         }
     957             : 
     958           0 :         ptr->AllowSizedTexFormat(sizedFormat, usage);
     959             : 
     960           0 :         if (isRenderable) {
     961           0 :             ptr->AllowRBFormat(sizedFormat, usage);
     962             :         }
     963           0 :     };
     964             : 
     965             : #define FOO(x) LOCAL_GL_ ## x, EffectiveFormat::x
     966             : 
     967             :     // GLES 3.0.4, p128-129 "Required Texture Formats"
     968             :     // GLES 3.0.4, p130-132, table 3.13
     969             :     //                                   render filter
     970             :     //                                    able   able
     971           0 :     fnAllowES3TexFormat(FOO(R8         ), true , true );
     972           0 :     fnAllowES3TexFormat(FOO(R8_SNORM   ), false, true );
     973           0 :     fnAllowES3TexFormat(FOO(RG8        ), true , true );
     974           0 :     fnAllowES3TexFormat(FOO(RG8_SNORM  ), false, true );
     975           0 :     fnAllowES3TexFormat(FOO(RGB8       ), true , true );
     976           0 :     fnAllowES3TexFormat(FOO(RGB8_SNORM ), false, true );
     977           0 :     fnAllowES3TexFormat(FOO(RGB565     ), true , true );
     978           0 :     fnAllowES3TexFormat(FOO(RGBA4      ), true , true );
     979           0 :     fnAllowES3TexFormat(FOO(RGB5_A1    ), true , true );
     980           0 :     fnAllowES3TexFormat(FOO(RGBA8      ), true , true );
     981           0 :     fnAllowES3TexFormat(FOO(RGBA8_SNORM), false, true );
     982           0 :     fnAllowES3TexFormat(FOO(RGB10_A2   ), true , true );
     983           0 :     fnAllowES3TexFormat(FOO(RGB10_A2UI ), true , false);
     984             : 
     985           0 :     fnAllowES3TexFormat(FOO(SRGB8       ), false, true);
     986           0 :     fnAllowES3TexFormat(FOO(SRGB8_ALPHA8), true , true);
     987             : 
     988           0 :     fnAllowES3TexFormat(FOO(R16F   ), false, true);
     989           0 :     fnAllowES3TexFormat(FOO(RG16F  ), false, true);
     990           0 :     fnAllowES3TexFormat(FOO(RGB16F ), false, true);
     991           0 :     fnAllowES3TexFormat(FOO(RGBA16F), false, true);
     992             : 
     993           0 :     fnAllowES3TexFormat(FOO(R32F   ), false, false);
     994           0 :     fnAllowES3TexFormat(FOO(RG32F  ), false, false);
     995           0 :     fnAllowES3TexFormat(FOO(RGB32F ), false, false);
     996           0 :     fnAllowES3TexFormat(FOO(RGBA32F), false, false);
     997             : 
     998           0 :     fnAllowES3TexFormat(FOO(R11F_G11F_B10F), false, true);
     999           0 :     fnAllowES3TexFormat(FOO(RGB9_E5       ), false, true);
    1000             : 
    1001           0 :     fnAllowES3TexFormat(FOO(R8I  ), true, false);
    1002           0 :     fnAllowES3TexFormat(FOO(R8UI ), true, false);
    1003           0 :     fnAllowES3TexFormat(FOO(R16I ), true, false);
    1004           0 :     fnAllowES3TexFormat(FOO(R16UI), true, false);
    1005           0 :     fnAllowES3TexFormat(FOO(R32I ), true, false);
    1006           0 :     fnAllowES3TexFormat(FOO(R32UI), true, false);
    1007             : 
    1008           0 :     fnAllowES3TexFormat(FOO(RG8I  ), true, false);
    1009           0 :     fnAllowES3TexFormat(FOO(RG8UI ), true, false);
    1010           0 :     fnAllowES3TexFormat(FOO(RG16I ), true, false);
    1011           0 :     fnAllowES3TexFormat(FOO(RG16UI), true, false);
    1012           0 :     fnAllowES3TexFormat(FOO(RG32I ), true, false);
    1013           0 :     fnAllowES3TexFormat(FOO(RG32UI), true, false);
    1014             : 
    1015           0 :     fnAllowES3TexFormat(FOO(RGB8I  ), false, false);
    1016           0 :     fnAllowES3TexFormat(FOO(RGB8UI ), false, false);
    1017           0 :     fnAllowES3TexFormat(FOO(RGB16I ), false, false);
    1018           0 :     fnAllowES3TexFormat(FOO(RGB16UI), false, false);
    1019           0 :     fnAllowES3TexFormat(FOO(RGB32I ), false, false);
    1020           0 :     fnAllowES3TexFormat(FOO(RGB32UI), false, false);
    1021             : 
    1022           0 :     fnAllowES3TexFormat(FOO(RGBA8I  ), true, false);
    1023           0 :     fnAllowES3TexFormat(FOO(RGBA8UI ), true, false);
    1024           0 :     fnAllowES3TexFormat(FOO(RGBA16I ), true, false);
    1025           0 :     fnAllowES3TexFormat(FOO(RGBA16UI), true, false);
    1026           0 :     fnAllowES3TexFormat(FOO(RGBA32I ), true, false);
    1027           0 :     fnAllowES3TexFormat(FOO(RGBA32UI), true, false);
    1028             : 
    1029             :     // GLES 3.0.4, p133, table 3.14
    1030           0 :     fnAllowES3TexFormat(FOO(DEPTH_COMPONENT16 ), true, false);
    1031           0 :     fnAllowES3TexFormat(FOO(DEPTH_COMPONENT24 ), true, false);
    1032           0 :     fnAllowES3TexFormat(FOO(DEPTH_COMPONENT32F), true, false);
    1033           0 :     fnAllowES3TexFormat(FOO(DEPTH24_STENCIL8  ), true, false);
    1034           0 :     fnAllowES3TexFormat(FOO(DEPTH32F_STENCIL8 ), true, false);
    1035             : 
    1036             : #undef FOO
    1037             : 
    1038             :     // GLES 3.0.4, p206, "Required Renderbuffer Formats":
    1039             :     // "Implementations are also required to support STENCIL_INDEX8. Requesting this
    1040             :     //  internal format for a renderbuffer will allocate at least 8 stencil bit planes."
    1041             : 
    1042           0 :     auto usage = ptr->EditUsage(EffectiveFormat::STENCIL_INDEX8);
    1043           0 :     usage->SetRenderable();
    1044           0 :     ptr->AllowRBFormat(LOCAL_GL_STENCIL_INDEX8, usage);
    1045             : 
    1046             :     ////////////////
    1047             :     // Legacy formats
    1048             : 
    1049           0 :     if (!AddUnsizedFormats(ptr, gl))
    1050           0 :         return nullptr;
    1051             : 
    1052           0 :     ptr->AllowRBFormat(LOCAL_GL_DEPTH_STENCIL,
    1053           0 :                        ptr->GetUsage(EffectiveFormat::DEPTH24_STENCIL8));
    1054             : 
    1055           0 :     if (gfxPrefs::WebGL2CompatMode()) {
    1056           0 :         AddSimpleUnsized(ptr, LOCAL_GL_RGBA, LOCAL_GL_FLOAT, EffectiveFormat::RGBA32F);
    1057           0 :         AddSimpleUnsized(ptr, LOCAL_GL_RGB , LOCAL_GL_FLOAT, EffectiveFormat::RGB32F );
    1058             : 
    1059           0 :         AddSimpleUnsized(ptr, LOCAL_GL_RGBA, LOCAL_GL_HALF_FLOAT_OES, EffectiveFormat::RGBA16F);
    1060           0 :         AddSimpleUnsized(ptr, LOCAL_GL_RGB , LOCAL_GL_HALF_FLOAT_OES, EffectiveFormat::RGB16F );
    1061             :     }
    1062             : 
    1063             :     ////////////////////////////////////
    1064             : 
    1065           0 :     return Move(ret);
    1066             : }
    1067             : 
    1068             : //////////////////////////////////////////////////////////////////////////////////////////
    1069             : 
    1070             : void
    1071           0 : FormatUsageAuthority::AddTexUnpack(FormatUsageInfo* usage, const PackingInfo& pi,
    1072             :                                    const DriverUnpackInfo& dui)
    1073             : {
    1074             :     // Don't AlwaysInsert here, since we'll see duplicates from sized and unsized formats.
    1075           0 :     auto res = usage->validUnpacks.insert({ pi, dui });
    1076           0 :     auto itr = res.first;
    1077             : 
    1078           0 :     if (!usage->idealUnpack) {
    1079             :         // First one!
    1080           0 :         usage->idealUnpack = &(itr->second);
    1081             :     }
    1082             : 
    1083           0 :     mValidTexUnpackFormats.insert(pi.format);
    1084           0 :     mValidTexUnpackTypes.insert(pi.type);
    1085           0 : }
    1086             : 
    1087             : static bool
    1088           0 : Contains(const std::set<GLenum>& set, GLenum key)
    1089             : {
    1090           0 :     return set.find(key) != set.end();
    1091             : }
    1092             : 
    1093             : bool
    1094           0 : FormatUsageAuthority::IsInternalFormatEnumValid(GLenum internalFormat) const
    1095             : {
    1096           0 :     return Contains(mValidTexInternalFormats, internalFormat);
    1097             : }
    1098             : 
    1099             : bool
    1100           0 : FormatUsageAuthority::AreUnpackEnumsValid(GLenum unpackFormat, GLenum unpackType) const
    1101             : {
    1102           0 :     return (Contains(mValidTexUnpackFormats, unpackFormat) &&
    1103           0 :             Contains(mValidTexUnpackTypes, unpackType));
    1104             : }
    1105             : 
    1106             : ////////////////////
    1107             : 
    1108             : void
    1109           0 : FormatUsageAuthority::AllowRBFormat(GLenum sizedFormat, const FormatUsageInfo* usage)
    1110             : {
    1111           0 :     MOZ_ASSERT(!usage->format->compression);
    1112           0 :     MOZ_ASSERT(usage->format->sizedFormat);
    1113           0 :     MOZ_ASSERT(usage->IsRenderable());
    1114             : 
    1115           0 :     AlwaysInsert(mRBFormatMap, sizedFormat, usage);
    1116           0 : }
    1117             : 
    1118             : void
    1119           0 : FormatUsageAuthority::AllowSizedTexFormat(GLenum sizedFormat,
    1120             :                                           const FormatUsageInfo* usage)
    1121             : {
    1122           0 :     if (usage->format->compression) {
    1123           0 :         MOZ_ASSERT(usage->isFilterable, "Compressed formats should be filterable.");
    1124             :     } else {
    1125           0 :         MOZ_ASSERT(usage->validUnpacks.size() && usage->idealUnpack,
    1126             :                    "AddTexUnpack() first.");
    1127             :     }
    1128             : 
    1129           0 :     AlwaysInsert(mSizedTexFormatMap, sizedFormat, usage);
    1130             : 
    1131           0 :     mValidTexInternalFormats.insert(sizedFormat);
    1132           0 : }
    1133             : 
    1134             : void
    1135           0 : FormatUsageAuthority::AllowUnsizedTexFormat(const PackingInfo& pi,
    1136             :                                             const FormatUsageInfo* usage)
    1137             : {
    1138           0 :     MOZ_ASSERT(!usage->format->compression);
    1139           0 :     MOZ_ASSERT(usage->validUnpacks.size() && usage->idealUnpack, "AddTexUnpack() first.");
    1140             : 
    1141           0 :     AlwaysInsert(mUnsizedTexFormatMap, pi, usage);
    1142             : 
    1143           0 :     mValidTexInternalFormats.insert(pi.format);
    1144           0 :     mValidTexUnpackFormats.insert(pi.format);
    1145           0 :     mValidTexUnpackTypes.insert(pi.type);
    1146           0 : }
    1147             : 
    1148             : const FormatUsageInfo*
    1149           0 : FormatUsageAuthority::GetRBUsage(GLenum sizedFormat) const
    1150             : {
    1151           0 :     return FindOrNull(mRBFormatMap, sizedFormat);
    1152             : }
    1153             : 
    1154             : const FormatUsageInfo*
    1155           0 : FormatUsageAuthority::GetSizedTexUsage(GLenum sizedFormat) const
    1156             : {
    1157           0 :     return FindOrNull(mSizedTexFormatMap, sizedFormat);
    1158             : }
    1159             : 
    1160             : const FormatUsageInfo*
    1161           0 : FormatUsageAuthority::GetUnsizedTexUsage(const PackingInfo& pi) const
    1162             : {
    1163           0 :     return FindOrNull(mUnsizedTexFormatMap, pi);
    1164             : }
    1165             : 
    1166             : FormatUsageInfo*
    1167           0 : FormatUsageAuthority::EditUsage(EffectiveFormat format)
    1168             : {
    1169           0 :     auto itr = mUsageMap.find(format);
    1170             : 
    1171           0 :     if (itr == mUsageMap.end()) {
    1172           0 :         const FormatInfo* formatInfo = GetFormat(format);
    1173           0 :         MOZ_RELEASE_ASSERT(formatInfo, "GFX: no format info set.");
    1174             : 
    1175           0 :         FormatUsageInfo usage(formatInfo);
    1176             : 
    1177           0 :         auto res = mUsageMap.insert({ format, usage });
    1178           0 :         DebugOnly<bool> didInsert = res.second;
    1179           0 :         MOZ_ASSERT(didInsert);
    1180             : 
    1181           0 :         itr = res.first;
    1182             :     }
    1183             : 
    1184           0 :     return &(itr->second);
    1185             : }
    1186             : 
    1187             : const FormatUsageInfo*
    1188           0 : FormatUsageAuthority::GetUsage(EffectiveFormat format) const
    1189             : {
    1190           0 :     auto itr = mUsageMap.find(format);
    1191           0 :     if (itr == mUsageMap.end())
    1192           0 :         return nullptr;
    1193             : 
    1194           0 :     return &(itr->second);
    1195             : }
    1196             : 
    1197             : ////////////////////////////////////////////////////////////////////////////////
    1198             : 
    1199             : } // namespace webgl
    1200             : } // namespace mozilla

Generated by: LCOV version 1.13