WebGLExtensions.cpp (35362B)
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/. */ 5 6 #include "WebGLExtensions.h" 7 8 #include "GLContext.h" 9 #include "WebGLContext.h" 10 #include "WebGLFormats.h" 11 #include "mozilla/Casting.h" 12 #include "mozilla/ScopeExit.h" 13 #include "mozilla/StaticPrefs_webgl.h" 14 #include "mozilla/dom/WebGLRenderingContextBinding.h" 15 16 namespace mozilla { 17 18 static bool TestShaderCompile(gl::GLContext* const gl, const GLenum type, 19 const std::string& source) { 20 const auto shader = gl->fCreateShader(type); 21 const auto cleanup = MakeScopeExit([&]() { gl->fDeleteShader(shader); }); 22 23 const std::array<const char*, 1> parts = {source.c_str()}; 24 gl->fShaderSource(shader, parts.size(), parts.data(), nullptr); 25 gl->fCompileShader(shader); 26 27 GLint status = 0; 28 gl->fGetShaderiv(shader, LOCAL_GL_COMPILE_STATUS, &status); 29 30 if (status == LOCAL_GL_TRUE) return true; 31 32 std::vector<char> chars; 33 chars.resize(1000); 34 gl->fGetShaderInfoLog(shader, LazyAssertedCast(chars.size() - 1), nullptr, 35 chars.data()); 36 printf_stderr("GetShaderInfoLog() ->\n%s\n", chars.data()); 37 38 #if defined(MOZ_WIDGET_ANDROID) && (defined(_M_IX86) || defined(__i386__) || \ 39 defined(__x86_64__) || defined(__amd64__)) 40 // Flakey gl on x86 android emulators in CI sometimes crash on the first 41 // GetShaderSource call. 42 printf_stderr("source ->\n%s\n", source.c_str()); 43 #else 44 gl->fGetShaderSource(shader, LazyAssertedCast(chars.size() - 1), nullptr, 45 chars.data()); 46 printf_stderr("GetShaderSource() ->\n%s\n", chars.data()); 47 #endif 48 49 return false; 50 } 51 52 // - 53 54 WebGLExtensionBlendMinMax::WebGLExtensionBlendMinMax(WebGLContext* webgl) 55 : WebGLExtensionBase(webgl) { 56 MOZ_ASSERT(IsSupported(webgl), "Don't construct extension if unsupported."); 57 } 58 59 bool WebGLExtensionBlendMinMax::IsSupported(const WebGLContext* webgl) { 60 if (webgl->IsWebGL2()) return false; 61 62 return webgl->GL()->IsSupported(gl::GLFeature::blend_minmax); 63 } 64 65 // - 66 67 WebGLExtensionColorBufferFloat::WebGLExtensionColorBufferFloat( 68 WebGLContext* webgl) 69 : WebGLExtensionBase(webgl) { 70 MOZ_ASSERT(IsSupported(webgl), "Don't construct extension if unsupported."); 71 SetRenderable(webgl::FormatRenderableState::Implicit( 72 WebGLExtensionID::WEBGL_color_buffer_float)); 73 } 74 75 void WebGLExtensionColorBufferFloat::SetRenderable( 76 const webgl::FormatRenderableState& state) { 77 auto& fua = mContext->mFormatUsage; 78 79 auto fnUpdateUsage = [&](GLenum sizedFormat, 80 webgl::EffectiveFormat effFormat) { 81 auto usage = fua->EditUsage(effFormat); 82 usage->SetRenderable(state); 83 fua->AllowRBFormat(sizedFormat, usage); 84 }; 85 86 #define FOO(x) fnUpdateUsage(LOCAL_GL_##x, webgl::EffectiveFormat::x) 87 88 // The extension doesn't actually add RGB32F; only RGBA32F. 89 FOO(RGBA32F); 90 91 #undef FOO 92 } 93 94 void WebGLExtensionColorBufferFloat::OnSetExplicit() { 95 SetRenderable(webgl::FormatRenderableState::Explicit()); 96 } 97 98 bool WebGLExtensionColorBufferFloat::IsSupported(const WebGLContext* webgl) { 99 if (webgl->IsWebGL2()) return false; 100 101 const auto& gl = webgl->gl; 102 return gl->IsSupported(gl::GLFeature::renderbuffer_color_float) && 103 gl->IsSupported(gl::GLFeature::frag_color_float); 104 } 105 106 // - 107 108 WebGLExtensionColorBufferHalfFloat::WebGLExtensionColorBufferHalfFloat( 109 WebGLContext* webgl) 110 : WebGLExtensionBase(webgl) { 111 MOZ_ASSERT(IsSupported(webgl), "Don't construct extension if unsupported."); 112 SetRenderable(webgl::FormatRenderableState::Implicit( 113 WebGLExtensionID::EXT_color_buffer_half_float)); 114 } 115 116 void WebGLExtensionColorBufferHalfFloat::SetRenderable( 117 const webgl::FormatRenderableState& state) { 118 auto& fua = mContext->mFormatUsage; 119 120 auto fnUpdateUsage = [&](GLenum sizedFormat, webgl::EffectiveFormat effFormat, 121 const bool renderable) { 122 auto usage = fua->EditUsage(effFormat); 123 if (renderable) { 124 usage->SetRenderable(state); 125 } 126 fua->AllowRBFormat(sizedFormat, usage, renderable); 127 }; 128 129 #define FOO(x, y) fnUpdateUsage(LOCAL_GL_##x, webgl::EffectiveFormat::x, y) 130 131 FOO(RGBA16F, true); 132 FOO(RGB16F, false); // It's not required, thus not portable. (Also there's a 133 // wicked driver bug on Mac+Intel) 134 135 #undef FOO 136 } 137 138 void WebGLExtensionColorBufferHalfFloat::OnSetExplicit() { 139 SetRenderable(webgl::FormatRenderableState::Explicit()); 140 } 141 142 bool WebGLExtensionColorBufferHalfFloat::IsSupported( 143 const WebGLContext* webgl) { 144 if (webgl->IsWebGL2()) return false; 145 146 const auto& gl = webgl->gl; 147 return gl->IsSupported(gl::GLFeature::renderbuffer_color_half_float) && 148 gl->IsSupported(gl::GLFeature::frag_color_float); 149 } 150 151 // - 152 153 WebGLExtensionCompressedTextureASTC::WebGLExtensionCompressedTextureASTC( 154 WebGLContext* webgl) 155 : WebGLExtensionBase(webgl) { 156 MOZ_ASSERT(IsSupported(webgl), "Don't construct extension if unsupported."); 157 158 RefPtr<WebGLContext> webgl_ = webgl; // Bug 1201275 159 const auto fnAdd = [&webgl_](GLenum sizedFormat, 160 webgl::EffectiveFormat effFormat) { 161 auto& fua = webgl_->mFormatUsage; 162 163 auto usage = fua->EditUsage(effFormat); 164 usage->isFilterable = true; 165 fua->AllowSizedTexFormat(sizedFormat, usage); 166 }; 167 168 #define FOO(x) LOCAL_GL_##x, webgl::EffectiveFormat::x 169 170 fnAdd(FOO(COMPRESSED_RGBA_ASTC_4x4_KHR)); 171 fnAdd(FOO(COMPRESSED_RGBA_ASTC_5x4_KHR)); 172 fnAdd(FOO(COMPRESSED_RGBA_ASTC_5x5_KHR)); 173 fnAdd(FOO(COMPRESSED_RGBA_ASTC_6x5_KHR)); 174 fnAdd(FOO(COMPRESSED_RGBA_ASTC_6x6_KHR)); 175 fnAdd(FOO(COMPRESSED_RGBA_ASTC_8x5_KHR)); 176 fnAdd(FOO(COMPRESSED_RGBA_ASTC_8x6_KHR)); 177 fnAdd(FOO(COMPRESSED_RGBA_ASTC_8x8_KHR)); 178 fnAdd(FOO(COMPRESSED_RGBA_ASTC_10x5_KHR)); 179 fnAdd(FOO(COMPRESSED_RGBA_ASTC_10x6_KHR)); 180 fnAdd(FOO(COMPRESSED_RGBA_ASTC_10x8_KHR)); 181 fnAdd(FOO(COMPRESSED_RGBA_ASTC_10x10_KHR)); 182 fnAdd(FOO(COMPRESSED_RGBA_ASTC_12x10_KHR)); 183 fnAdd(FOO(COMPRESSED_RGBA_ASTC_12x12_KHR)); 184 185 fnAdd(FOO(COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR)); 186 fnAdd(FOO(COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR)); 187 fnAdd(FOO(COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR)); 188 fnAdd(FOO(COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR)); 189 fnAdd(FOO(COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR)); 190 fnAdd(FOO(COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR)); 191 fnAdd(FOO(COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR)); 192 fnAdd(FOO(COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR)); 193 fnAdd(FOO(COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR)); 194 fnAdd(FOO(COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR)); 195 fnAdd(FOO(COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR)); 196 fnAdd(FOO(COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR)); 197 fnAdd(FOO(COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR)); 198 fnAdd(FOO(COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR)); 199 200 #undef FOO 201 } 202 203 bool WebGLExtensionCompressedTextureASTC::IsSupported( 204 const WebGLContext* webgl) { 205 gl::GLContext* gl = webgl->GL(); 206 return gl->IsExtensionSupported( 207 gl::GLContext::KHR_texture_compression_astc_ldr); 208 } 209 210 // - 211 212 WebGLExtensionCompressedTextureBPTC::WebGLExtensionCompressedTextureBPTC( 213 WebGLContext* const webgl) 214 : WebGLExtensionBase(webgl) { 215 MOZ_ASSERT(IsSupported(webgl), "Don't construct extension if unsupported."); 216 217 auto& fua = webgl->mFormatUsage; 218 219 const auto fnAdd = [&](const GLenum sizedFormat, 220 const webgl::EffectiveFormat effFormat) { 221 auto usage = fua->EditUsage(effFormat); 222 usage->isFilterable = true; 223 fua->AllowSizedTexFormat(sizedFormat, usage); 224 }; 225 226 #define _(X) LOCAL_GL_##X, webgl::EffectiveFormat::X 227 228 fnAdd(_(COMPRESSED_RGBA_BPTC_UNORM)); 229 fnAdd(_(COMPRESSED_SRGB_ALPHA_BPTC_UNORM)); 230 fnAdd(_(COMPRESSED_RGB_BPTC_SIGNED_FLOAT)); 231 fnAdd(_(COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT)); 232 233 #undef _ 234 } 235 236 bool WebGLExtensionCompressedTextureBPTC::IsSupported( 237 const WebGLContext* const webgl) { 238 return webgl->gl->IsSupported(gl::GLFeature::texture_compression_bptc); 239 } 240 241 // - 242 243 WebGLExtensionCompressedTextureES3::WebGLExtensionCompressedTextureES3( 244 WebGLContext* webgl) 245 : WebGLExtensionBase(webgl) { 246 // GLES 3.0.4, p147, table 3.19 247 // GLES 3.0.4, p286+, $C.1 "ETC Compressed Texture Image Formats" 248 // Note that all compressed texture formats are filterable: 249 // GLES 3.0.4 p161: 250 // "[A] texture is complete unless any of the following conditions hold true: 251 // [...] 252 // * The effective internal format specified for the texture arrays is a 253 // sized internal color format that is not texture-filterable (see table 254 // 3.13) and [the mag filter requires filtering]." 255 // Compressed formats are not sized internal color formats, and indeed they 256 // are not listed in table 3.13. 257 258 RefPtr<WebGLContext> webgl_ = webgl; // Bug 1201275 259 const auto fnAdd = [&webgl_](GLenum sizedFormat, 260 webgl::EffectiveFormat effFormat) { 261 auto& fua = webgl_->mFormatUsage; 262 263 auto usage = fua->EditUsage(effFormat); 264 usage->isFilterable = true; 265 fua->AllowSizedTexFormat(sizedFormat, usage); 266 }; 267 268 #define FOO(x) LOCAL_GL_##x, webgl::EffectiveFormat::x 269 270 fnAdd(FOO(COMPRESSED_R11_EAC)); 271 fnAdd(FOO(COMPRESSED_SIGNED_R11_EAC)); 272 fnAdd(FOO(COMPRESSED_RG11_EAC)); 273 fnAdd(FOO(COMPRESSED_SIGNED_RG11_EAC)); 274 fnAdd(FOO(COMPRESSED_RGB8_ETC2)); 275 fnAdd(FOO(COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2)); 276 fnAdd(FOO(COMPRESSED_RGBA8_ETC2_EAC)); 277 278 // sRGB support is manadatory in GL 4.3 and GL ES 3.0, which are the only 279 // versions to support ETC2. 280 fnAdd(FOO(COMPRESSED_SRGB8_ALPHA8_ETC2_EAC)); 281 fnAdd(FOO(COMPRESSED_SRGB8_ETC2)); 282 fnAdd(FOO(COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2)); 283 284 #undef FOO 285 } 286 287 // - 288 289 WebGLExtensionCompressedTextureETC1::WebGLExtensionCompressedTextureETC1( 290 WebGLContext* webgl) 291 : WebGLExtensionBase(webgl) { 292 RefPtr<WebGLContext> webgl_ = webgl; // Bug 1201275 293 const auto fnAdd = [&webgl_](GLenum sizedFormat, 294 webgl::EffectiveFormat effFormat) { 295 auto& fua = webgl_->mFormatUsage; 296 297 auto usage = fua->EditUsage(effFormat); 298 usage->isFilterable = true; 299 fua->AllowSizedTexFormat(sizedFormat, usage); 300 }; 301 302 #define FOO(x) LOCAL_GL_##x, webgl::EffectiveFormat::x 303 304 fnAdd(FOO(ETC1_RGB8_OES)); 305 306 #undef FOO 307 } 308 309 // - 310 311 WebGLExtensionCompressedTexturePVRTC::WebGLExtensionCompressedTexturePVRTC( 312 WebGLContext* webgl) 313 : WebGLExtensionBase(webgl) { 314 RefPtr<WebGLContext> webgl_ = webgl; // Bug 1201275 315 const auto fnAdd = [&webgl_](GLenum sizedFormat, 316 webgl::EffectiveFormat effFormat) { 317 auto& fua = webgl_->mFormatUsage; 318 319 auto usage = fua->EditUsage(effFormat); 320 usage->isFilterable = true; 321 fua->AllowSizedTexFormat(sizedFormat, usage); 322 }; 323 324 #define FOO(x) LOCAL_GL_##x, webgl::EffectiveFormat::x 325 326 fnAdd(FOO(COMPRESSED_RGB_PVRTC_4BPPV1)); 327 fnAdd(FOO(COMPRESSED_RGB_PVRTC_2BPPV1)); 328 fnAdd(FOO(COMPRESSED_RGBA_PVRTC_4BPPV1)); 329 fnAdd(FOO(COMPRESSED_RGBA_PVRTC_2BPPV1)); 330 331 #undef FOO 332 } 333 334 // - 335 336 WebGLExtensionCompressedTextureRGTC::WebGLExtensionCompressedTextureRGTC( 337 WebGLContext* const webgl) 338 : WebGLExtensionBase(webgl) { 339 MOZ_ASSERT(IsSupported(webgl), "Don't construct extension if unsupported."); 340 341 auto& fua = webgl->mFormatUsage; 342 343 const auto fnAdd = [&](const GLenum sizedFormat, 344 const webgl::EffectiveFormat effFormat) { 345 auto usage = fua->EditUsage(effFormat); 346 usage->isFilterable = true; 347 fua->AllowSizedTexFormat(sizedFormat, usage); 348 }; 349 350 #define _(X) LOCAL_GL_##X, webgl::EffectiveFormat::X 351 352 fnAdd(_(COMPRESSED_RED_RGTC1)); 353 fnAdd(_(COMPRESSED_SIGNED_RED_RGTC1)); 354 fnAdd(_(COMPRESSED_RG_RGTC2)); 355 fnAdd(_(COMPRESSED_SIGNED_RG_RGTC2)); 356 357 #undef _ 358 } 359 360 bool WebGLExtensionCompressedTextureRGTC::IsSupported( 361 const WebGLContext* const webgl) { 362 return webgl->gl->IsSupported(gl::GLFeature::texture_compression_rgtc); 363 } 364 365 // - 366 367 WebGLExtensionCompressedTextureS3TC::WebGLExtensionCompressedTextureS3TC( 368 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; 374 375 auto usage = fua->EditUsage(effFormat); 376 usage->isFilterable = true; 377 fua->AllowSizedTexFormat(sizedFormat, usage); 378 }; 379 380 #define FOO(x) LOCAL_GL_##x, webgl::EffectiveFormat::x 381 382 fnAdd(FOO(COMPRESSED_RGB_S3TC_DXT1_EXT)); 383 fnAdd(FOO(COMPRESSED_RGBA_S3TC_DXT1_EXT)); 384 fnAdd(FOO(COMPRESSED_RGBA_S3TC_DXT3_EXT)); 385 fnAdd(FOO(COMPRESSED_RGBA_S3TC_DXT5_EXT)); 386 387 #undef FOO 388 } 389 390 bool WebGLExtensionCompressedTextureS3TC::IsSupported( 391 const WebGLContext* webgl) { 392 gl::GLContext* gl = webgl->GL(); 393 if (gl->IsExtensionSupported(gl::GLContext::EXT_texture_compression_s3tc)) 394 return true; 395 396 return gl->IsExtensionSupported( 397 gl::GLContext::EXT_texture_compression_dxt1) && 398 gl->IsExtensionSupported( 399 gl::GLContext::ANGLE_texture_compression_dxt3) && 400 gl->IsExtensionSupported( 401 gl::GLContext::ANGLE_texture_compression_dxt5); 402 } 403 404 // - 405 406 WebGLExtensionCompressedTextureS3TC_SRGB:: 407 WebGLExtensionCompressedTextureS3TC_SRGB(WebGLContext* webgl) 408 : WebGLExtensionBase(webgl) { 409 RefPtr<WebGLContext> webgl_ = webgl; // Bug 1201275 410 const auto fnAdd = [&webgl_](GLenum sizedFormat, 411 webgl::EffectiveFormat effFormat) { 412 auto& fua = webgl_->mFormatUsage; 413 414 auto usage = fua->EditUsage(effFormat); 415 usage->isFilterable = true; 416 fua->AllowSizedTexFormat(sizedFormat, usage); 417 }; 418 419 #define FOO(x) LOCAL_GL_##x, webgl::EffectiveFormat::x 420 421 fnAdd(FOO(COMPRESSED_SRGB_S3TC_DXT1_EXT)); 422 fnAdd(FOO(COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT)); 423 fnAdd(FOO(COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT)); 424 fnAdd(FOO(COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT)); 425 426 #undef FOO 427 } 428 429 bool WebGLExtensionCompressedTextureS3TC_SRGB::IsSupported( 430 const WebGLContext* webgl) { 431 gl::GLContext* gl = webgl->GL(); 432 if (gl->IsGLES()) 433 return gl->IsExtensionSupported( 434 gl::GLContext::EXT_texture_compression_s3tc_srgb); 435 436 // Desktop GL is more complicated: It's EXT_texture_sRGB, when 437 // EXT_texture_compression_s3tc is supported, that enables srgb+s3tc. 438 return gl->IsExtensionSupported(gl::GLContext::EXT_texture_sRGB) && 439 gl->IsExtensionSupported(gl::GLContext::EXT_texture_compression_s3tc); 440 } 441 442 // - 443 444 WebGLExtensionDepthClamp::WebGLExtensionDepthClamp(WebGLContext* const webgl) 445 : WebGLExtensionBase(webgl) { 446 webgl->mIsEnabledMapKeys.insert(LOCAL_GL_DEPTH_CLAMP); 447 } 448 449 // - 450 451 WebGLExtensionDepthTexture::WebGLExtensionDepthTexture( 452 WebGLContext* const webgl) 453 : WebGLExtensionBase(webgl) { 454 auto& fua = webgl->mFormatUsage; 455 456 const auto fnAdd = [&fua](webgl::EffectiveFormat effFormat, 457 GLenum unpackFormat, GLenum unpackType) { 458 auto usage = fua->EditUsage(effFormat); 459 MOZ_ASSERT(usage->isFilterable); 460 MOZ_ASSERT(usage->IsRenderable()); 461 462 const webgl::PackingInfo pi = {unpackFormat, unpackType}; 463 const webgl::DriverUnpackInfo dui = {unpackFormat, unpackFormat, 464 unpackType}; 465 fua->AddTexUnpack(usage, pi, dui); 466 fua->AllowUnsizedTexFormat(pi, usage); 467 }; 468 469 fnAdd(webgl::EffectiveFormat::DEPTH_COMPONENT16, LOCAL_GL_DEPTH_COMPONENT, 470 LOCAL_GL_UNSIGNED_SHORT); 471 fnAdd(webgl::EffectiveFormat::DEPTH_COMPONENT24, LOCAL_GL_DEPTH_COMPONENT, 472 LOCAL_GL_UNSIGNED_INT); 473 fnAdd(webgl::EffectiveFormat::DEPTH24_STENCIL8, LOCAL_GL_DEPTH_STENCIL, 474 LOCAL_GL_UNSIGNED_INT_24_8); 475 } 476 477 bool WebGLExtensionDepthTexture::IsSupported(const WebGLContext* const webgl) { 478 if (webgl->IsWebGL2()) return false; 479 480 // WEBGL_depth_texture supports DEPTH_STENCIL textures 481 const auto& gl = webgl->gl; 482 if (!gl->IsSupported(gl::GLFeature::packed_depth_stencil)) return false; 483 484 return gl->IsSupported(gl::GLFeature::depth_texture) || 485 gl->IsExtensionSupported(gl::GLContext::ANGLE_depth_texture); 486 } 487 488 // - 489 490 WebGLExtensionDisjointTimerQuery::WebGLExtensionDisjointTimerQuery( 491 WebGLContext* webgl) 492 : WebGLExtensionBase(webgl) { 493 MOZ_ASSERT(IsSupported(webgl), "Don't construct extension if unsupported."); 494 } 495 496 bool WebGLExtensionDisjointTimerQuery::IsSupported( 497 const WebGLContext* const webgl) { 498 if (!StaticPrefs::webgl_enable_privileged_extensions()) return false; 499 500 gl::GLContext* gl = webgl->GL(); 501 return gl->IsSupported(gl::GLFeature::query_objects) && 502 gl->IsSupported(gl::GLFeature::get_query_object_i64v) && 503 gl->IsSupported( 504 gl::GLFeature::query_counter); // provides GL_TIMESTAMP 505 } 506 507 // - 508 509 WebGLExtensionDrawBuffers::WebGLExtensionDrawBuffers(WebGLContext* webgl) 510 : WebGLExtensionBase(webgl) { 511 MOZ_ASSERT(IsSupported(webgl), "Don't construct extension if unsupported."); 512 } 513 514 bool WebGLExtensionDrawBuffers::IsSupported(const WebGLContext* webgl) { 515 if (!webgl->mIsSupportedCache_DrawBuffers) { 516 webgl->mIsSupportedCache_DrawBuffers = [&]() { 517 gl::GLContext* const gl = webgl->GL(); 518 519 if (webgl->IsWebGL2()) return false; 520 if (!gl->IsSupported(gl::GLFeature::draw_buffers)) return false; 521 522 if (gl->IsGLES() && gl->Version() >= 300) { 523 // ANGLE's shader translator can't translate ESSL1 exts to ESSL3. (bug 524 // 1524804) 525 // The spec (and some implementations of ES3) don't require support for 526 // any extensions in ESSL 100, but an implementation can choose to 527 // support them anyway. So let's check! 528 const bool ok = TestShaderCompile(gl, LOCAL_GL_FRAGMENT_SHADER, R"( 529 #extension GL_EXT_draw_buffers: require 530 void main() {} 531 )"); 532 if (!ok) return false; 533 } 534 535 return true; 536 }(); 537 } 538 539 return *webgl->mIsSupportedCache_DrawBuffers; 540 } 541 542 // - 543 544 WebGLExtensionExplicitPresent::WebGLExtensionExplicitPresent( 545 WebGLContext* const webgl) 546 : WebGLExtensionBase(webgl) { 547 if (!IsSupported(webgl)) { 548 NS_WARNING( 549 "Constructing WebGLExtensionExplicitPresent but IsSupported() is " 550 "false!"); 551 // This was previously an assert, but it seems like we get races against 552 // StaticPrefs changes/initialization? 553 } 554 } 555 556 bool WebGLExtensionExplicitPresent::IsSupported( 557 const WebGLContext* const webgl) { 558 return StaticPrefs::webgl_enable_draft_extensions(); 559 } 560 561 // - 562 563 WebGLExtensionEXTColorBufferFloat::WebGLExtensionEXTColorBufferFloat( 564 WebGLContext* webgl) 565 : WebGLExtensionBase(webgl) { 566 MOZ_ASSERT(IsSupported(webgl), "Don't construct extension if unsupported."); 567 568 auto& fua = webgl->mFormatUsage; 569 570 auto fnUpdateUsage = [&fua](GLenum sizedFormat, 571 webgl::EffectiveFormat effFormat) { 572 auto usage = fua->EditUsage(effFormat); 573 usage->SetRenderable(); 574 fua->AllowRBFormat(sizedFormat, usage); 575 }; 576 577 #define FOO(x) fnUpdateUsage(LOCAL_GL_##x, webgl::EffectiveFormat::x) 578 579 FOO(R16F); 580 FOO(RG16F); 581 FOO(RGBA16F); 582 583 FOO(R32F); 584 FOO(RG32F); 585 FOO(RGBA32F); 586 587 FOO(R11F_G11F_B10F); 588 589 #undef FOO 590 } 591 592 /*static*/ 593 bool WebGLExtensionEXTColorBufferFloat::IsSupported(const WebGLContext* webgl) { 594 if (!webgl->IsWebGL2()) return false; 595 596 const gl::GLContext* gl = webgl->GL(); 597 return gl->IsSupported(gl::GLFeature::EXT_color_buffer_float); 598 } 599 600 // - 601 602 WebGLExtensionFBORenderMipmap::WebGLExtensionFBORenderMipmap( 603 WebGLContext* const webgl) 604 : WebGLExtensionBase(webgl) { 605 MOZ_ASSERT(IsSupported(webgl), "Don't construct extension if unsupported."); 606 } 607 608 bool WebGLExtensionFBORenderMipmap::IsSupported( 609 const WebGLContext* const webgl) { 610 if (webgl->IsWebGL2()) return false; 611 612 const auto& gl = webgl->gl; 613 if (!gl->IsGLES()) return true; 614 if (gl->Version() >= 300) return true; 615 return gl->IsExtensionSupported(gl::GLContext::OES_fbo_render_mipmap); 616 } 617 618 // - 619 620 WebGLExtensionFloatBlend::WebGLExtensionFloatBlend(WebGLContext* const webgl) 621 : WebGLExtensionBase(webgl) { 622 MOZ_ASSERT(IsSupported(webgl), "Don't construct extension if unsupported."); 623 } 624 625 bool WebGLExtensionFloatBlend::IsSupported(const WebGLContext* const webgl) { 626 if (!WebGLExtensionColorBufferFloat::IsSupported(webgl) && 627 !WebGLExtensionEXTColorBufferFloat::IsSupported(webgl)) 628 return false; 629 630 const auto& gl = webgl->gl; 631 if (!gl->IsGLES() && gl->Version() >= 300) return true; 632 if (gl->IsGLES() && gl->Version() >= 320) return true; 633 return gl->IsExtensionSupported(gl::GLContext::EXT_float_blend); 634 } 635 636 // - 637 638 WebGLExtensionFragDepth::WebGLExtensionFragDepth(WebGLContext* webgl) 639 : WebGLExtensionBase(webgl) { 640 MOZ_ASSERT(IsSupported(webgl), "Don't construct extension if unsupported."); 641 } 642 643 bool WebGLExtensionFragDepth::IsSupported(const WebGLContext* const webgl) { 644 if (!webgl->mIsSupportedCache_FragDepth) { 645 webgl->mIsSupportedCache_FragDepth = [&]() { 646 gl::GLContext* const gl = webgl->GL(); 647 648 if (webgl->IsWebGL2()) return false; 649 if (!gl->IsSupported(gl::GLFeature::frag_depth)) return false; 650 651 if (gl->IsGLES() && gl->Version() >= 300) { 652 // ANGLE's shader translator can't translate ESSL1 exts to ESSL3. (bug 653 // 1524804) 654 // The spec (and some implementations of ES3) don't require support for 655 // any extensions in ESSL 100, but an implementation can choose to 656 // support them anyway. So let's check! 657 const bool ok = TestShaderCompile(gl, LOCAL_GL_FRAGMENT_SHADER, R"( 658 #extension GL_EXT_frag_depth: require 659 void main() {} 660 )"); 661 if (!ok) return false; 662 } 663 664 return true; 665 }(); 666 } 667 668 return *webgl->mIsSupportedCache_FragDepth; 669 } 670 671 // - 672 673 WebGLExtensionInstancedArrays::WebGLExtensionInstancedArrays( 674 WebGLContext* webgl) 675 : WebGLExtensionBase(webgl) { 676 MOZ_ASSERT(IsSupported(webgl), "Don't construct extension if unsupported."); 677 } 678 679 bool WebGLExtensionInstancedArrays::IsSupported(const WebGLContext* webgl) { 680 if (webgl->IsWebGL2()) return false; 681 682 gl::GLContext* gl = webgl->GL(); 683 return gl->IsSupported(gl::GLFeature::draw_instanced) && 684 gl->IsSupported(gl::GLFeature::instanced_arrays); 685 } 686 687 // - 688 689 WebGLExtensionMultiview::WebGLExtensionMultiview(WebGLContext* const webgl) 690 : WebGLExtensionBase(webgl) { 691 MOZ_ASSERT(IsSupported(webgl), "Don't construct extension if unsupported."); 692 } 693 694 bool WebGLExtensionMultiview::IsSupported(const WebGLContext* const webgl) { 695 if (!webgl->IsWebGL2()) return false; 696 697 const auto& gl = webgl->gl; 698 return gl->IsSupported(gl::GLFeature::multiview); 699 } 700 701 // - 702 703 WebGLExtensionShaderTextureLod::WebGLExtensionShaderTextureLod( 704 WebGLContext* webgl) 705 : WebGLExtensionBase(webgl) { 706 MOZ_ASSERT(IsSupported(webgl), "Don't construct extension if unsupported."); 707 } 708 709 bool WebGLExtensionShaderTextureLod::IsSupported(const WebGLContext* webgl) { 710 if (!webgl->mIsSupportedCache_ShaderTextureLod) { 711 webgl->mIsSupportedCache_ShaderTextureLod = [&]() { 712 gl::GLContext* const gl = webgl->GL(); 713 714 if (webgl->IsWebGL2()) return false; 715 if (!gl->IsSupported(gl::GLFeature::shader_texture_lod)) return false; 716 717 if (gl->IsGLES() && gl->Version() >= 300) { 718 // ANGLE's shader translator doesn't yet translate 719 // WebGL1+EXT_shader_texture_lod to ES3. (Bug 1491221) 720 // The spec (and some implementations of ES3) don't require support for 721 // any extensions in ESSL 100, but an implementation can choose to 722 // support them anyway. So let's check! 723 const bool ok = TestShaderCompile(gl, LOCAL_GL_FRAGMENT_SHADER, R"( 724 #extension GL_EXT_shader_texture_lod: require 725 void main() {} 726 )"); 727 if (!ok) return false; 728 } 729 730 return true; 731 }(); 732 } 733 return *webgl->mIsSupportedCache_ShaderTextureLod; 734 } 735 736 // - 737 738 WebGLExtensionSRGB::WebGLExtensionSRGB(WebGLContext* webgl) 739 : WebGLExtensionBase(webgl) { 740 MOZ_ASSERT(IsSupported(webgl), "Don't construct extension if unsupported."); 741 742 gl::GLContext* gl = webgl->GL(); 743 if (!gl->IsGLES()) { 744 // Desktop OpenGL requires the following to be enabled in order to 745 // support sRGB operations on framebuffers. 746 gl->fEnable(LOCAL_GL_FRAMEBUFFER_SRGB_EXT); 747 } 748 749 auto& fua = webgl->mFormatUsage; 750 751 RefPtr<gl::GLContext> gl_ = gl; // Bug 1201275 752 const auto fnAdd = [&fua, &gl_](webgl::EffectiveFormat effFormat, 753 GLenum format, GLenum desktopUnpackFormat) { 754 auto usage = fua->EditUsage(effFormat); 755 usage->isFilterable = true; 756 757 webgl::DriverUnpackInfo dui = {format, format, LOCAL_GL_UNSIGNED_BYTE}; 758 const auto pi = dui.ToPacking(); 759 760 if (!gl_->IsGLES()) dui.unpackFormat = desktopUnpackFormat; 761 762 fua->AddTexUnpack(usage, pi, dui); 763 764 fua->AllowUnsizedTexFormat(pi, usage); 765 }; 766 767 fnAdd(webgl::EffectiveFormat::SRGB8, LOCAL_GL_SRGB, LOCAL_GL_RGB); 768 fnAdd(webgl::EffectiveFormat::SRGB8_ALPHA8, LOCAL_GL_SRGB_ALPHA, 769 LOCAL_GL_RGBA); 770 771 auto usage = fua->EditUsage(webgl::EffectiveFormat::SRGB8_ALPHA8); 772 usage->SetRenderable(); 773 fua->AllowRBFormat(LOCAL_GL_SRGB8_ALPHA8, usage); 774 } 775 776 bool WebGLExtensionSRGB::IsSupported(const WebGLContext* const webgl) { 777 if (webgl->IsWebGL2()) return false; 778 779 return webgl->gl->IsSupported(gl::GLFeature::sRGB); 780 } 781 782 // - 783 784 WebGLExtensionTextureFloat::WebGLExtensionTextureFloat(WebGLContext* webgl) 785 : WebGLExtensionBase(webgl) { 786 MOZ_ASSERT(IsSupported(webgl)); 787 788 auto& fua = webgl->mFormatUsage; 789 gl::GLContext* gl = webgl->GL(); 790 791 webgl::PackingInfo pi; 792 webgl::DriverUnpackInfo dui; 793 const GLint* swizzle = nullptr; 794 795 const auto fnAdd = [&](webgl::EffectiveFormat effFormat) { 796 MOZ_ASSERT_IF(swizzle, gl->IsSupported(gl::GLFeature::texture_swizzle)); 797 798 auto usage = fua->EditUsage(effFormat); 799 usage->textureSwizzleRGBA = swizzle; 800 fua->AddTexUnpack(usage, pi, dui); 801 802 fua->AllowUnsizedTexFormat(pi, usage); 803 }; 804 805 bool useSizedFormats = true; 806 const bool hasSizedLegacyFormats = gl->IsCompatibilityProfile(); 807 if (gl->IsGLES() && gl->Version() < 300) { 808 useSizedFormats = false; 809 } 810 811 //////////////// 812 813 pi = {LOCAL_GL_RGBA, LOCAL_GL_FLOAT}; 814 dui = {pi.format, pi.format, pi.type}; 815 swizzle = nullptr; 816 if (useSizedFormats || gl->IsExtensionSupported( 817 gl::GLContext::CHROMIUM_color_buffer_float_rgba)) { 818 // ANGLE only exposes renderable RGBA32F via 819 // CHROMIUM_color_buffer_float_rgba, which uses sized formats. 820 dui.internalFormat = LOCAL_GL_RGBA32F; 821 } 822 fnAdd(webgl::EffectiveFormat::RGBA32F); 823 824 ////// 825 826 pi = {LOCAL_GL_RGB, LOCAL_GL_FLOAT}; 827 dui = {pi.format, pi.format, pi.type}; 828 swizzle = nullptr; 829 if (useSizedFormats) { 830 dui.internalFormat = LOCAL_GL_RGB32F; 831 } 832 fnAdd(webgl::EffectiveFormat::RGB32F); 833 834 ////// 835 836 pi = {LOCAL_GL_LUMINANCE, LOCAL_GL_FLOAT}; 837 dui = {pi.format, pi.format, pi.type}; 838 swizzle = nullptr; 839 if (useSizedFormats) { 840 if (hasSizedLegacyFormats) { 841 dui.internalFormat = LOCAL_GL_LUMINANCE32F_ARB; 842 } else { 843 dui.internalFormat = LOCAL_GL_R32F; 844 dui.unpackFormat = LOCAL_GL_RED; 845 swizzle = webgl::FormatUsageInfo::kLuminanceSwizzleRGBA; 846 } 847 } 848 fnAdd(webgl::EffectiveFormat::Luminance32F); 849 850 ////// 851 852 pi = {LOCAL_GL_ALPHA, LOCAL_GL_FLOAT}; 853 dui = {pi.format, pi.format, pi.type}; 854 swizzle = nullptr; 855 if (useSizedFormats) { 856 if (hasSizedLegacyFormats) { 857 dui.internalFormat = LOCAL_GL_ALPHA32F_ARB; 858 } else { 859 dui.internalFormat = LOCAL_GL_R32F; 860 dui.unpackFormat = LOCAL_GL_RED; 861 swizzle = webgl::FormatUsageInfo::kAlphaSwizzleRGBA; 862 } 863 } 864 fnAdd(webgl::EffectiveFormat::Alpha32F); 865 866 ////// 867 868 pi = {LOCAL_GL_LUMINANCE_ALPHA, LOCAL_GL_FLOAT}; 869 dui = {pi.format, pi.format, pi.type}; 870 swizzle = nullptr; 871 if (useSizedFormats) { 872 if (hasSizedLegacyFormats) { 873 dui.internalFormat = LOCAL_GL_LUMINANCE_ALPHA32F_ARB; 874 } else { 875 dui.internalFormat = LOCAL_GL_RG32F; 876 dui.unpackFormat = LOCAL_GL_RG; 877 swizzle = webgl::FormatUsageInfo::kLumAlphaSwizzleRGBA; 878 } 879 } 880 fnAdd(webgl::EffectiveFormat::Luminance32FAlpha32F); 881 } 882 883 bool WebGLExtensionTextureFloat::IsSupported(const WebGLContext* webgl) { 884 if (webgl->IsWebGL2()) return false; 885 886 gl::GLContext* gl = webgl->GL(); 887 if (!gl->IsSupported(gl::GLFeature::texture_float)) return false; 888 889 const bool needsSwizzle = gl->IsCoreProfile(); 890 const bool hasSwizzle = gl->IsSupported(gl::GLFeature::texture_swizzle); 891 if (needsSwizzle && !hasSwizzle) return false; 892 893 return true; 894 } 895 896 // - 897 898 WebGLExtensionTextureFloatLinear::WebGLExtensionTextureFloatLinear( 899 WebGLContext* webgl) 900 : WebGLExtensionBase(webgl) { 901 auto& fua = webgl->mFormatUsage; 902 903 fua->EditUsage(webgl::EffectiveFormat::RGBA32F)->isFilterable = true; 904 fua->EditUsage(webgl::EffectiveFormat::RGB32F)->isFilterable = true; 905 906 if (webgl->IsWebGL2()) { 907 fua->EditUsage(webgl::EffectiveFormat::R32F)->isFilterable = true; 908 fua->EditUsage(webgl::EffectiveFormat::RG32F)->isFilterable = true; 909 } else { 910 fua->EditUsage(webgl::EffectiveFormat::Luminance32FAlpha32F)->isFilterable = 911 true; 912 fua->EditUsage(webgl::EffectiveFormat::Luminance32F)->isFilterable = true; 913 fua->EditUsage(webgl::EffectiveFormat::Alpha32F)->isFilterable = true; 914 } 915 } 916 917 // - 918 919 WebGLExtensionTextureHalfFloat::WebGLExtensionTextureHalfFloat( 920 WebGLContext* webgl) 921 : WebGLExtensionBase(webgl) { 922 auto& fua = webgl->mFormatUsage; 923 gl::GLContext* gl = webgl->GL(); 924 925 webgl::PackingInfo pi; 926 webgl::DriverUnpackInfo dui; 927 const GLint* swizzle = nullptr; 928 929 const auto fnAdd = [&](webgl::EffectiveFormat effFormat) { 930 MOZ_ASSERT_IF(swizzle, gl->IsSupported(gl::GLFeature::texture_swizzle)); 931 932 auto usage = fua->EditUsage(effFormat); 933 usage->textureSwizzleRGBA = swizzle; 934 fua->AddTexUnpack(usage, pi, dui); 935 936 fua->AllowUnsizedTexFormat(pi, usage); 937 }; 938 939 bool useSizedFormats = true; 940 const bool hasSizedLegacyFormats = gl->IsCompatibilityProfile(); 941 if (gl->IsGLES() && gl->Version() < 300) { 942 useSizedFormats = false; 943 } 944 945 GLenum driverUnpackType = LOCAL_GL_HALF_FLOAT; 946 if (!gl->IsSupported(gl::GLFeature::texture_half_float)) { 947 MOZ_ASSERT(gl->IsExtensionSupported(gl::GLContext::OES_texture_half_float)); 948 driverUnpackType = LOCAL_GL_HALF_FLOAT_OES; 949 } 950 951 //////////////// 952 953 pi = {LOCAL_GL_RGBA, LOCAL_GL_HALF_FLOAT_OES}; 954 dui = {pi.format, pi.format, driverUnpackType}; 955 swizzle = nullptr; 956 if (useSizedFormats) { 957 dui.internalFormat = LOCAL_GL_RGBA16F; 958 } 959 fnAdd(webgl::EffectiveFormat::RGBA16F); 960 961 ////// 962 963 pi = {LOCAL_GL_RGB, LOCAL_GL_HALF_FLOAT_OES}; 964 dui = {pi.format, pi.format, driverUnpackType}; 965 swizzle = nullptr; 966 if (useSizedFormats) { 967 dui.internalFormat = LOCAL_GL_RGB16F; 968 } 969 fnAdd(webgl::EffectiveFormat::RGB16F); 970 971 ////// 972 973 pi = {LOCAL_GL_LUMINANCE, LOCAL_GL_HALF_FLOAT_OES}; 974 dui = {pi.format, pi.format, driverUnpackType}; 975 swizzle = nullptr; 976 if (useSizedFormats) { 977 if (hasSizedLegacyFormats) { 978 dui.internalFormat = LOCAL_GL_LUMINANCE16F_ARB; 979 } else { 980 dui.internalFormat = LOCAL_GL_R16F; 981 dui.unpackFormat = LOCAL_GL_RED; 982 swizzle = webgl::FormatUsageInfo::kLuminanceSwizzleRGBA; 983 } 984 } 985 fnAdd(webgl::EffectiveFormat::Luminance16F); 986 987 ////// 988 989 pi = {LOCAL_GL_ALPHA, LOCAL_GL_HALF_FLOAT_OES}; 990 dui = {pi.format, pi.format, driverUnpackType}; 991 swizzle = nullptr; 992 if (useSizedFormats) { 993 if (hasSizedLegacyFormats) { 994 dui.internalFormat = LOCAL_GL_ALPHA16F_ARB; 995 } else { 996 dui.internalFormat = LOCAL_GL_R16F; 997 dui.unpackFormat = LOCAL_GL_RED; 998 swizzle = webgl::FormatUsageInfo::kAlphaSwizzleRGBA; 999 } 1000 } 1001 fnAdd(webgl::EffectiveFormat::Alpha16F); 1002 1003 ////// 1004 1005 pi = {LOCAL_GL_LUMINANCE_ALPHA, LOCAL_GL_HALF_FLOAT_OES}; 1006 dui = {pi.format, pi.format, driverUnpackType}; 1007 swizzle = nullptr; 1008 if (useSizedFormats) { 1009 if (hasSizedLegacyFormats) { 1010 dui.internalFormat = LOCAL_GL_LUMINANCE_ALPHA16F_ARB; 1011 } else { 1012 dui.internalFormat = LOCAL_GL_RG16F; 1013 dui.unpackFormat = LOCAL_GL_RG; 1014 swizzle = webgl::FormatUsageInfo::kLumAlphaSwizzleRGBA; 1015 } 1016 } 1017 fnAdd(webgl::EffectiveFormat::Luminance16FAlpha16F); 1018 } 1019 1020 bool WebGLExtensionTextureHalfFloat::IsSupported(const WebGLContext* webgl) { 1021 if (webgl->IsWebGL2()) return false; 1022 1023 gl::GLContext* gl = webgl->GL(); 1024 if (!gl->IsSupported(gl::GLFeature::texture_half_float) && 1025 !gl->IsExtensionSupported(gl::GLContext::OES_texture_half_float)) { 1026 return false; 1027 } 1028 1029 const bool needsSwizzle = gl->IsCoreProfile(); 1030 const bool hasSwizzle = gl->IsSupported(gl::GLFeature::texture_swizzle); 1031 if (needsSwizzle && !hasSwizzle) return false; 1032 1033 return true; 1034 } 1035 1036 // - 1037 1038 WebGLExtensionTextureHalfFloatLinear::WebGLExtensionTextureHalfFloatLinear( 1039 WebGLContext* webgl) 1040 : WebGLExtensionBase(webgl) { 1041 MOZ_ASSERT(!webgl->IsWebGL2()); 1042 auto& fua = webgl->mFormatUsage; 1043 1044 fua->EditUsage(webgl::EffectiveFormat::RGBA16F)->isFilterable = true; 1045 fua->EditUsage(webgl::EffectiveFormat::RGB16F)->isFilterable = true; 1046 fua->EditUsage(webgl::EffectiveFormat::Luminance16FAlpha16F)->isFilterable = 1047 true; 1048 fua->EditUsage(webgl::EffectiveFormat::Luminance16F)->isFilterable = true; 1049 fua->EditUsage(webgl::EffectiveFormat::Alpha16F)->isFilterable = true; 1050 } 1051 1052 // - 1053 1054 bool WebGLExtensionTextureNorm16::IsSupported(const WebGLContext* const webgl) { 1055 if (!StaticPrefs::webgl_enable_draft_extensions()) return false; 1056 if (!webgl->IsWebGL2()) return false; 1057 1058 const auto& gl = webgl->gl; 1059 1060 // ANGLE's support is broken in our checkout. 1061 if (gl->IsANGLE()) return false; 1062 1063 return gl->IsSupported(gl::GLFeature::texture_norm16); 1064 } 1065 1066 WebGLExtensionTextureNorm16::WebGLExtensionTextureNorm16(WebGLContext* webgl) 1067 : WebGLExtensionBase(webgl) { 1068 if (!IsSupported(webgl)) { 1069 NS_WARNING( 1070 "Constructing WebGLExtensionTextureNorm16 but IsSupported() is " 1071 "false!"); 1072 // This was previously an assert, but it seems like we get races against 1073 // StaticPrefs changes/initialization? 1074 } 1075 1076 auto& fua = *webgl->mFormatUsage; 1077 1078 const auto fnAdd = [&](webgl::EffectiveFormat effFormat, 1079 const bool renderable, const webgl::PackingInfo& pi) { 1080 auto& usage = *fua.EditUsage(effFormat); 1081 const auto& format = *usage.format; 1082 1083 const auto dui = 1084 webgl::DriverUnpackInfo{format.sizedFormat, pi.format, pi.type}; 1085 fua.AddTexUnpack(&usage, pi, dui); 1086 1087 fua.AllowSizedTexFormat(format.sizedFormat, &usage); 1088 fua.AllowUnsizedTexFormat(pi, &usage); 1089 1090 if (renderable) { 1091 usage.SetRenderable(); 1092 fua.AllowRBFormat(format.sizedFormat, &usage); 1093 } 1094 }; 1095 1096 fnAdd(webgl::EffectiveFormat::R16, true, 1097 {LOCAL_GL_RED, LOCAL_GL_UNSIGNED_SHORT}); 1098 fnAdd(webgl::EffectiveFormat::RG16, true, 1099 {LOCAL_GL_RG, LOCAL_GL_UNSIGNED_SHORT}); 1100 fnAdd(webgl::EffectiveFormat::RGB16, false, 1101 {LOCAL_GL_RGB, LOCAL_GL_UNSIGNED_SHORT}); 1102 fnAdd(webgl::EffectiveFormat::RGBA16, true, 1103 {LOCAL_GL_RGBA, LOCAL_GL_UNSIGNED_SHORT}); 1104 1105 fnAdd(webgl::EffectiveFormat::R16_SNORM, false, 1106 {LOCAL_GL_RED, LOCAL_GL_SHORT}); 1107 fnAdd(webgl::EffectiveFormat::RG16_SNORM, false, 1108 {LOCAL_GL_RG, LOCAL_GL_SHORT}); 1109 fnAdd(webgl::EffectiveFormat::RGB16_SNORM, false, 1110 {LOCAL_GL_RGB, LOCAL_GL_SHORT}); 1111 fnAdd(webgl::EffectiveFormat::RGBA16_SNORM, false, 1112 {LOCAL_GL_RGBA, LOCAL_GL_SHORT}); 1113 } 1114 1115 } // namespace mozilla