Bug 1702375 [wpt PR 28327] - Update docs to point directly at RuntimeEnabledFeatures...
[gecko.git] / dom / canvas / WebGLFormats.h
blobfa1a840b2f1306bf3f7fcd2b8d371fa17d68258c
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 #ifndef WEBGL_FORMATS_H_
7 #define WEBGL_FORMATS_H_
9 #include <map>
10 #include <set>
12 #include "mozilla/UniquePtr.h"
13 #include "WebGLTypes.h"
15 namespace mozilla {
16 namespace webgl {
18 typedef uint8_t EffectiveFormatValueT;
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,
36 RGB8,
37 RGB565,
39 RG32I,
40 RG32UI,
41 RG16I,
42 RG16UI,
43 RG8,
44 RG8I,
45 RG8UI,
47 R32I,
48 R32UI,
49 R16I,
50 R16UI,
51 R8,
52 R8I,
53 R8UI,
55 // "Texture-only color formats"
56 RGBA32F,
57 RGBA16F,
58 RGBA8_SNORM,
60 RGB32F,
61 RGB32I,
62 RGB32UI,
64 RGB16F,
65 RGB16I,
66 RGB16UI,
68 RGB8_SNORM,
69 RGB8I,
70 RGB8UI,
71 SRGB8,
73 R11F_G11F_B10F,
74 RGB9_E5,
76 RG32F,
77 RG16F,
78 RG8_SNORM,
80 R32F,
81 R16F,
82 R8_SNORM,
84 // "Depth formats"
85 DEPTH_COMPONENT32F,
86 DEPTH_COMPONENT24,
87 DEPTH_COMPONENT16,
89 // "Combined depth+stencil formats"
90 DEPTH32F_STENCIL8,
91 DEPTH24_STENCIL8,
93 // GLES 3.0.4, p205-206, "Required Renderbuffer Formats"
94 STENCIL_INDEX8,
96 ////////////////////////////////////
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,
111 // EXT_texture_compression_bptc
112 COMPRESSED_RGBA_BPTC_UNORM,
113 COMPRESSED_SRGB_ALPHA_BPTC_UNORM,
114 COMPRESSED_RGB_BPTC_SIGNED_FLOAT,
115 COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT,
117 // EXT_texture_compression_rgtc
118 COMPRESSED_RED_RGTC1,
119 COMPRESSED_SIGNED_RED_RGTC1,
120 COMPRESSED_RG_RGTC2,
121 COMPRESSED_SIGNED_RG_RGTC2,
123 // EXT_texture_compression_s3tc
124 COMPRESSED_RGB_S3TC_DXT1_EXT,
125 COMPRESSED_RGBA_S3TC_DXT1_EXT,
126 COMPRESSED_RGBA_S3TC_DXT3_EXT,
127 COMPRESSED_RGBA_S3TC_DXT5_EXT,
129 // EXT_texture_sRGB
130 COMPRESSED_SRGB_S3TC_DXT1_EXT,
131 COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT,
132 COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT,
133 COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT,
135 // KHR_texture_compression_astc_ldr
136 COMPRESSED_RGBA_ASTC_4x4_KHR,
137 COMPRESSED_RGBA_ASTC_5x4_KHR,
138 COMPRESSED_RGBA_ASTC_5x5_KHR,
139 COMPRESSED_RGBA_ASTC_6x5_KHR,
140 COMPRESSED_RGBA_ASTC_6x6_KHR,
141 COMPRESSED_RGBA_ASTC_8x5_KHR,
142 COMPRESSED_RGBA_ASTC_8x6_KHR,
143 COMPRESSED_RGBA_ASTC_8x8_KHR,
144 COMPRESSED_RGBA_ASTC_10x5_KHR,
145 COMPRESSED_RGBA_ASTC_10x6_KHR,
146 COMPRESSED_RGBA_ASTC_10x8_KHR,
147 COMPRESSED_RGBA_ASTC_10x10_KHR,
148 COMPRESSED_RGBA_ASTC_12x10_KHR,
149 COMPRESSED_RGBA_ASTC_12x12_KHR,
151 COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR,
152 COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR,
153 COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR,
154 COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR,
155 COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR,
156 COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR,
157 COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR,
158 COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR,
159 COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR,
160 COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR,
161 COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR,
162 COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR,
163 COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR,
164 COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR,
166 // IMG_texture_compression_pvrtc
167 COMPRESSED_RGB_PVRTC_4BPPV1,
168 COMPRESSED_RGBA_PVRTC_4BPPV1,
169 COMPRESSED_RGB_PVRTC_2BPPV1,
170 COMPRESSED_RGBA_PVRTC_2BPPV1,
172 // OES_compressed_ETC1_RGB8_texture
173 ETC1_RGB8_OES,
175 ////////////////////////////////////
177 // GLES 3.0.4, p128, table 3.12.
178 Luminance8Alpha8,
179 Luminance8,
180 Alpha8,
182 // OES_texture_float
183 Luminance32FAlpha32F,
184 Luminance32F,
185 Alpha32F,
187 // OES_texture_half_float
188 Luminance16FAlpha16F,
189 Luminance16F,
190 Alpha16F,
192 // EXT_texture_norm16
193 R16,
194 RG16,
195 RGB16,
196 RGBA16,
197 R16_SNORM,
198 RG16_SNORM,
199 RGB16_SNORM,
200 RGBA16_SNORM,
202 MAX,
205 enum class UnsizedFormat : uint8_t {
208 RGB,
209 RGBA,
215 DEPTH_STENCIL, // `DS` is a macro on Solaris. (regset.h)
218 // GLES 3.0.4 p114 Table 3.4, p240
219 enum class ComponentType : uint8_t {
220 Int, // RGBA32I
221 UInt, // RGBA32UI
222 NormInt, // RGBA8_SNORM
223 NormUInt, // RGBA8
224 Float, // RGBA32F
226 const char* ToString(ComponentType);
228 enum class TextureBaseType : uint8_t {
229 Int = uint8_t(ComponentType::Int),
230 UInt = uint8_t(ComponentType::UInt),
231 Float = uint8_t(ComponentType::Float), // Also includes NormU?Int and Depth
234 const char* ToString(TextureBaseType);
236 enum class CompressionFamily : uint8_t {
237 ASTC,
238 BPTC,
239 ES3, // ETC2 or EAC
240 ETC1,
241 PVRTC,
242 RGTC,
243 S3TC,
246 ////////////////////////////////////////////////////////////////////////////////
248 struct CompressedFormatInfo {
249 const EffectiveFormat effectiveFormat;
250 const uint8_t bytesPerBlock;
251 const uint8_t blockWidth;
252 const uint8_t blockHeight;
253 const CompressionFamily family;
256 struct FormatInfo {
257 const EffectiveFormat effectiveFormat;
258 const char* const name;
259 const GLenum sizedFormat;
260 const UnsizedFormat unsizedFormat;
261 const ComponentType componentType;
262 const TextureBaseType baseType;
263 const bool isSRGB;
265 const CompressedFormatInfo* const compression;
267 const uint8_t estimatedBytesPerPixel; // 0 iff bool(compression).
269 // In bits. Iff bool(compression), active channels are 1.
270 const uint8_t r;
271 const uint8_t g;
272 const uint8_t b;
273 const uint8_t a;
274 const uint8_t d;
275 const uint8_t s;
277 //////
279 std::map<UnsizedFormat, const FormatInfo*> copyDecayFormats;
281 const FormatInfo* GetCopyDecayFormat(UnsizedFormat) const;
283 bool IsColorFormat() const {
284 // Alpha is a 'color format' since it's 'color-attachable'.
285 return bool(compression) || bool(r | g | b | a);
289 //////////////////////////////////////////////////////////////////////////////////////////
291 const FormatInfo* GetFormat(EffectiveFormat format);
292 uint8_t BytesPerPixel(const PackingInfo& packing);
293 bool GetBytesPerPixel(const PackingInfo& packing, uint8_t* const out_bytes);
295 GLint ComponentSize(const FormatInfo* format, GLenum component);
296 GLenum ComponentType(const FormatInfo* format);
298 ////////////////////////////////////////
300 struct FormatRenderableState final {
301 private:
302 enum class RenderableState {
303 Disabled,
304 Implicit,
305 Explicit,
308 public:
309 RenderableState state = RenderableState::Disabled;
310 WebGLExtensionID extid = WebGLExtensionID::Max;
312 static FormatRenderableState Explicit() {
313 return {RenderableState::Explicit};
316 static FormatRenderableState Implicit(WebGLExtensionID extid) {
317 return {RenderableState::Implicit, extid};
320 bool IsRenderable() const { return state != RenderableState::Disabled; }
321 bool IsExplicit() const { return state == RenderableState::Explicit; }
324 struct FormatUsageInfo {
325 const FormatInfo* const format;
327 private:
328 FormatRenderableState renderableState;
330 public:
331 bool isFilterable = false;
333 std::map<PackingInfo, DriverUnpackInfo> validUnpacks;
334 const DriverUnpackInfo* idealUnpack = nullptr;
336 const GLint* textureSwizzleRGBA = nullptr;
338 private:
339 mutable bool maxSamplesKnown = false;
340 mutable uint32_t maxSamples = 0;
342 public:
343 static const GLint kLuminanceSwizzleRGBA[4];
344 static const GLint kAlphaSwizzleRGBA[4];
345 static const GLint kLumAlphaSwizzleRGBA[4];
347 explicit FormatUsageInfo(const FormatInfo* const _format) : format(_format) {
348 if (format->IsColorFormat() && format->baseType != TextureBaseType::Float) {
349 maxSamplesKnown = true;
353 bool IsRenderable() const { return renderableState.IsRenderable(); }
354 void SetRenderable(
355 const FormatRenderableState& state = FormatRenderableState::Explicit());
356 bool IsExplicitlyRenderable() const { return renderableState.IsExplicit(); }
357 WebGLExtensionID GetExtensionID() const {
358 MOZ_ASSERT(renderableState.extid != WebGLExtensionID::Max);
359 return renderableState.extid;
362 bool IsUnpackValid(const PackingInfo& key,
363 const DriverUnpackInfo** const out_value) const;
365 private:
366 void ResolveMaxSamples(gl::GLContext& gl) const;
368 public:
369 uint32_t MaxSamples(gl::GLContext& gl) const {
370 if (!maxSamplesKnown) {
371 ResolveMaxSamples(gl);
373 return maxSamples;
377 class FormatUsageAuthority {
378 std::map<EffectiveFormat, FormatUsageInfo> mUsageMap;
380 std::map<GLenum, const FormatUsageInfo*> mRBFormatMap;
381 std::map<GLenum, const FormatUsageInfo*> mSizedTexFormatMap;
382 std::map<PackingInfo, const FormatUsageInfo*> mUnsizedTexFormatMap;
384 std::set<GLenum> mValidTexInternalFormats;
385 std::set<GLenum> mValidTexUnpackFormats;
386 std::set<GLenum> mValidTexUnpackTypes;
388 public:
389 static UniquePtr<FormatUsageAuthority> CreateForWebGL1(gl::GLContext* gl);
390 static UniquePtr<FormatUsageAuthority> CreateForWebGL2(gl::GLContext* gl);
392 private:
393 FormatUsageAuthority() = default;
395 public:
396 FormatUsageInfo* EditUsage(EffectiveFormat format);
397 const FormatUsageInfo* GetUsage(EffectiveFormat format) const;
399 void AddTexUnpack(FormatUsageInfo* usage, const PackingInfo& pi,
400 const DriverUnpackInfo& dui);
402 bool IsInternalFormatEnumValid(GLenum internalFormat) const;
403 bool AreUnpackEnumsValid(GLenum unpackFormat, GLenum unpackType) const;
405 void AllowRBFormat(GLenum sizedFormat, const FormatUsageInfo* usage,
406 bool expectRenderable = true);
407 void AllowSizedTexFormat(GLenum sizedFormat, const FormatUsageInfo* usage);
408 void AllowUnsizedTexFormat(const PackingInfo& pi,
409 const FormatUsageInfo* usage);
411 const FormatUsageInfo* GetRBUsage(GLenum sizedFormat) const;
412 const FormatUsageInfo* GetSizedTexUsage(GLenum sizedFormat) const;
413 const FormatUsageInfo* GetUnsizedTexUsage(const PackingInfo& pi) const;
416 } // namespace webgl
417 } // namespace mozilla
419 #endif // WEBGL_FORMATS_H_