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
|