1 /* -*- Mode: C++; tab-width: 20; 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 #include "WebGLExtensions.h"
9 #include "mozilla/dom/WebGLRenderingContextBinding.h"
10 #include "mozilla/StaticPrefs_webgl.h"
11 #include "WebGLContext.h"
15 WebGLExtensionBlendMinMax::WebGLExtensionBlendMinMax(WebGLContext
* webgl
)
16 : WebGLExtensionBase(webgl
) {
17 MOZ_ASSERT(IsSupported(webgl
), "Don't construct extension if unsupported.");
20 bool WebGLExtensionBlendMinMax::IsSupported(const WebGLContext
* webgl
) {
21 if (webgl
->IsWebGL2()) return false;
23 return webgl
->GL()->IsSupported(gl::GLFeature::blend_minmax
);
28 WebGLExtensionColorBufferFloat::WebGLExtensionColorBufferFloat(
30 : WebGLExtensionBase(webgl
) {
31 MOZ_ASSERT(IsSupported(webgl
), "Don't construct extension if unsupported.");
32 SetRenderable(webgl::FormatRenderableState::Implicit(
33 WebGLExtensionID::WEBGL_color_buffer_float
));
36 void WebGLExtensionColorBufferFloat::SetRenderable(
37 const webgl::FormatRenderableState state
) {
38 auto& fua
= mContext
->mFormatUsage
;
40 auto fnUpdateUsage
= [&](GLenum sizedFormat
,
41 webgl::EffectiveFormat effFormat
) {
42 auto usage
= fua
->EditUsage(effFormat
);
43 usage
->SetRenderable(state
);
44 fua
->AllowRBFormat(sizedFormat
, usage
);
47 #define FOO(x) fnUpdateUsage(LOCAL_GL_##x, webgl::EffectiveFormat::x)
49 // The extension doesn't actually add RGB32F; only RGBA32F.
55 void WebGLExtensionColorBufferFloat::OnSetExplicit() {
56 SetRenderable(webgl::FormatRenderableState::Explicit());
59 bool WebGLExtensionColorBufferFloat::IsSupported(const WebGLContext
* webgl
) {
60 if (webgl
->IsWebGL2()) return false;
62 const auto& gl
= webgl
->gl
;
63 return gl
->IsSupported(gl::GLFeature::renderbuffer_color_float
) &&
64 gl
->IsSupported(gl::GLFeature::frag_color_float
);
69 WebGLExtensionColorBufferHalfFloat::WebGLExtensionColorBufferHalfFloat(
71 : WebGLExtensionBase(webgl
) {
72 MOZ_ASSERT(IsSupported(webgl
), "Don't construct extension if unsupported.");
73 SetRenderable(webgl::FormatRenderableState::Implicit(
74 WebGLExtensionID::EXT_color_buffer_half_float
));
77 void WebGLExtensionColorBufferHalfFloat::SetRenderable(
78 const webgl::FormatRenderableState state
) {
79 auto& fua
= mContext
->mFormatUsage
;
81 auto fnUpdateUsage
= [&](GLenum sizedFormat
, webgl::EffectiveFormat effFormat
,
82 const bool renderable
) {
83 auto usage
= fua
->EditUsage(effFormat
);
85 usage
->SetRenderable(state
);
87 fua
->AllowRBFormat(sizedFormat
, usage
, renderable
);
90 #define FOO(x, y) fnUpdateUsage(LOCAL_GL_##x, webgl::EffectiveFormat::x, y)
93 FOO(RGB16F
, false); // It's not required, thus not portable. (Also there's a
94 // wicked driver bug on Mac+Intel)
99 void WebGLExtensionColorBufferHalfFloat::OnSetExplicit() {
100 SetRenderable(webgl::FormatRenderableState::Explicit());
103 bool WebGLExtensionColorBufferHalfFloat::IsSupported(
104 const WebGLContext
* webgl
) {
105 if (webgl
->IsWebGL2()) return false;
107 const auto& gl
= webgl
->gl
;
108 return gl
->IsSupported(gl::GLFeature::renderbuffer_color_half_float
) &&
109 gl
->IsSupported(gl::GLFeature::frag_color_float
);
114 WebGLExtensionCompressedTextureASTC::WebGLExtensionCompressedTextureASTC(
116 : WebGLExtensionBase(webgl
) {
117 MOZ_ASSERT(IsSupported(webgl
), "Don't construct extension if unsupported.");
119 RefPtr
<WebGLContext
> webgl_
= webgl
; // Bug 1201275
120 const auto fnAdd
= [&webgl_
](GLenum sizedFormat
,
121 webgl::EffectiveFormat effFormat
) {
122 auto& fua
= webgl_
->mFormatUsage
;
124 auto usage
= fua
->EditUsage(effFormat
);
125 usage
->isFilterable
= true;
126 fua
->AllowSizedTexFormat(sizedFormat
, usage
);
129 #define FOO(x) LOCAL_GL_##x, webgl::EffectiveFormat::x
131 fnAdd(FOO(COMPRESSED_RGBA_ASTC_4x4_KHR
));
132 fnAdd(FOO(COMPRESSED_RGBA_ASTC_5x4_KHR
));
133 fnAdd(FOO(COMPRESSED_RGBA_ASTC_5x5_KHR
));
134 fnAdd(FOO(COMPRESSED_RGBA_ASTC_6x5_KHR
));
135 fnAdd(FOO(COMPRESSED_RGBA_ASTC_6x6_KHR
));
136 fnAdd(FOO(COMPRESSED_RGBA_ASTC_8x5_KHR
));
137 fnAdd(FOO(COMPRESSED_RGBA_ASTC_8x6_KHR
));
138 fnAdd(FOO(COMPRESSED_RGBA_ASTC_8x8_KHR
));
139 fnAdd(FOO(COMPRESSED_RGBA_ASTC_10x5_KHR
));
140 fnAdd(FOO(COMPRESSED_RGBA_ASTC_10x6_KHR
));
141 fnAdd(FOO(COMPRESSED_RGBA_ASTC_10x8_KHR
));
142 fnAdd(FOO(COMPRESSED_RGBA_ASTC_10x10_KHR
));
143 fnAdd(FOO(COMPRESSED_RGBA_ASTC_12x10_KHR
));
144 fnAdd(FOO(COMPRESSED_RGBA_ASTC_12x12_KHR
));
146 fnAdd(FOO(COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR
));
147 fnAdd(FOO(COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR
));
148 fnAdd(FOO(COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR
));
149 fnAdd(FOO(COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR
));
150 fnAdd(FOO(COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR
));
151 fnAdd(FOO(COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR
));
152 fnAdd(FOO(COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR
));
153 fnAdd(FOO(COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR
));
154 fnAdd(FOO(COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR
));
155 fnAdd(FOO(COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR
));
156 fnAdd(FOO(COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR
));
157 fnAdd(FOO(COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR
));
158 fnAdd(FOO(COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR
));
159 fnAdd(FOO(COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR
));
164 bool WebGLExtensionCompressedTextureASTC::IsSupported(
165 const WebGLContext
* webgl
) {
166 gl::GLContext
* gl
= webgl
->GL();
167 return gl
->IsExtensionSupported(
168 gl::GLContext::KHR_texture_compression_astc_ldr
);
173 WebGLExtensionCompressedTextureBPTC::WebGLExtensionCompressedTextureBPTC(
174 WebGLContext
* const webgl
)
175 : WebGLExtensionBase(webgl
) {
176 MOZ_ASSERT(IsSupported(webgl
), "Don't construct extension if unsupported.");
178 auto& fua
= webgl
->mFormatUsage
;
180 const auto fnAdd
= [&](const GLenum sizedFormat
,
181 const webgl::EffectiveFormat effFormat
) {
182 auto usage
= fua
->EditUsage(effFormat
);
183 usage
->isFilterable
= true;
184 fua
->AllowSizedTexFormat(sizedFormat
, usage
);
187 #define _(X) LOCAL_GL_##X, webgl::EffectiveFormat::X
189 fnAdd(_(COMPRESSED_RGBA_BPTC_UNORM
));
190 fnAdd(_(COMPRESSED_SRGB_ALPHA_BPTC_UNORM
));
191 fnAdd(_(COMPRESSED_RGB_BPTC_SIGNED_FLOAT
));
192 fnAdd(_(COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT
));
197 bool WebGLExtensionCompressedTextureBPTC::IsSupported(
198 const WebGLContext
* const webgl
) {
199 return webgl
->gl
->IsSupported(gl::GLFeature::texture_compression_bptc
);
204 WebGLExtensionCompressedTextureES3::WebGLExtensionCompressedTextureES3(
206 : WebGLExtensionBase(webgl
) {
207 // GLES 3.0.4, p147, table 3.19
208 // GLES 3.0.4, p286+, $C.1 "ETC Compressed Texture Image Formats"
209 // Note that all compressed texture formats are filterable:
211 // "[A] texture is complete unless any of the following conditions hold true:
213 // * The effective internal format specified for the texture arrays is a
214 // sized internal color format that is not texture-filterable (see table
215 // 3.13) and [the mag filter requires filtering]."
216 // Compressed formats are not sized internal color formats, and indeed they
217 // are not listed in table 3.13.
219 RefPtr
<WebGLContext
> webgl_
= webgl
; // Bug 1201275
220 const auto fnAdd
= [&webgl_
](GLenum sizedFormat
,
221 webgl::EffectiveFormat effFormat
) {
222 auto& fua
= webgl_
->mFormatUsage
;
224 auto usage
= fua
->EditUsage(effFormat
);
225 usage
->isFilterable
= true;
226 fua
->AllowSizedTexFormat(sizedFormat
, usage
);
229 #define FOO(x) LOCAL_GL_##x, webgl::EffectiveFormat::x
231 fnAdd(FOO(COMPRESSED_R11_EAC
));
232 fnAdd(FOO(COMPRESSED_SIGNED_R11_EAC
));
233 fnAdd(FOO(COMPRESSED_RG11_EAC
));
234 fnAdd(FOO(COMPRESSED_SIGNED_RG11_EAC
));
235 fnAdd(FOO(COMPRESSED_RGB8_ETC2
));
236 fnAdd(FOO(COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2
));
237 fnAdd(FOO(COMPRESSED_RGBA8_ETC2_EAC
));
239 // sRGB support is manadatory in GL 4.3 and GL ES 3.0, which are the only
240 // versions to support ETC2.
241 fnAdd(FOO(COMPRESSED_SRGB8_ALPHA8_ETC2_EAC
));
242 fnAdd(FOO(COMPRESSED_SRGB8_ETC2
));
243 fnAdd(FOO(COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2
));
250 WebGLExtensionCompressedTextureETC1::WebGLExtensionCompressedTextureETC1(
252 : WebGLExtensionBase(webgl
) {
253 RefPtr
<WebGLContext
> webgl_
= webgl
; // Bug 1201275
254 const auto fnAdd
= [&webgl_
](GLenum sizedFormat
,
255 webgl::EffectiveFormat effFormat
) {
256 auto& fua
= webgl_
->mFormatUsage
;
258 auto usage
= fua
->EditUsage(effFormat
);
259 usage
->isFilterable
= true;
260 fua
->AllowSizedTexFormat(sizedFormat
, usage
);
263 #define FOO(x) LOCAL_GL_##x, webgl::EffectiveFormat::x
265 fnAdd(FOO(ETC1_RGB8_OES
));
272 WebGLExtensionCompressedTexturePVRTC::WebGLExtensionCompressedTexturePVRTC(
274 : WebGLExtensionBase(webgl
) {
275 RefPtr
<WebGLContext
> webgl_
= webgl
; // Bug 1201275
276 const auto fnAdd
= [&webgl_
](GLenum sizedFormat
,
277 webgl::EffectiveFormat effFormat
) {
278 auto& fua
= webgl_
->mFormatUsage
;
280 auto usage
= fua
->EditUsage(effFormat
);
281 usage
->isFilterable
= true;
282 fua
->AllowSizedTexFormat(sizedFormat
, usage
);
285 #define FOO(x) LOCAL_GL_##x, webgl::EffectiveFormat::x
287 fnAdd(FOO(COMPRESSED_RGB_PVRTC_4BPPV1
));
288 fnAdd(FOO(COMPRESSED_RGB_PVRTC_2BPPV1
));
289 fnAdd(FOO(COMPRESSED_RGBA_PVRTC_4BPPV1
));
290 fnAdd(FOO(COMPRESSED_RGBA_PVRTC_2BPPV1
));
297 WebGLExtensionCompressedTextureRGTC::WebGLExtensionCompressedTextureRGTC(
298 WebGLContext
* const webgl
)
299 : WebGLExtensionBase(webgl
) {
300 MOZ_ASSERT(IsSupported(webgl
), "Don't construct extension if unsupported.");
302 auto& fua
= webgl
->mFormatUsage
;
304 const auto fnAdd
= [&](const GLenum sizedFormat
,
305 const webgl::EffectiveFormat effFormat
) {
306 auto usage
= fua
->EditUsage(effFormat
);
307 usage
->isFilterable
= true;
308 fua
->AllowSizedTexFormat(sizedFormat
, usage
);
311 #define _(X) LOCAL_GL_##X, webgl::EffectiveFormat::X
313 fnAdd(_(COMPRESSED_RED_RGTC1
));
314 fnAdd(_(COMPRESSED_SIGNED_RED_RGTC1
));
315 fnAdd(_(COMPRESSED_RG_RGTC2
));
316 fnAdd(_(COMPRESSED_SIGNED_RG_RGTC2
));
321 bool WebGLExtensionCompressedTextureRGTC::IsSupported(
322 const WebGLContext
* const webgl
) {
323 return webgl
->gl
->IsSupported(gl::GLFeature::texture_compression_rgtc
);
328 WebGLExtensionCompressedTextureS3TC::WebGLExtensionCompressedTextureS3TC(
330 : WebGLExtensionBase(webgl
) {
331 RefPtr
<WebGLContext
> webgl_
= webgl
; // Bug 1201275
332 const auto fnAdd
= [&webgl_
](GLenum sizedFormat
,
333 webgl::EffectiveFormat effFormat
) {
334 auto& fua
= webgl_
->mFormatUsage
;
336 auto usage
= fua
->EditUsage(effFormat
);
337 usage
->isFilterable
= true;
338 fua
->AllowSizedTexFormat(sizedFormat
, usage
);
341 #define FOO(x) LOCAL_GL_##x, webgl::EffectiveFormat::x
343 fnAdd(FOO(COMPRESSED_RGB_S3TC_DXT1_EXT
));
344 fnAdd(FOO(COMPRESSED_RGBA_S3TC_DXT1_EXT
));
345 fnAdd(FOO(COMPRESSED_RGBA_S3TC_DXT3_EXT
));
346 fnAdd(FOO(COMPRESSED_RGBA_S3TC_DXT5_EXT
));
351 bool WebGLExtensionCompressedTextureS3TC::IsSupported(
352 const WebGLContext
* webgl
) {
353 gl::GLContext
* gl
= webgl
->GL();
354 if (gl
->IsExtensionSupported(gl::GLContext::EXT_texture_compression_s3tc
))
357 return gl
->IsExtensionSupported(
358 gl::GLContext::EXT_texture_compression_dxt1
) &&
359 gl
->IsExtensionSupported(
360 gl::GLContext::ANGLE_texture_compression_dxt3
) &&
361 gl
->IsExtensionSupported(
362 gl::GLContext::ANGLE_texture_compression_dxt5
);
367 WebGLExtensionCompressedTextureS3TC_SRGB::
368 WebGLExtensionCompressedTextureS3TC_SRGB(WebGLContext
* webgl
)
369 : WebGLExtensionBase(webgl
) {
370 RefPtr
<WebGLContext
> webgl_
= webgl
; // Bug 1201275
371 const auto fnAdd
= [&webgl_
](GLenum sizedFormat
,
372 webgl::EffectiveFormat effFormat
) {
373 auto& fua
= webgl_
->mFormatUsage
;
375 auto usage
= fua
->EditUsage(effFormat
);
376 usage
->isFilterable
= true;
377 fua
->AllowSizedTexFormat(sizedFormat
, usage
);
380 #define FOO(x) LOCAL_GL_##x, webgl::EffectiveFormat::x
382 fnAdd(FOO(COMPRESSED_SRGB_S3TC_DXT1_EXT
));
383 fnAdd(FOO(COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT
));
384 fnAdd(FOO(COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT
));
385 fnAdd(FOO(COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT
));
390 bool WebGLExtensionCompressedTextureS3TC_SRGB::IsSupported(
391 const WebGLContext
* webgl
) {
392 gl::GLContext
* gl
= webgl
->GL();
394 return gl
->IsExtensionSupported(
395 gl::GLContext::EXT_texture_compression_s3tc_srgb
);
397 // Desktop GL is more complicated: It's EXT_texture_sRGB, when
398 // EXT_texture_compression_s3tc is supported, that enables srgb+s3tc.
399 return gl
->IsExtensionSupported(gl::GLContext::EXT_texture_sRGB
) &&
400 gl
->IsExtensionSupported(gl::GLContext::EXT_texture_compression_s3tc
);
405 WebGLExtensionDepthTexture::WebGLExtensionDepthTexture(
406 WebGLContext
* const webgl
)
407 : WebGLExtensionBase(webgl
) {
408 auto& fua
= webgl
->mFormatUsage
;
410 const auto fnAdd
= [&fua
](webgl::EffectiveFormat effFormat
,
411 GLenum unpackFormat
, GLenum unpackType
) {
412 auto usage
= fua
->EditUsage(effFormat
);
413 MOZ_ASSERT(usage
->isFilterable
);
414 MOZ_ASSERT(usage
->IsRenderable());
416 const webgl::PackingInfo pi
= {unpackFormat
, unpackType
};
417 const webgl::DriverUnpackInfo dui
= {unpackFormat
, unpackFormat
,
419 fua
->AddTexUnpack(usage
, pi
, dui
);
420 fua
->AllowUnsizedTexFormat(pi
, usage
);
423 fnAdd(webgl::EffectiveFormat::DEPTH_COMPONENT16
, LOCAL_GL_DEPTH_COMPONENT
,
424 LOCAL_GL_UNSIGNED_SHORT
);
425 fnAdd(webgl::EffectiveFormat::DEPTH_COMPONENT24
, LOCAL_GL_DEPTH_COMPONENT
,
426 LOCAL_GL_UNSIGNED_INT
);
427 fnAdd(webgl::EffectiveFormat::DEPTH24_STENCIL8
, LOCAL_GL_DEPTH_STENCIL
,
428 LOCAL_GL_UNSIGNED_INT_24_8
);
431 bool WebGLExtensionDepthTexture::IsSupported(const WebGLContext
* const webgl
) {
432 if (webgl
->IsWebGL2()) return false;
434 // WEBGL_depth_texture supports DEPTH_STENCIL textures
435 const auto& gl
= webgl
->gl
;
436 if (!gl
->IsSupported(gl::GLFeature::packed_depth_stencil
)) return false;
438 return gl
->IsSupported(gl::GLFeature::depth_texture
) ||
439 gl
->IsExtensionSupported(gl::GLContext::ANGLE_depth_texture
);
444 WebGLExtensionDisjointTimerQuery::WebGLExtensionDisjointTimerQuery(
446 : WebGLExtensionBase(webgl
) {
447 MOZ_ASSERT(IsSupported(webgl
), "Don't construct extension if unsupported.");
450 bool WebGLExtensionDisjointTimerQuery::IsSupported(
451 const WebGLContext
* const webgl
) {
452 if (!StaticPrefs::webgl_enable_privileged_extensions()) return false;
454 gl::GLContext
* gl
= webgl
->GL();
455 return gl
->IsSupported(gl::GLFeature::query_objects
) &&
456 gl
->IsSupported(gl::GLFeature::get_query_object_i64v
) &&
458 gl::GLFeature::query_counter
); // provides GL_TIMESTAMP
463 WebGLExtensionDrawBuffers::WebGLExtensionDrawBuffers(WebGLContext
* webgl
)
464 : WebGLExtensionBase(webgl
) {
465 MOZ_ASSERT(IsSupported(webgl
), "Don't construct extension if unsupported.");
468 bool WebGLExtensionDrawBuffers::IsSupported(const WebGLContext
* webgl
) {
469 if (webgl
->IsWebGL2()) return false;
471 gl::GLContext
* gl
= webgl
->GL();
472 if (gl
->IsGLES() && gl
->Version() >= 300) {
473 // ANGLE's shader translator can't translate ESSL1 exts to ESSL3. (bug
477 return gl
->IsSupported(gl::GLFeature::draw_buffers
);
482 WebGLExtensionExplicitPresent::WebGLExtensionExplicitPresent(
483 WebGLContext
* const webgl
)
484 : WebGLExtensionBase(webgl
) {
485 if (!IsSupported(webgl
)) {
487 "Constructing WebGLExtensionExplicitPresent but IsSupported() is "
489 // This was previously an assert, but it seems like we get races against
490 // StaticPrefs changes/initialization?
494 bool WebGLExtensionExplicitPresent::IsSupported(
495 const WebGLContext
* const webgl
) {
496 return StaticPrefs::webgl_enable_draft_extensions();
501 WebGLExtensionEXTColorBufferFloat::WebGLExtensionEXTColorBufferFloat(
503 : WebGLExtensionBase(webgl
) {
504 MOZ_ASSERT(IsSupported(webgl
), "Don't construct extension if unsupported.");
506 auto& fua
= webgl
->mFormatUsage
;
508 auto fnUpdateUsage
= [&fua
](GLenum sizedFormat
,
509 webgl::EffectiveFormat effFormat
) {
510 auto usage
= fua
->EditUsage(effFormat
);
511 usage
->SetRenderable();
512 fua
->AllowRBFormat(sizedFormat
, usage
);
515 #define FOO(x) fnUpdateUsage(LOCAL_GL_##x, webgl::EffectiveFormat::x)
531 bool WebGLExtensionEXTColorBufferFloat::IsSupported(const WebGLContext
* webgl
) {
532 if (!webgl
->IsWebGL2()) return false;
534 const gl::GLContext
* gl
= webgl
->GL();
535 return gl
->IsSupported(gl::GLFeature::EXT_color_buffer_float
);
540 WebGLExtensionFBORenderMipmap::WebGLExtensionFBORenderMipmap(
541 WebGLContext
* const webgl
)
542 : WebGLExtensionBase(webgl
) {
543 MOZ_ASSERT(IsSupported(webgl
), "Don't construct extension if unsupported.");
546 bool WebGLExtensionFBORenderMipmap::IsSupported(
547 const WebGLContext
* const webgl
) {
548 if (webgl
->IsWebGL2()) return false;
550 const auto& gl
= webgl
->gl
;
551 if (!gl
->IsGLES()) return true;
552 if (gl
->Version() >= 300) return true;
553 return gl
->IsExtensionSupported(gl::GLContext::OES_fbo_render_mipmap
);
558 WebGLExtensionFloatBlend::WebGLExtensionFloatBlend(WebGLContext
* const webgl
)
559 : WebGLExtensionBase(webgl
) {
560 MOZ_ASSERT(IsSupported(webgl
), "Don't construct extension if unsupported.");
563 bool WebGLExtensionFloatBlend::IsSupported(const WebGLContext
* const webgl
) {
564 if (!WebGLExtensionColorBufferFloat::IsSupported(webgl
) &&
565 !WebGLExtensionEXTColorBufferFloat::IsSupported(webgl
))
568 const auto& gl
= webgl
->gl
;
569 if (!gl
->IsGLES() && gl
->Version() >= 300) return true;
570 if (gl
->IsGLES() && gl
->Version() >= 320) return true;
571 return gl
->IsExtensionSupported(gl::GLContext::EXT_float_blend
);
576 WebGLExtensionFragDepth::WebGLExtensionFragDepth(WebGLContext
* webgl
)
577 : WebGLExtensionBase(webgl
) {
578 MOZ_ASSERT(IsSupported(webgl
), "Don't construct extension if unsupported.");
581 bool WebGLExtensionFragDepth::IsSupported(const WebGLContext
* webgl
) {
582 if (webgl
->IsWebGL2()) return false;
584 gl::GLContext
* gl
= webgl
->GL();
585 if (gl
->IsGLES() && gl
->Version() >= 300) {
586 // ANGLE's shader translator can't translate ESSL1 exts to ESSL3. (bug
590 return gl
->IsSupported(gl::GLFeature::frag_depth
);
595 WebGLExtensionInstancedArrays::WebGLExtensionInstancedArrays(
597 : WebGLExtensionBase(webgl
) {
598 MOZ_ASSERT(IsSupported(webgl
), "Don't construct extension if unsupported.");
601 bool WebGLExtensionInstancedArrays::IsSupported(const WebGLContext
* webgl
) {
602 if (webgl
->IsWebGL2()) return false;
604 gl::GLContext
* gl
= webgl
->GL();
605 return gl
->IsSupported(gl::GLFeature::draw_instanced
) &&
606 gl
->IsSupported(gl::GLFeature::instanced_arrays
);
611 WebGLExtensionMultiview::WebGLExtensionMultiview(WebGLContext
* const webgl
)
612 : WebGLExtensionBase(webgl
) {
613 MOZ_ASSERT(IsSupported(webgl
), "Don't construct extension if unsupported.");
616 bool WebGLExtensionMultiview::IsSupported(const WebGLContext
* const webgl
) {
617 if (!webgl
->IsWebGL2()) return false;
619 const auto& gl
= webgl
->gl
;
620 return gl
->IsSupported(gl::GLFeature::multiview
);
625 WebGLExtensionShaderTextureLod::WebGLExtensionShaderTextureLod(
627 : WebGLExtensionBase(webgl
) {
628 MOZ_ASSERT(IsSupported(webgl
), "Don't construct extension if unsupported.");
631 bool WebGLExtensionShaderTextureLod::IsSupported(const WebGLContext
* webgl
) {
632 if (webgl
->IsWebGL2()) return false;
634 gl::GLContext
* gl
= webgl
->GL();
635 if (gl
->IsGLES() && gl
->Version() >= 300) {
636 // ANGLE's shader translator doesn't yet translate
637 // WebGL1+EXT_shader_texture_lod to ES3. (Bug 1491221)
640 return gl
->IsSupported(gl::GLFeature::shader_texture_lod
);
645 WebGLExtensionSRGB::WebGLExtensionSRGB(WebGLContext
* webgl
)
646 : WebGLExtensionBase(webgl
) {
647 MOZ_ASSERT(IsSupported(webgl
), "Don't construct extension if unsupported.");
649 gl::GLContext
* gl
= webgl
->GL();
651 // Desktop OpenGL requires the following to be enabled in order to
652 // support sRGB operations on framebuffers.
653 gl
->fEnable(LOCAL_GL_FRAMEBUFFER_SRGB_EXT
);
656 auto& fua
= webgl
->mFormatUsage
;
658 RefPtr
<gl::GLContext
> gl_
= gl
; // Bug 1201275
659 const auto fnAdd
= [&fua
, &gl_
](webgl::EffectiveFormat effFormat
,
660 GLenum format
, GLenum desktopUnpackFormat
) {
661 auto usage
= fua
->EditUsage(effFormat
);
662 usage
->isFilterable
= true;
664 webgl::DriverUnpackInfo dui
= {format
, format
, LOCAL_GL_UNSIGNED_BYTE
};
665 const auto pi
= dui
.ToPacking();
667 if (!gl_
->IsGLES()) dui
.unpackFormat
= desktopUnpackFormat
;
669 fua
->AddTexUnpack(usage
, pi
, dui
);
671 fua
->AllowUnsizedTexFormat(pi
, usage
);
674 fnAdd(webgl::EffectiveFormat::SRGB8
, LOCAL_GL_SRGB
, LOCAL_GL_RGB
);
675 fnAdd(webgl::EffectiveFormat::SRGB8_ALPHA8
, LOCAL_GL_SRGB_ALPHA
,
678 auto usage
= fua
->EditUsage(webgl::EffectiveFormat::SRGB8_ALPHA8
);
679 usage
->SetRenderable();
680 fua
->AllowRBFormat(LOCAL_GL_SRGB8_ALPHA8
, usage
);
683 bool WebGLExtensionSRGB::IsSupported(const WebGLContext
* const webgl
) {
684 if (webgl
->IsWebGL2()) return false;
686 return webgl
->gl
->IsSupported(gl::GLFeature::sRGB
);
691 WebGLExtensionTextureFloat::WebGLExtensionTextureFloat(WebGLContext
* webgl
)
692 : WebGLExtensionBase(webgl
) {
693 MOZ_ASSERT(IsSupported(webgl
));
695 auto& fua
= webgl
->mFormatUsage
;
696 gl::GLContext
* gl
= webgl
->GL();
698 webgl::PackingInfo pi
;
699 webgl::DriverUnpackInfo dui
;
700 const GLint
* swizzle
= nullptr;
702 const auto fnAdd
= [&](webgl::EffectiveFormat effFormat
) {
703 MOZ_ASSERT_IF(swizzle
, gl
->IsSupported(gl::GLFeature::texture_swizzle
));
705 auto usage
= fua
->EditUsage(effFormat
);
706 usage
->textureSwizzleRGBA
= swizzle
;
707 fua
->AddTexUnpack(usage
, pi
, dui
);
709 fua
->AllowUnsizedTexFormat(pi
, usage
);
712 bool useSizedFormats
= true;
713 const bool hasSizedLegacyFormats
= gl
->IsCompatibilityProfile();
714 if (gl
->IsGLES() && gl
->Version() < 300) {
715 useSizedFormats
= false;
720 pi
= {LOCAL_GL_RGBA
, LOCAL_GL_FLOAT
};
721 dui
= {pi
.format
, pi
.format
, pi
.type
};
723 if (useSizedFormats
|| gl
->IsExtensionSupported(
724 gl::GLContext::CHROMIUM_color_buffer_float_rgba
)) {
725 // ANGLE only exposes renderable RGBA32F via
726 // CHROMIUM_color_buffer_float_rgba, which uses sized formats.
727 dui
.internalFormat
= LOCAL_GL_RGBA32F
;
729 fnAdd(webgl::EffectiveFormat::RGBA32F
);
733 pi
= {LOCAL_GL_RGB
, LOCAL_GL_FLOAT
};
734 dui
= {pi
.format
, pi
.format
, pi
.type
};
736 if (useSizedFormats
) {
737 dui
.internalFormat
= LOCAL_GL_RGB32F
;
739 fnAdd(webgl::EffectiveFormat::RGB32F
);
743 pi
= {LOCAL_GL_LUMINANCE
, LOCAL_GL_FLOAT
};
744 dui
= {pi
.format
, pi
.format
, pi
.type
};
746 if (useSizedFormats
) {
747 if (hasSizedLegacyFormats
) {
748 dui
.internalFormat
= LOCAL_GL_LUMINANCE32F_ARB
;
750 dui
.internalFormat
= LOCAL_GL_R32F
;
751 dui
.unpackFormat
= LOCAL_GL_RED
;
752 swizzle
= webgl::FormatUsageInfo::kLuminanceSwizzleRGBA
;
755 fnAdd(webgl::EffectiveFormat::Luminance32F
);
759 pi
= {LOCAL_GL_ALPHA
, LOCAL_GL_FLOAT
};
760 dui
= {pi
.format
, pi
.format
, pi
.type
};
762 if (useSizedFormats
) {
763 if (hasSizedLegacyFormats
) {
764 dui
.internalFormat
= LOCAL_GL_ALPHA32F_ARB
;
766 dui
.internalFormat
= LOCAL_GL_R32F
;
767 dui
.unpackFormat
= LOCAL_GL_RED
;
768 swizzle
= webgl::FormatUsageInfo::kAlphaSwizzleRGBA
;
771 fnAdd(webgl::EffectiveFormat::Alpha32F
);
775 pi
= {LOCAL_GL_LUMINANCE_ALPHA
, LOCAL_GL_FLOAT
};
776 dui
= {pi
.format
, pi
.format
, pi
.type
};
778 if (useSizedFormats
) {
779 if (hasSizedLegacyFormats
) {
780 dui
.internalFormat
= LOCAL_GL_LUMINANCE_ALPHA32F_ARB
;
782 dui
.internalFormat
= LOCAL_GL_RG32F
;
783 dui
.unpackFormat
= LOCAL_GL_RG
;
784 swizzle
= webgl::FormatUsageInfo::kLumAlphaSwizzleRGBA
;
787 fnAdd(webgl::EffectiveFormat::Luminance32FAlpha32F
);
790 bool WebGLExtensionTextureFloat::IsSupported(const WebGLContext
* webgl
) {
791 if (webgl
->IsWebGL2()) return false;
793 gl::GLContext
* gl
= webgl
->GL();
794 if (!gl
->IsSupported(gl::GLFeature::texture_float
)) return false;
796 const bool needsSwizzle
= gl
->IsCoreProfile();
797 const bool hasSwizzle
= gl
->IsSupported(gl::GLFeature::texture_swizzle
);
798 if (needsSwizzle
&& !hasSwizzle
) return false;
805 WebGLExtensionTextureFloatLinear::WebGLExtensionTextureFloatLinear(
807 : WebGLExtensionBase(webgl
) {
808 auto& fua
= webgl
->mFormatUsage
;
810 fua
->EditUsage(webgl::EffectiveFormat::RGBA32F
)->isFilterable
= true;
811 fua
->EditUsage(webgl::EffectiveFormat::RGB32F
)->isFilterable
= true;
813 if (webgl
->IsWebGL2()) {
814 fua
->EditUsage(webgl::EffectiveFormat::R32F
)->isFilterable
= true;
815 fua
->EditUsage(webgl::EffectiveFormat::RG32F
)->isFilterable
= true;
817 fua
->EditUsage(webgl::EffectiveFormat::Luminance32FAlpha32F
)->isFilterable
=
819 fua
->EditUsage(webgl::EffectiveFormat::Luminance32F
)->isFilterable
= true;
820 fua
->EditUsage(webgl::EffectiveFormat::Alpha32F
)->isFilterable
= true;
826 WebGLExtensionTextureHalfFloat::WebGLExtensionTextureHalfFloat(
828 : WebGLExtensionBase(webgl
) {
829 auto& fua
= webgl
->mFormatUsage
;
830 gl::GLContext
* gl
= webgl
->GL();
832 webgl::PackingInfo pi
;
833 webgl::DriverUnpackInfo dui
;
834 const GLint
* swizzle
= nullptr;
836 const auto fnAdd
= [&](webgl::EffectiveFormat effFormat
) {
837 MOZ_ASSERT_IF(swizzle
, gl
->IsSupported(gl::GLFeature::texture_swizzle
));
839 auto usage
= fua
->EditUsage(effFormat
);
840 usage
->textureSwizzleRGBA
= swizzle
;
841 fua
->AddTexUnpack(usage
, pi
, dui
);
843 fua
->AllowUnsizedTexFormat(pi
, usage
);
846 bool useSizedFormats
= true;
847 const bool hasSizedLegacyFormats
= gl
->IsCompatibilityProfile();
848 if (gl
->IsGLES() && gl
->Version() < 300) {
849 useSizedFormats
= false;
852 GLenum driverUnpackType
= LOCAL_GL_HALF_FLOAT
;
853 if (!gl
->IsSupported(gl::GLFeature::texture_half_float
)) {
854 MOZ_ASSERT(gl
->IsExtensionSupported(gl::GLContext::OES_texture_half_float
));
855 driverUnpackType
= LOCAL_GL_HALF_FLOAT_OES
;
860 pi
= {LOCAL_GL_RGBA
, LOCAL_GL_HALF_FLOAT_OES
};
861 dui
= {pi
.format
, pi
.format
, driverUnpackType
};
863 if (useSizedFormats
) {
864 dui
.internalFormat
= LOCAL_GL_RGBA16F
;
866 fnAdd(webgl::EffectiveFormat::RGBA16F
);
870 pi
= {LOCAL_GL_RGB
, LOCAL_GL_HALF_FLOAT_OES
};
871 dui
= {pi
.format
, pi
.format
, driverUnpackType
};
873 if (useSizedFormats
) {
874 dui
.internalFormat
= LOCAL_GL_RGB16F
;
876 fnAdd(webgl::EffectiveFormat::RGB16F
);
880 pi
= {LOCAL_GL_LUMINANCE
, LOCAL_GL_HALF_FLOAT_OES
};
881 dui
= {pi
.format
, pi
.format
, driverUnpackType
};
883 if (useSizedFormats
) {
884 if (hasSizedLegacyFormats
) {
885 dui
.internalFormat
= LOCAL_GL_LUMINANCE16F_ARB
;
887 dui
.internalFormat
= LOCAL_GL_R16F
;
888 dui
.unpackFormat
= LOCAL_GL_RED
;
889 swizzle
= webgl::FormatUsageInfo::kLuminanceSwizzleRGBA
;
892 fnAdd(webgl::EffectiveFormat::Luminance16F
);
896 pi
= {LOCAL_GL_ALPHA
, LOCAL_GL_HALF_FLOAT_OES
};
897 dui
= {pi
.format
, pi
.format
, driverUnpackType
};
899 if (useSizedFormats
) {
900 if (hasSizedLegacyFormats
) {
901 dui
.internalFormat
= LOCAL_GL_ALPHA16F_ARB
;
903 dui
.internalFormat
= LOCAL_GL_R16F
;
904 dui
.unpackFormat
= LOCAL_GL_RED
;
905 swizzle
= webgl::FormatUsageInfo::kAlphaSwizzleRGBA
;
908 fnAdd(webgl::EffectiveFormat::Alpha16F
);
912 pi
= {LOCAL_GL_LUMINANCE_ALPHA
, LOCAL_GL_HALF_FLOAT_OES
};
913 dui
= {pi
.format
, pi
.format
, driverUnpackType
};
915 if (useSizedFormats
) {
916 if (hasSizedLegacyFormats
) {
917 dui
.internalFormat
= LOCAL_GL_LUMINANCE_ALPHA16F_ARB
;
919 dui
.internalFormat
= LOCAL_GL_RG16F
;
920 dui
.unpackFormat
= LOCAL_GL_RG
;
921 swizzle
= webgl::FormatUsageInfo::kLumAlphaSwizzleRGBA
;
924 fnAdd(webgl::EffectiveFormat::Luminance16FAlpha16F
);
927 bool WebGLExtensionTextureHalfFloat::IsSupported(const WebGLContext
* webgl
) {
928 if (webgl
->IsWebGL2()) return false;
930 gl::GLContext
* gl
= webgl
->GL();
931 if (!gl
->IsSupported(gl::GLFeature::texture_half_float
) &&
932 !gl
->IsExtensionSupported(gl::GLContext::OES_texture_half_float
)) {
936 const bool needsSwizzle
= gl
->IsCoreProfile();
937 const bool hasSwizzle
= gl
->IsSupported(gl::GLFeature::texture_swizzle
);
938 if (needsSwizzle
&& !hasSwizzle
) return false;
945 WebGLExtensionTextureHalfFloatLinear::WebGLExtensionTextureHalfFloatLinear(
947 : WebGLExtensionBase(webgl
) {
948 MOZ_ASSERT(!webgl
->IsWebGL2());
949 auto& fua
= webgl
->mFormatUsage
;
951 fua
->EditUsage(webgl::EffectiveFormat::RGBA16F
)->isFilterable
= true;
952 fua
->EditUsage(webgl::EffectiveFormat::RGB16F
)->isFilterable
= true;
953 fua
->EditUsage(webgl::EffectiveFormat::Luminance16FAlpha16F
)->isFilterable
=
955 fua
->EditUsage(webgl::EffectiveFormat::Luminance16F
)->isFilterable
= true;
956 fua
->EditUsage(webgl::EffectiveFormat::Alpha16F
)->isFilterable
= true;
961 bool WebGLExtensionTextureNorm16::IsSupported(const WebGLContext
* const webgl
) {
962 if (!StaticPrefs::webgl_enable_draft_extensions()) return false;
963 if (!webgl
->IsWebGL2()) return false;
965 const auto& gl
= webgl
->gl
;
967 // ANGLE's support is broken in our checkout.
968 if (gl
->IsANGLE()) return false;
970 return gl
->IsSupported(gl::GLFeature::texture_norm16
);
973 WebGLExtensionTextureNorm16::WebGLExtensionTextureNorm16(WebGLContext
* webgl
)
974 : WebGLExtensionBase(webgl
) {
975 if (!IsSupported(webgl
)) {
977 "Constructing WebGLExtensionTextureNorm16 but IsSupported() is "
979 // This was previously an assert, but it seems like we get races against
980 // StaticPrefs changes/initialization?
983 auto& fua
= *webgl
->mFormatUsage
;
985 const auto fnAdd
= [&](webgl::EffectiveFormat effFormat
,
986 const bool renderable
, const webgl::PackingInfo
& pi
) {
987 auto& usage
= *fua
.EditUsage(effFormat
);
988 const auto& format
= *usage
.format
;
991 webgl::DriverUnpackInfo
{format
.sizedFormat
, pi
.format
, pi
.type
};
992 fua
.AddTexUnpack(&usage
, pi
, dui
);
994 fua
.AllowSizedTexFormat(format
.sizedFormat
, &usage
);
995 fua
.AllowUnsizedTexFormat(pi
, &usage
);
998 usage
.SetRenderable();
999 fua
.AllowRBFormat(format
.sizedFormat
, &usage
);
1003 fnAdd(webgl::EffectiveFormat::R16
, true,
1004 {LOCAL_GL_RED
, LOCAL_GL_UNSIGNED_SHORT
});
1005 fnAdd(webgl::EffectiveFormat::RG16
, true,
1006 {LOCAL_GL_RG
, LOCAL_GL_UNSIGNED_SHORT
});
1007 fnAdd(webgl::EffectiveFormat::RGB16
, false,
1008 {LOCAL_GL_RGB
, LOCAL_GL_UNSIGNED_SHORT
});
1009 fnAdd(webgl::EffectiveFormat::RGBA16
, true,
1010 {LOCAL_GL_RGBA
, LOCAL_GL_UNSIGNED_SHORT
});
1012 fnAdd(webgl::EffectiveFormat::R16_SNORM
, false,
1013 {LOCAL_GL_RED
, LOCAL_GL_SHORT
});
1014 fnAdd(webgl::EffectiveFormat::RG16_SNORM
, false,
1015 {LOCAL_GL_RG
, LOCAL_GL_SHORT
});
1016 fnAdd(webgl::EffectiveFormat::RGB16_SNORM
, false,
1017 {LOCAL_GL_RGB
, LOCAL_GL_SHORT
});
1018 fnAdd(webgl::EffectiveFormat::RGBA16_SNORM
, false,
1019 {LOCAL_GL_RGBA
, LOCAL_GL_SHORT
});
1022 } // namespace mozilla