/src/mozilla-central/dom/canvas/WebGLFormats.h
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 | | #ifndef WEBGL_FORMATS_H_ |
7 | | #define WEBGL_FORMATS_H_ |
8 | | |
9 | | #include <map> |
10 | | #include <set> |
11 | | |
12 | | #include "mozilla/UniquePtr.h" |
13 | | #include "WebGLTypes.h" |
14 | | |
15 | | namespace mozilla { |
16 | | namespace webgl { |
17 | | |
18 | | typedef uint8_t EffectiveFormatValueT; |
19 | | |
20 | | enum class EffectiveFormat : EffectiveFormatValueT { |
21 | | // GLES 3.0.4, p128-129, "Required Texture Formats" |
22 | | // "Texture and renderbuffer color formats" |
23 | | RGBA32I, |
24 | | RGBA32UI, |
25 | | RGBA16I, |
26 | | RGBA16UI, |
27 | | RGBA8, |
28 | | RGBA8I, |
29 | | RGBA8UI, |
30 | | SRGB8_ALPHA8, |
31 | | RGB10_A2, |
32 | | RGB10_A2UI, |
33 | | RGBA4, |
34 | | RGB5_A1, |
35 | | |
36 | | RGB8, |
37 | | RGB565, |
38 | | |
39 | | RG32I, |
40 | | RG32UI, |
41 | | RG16I, |
42 | | RG16UI, |
43 | | RG8, |
44 | | RG8I, |
45 | | RG8UI, |
46 | | |
47 | | R32I, |
48 | | R32UI, |
49 | | R16I, |
50 | | R16UI, |
51 | | R8, |
52 | | R8I, |
53 | | R8UI, |
54 | | |
55 | | // "Texture-only color formats" |
56 | | RGBA32F, |
57 | | RGBA16F, |
58 | | RGBA8_SNORM, |
59 | | |
60 | | RGB32F, |
61 | | RGB32I, |
62 | | RGB32UI, |
63 | | |
64 | | RGB16F, |
65 | | RGB16I, |
66 | | RGB16UI, |
67 | | |
68 | | RGB8_SNORM, |
69 | | RGB8I, |
70 | | RGB8UI, |
71 | | SRGB8, |
72 | | |
73 | | R11F_G11F_B10F, |
74 | | RGB9_E5, |
75 | | |
76 | | RG32F, |
77 | | RG16F, |
78 | | RG8_SNORM, |
79 | | |
80 | | R32F, |
81 | | R16F, |
82 | | R8_SNORM, |
83 | | |
84 | | // "Depth formats" |
85 | | DEPTH_COMPONENT32F, |
86 | | DEPTH_COMPONENT24, |
87 | | DEPTH_COMPONENT16, |
88 | | |
89 | | // "Combined depth+stencil formats" |
90 | | DEPTH32F_STENCIL8, |
91 | | DEPTH24_STENCIL8, |
92 | | |
93 | | // GLES 3.0.4, p205-206, "Required Renderbuffer Formats" |
94 | | STENCIL_INDEX8, |
95 | | |
96 | | //////////////////////////////////// |
97 | | |
98 | | // GLES 3.0.4, p147, table 3.19 |
99 | | // GLES 3.0.4, p286+, $C.1 "ETC Compressed Texture Image Formats" |
100 | | COMPRESSED_R11_EAC, |
101 | | COMPRESSED_SIGNED_R11_EAC, |
102 | | COMPRESSED_RG11_EAC, |
103 | | COMPRESSED_SIGNED_RG11_EAC, |
104 | | COMPRESSED_RGB8_ETC2, |
105 | | COMPRESSED_SRGB8_ETC2, |
106 | | COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2, |
107 | | COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2, |
108 | | COMPRESSED_RGBA8_ETC2_EAC, |
109 | | COMPRESSED_SRGB8_ALPHA8_ETC2_EAC, |
110 | | |
111 | | // AMD_compressed_ATC_texture |
112 | | ATC_RGB_AMD, |
113 | | ATC_RGBA_EXPLICIT_ALPHA_AMD, |
114 | | ATC_RGBA_INTERPOLATED_ALPHA_AMD, |
115 | | |
116 | | // EXT_texture_compression_s3tc |
117 | | COMPRESSED_RGB_S3TC_DXT1_EXT, |
118 | | COMPRESSED_RGBA_S3TC_DXT1_EXT, |
119 | | COMPRESSED_RGBA_S3TC_DXT3_EXT, |
120 | | COMPRESSED_RGBA_S3TC_DXT5_EXT, |
121 | | |
122 | | // EXT_texture_sRGB |
123 | | COMPRESSED_SRGB_S3TC_DXT1_EXT, |
124 | | COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT, |
125 | | COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT, |
126 | | COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT, |
127 | | |
128 | | // KHR_texture_compression_astc_ldr |
129 | | COMPRESSED_RGBA_ASTC_4x4_KHR, |
130 | | COMPRESSED_RGBA_ASTC_5x4_KHR, |
131 | | COMPRESSED_RGBA_ASTC_5x5_KHR, |
132 | | COMPRESSED_RGBA_ASTC_6x5_KHR, |
133 | | COMPRESSED_RGBA_ASTC_6x6_KHR, |
134 | | COMPRESSED_RGBA_ASTC_8x5_KHR, |
135 | | COMPRESSED_RGBA_ASTC_8x6_KHR, |
136 | | COMPRESSED_RGBA_ASTC_8x8_KHR, |
137 | | COMPRESSED_RGBA_ASTC_10x5_KHR, |
138 | | COMPRESSED_RGBA_ASTC_10x6_KHR, |
139 | | COMPRESSED_RGBA_ASTC_10x8_KHR, |
140 | | COMPRESSED_RGBA_ASTC_10x10_KHR, |
141 | | COMPRESSED_RGBA_ASTC_12x10_KHR, |
142 | | COMPRESSED_RGBA_ASTC_12x12_KHR, |
143 | | |
144 | | COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR, |
145 | | COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR, |
146 | | COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR, |
147 | | COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR, |
148 | | COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR, |
149 | | COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR, |
150 | | COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR, |
151 | | COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR, |
152 | | COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR, |
153 | | COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR, |
154 | | COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR, |
155 | | COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR, |
156 | | COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR, |
157 | | COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR, |
158 | | |
159 | | // IMG_texture_compression_pvrtc |
160 | | COMPRESSED_RGB_PVRTC_4BPPV1, |
161 | | COMPRESSED_RGBA_PVRTC_4BPPV1, |
162 | | COMPRESSED_RGB_PVRTC_2BPPV1, |
163 | | COMPRESSED_RGBA_PVRTC_2BPPV1, |
164 | | |
165 | | // OES_compressed_ETC1_RGB8_texture |
166 | | ETC1_RGB8_OES, |
167 | | |
168 | | //////////////////////////////////// |
169 | | |
170 | | // GLES 3.0.4, p128, table 3.12. |
171 | | Luminance8Alpha8, |
172 | | Luminance8, |
173 | | Alpha8, |
174 | | |
175 | | // OES_texture_float |
176 | | Luminance32FAlpha32F, |
177 | | Luminance32F, |
178 | | Alpha32F, |
179 | | |
180 | | // OES_texture_half_float |
181 | | Luminance16FAlpha16F, |
182 | | Luminance16F, |
183 | | Alpha16F, |
184 | | |
185 | | MAX, |
186 | | }; |
187 | | |
188 | | enum class UnsizedFormat : uint8_t { |
189 | | R, |
190 | | RG, |
191 | | RGB, |
192 | | RGBA, |
193 | | LA, |
194 | | L, |
195 | | A, |
196 | | D, |
197 | | S, |
198 | | DEPTH_STENCIL, // `DS` is a macro on Solaris. (regset.h) |
199 | | }; |
200 | | |
201 | | // GLES 3.0.4 p114 Table 3.4, p240 |
202 | | enum class ComponentType : uint8_t { |
203 | | None, |
204 | | Int, // RGBA32I |
205 | | UInt, // RGBA32UI, STENCIL_INDEX8 |
206 | | NormInt, // RGBA8_SNORM |
207 | | NormUInt, // RGBA8, DEPTH_COMPONENT16 |
208 | | Float, // RGBA32F |
209 | | Special, // DEPTH24_STENCIL8 |
210 | | }; |
211 | | |
212 | | enum class CompressionFamily : uint8_t { |
213 | | ASTC, |
214 | | ATC, |
215 | | ES3, // ETC2 or EAC |
216 | | ETC1, |
217 | | PVRTC, |
218 | | S3TC, |
219 | | }; |
220 | | |
221 | | //////////////////////////////////////////////////////////////////////////////// |
222 | | |
223 | | struct CompressedFormatInfo |
224 | | { |
225 | | const EffectiveFormat effectiveFormat; |
226 | | const uint8_t bytesPerBlock; |
227 | | const uint8_t blockWidth; |
228 | | const uint8_t blockHeight; |
229 | | const CompressionFamily family; |
230 | | }; |
231 | | |
232 | | struct FormatInfo |
233 | | { |
234 | | const EffectiveFormat effectiveFormat; |
235 | | const char* const name; |
236 | | const GLenum sizedFormat; |
237 | | const UnsizedFormat unsizedFormat; |
238 | | const ComponentType componentType; |
239 | | const bool isSRGB; |
240 | | |
241 | | const CompressedFormatInfo* const compression; |
242 | | |
243 | | const uint8_t estimatedBytesPerPixel; // 0 iff bool(compression). |
244 | | |
245 | | // In bits. Iff bool(compression), active channels are 1. |
246 | | const uint8_t r; |
247 | | const uint8_t g; |
248 | | const uint8_t b; |
249 | | const uint8_t a; |
250 | | const uint8_t d; |
251 | | const uint8_t s; |
252 | | |
253 | | ////// |
254 | | |
255 | | std::map<UnsizedFormat, const FormatInfo*> copyDecayFormats; |
256 | | |
257 | | const FormatInfo* GetCopyDecayFormat(UnsizedFormat) const; |
258 | | |
259 | 0 | bool IsColorFormat() const { |
260 | 0 | // Alpha is a 'color format' since it's 'color-attachable'. |
261 | 0 | return bool(compression) || |
262 | 0 | bool(r | g | b | a); |
263 | 0 | } |
264 | | }; |
265 | | |
266 | | struct PackingInfo |
267 | | { |
268 | | GLenum format; |
269 | | GLenum type; |
270 | | |
271 | | bool operator <(const PackingInfo& x) const |
272 | 0 | { |
273 | 0 | if (format != x.format) |
274 | 0 | return format < x.format; |
275 | 0 | |
276 | 0 | return type < x.type; |
277 | 0 | } |
278 | | |
279 | 0 | bool operator ==(const PackingInfo& x) const { |
280 | 0 | return (format == x.format && |
281 | 0 | type == x.type); |
282 | 0 | } |
283 | | }; |
284 | | |
285 | | struct DriverUnpackInfo |
286 | | { |
287 | | GLenum internalFormat; |
288 | | GLenum unpackFormat; |
289 | | GLenum unpackType; |
290 | | |
291 | 0 | PackingInfo ToPacking() const { |
292 | 0 | return {unpackFormat, unpackType}; |
293 | 0 | } |
294 | | }; |
295 | | |
296 | | ////////////////////////////////////////////////////////////////////////////////////////// |
297 | | |
298 | | const FormatInfo* GetFormat(EffectiveFormat format); |
299 | | uint8_t BytesPerPixel(const PackingInfo& packing); |
300 | | bool GetBytesPerPixel(const PackingInfo& packing, uint8_t* const out_bytes); |
301 | | /* |
302 | | GLint ComponentSize(const FormatInfo* format, GLenum component); |
303 | | GLenum ComponentType(const FormatInfo* format); |
304 | | */ |
305 | | //////////////////////////////////////// |
306 | | |
307 | | struct FormatUsageInfo |
308 | | { |
309 | | const FormatInfo* const format; |
310 | | private: |
311 | | bool isRenderable; |
312 | | public: |
313 | | bool isFilterable; |
314 | | |
315 | | std::map<PackingInfo, DriverUnpackInfo> validUnpacks; |
316 | | const DriverUnpackInfo* idealUnpack; |
317 | | |
318 | | const GLint* textureSwizzleRGBA; |
319 | | |
320 | | bool maxSamplesKnown; |
321 | | uint32_t maxSamples; |
322 | | |
323 | | static const GLint kLuminanceSwizzleRGBA[4]; |
324 | | static const GLint kAlphaSwizzleRGBA[4]; |
325 | | static const GLint kLumAlphaSwizzleRGBA[4]; |
326 | | |
327 | | explicit FormatUsageInfo(const FormatInfo* _format) |
328 | | : format(_format) |
329 | | , isRenderable(false) |
330 | | , isFilterable(false) |
331 | | , idealUnpack(nullptr) |
332 | | , textureSwizzleRGBA(nullptr) |
333 | | , maxSamplesKnown(false) |
334 | | , maxSamples(0) |
335 | 0 | { } |
336 | | |
337 | 0 | bool IsRenderable() const { return isRenderable; } |
338 | | void SetRenderable(); |
339 | | |
340 | | bool IsUnpackValid(const PackingInfo& key, |
341 | | const DriverUnpackInfo** const out_value) const; |
342 | | |
343 | | void ResolveMaxSamples(gl::GLContext* gl); |
344 | | }; |
345 | | |
346 | | class FormatUsageAuthority |
347 | | { |
348 | | std::map<EffectiveFormat, FormatUsageInfo> mUsageMap; |
349 | | |
350 | | std::map<GLenum, const FormatUsageInfo*> mRBFormatMap; |
351 | | std::map<GLenum, const FormatUsageInfo*> mSizedTexFormatMap; |
352 | | std::map<PackingInfo, const FormatUsageInfo*> mUnsizedTexFormatMap; |
353 | | |
354 | | std::set<GLenum> mValidTexInternalFormats; |
355 | | std::set<GLenum> mValidTexUnpackFormats; |
356 | | std::set<GLenum> mValidTexUnpackTypes; |
357 | | |
358 | | public: |
359 | | static UniquePtr<FormatUsageAuthority> CreateForWebGL1(gl::GLContext* gl); |
360 | | static UniquePtr<FormatUsageAuthority> CreateForWebGL2(gl::GLContext* gl); |
361 | | |
362 | | private: |
363 | 0 | FormatUsageAuthority() { } |
364 | | |
365 | | public: |
366 | | FormatUsageInfo* EditUsage(EffectiveFormat format); |
367 | | const FormatUsageInfo* GetUsage(EffectiveFormat format) const; |
368 | | |
369 | | void AddTexUnpack(FormatUsageInfo* usage, const PackingInfo& pi, |
370 | | const DriverUnpackInfo& dui); |
371 | | |
372 | | bool IsInternalFormatEnumValid(GLenum internalFormat) const; |
373 | | bool AreUnpackEnumsValid(GLenum unpackFormat, GLenum unpackType) const; |
374 | | |
375 | | void AllowRBFormat(GLenum sizedFormat, const FormatUsageInfo* usage); |
376 | | void AllowSizedTexFormat(GLenum sizedFormat, const FormatUsageInfo* usage); |
377 | | void AllowUnsizedTexFormat(const PackingInfo& pi, const FormatUsageInfo* usage); |
378 | | |
379 | | const FormatUsageInfo* GetRBUsage(GLenum sizedFormat) const; |
380 | | const FormatUsageInfo* GetSizedTexUsage(GLenum sizedFormat) const; |
381 | | const FormatUsageInfo* GetUnsizedTexUsage(const PackingInfo& pi) const; |
382 | | }; |
383 | | |
384 | | } // namespace webgl |
385 | | } // namespace mozilla |
386 | | |
387 | | #endif // WEBGL_FORMATS_H_ |