Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/dom/canvas/WebGLFormats.cpp
Line
Count
Source (jump to first uncovered line)
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
AlwaysInsert(std::map<K,V>& dest, const K2& key, const V2& val)
24
0
{
25
0
    auto res = dest.insert({ key, val });
26
0
    bool didInsert = res.second;
27
0
    MOZ_ALWAYS_TRUE(didInsert);
28
0
}
Unexecuted instantiation: Unified_cpp_dom_canvas4.cpp:void mozilla::webgl::AlwaysInsert<mozilla::webgl::EffectiveFormat, mozilla::webgl::CompressedFormatInfo const, mozilla::webgl::EffectiveFormat, mozilla::webgl::CompressedFormatInfo>(std::__1::map<mozilla::webgl::EffectiveFormat, mozilla::webgl::CompressedFormatInfo const, std::__1::less<mozilla::webgl::EffectiveFormat>, std::__1::allocator<std::__1::pair<mozilla::webgl::EffectiveFormat const, mozilla::webgl::CompressedFormatInfo const> > >&, mozilla::webgl::EffectiveFormat const&, mozilla::webgl::CompressedFormatInfo const&)
Unexecuted instantiation: Unified_cpp_dom_canvas4.cpp:void mozilla::webgl::AlwaysInsert<mozilla::webgl::EffectiveFormat, mozilla::webgl::FormatInfo, mozilla::webgl::EffectiveFormat, mozilla::webgl::FormatInfo>(std::__1::map<mozilla::webgl::EffectiveFormat, mozilla::webgl::FormatInfo, std::__1::less<mozilla::webgl::EffectiveFormat>, std::__1::allocator<std::__1::pair<mozilla::webgl::EffectiveFormat const, mozilla::webgl::FormatInfo> > >&, mozilla::webgl::EffectiveFormat const&, mozilla::webgl::FormatInfo const&)
Unexecuted instantiation: Unified_cpp_dom_canvas4.cpp:void mozilla::webgl::AlwaysInsert<mozilla::webgl::UnsizedFormat, mozilla::webgl::FormatInfo const*, mozilla::webgl::UnsizedFormat, mozilla::webgl::FormatInfo const*>(std::__1::map<mozilla::webgl::UnsizedFormat, mozilla::webgl::FormatInfo const*, std::__1::less<mozilla::webgl::UnsizedFormat>, std::__1::allocator<std::__1::pair<mozilla::webgl::UnsizedFormat const, mozilla::webgl::FormatInfo const*> > >&, mozilla::webgl::UnsizedFormat const&, mozilla::webgl::FormatInfo const* const&)
Unexecuted instantiation: Unified_cpp_dom_canvas4.cpp:void mozilla::webgl::AlwaysInsert<unsigned int, mozilla::webgl::FormatUsageInfo const*, unsigned int, mozilla::webgl::FormatUsageInfo const*>(std::__1::map<unsigned int, mozilla::webgl::FormatUsageInfo const*, std::__1::less<unsigned int>, std::__1::allocator<std::__1::pair<unsigned int const, mozilla::webgl::FormatUsageInfo const*> > >&, unsigned int const&, mozilla::webgl::FormatUsageInfo const* const&)
Unexecuted instantiation: Unified_cpp_dom_canvas4.cpp:void mozilla::webgl::AlwaysInsert<mozilla::webgl::PackingInfo, mozilla::webgl::FormatUsageInfo const*, mozilla::webgl::PackingInfo, mozilla::webgl::FormatUsageInfo const*>(std::__1::map<mozilla::webgl::PackingInfo, mozilla::webgl::FormatUsageInfo const*, std::__1::less<mozilla::webgl::PackingInfo>, std::__1::allocator<std::__1::pair<mozilla::webgl::PackingInfo const, mozilla::webgl::FormatUsageInfo const*> > >&, mozilla::webgl::PackingInfo const&, mozilla::webgl::FormatUsageInfo const* const&)
29
30
template<typename K, typename V, typename K2>
31
static inline V*
32
FindOrNull(const std::map<K,V*>& dest, const K2& key)
33
0
{
34
0
    auto itr = dest.find(key);
35
0
    if (itr == dest.end())
36
0
        return nullptr;
37
0
38
0
    return itr->second;
39
0
}
Unexecuted instantiation: Unified_cpp_dom_canvas4.cpp:mozilla::webgl::FormatInfo const* mozilla::webgl::FindOrNull<mozilla::webgl::UnsizedFormat, mozilla::webgl::FormatInfo const, mozilla::webgl::UnsizedFormat>(std::__1::map<mozilla::webgl::UnsizedFormat, mozilla::webgl::FormatInfo const*, std::__1::less<mozilla::webgl::UnsizedFormat>, std::__1::allocator<std::__1::pair<mozilla::webgl::UnsizedFormat const, mozilla::webgl::FormatInfo const*> > > const&, mozilla::webgl::UnsizedFormat const&)
Unexecuted instantiation: Unified_cpp_dom_canvas4.cpp:mozilla::webgl::FormatUsageInfo const* mozilla::webgl::FindOrNull<unsigned int, mozilla::webgl::FormatUsageInfo const, unsigned int>(std::__1::map<unsigned int, mozilla::webgl::FormatUsageInfo const*, std::__1::less<unsigned int>, std::__1::allocator<std::__1::pair<unsigned int const, mozilla::webgl::FormatUsageInfo const*> > > const&, unsigned int const&)
Unexecuted instantiation: Unified_cpp_dom_canvas4.cpp:mozilla::webgl::FormatUsageInfo const* mozilla::webgl::FindOrNull<mozilla::webgl::PackingInfo, mozilla::webgl::FormatUsageInfo const, mozilla::webgl::PackingInfo>(std::__1::map<mozilla::webgl::PackingInfo, mozilla::webgl::FormatUsageInfo const*, std::__1::less<mozilla::webgl::PackingInfo>, std::__1::allocator<std::__1::pair<mozilla::webgl::PackingInfo const, mozilla::webgl::FormatUsageInfo const*> > > const&, mozilla::webgl::PackingInfo const&)
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
FindPtrOrNull(std::map<K,V>& dest, const K2& key)
45
0
{
46
0
    auto itr = dest.find(key);
47
0
    if (itr == dest.end())
48
0
        return nullptr;
49
0
50
0
    return &(itr->second);
51
0
}
Unexecuted instantiation: Unified_cpp_dom_canvas4.cpp:mozilla::webgl::CompressedFormatInfo const* mozilla::webgl::FindPtrOrNull<mozilla::webgl::EffectiveFormat, mozilla::webgl::CompressedFormatInfo const, mozilla::webgl::EffectiveFormat>(std::__1::map<mozilla::webgl::EffectiveFormat, mozilla::webgl::CompressedFormatInfo const, std::__1::less<mozilla::webgl::EffectiveFormat>, std::__1::allocator<std::__1::pair<mozilla::webgl::EffectiveFormat const, mozilla::webgl::CompressedFormatInfo const> > >&, mozilla::webgl::EffectiveFormat const&)
Unexecuted instantiation: Unified_cpp_dom_canvas4.cpp:mozilla::webgl::FormatInfo* mozilla::webgl::FindPtrOrNull<mozilla::webgl::EffectiveFormat, mozilla::webgl::FormatInfo, mozilla::webgl::EffectiveFormat>(std::__1::map<mozilla::webgl::EffectiveFormat, mozilla::webgl::FormatInfo, std::__1::less<mozilla::webgl::EffectiveFormat>, std::__1::allocator<std::__1::pair<mozilla::webgl::EffectiveFormat const, mozilla::webgl::FormatInfo> > >&, mozilla::webgl::EffectiveFormat const&)
52
53
//////////////////////////////////////////////////////////////////////////////////////////
54
55
std::map<EffectiveFormat, const CompressedFormatInfo> gCompressedFormatInfoMap;
56
std::map<EffectiveFormat, FormatInfo> gFormatInfoMap;
57
58
static inline const CompressedFormatInfo*
59
GetCompressedFormatInfo(EffectiveFormat format)
60
0
{
61
0
    MOZ_ASSERT(!gCompressedFormatInfoMap.empty());
62
0
    return FindPtrOrNull(gCompressedFormatInfoMap, format);
63
0
}
64
65
static inline FormatInfo*
66
GetFormatInfo_NoLock(EffectiveFormat format)
67
0
{
68
0
    MOZ_ASSERT(!gFormatInfoMap.empty());
69
0
    return FindPtrOrNull(gFormatInfoMap, format);
70
0
}
71
72
//////////////////////////////////////////////////////////////////////////////////////////
73
74
static void
75
AddCompressedFormatInfo(EffectiveFormat format, uint16_t bitsPerBlock, uint8_t blockWidth,
76
                        uint8_t blockHeight, CompressionFamily family)
77
0
{
78
0
    MOZ_ASSERT(bitsPerBlock % 8 == 0);
79
0
    uint16_t bytesPerBlock = bitsPerBlock / 8; // The specs always state these in bits,
80
0
                                               // but it's only ever useful to us as
81
0
                                               // bytes.
82
0
    MOZ_ASSERT(bytesPerBlock <= 255);
83
0
84
0
    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
InitCompressedFormatInfo()
91
0
{
92
0
    // GLES 3.0.4, p147, table 3.19
93
0
    // 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
0
105
0
    // 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
0
110
0
    // 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
0
116
0
    // 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
0
122
0
    // 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
0
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
0
153
0
    // 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
0
159
0
    // 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
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
0
{
171
0
    switch (unsizedFormat) {
172
0
    case UnsizedFormat::R:
173
0
        MOZ_ASSERT(r && !g && !b && !a && !d && !s);
174
0
        break;
175
0
176
0
    case UnsizedFormat::RG:
177
0
        MOZ_ASSERT(r && g && !b && !a && !d && !s);
178
0
        break;
179
0
180
0
    case UnsizedFormat::RGB:
181
0
        MOZ_ASSERT(r && g && b && !a && !d && !s);
182
0
        break;
183
0
184
0
    case UnsizedFormat::RGBA:
185
0
        MOZ_ASSERT(r && g && b && a && !d && !s);
186
0
        break;
187
0
188
0
    case UnsizedFormat::L:
189
0
        MOZ_ASSERT(r && !g && !b && !a && !d && !s);
190
0
        break;
191
0
192
0
    case UnsizedFormat::A:
193
0
        MOZ_ASSERT(!r && !g && !b && a && !d && !s);
194
0
        break;
195
0
196
0
    case UnsizedFormat::LA:
197
0
        MOZ_ASSERT(r && !g && !b && a && !d && !s);
198
0
        break;
199
0
200
0
    case UnsizedFormat::D:
201
0
        MOZ_ASSERT(!r && !g && !b && !a && d && !s);
202
0
        break;
203
0
204
0
    case UnsizedFormat::S:
205
0
        MOZ_ASSERT(!r && !g && !b && !a && !d && s);
206
0
        break;
207
0
208
0
    case UnsizedFormat::DEPTH_STENCIL:
209
0
        MOZ_ASSERT(!r && !g && !b && !a && d && s);
210
0
        break;
211
0
    }
212
0
213
0
    const CompressedFormatInfo* compressedFormatInfo = GetCompressedFormatInfo(format);
214
0
    MOZ_ASSERT(!bytesPerPixel == bool(compressedFormatInfo));
215
0
216
#ifdef DEBUG
217
    uint8_t totalBits = r + g + b + a + d + s;
218
    if (format == EffectiveFormat::RGB9_E5) {
219
        totalBits = 9 + 9 + 9 + 5;
220
    }
221
222
    if (compressedFormatInfo) {
223
        MOZ_ASSERT(totalBits);
224
        MOZ_ASSERT(!bytesPerPixel);
225
    } else {
226
        MOZ_ASSERT(totalBits == bytesPerPixel*8);
227
    }
228
#endif
229
230
0
    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
InitFormatInfo()
237
0
{
238
0
#define FOO(x) EffectiveFormat::x, #x, LOCAL_GL_ ## x
239
0
240
0
    // 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
0
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
0
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
0
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
0
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
0
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
0
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
0
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
0
298
0
    // 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
0
305
0
    // 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
0
308
0
    // GLES 3.0.4, p147, table 3.19
309
0
    // 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
0
321
0
    // 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
0
326
0
    // 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
0
332
0
    // 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
0
338
0
    // 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
0
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
0
369
0
    // 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
0
375
0
    // 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
0
378
0
#undef FOO
379
0
380
0
    // 'Virtual' effective formats have no sizedFormat.
381
0
#define FOO(x) EffectiveFormat::x, #x, 0
382
0
383
0
    // 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
0
388
0
    // 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
0
393
0
    // 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
0
398
0
#undef FOO
399
0
400
0
    ////////////////////////////////////////////////////////////////////////////
401
0
402
0
    const auto fnSetCopyDecay = [](EffectiveFormat src, EffectiveFormat asR,
403
0
                                   EffectiveFormat asRG, EffectiveFormat asRGB,
404
0
                                   EffectiveFormat asRGBA, EffectiveFormat asL,
405
0
                                   EffectiveFormat asA, EffectiveFormat asLA)
406
0
    {
407
0
        auto& map = GetFormatInfo_NoLock(src)->copyDecayFormats;
408
0
409
0
        const auto fnSet = [&map](UnsizedFormat uf, EffectiveFormat ef) {
410
0
            if (ef == EffectiveFormat::MAX)
411
0
                return;
412
0
413
0
            const auto* format = GetFormatInfo_NoLock(ef);
414
0
            MOZ_ASSERT(format->unsizedFormat == uf);
415
0
            AlwaysInsert(map, uf, format);
416
0
        };
417
0
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
0
427
0
#define SET_COPY_DECAY(src,asR,asRG,asRGB,asRGBA,asL,asA,asLA) \
428
0
    fnSetCopyDecay(EffectiveFormat::src, EffectiveFormat::asR, EffectiveFormat::asRG,     \
429
0
                   EffectiveFormat::asRGB, EffectiveFormat::asRGBA, EffectiveFormat::asL, \
430
0
                   EffectiveFormat::asA, EffectiveFormat::asLA);
431
0
432
0
    //////
433
0
434
0
#define SET_BY_SUFFIX(X) \
435
0
        SET_COPY_DECAY(   R##X, R##X,   MAX,    MAX,     MAX, Luminance##X,      MAX,                    MAX) \
436
0
        SET_COPY_DECAY(  RG##X, R##X, RG##X,    MAX,     MAX, Luminance##X,      MAX,                    MAX) \
437
0
        SET_COPY_DECAY( RGB##X, R##X, RG##X, RGB##X,     MAX, Luminance##X,      MAX,                    MAX) \
438
0
        SET_COPY_DECAY(RGBA##X, R##X, RG##X, RGB##X, RGBA##X, Luminance##X, Alpha##X, Luminance##X##Alpha##X)
439
0
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
0
                       // EXT_color_buffer_float.
443
0
    SET_BY_SUFFIX(32F) // Technically RGB32F is never renderable, but no harm here.
444
0
445
0
#undef SET_BY_SUFFIX
446
0
447
0
    //////
448
0
449
0
#define SET_BY_SUFFIX(X) \
450
0
        SET_COPY_DECAY(   R##X, R##X,   MAX,    MAX,     MAX, MAX, MAX, MAX) \
451
0
        SET_COPY_DECAY(  RG##X, R##X, RG##X,    MAX,     MAX, MAX, MAX, MAX) \
452
0
        SET_COPY_DECAY(RGBA##X, R##X, RG##X, RGB##X, RGBA##X, MAX, MAX, MAX)
453
0
454
0
    SET_BY_SUFFIX(8I)
455
0
    SET_BY_SUFFIX(8UI)
456
0
457
0
    SET_BY_SUFFIX(16I)
458
0
    SET_BY_SUFFIX(16UI)
459
0
460
0
    SET_BY_SUFFIX(32I)
461
0
    SET_BY_SUFFIX(32UI)
462
0
463
0
#undef SET_BY_SUFFIX
464
0
465
0
    //////
466
0
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
0
472
0
    SET_COPY_DECAY(RGB10_A2UI, R8UI, RG8UI, RGB8UI, RGB10_A2UI, MAX, MAX, MAX)
473
0
474
0
    SET_COPY_DECAY(SRGB8_ALPHA8, MAX, MAX, MAX, SRGB8_ALPHA8, MAX, Alpha8, MAX)
475
0
476
0
    SET_COPY_DECAY(R11F_G11F_B10F, R16F, RG16F, R11F_G11F_B10F, MAX, Luminance16F, MAX, MAX)
477
0
478
0
#undef SET_COPY_DECAY
479
0
}
480
481
//////////////////////////////////////////////////////////////////////////////////////////
482
483
bool gAreFormatTablesInitialized = false;
484
485
static void
486
EnsureInitFormatTables(const StaticMutexAutoLock&) // Prove that you locked it!
487
0
{
488
0
    if (MOZ_LIKELY(gAreFormatTablesInitialized))
489
0
        return;
490
0
491
0
    gAreFormatTablesInitialized = true;
492
0
493
0
    InitCompressedFormatInfo();
494
0
    InitFormatInfo();
495
0
}
496
497
//////////////////////////////////////////////////////////////////////////////////////////
498
// Public funcs
499
500
StaticMutex gFormatMapMutex;
501
502
const FormatInfo*
503
GetFormat(EffectiveFormat format)
504
0
{
505
0
    StaticMutexAutoLock lock(gFormatMapMutex);
506
0
    EnsureInitFormatTables(lock);
507
0
508
0
    return GetFormatInfo_NoLock(format);
509
0
}
510
511
//////////////////////////////////////////////////////////////////////////////////////////
512
513
const FormatInfo*
514
FormatInfo::GetCopyDecayFormat(UnsizedFormat uf) const
515
0
{
516
0
    return FindOrNull(this->copyDecayFormats, uf);
517
0
}
518
519
bool
520
GetBytesPerPixel(const PackingInfo& packing, uint8_t* const out_bytes)
521
0
{
522
0
    uint8_t bytesPerChannel;
523
0
524
0
    switch (packing.type) {
525
0
    case LOCAL_GL_UNSIGNED_SHORT_4_4_4_4:
526
0
    case LOCAL_GL_UNSIGNED_SHORT_5_5_5_1:
527
0
    case LOCAL_GL_UNSIGNED_SHORT_5_6_5:
528
0
        *out_bytes = 2;
529
0
        return true;
530
0
531
0
    case LOCAL_GL_UNSIGNED_INT_10F_11F_11F_REV:
532
0
    case LOCAL_GL_UNSIGNED_INT_2_10_10_10_REV:
533
0
    case LOCAL_GL_UNSIGNED_INT_24_8:
534
0
    case LOCAL_GL_UNSIGNED_INT_5_9_9_9_REV:
535
0
        *out_bytes = 4;
536
0
        return true;
537
0
538
0
    case LOCAL_GL_FLOAT_32_UNSIGNED_INT_24_8_REV:
539
0
        *out_bytes = 8;
540
0
        return true;
541
0
542
0
    // Alright, that's all the fixed-size unpackTypes.
543
0
544
0
    case LOCAL_GL_BYTE:
545
0
    case LOCAL_GL_UNSIGNED_BYTE:
546
0
        bytesPerChannel = 1;
547
0
        break;
548
0
549
0
    case LOCAL_GL_SHORT:
550
0
    case LOCAL_GL_UNSIGNED_SHORT:
551
0
    case LOCAL_GL_HALF_FLOAT:
552
0
    case LOCAL_GL_HALF_FLOAT_OES:
553
0
        bytesPerChannel = 2;
554
0
        break;
555
0
556
0
    case LOCAL_GL_INT:
557
0
    case LOCAL_GL_UNSIGNED_INT:
558
0
    case LOCAL_GL_FLOAT:
559
0
        bytesPerChannel = 4;
560
0
        break;
561
0
562
0
    default:
563
0
        return false;
564
0
    }
565
0
566
0
    uint8_t channels;
567
0
568
0
    switch (packing.format) {
569
0
    case LOCAL_GL_RED:
570
0
    case LOCAL_GL_RED_INTEGER:
571
0
    case LOCAL_GL_LUMINANCE:
572
0
    case LOCAL_GL_ALPHA:
573
0
    case LOCAL_GL_DEPTH_COMPONENT:
574
0
        channels = 1;
575
0
        break;
576
0
577
0
    case LOCAL_GL_RG:
578
0
    case LOCAL_GL_RG_INTEGER:
579
0
    case LOCAL_GL_LUMINANCE_ALPHA:
580
0
        channels = 2;
581
0
        break;
582
0
583
0
    case LOCAL_GL_RGB:
584
0
    case LOCAL_GL_RGB_INTEGER:
585
0
    case LOCAL_GL_SRGB:
586
0
        channels = 3;
587
0
        break;
588
0
589
0
    case LOCAL_GL_BGRA:
590
0
    case LOCAL_GL_RGBA:
591
0
    case LOCAL_GL_RGBA_INTEGER:
592
0
    case LOCAL_GL_SRGB_ALPHA:
593
0
        channels = 4;
594
0
        break;
595
0
596
0
    default:
597
0
        return false;
598
0
    }
599
0
600
0
    *out_bytes = bytesPerChannel * channels;
601
0
    return true;
602
0
}
603
604
uint8_t
605
BytesPerPixel(const PackingInfo& packing)
606
0
{
607
0
    uint8_t ret;
608
0
    if (MOZ_LIKELY(GetBytesPerPixel(packing, &ret)))
609
0
        return ret;
610
0
611
0
    gfxCriticalError() << "Bad `packing`: " << gfx::hexa(packing.format) << ", "
612
0
                       << gfx::hexa(packing.type);
613
0
    MOZ_CRASH("Bad `packing`.");
614
0
}
615
616
//////////////////////////////////////////////////////////////////////////////////////////
617
//////////////////////////////////////////////////////////////////////////////////////////
618
//////////////////////////////////////////////////////////////////////////////////////////
619
//////////////////////////////////////////////////////////////////////////////////////////
620
//////////////////////////////////////////////////////////////////////////////////////////
621
//////////////////////////////////////////////////////////////////////////////////////////
622
//////////////////////////////////////////////////////////////////////////////////////////
623
//////////////////////////////////////////////////////////////////////////////////////////
624
// FormatUsageAuthority
625
626
bool
627
FormatUsageInfo::IsUnpackValid(const PackingInfo& key,
628
                               const DriverUnpackInfo** const out_value) const
629
0
{
630
0
    auto itr = validUnpacks.find(key);
631
0
    if (itr == validUnpacks.end())
632
0
        return false;
633
0
634
0
    *out_value = &(itr->second);
635
0
    return true;
636
0
}
637
638
void
639
FormatUsageInfo::ResolveMaxSamples(gl::GLContext* gl)
640
0
{
641
0
    MOZ_ASSERT(!this->maxSamplesKnown);
642
0
    MOZ_ASSERT(this->maxSamples == 0);
643
0
    MOZ_ASSERT(gl->IsCurrent());
644
0
645
0
    this->maxSamplesKnown = true;
646
0
647
0
    const GLenum internalFormat = this->format->sizedFormat;
648
0
    if (!internalFormat)
649
0
        return;
650
0
651
0
    if (!gl->IsSupported(gl::GLFeature::internalformat_query))
652
0
        return; // Leave it at 0.
653
0
654
0
    GLint maxSamplesGL = 0;
655
0
    gl->fGetInternalformativ(LOCAL_GL_RENDERBUFFER, internalFormat, LOCAL_GL_SAMPLES, 1,
656
0
                             &maxSamplesGL);
657
0
658
0
    this->maxSamples = maxSamplesGL;
659
0
}
660
661
////////////////////////////////////////
662
663
static void
664
AddSimpleUnsized(FormatUsageAuthority* fua, GLenum unpackFormat, GLenum unpackType,
665
                 EffectiveFormat effFormat)
666
0
{
667
0
    auto usage = fua->EditUsage(effFormat);
668
0
    usage->isFilterable = true;
669
0
670
0
    const PackingInfo pi = {unpackFormat, unpackType};
671
0
    const DriverUnpackInfo dui = {unpackFormat, unpackFormat, unpackType};
672
0
    fua->AddTexUnpack(usage, pi, dui);
673
0
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
AddLegacyFormats_LA8(FormatUsageAuthority* fua, gl::GLContext* gl)
693
0
{
694
0
    if (gl->IsCoreProfile()) {
695
0
        if (!gl->IsSupported(gl::GLFeature::texture_swizzle))
696
0
            return false;
697
0
698
0
        PackingInfo pi;
699
0
        DriverUnpackInfo dui;
700
0
701
0
        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
0
708
0
            fua->AddTexUnpack(usage, pi, dui);
709
0
710
0
            fua->AllowUnsizedTexFormat(pi, usage);
711
0
        };
712
0
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
0
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
0
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
0
    } 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
0
    }
729
0
730
0
    return true;
731
0
}
732
733
static bool
734
AddUnsizedFormats(FormatUsageAuthority* fua, gl::GLContext* gl)
735
0
{
736
0
    // 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
0
743
0
    // L, A, LA
744
0
    return AddLegacyFormats_LA8(fua, gl);
745
0
}
746
747
void
748
FormatUsageInfo::SetRenderable()
749
0
{
750
0
    this->isRenderable = true;
751
0
752
#ifdef DEBUG
753
    const auto format = this->format;
754
    if (format->IsColorFormat()) {
755
        const auto& map = format->copyDecayFormats;
756
        const auto itr = map.find(format->unsizedFormat);
757
        MOZ_ASSERT(itr != map.end(), "Renderable formats must be in copyDecayFormats.");
758
        MOZ_ASSERT(itr->second == format);
759
    }
760
#endif
761
}
762
763
UniquePtr<FormatUsageAuthority>
764
FormatUsageAuthority::CreateForWebGL1(gl::GLContext* gl)
765
0
{
766
0
    UniquePtr<FormatUsageAuthority> ret(new FormatUsageAuthority);
767
0
    const auto ptr = ret.get();
768
0
769
0
    ////////////////////////////////////////////////////////////////////////////
770
0
    // Usages
771
0
772
0
    const auto fnSet = [ptr](EffectiveFormat effFormat, bool isRenderable,
773
0
                             bool isFilterable)
774
0
    {
775
0
        MOZ_ASSERT(!ptr->GetUsage(effFormat));
776
0
777
0
        auto usage = ptr->EditUsage(effFormat);
778
0
        usage->isFilterable = isFilterable;
779
0
780
0
        if (isRenderable) {
781
0
            usage->SetRenderable();
782
0
        }
783
0
    };
784
0
785
0
    // GLES 2.0.25, p117, Table 4.5
786
0
    // RGBA8 is made renderable in WebGL 1.0, "Framebuffer Object Attachments"
787
0
    //                              render filter
788
0
    //                              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
0
794
0
    // RGB8 is not guaranteed to be renderable, but we should allow it for web-compat.
795
0
    // Min-capability mode should mark this as non-renderable.
796
0
    fnSet(EffectiveFormat::RGB8, true, true);
797
0
798
0
    fnSet(EffectiveFormat::Luminance8Alpha8, false, true);
799
0
    fnSet(EffectiveFormat::Luminance8      , false, true);
800
0
    fnSet(EffectiveFormat::Alpha8          , false, true);
801
0
802
0
    fnSet(EffectiveFormat::DEPTH_COMPONENT16, true, false);
803
0
    fnSet(EffectiveFormat::STENCIL_INDEX8   , true, false);
804
0
805
0
    // Added in WebGL 1.0 spec:
806
0
    fnSet(EffectiveFormat::DEPTH24_STENCIL8, true, false);
807
0
808
0
    ////////////////////////////////////
809
0
    // RB formats
810
0
811
0
#define FOO(x) ptr->AllowRBFormat(LOCAL_GL_ ## x, ptr->GetUsage(EffectiveFormat::x))
812
0
813
0
    FOO(RGBA4            );
814
0
    FOO(RGB5_A1          );
815
0
    FOO(RGB565           );
816
0
    FOO(DEPTH_COMPONENT16);
817
0
    FOO(STENCIL_INDEX8   );
818
0
    //FOO(DEPTH24_STENCIL8 ); // WebGL 1 uses DEPTH_STENCIL instead of DEPTH24_STENCIL8.
819
0
820
0
#undef FOO
821
0
822
0
    ptr->AllowRBFormat(LOCAL_GL_DEPTH_STENCIL,
823
0
                       ptr->GetUsage(EffectiveFormat::DEPTH24_STENCIL8));
824
0
825
0
    ////////////////////////////////////////////////////////////////////////////
826
0
827
0
    if (!AddUnsizedFormats(ptr, gl))
828
0
        return nullptr;
829
0
830
0
    return ret;
831
0
}
832
833
UniquePtr<FormatUsageAuthority>
834
FormatUsageAuthority::CreateForWebGL2(gl::GLContext* gl)
835
0
{
836
0
    UniquePtr<FormatUsageAuthority> ret(new FormatUsageAuthority);
837
0
    const auto ptr = ret.get();
838
0
839
0
    ////////////////////////////////////////////////////////////////////////////
840
0
    // GLES 3.0.4 p111-113
841
0
842
0
    const auto fnAddSizedUnpack = [ptr](EffectiveFormat effFormat, GLenum internalFormat,
843
0
                                        GLenum unpackFormat, GLenum unpackType)
844
0
    {
845
0
        auto usage = ptr->EditUsage(effFormat);
846
0
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
0
852
0
#define FOO(x) EffectiveFormat::x, LOCAL_GL_ ## x
853
0
854
0
    // 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
0
868
0
    // 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
0
877
0
    // 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
0
893
0
    // 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
0
901
0
    // 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
0
908
0
    // 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
0
916
0
    // 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
0
923
0
    // 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
0
931
0
    // 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
0
937
0
    // 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
0
941
0
#undef FOO
942
0
943
0
    ////////////////////////////////////////////////////////////////////////////
944
0
945
0
    // For renderable, see GLES 3.0.4, p212 "Framebuffer Completeness"
946
0
    // For filterable, see GLES 3.0.4, p161 "...a texture is complete unless..."
947
0
948
0
    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
0
954
0
        if (isRenderable) {
955
0
            usage->SetRenderable();
956
0
        }
957
0
958
0
        ptr->AllowSizedTexFormat(sizedFormat, usage);
959
0
960
0
        if (isRenderable) {
961
0
            ptr->AllowRBFormat(sizedFormat, usage);
962
0
        }
963
0
    };
964
0
965
0
#define FOO(x) LOCAL_GL_ ## x, EffectiveFormat::x
966
0
967
0
    // GLES 3.0.4, p128-129 "Required Texture Formats"
968
0
    // GLES 3.0.4, p130-132, table 3.13
969
0
    //                                   render filter
970
0
    //                                    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
0
985
0
    fnAllowES3TexFormat(FOO(SRGB8       ), false, true);
986
0
    fnAllowES3TexFormat(FOO(SRGB8_ALPHA8), true , true);
987
0
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
0
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
0
998
0
    fnAllowES3TexFormat(FOO(R11F_G11F_B10F), false, true);
999
0
    fnAllowES3TexFormat(FOO(RGB9_E5       ), false, true);
1000
0
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
0
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
0
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
0
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
0
1029
0
    // 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
0
1036
0
#undef FOO
1037
0
1038
0
    // GLES 3.0.4, p206, "Required Renderbuffer Formats":
1039
0
    // "Implementations are also required to support STENCIL_INDEX8. Requesting this
1040
0
    //  internal format for a renderbuffer will allocate at least 8 stencil bit planes."
1041
0
1042
0
    auto usage = ptr->EditUsage(EffectiveFormat::STENCIL_INDEX8);
1043
0
    usage->SetRenderable();
1044
0
    ptr->AllowRBFormat(LOCAL_GL_STENCIL_INDEX8, usage);
1045
0
1046
0
    ////////////////
1047
0
    // Legacy formats
1048
0
1049
0
    if (!AddUnsizedFormats(ptr, gl))
1050
0
        return nullptr;
1051
0
1052
0
    ptr->AllowRBFormat(LOCAL_GL_DEPTH_STENCIL,
1053
0
                       ptr->GetUsage(EffectiveFormat::DEPTH24_STENCIL8));
1054
0
1055
0
    ////////////////////////////////////
1056
0
1057
0
    return ret;
1058
0
}
1059
1060
//////////////////////////////////////////////////////////////////////////////////////////
1061
1062
void
1063
FormatUsageAuthority::AddTexUnpack(FormatUsageInfo* usage, const PackingInfo& pi,
1064
                                   const DriverUnpackInfo& dui)
1065
0
{
1066
0
    // Don't AlwaysInsert here, since we'll see duplicates from sized and unsized formats.
1067
0
    auto res = usage->validUnpacks.insert({ pi, dui });
1068
0
    auto itr = res.first;
1069
0
1070
0
    if (!usage->idealUnpack) {
1071
0
        // First one!
1072
0
        usage->idealUnpack = &(itr->second);
1073
0
    }
1074
0
1075
0
    mValidTexUnpackFormats.insert(pi.format);
1076
0
    mValidTexUnpackTypes.insert(pi.type);
1077
0
}
1078
1079
static bool
1080
Contains(const std::set<GLenum>& set, GLenum key)
1081
0
{
1082
0
    return set.find(key) != set.end();
1083
0
}
1084
1085
bool
1086
FormatUsageAuthority::IsInternalFormatEnumValid(GLenum internalFormat) const
1087
0
{
1088
0
    return Contains(mValidTexInternalFormats, internalFormat);
1089
0
}
1090
1091
bool
1092
FormatUsageAuthority::AreUnpackEnumsValid(GLenum unpackFormat, GLenum unpackType) const
1093
0
{
1094
0
    return (Contains(mValidTexUnpackFormats, unpackFormat) &&
1095
0
            Contains(mValidTexUnpackTypes, unpackType));
1096
0
}
1097
1098
////////////////////
1099
1100
void
1101
FormatUsageAuthority::AllowRBFormat(GLenum sizedFormat, const FormatUsageInfo* usage)
1102
0
{
1103
0
    MOZ_ASSERT(!usage->format->compression);
1104
0
    MOZ_ASSERT(usage->format->sizedFormat);
1105
0
    MOZ_ASSERT(usage->IsRenderable());
1106
0
1107
0
    AlwaysInsert(mRBFormatMap, sizedFormat, usage);
1108
0
}
1109
1110
void
1111
FormatUsageAuthority::AllowSizedTexFormat(GLenum sizedFormat,
1112
                                          const FormatUsageInfo* usage)
1113
0
{
1114
0
    if (usage->format->compression) {
1115
0
        MOZ_ASSERT(usage->isFilterable, "Compressed formats should be filterable.");
1116
0
    } else {
1117
0
        MOZ_ASSERT(usage->validUnpacks.size() && usage->idealUnpack,
1118
0
                   "AddTexUnpack() first.");
1119
0
    }
1120
0
1121
0
    AlwaysInsert(mSizedTexFormatMap, sizedFormat, usage);
1122
0
1123
0
    mValidTexInternalFormats.insert(sizedFormat);
1124
0
}
1125
1126
void
1127
FormatUsageAuthority::AllowUnsizedTexFormat(const PackingInfo& pi,
1128
                                            const FormatUsageInfo* usage)
1129
0
{
1130
0
    MOZ_ASSERT(!usage->format->compression);
1131
0
    MOZ_ASSERT(usage->validUnpacks.size() && usage->idealUnpack, "AddTexUnpack() first.");
1132
0
1133
0
    AlwaysInsert(mUnsizedTexFormatMap, pi, usage);
1134
0
1135
0
    mValidTexInternalFormats.insert(pi.format);
1136
0
    mValidTexUnpackFormats.insert(pi.format);
1137
0
    mValidTexUnpackTypes.insert(pi.type);
1138
0
}
1139
1140
const FormatUsageInfo*
1141
FormatUsageAuthority::GetRBUsage(GLenum sizedFormat) const
1142
0
{
1143
0
    return FindOrNull(mRBFormatMap, sizedFormat);
1144
0
}
1145
1146
const FormatUsageInfo*
1147
FormatUsageAuthority::GetSizedTexUsage(GLenum sizedFormat) const
1148
0
{
1149
0
    return FindOrNull(mSizedTexFormatMap, sizedFormat);
1150
0
}
1151
1152
const FormatUsageInfo*
1153
FormatUsageAuthority::GetUnsizedTexUsage(const PackingInfo& pi) const
1154
0
{
1155
0
    return FindOrNull(mUnsizedTexFormatMap, pi);
1156
0
}
1157
1158
FormatUsageInfo*
1159
FormatUsageAuthority::EditUsage(EffectiveFormat format)
1160
0
{
1161
0
    auto itr = mUsageMap.find(format);
1162
0
1163
0
    if (itr == mUsageMap.end()) {
1164
0
        const FormatInfo* formatInfo = GetFormat(format);
1165
0
        MOZ_RELEASE_ASSERT(formatInfo, "GFX: no format info set.");
1166
0
1167
0
        FormatUsageInfo usage(formatInfo);
1168
0
1169
0
        auto res = mUsageMap.insert({ format, usage });
1170
0
        DebugOnly<bool> didInsert = res.second;
1171
0
        MOZ_ASSERT(didInsert);
1172
0
1173
0
        itr = res.first;
1174
0
    }
1175
0
1176
0
    return &(itr->second);
1177
0
}
1178
1179
const FormatUsageInfo*
1180
FormatUsageAuthority::GetUsage(EffectiveFormat format) const
1181
0
{
1182
0
    auto itr = mUsageMap.find(format);
1183
0
    if (itr == mUsageMap.end())
1184
0
        return nullptr;
1185
0
1186
0
    return &(itr->second);
1187
0
}
1188
1189
////////////////////////////////////////////////////////////////////////////////
1190
1191
} // namespace webgl
1192
} // namespace mozilla