WebGLTexelConversions.h (48836B)
1 /* 2 * Copyright (C) 2010 Apple Inc. All rights reserved. 3 * Copyright (C) 2010 Google Inc. All rights reserved. 4 * Copyright (C) 2010 Mozilla Corporation. All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY 16 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 18 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR 19 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 20 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 21 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 22 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 23 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 25 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 */ 27 28 #ifndef WEBGLTEXELCONVERSIONS_H_ 29 #define WEBGLTEXELCONVERSIONS_H_ 30 31 #ifdef __SUNPRO_CC 32 # define __restrict 33 #endif 34 35 #include <stdint.h> 36 37 #include "WebGLTypes.h" 38 #include "mozilla/Attributes.h" 39 #include "mozilla/Casting.h" 40 41 namespace mozilla { 42 43 namespace gl { 44 enum class OriginPos : uint8_t; 45 } 46 47 bool ConvertImage(size_t width, size_t height, const void* srcBegin, 48 size_t srcStride, gl::OriginPos srcOrigin, 49 WebGLTexelFormat srcFormat, bool srcPremultiplied, 50 void* dstBegin, size_t dstStride, gl::OriginPos dstOrigin, 51 WebGLTexelFormat dstFormat, bool dstPremultiplied, 52 dom::PredefinedColorSpace srcColorSpace, 53 dom::PredefinedColorSpace dstColorSpace, 54 bool* out_wasTrivial); 55 56 ////////////////////////////////////////////////////////////////////////////////////////// 57 58 // single precision float 59 // seeeeeeeemmmmmmmmmmmmmmmmmmmmmmm 60 61 // half precision float 62 // seeeeemmmmmmmmmm 63 64 // IEEE 16bits floating point: 65 const uint16_t kFloat16Value_Zero = 0x0000; // = 0000000000000000b 66 const uint16_t kFloat16Value_One = 0x3C00; // = 0011110000000000b 67 const uint16_t kFloat16Value_Infinity = 0x7C00; // = 0111110000000000b 68 const uint16_t kFloat16Value_NaN = 0x7FFF; // = 011111yyyyyyyyyyb (nonzero y) 69 70 MOZ_ALWAYS_INLINE uint16_t packToFloat16(float v) { 71 union { 72 float f32Value; 73 uint32_t f32Bits; 74 }; 75 76 f32Value = v; 77 78 // pull the sign from v into f16bits 79 uint16_t f16Bits = uint16_t(f32Bits >> 16) & 0x8000; 80 const uint32_t mantissa = f32Bits & 0x7FFFFF; 81 const uint32_t exp = (f32Bits >> 23) & 0xFF; 82 83 // Adapted from: OpenGL ES 2.0 Programming Guide Appx. 84 // Converting Float to Half-Float 85 // 143 = 255 - 127 + 15 86 // = sp_max - sp_bias + hp_bias 87 if (exp >= 143) { 88 if (mantissa && exp == 0xFF) { 89 // Single precision was NaN 90 return f16Bits | kFloat16Value_NaN; 91 } else { 92 // Outside range, store as infinity 93 return f16Bits | kFloat16Value_Infinity; 94 } 95 } 96 97 // too small, try to make a denormalized number 98 // 112 = 255 - 127 - (15 + 1) 99 // = sp_max - sp_bias - (hp_bias + 1) 100 if (exp <= 112) { 101 return f16Bits | uint16_t(mantissa >> (14 + 112 - exp)); 102 } 103 104 f16Bits |= uint16_t(exp - 112) << 10; 105 f16Bits |= uint16_t(mantissa >> 13) & 0x03FF; 106 107 return f16Bits; 108 } 109 110 MOZ_ALWAYS_INLINE float unpackFromFloat16(uint16_t v) { 111 union { 112 float f32Value; 113 uint32_t f32Bits; 114 }; 115 116 // grab sign bit 117 f32Bits = uint32_t(v & 0x8000) << 16; 118 uint16_t exp = (v >> 10) & 0x001F; 119 uint16_t mantissa = v & 0x03FF; 120 121 if (!exp) { 122 // Handle denormalized numbers 123 // Adapted from: OpenGL ES 2.0 Programming Guide Appx. 124 // Converting Float to Half-Float 125 if (mantissa) { 126 exp = 112; // See packToFloat16 127 mantissa <<= 1; 128 // For every leading zero, decrement the exponent 129 // and shift the mantissa to the left 130 while ((mantissa & (1 << 10)) == 0) { 131 mantissa <<= 1; 132 --exp; 133 } 134 mantissa &= 0x03FF; 135 136 f32Bits |= (exp << 23) | (mantissa << 13); 137 138 // Denormalized number 139 return f32Value; 140 } 141 142 // +/- zero 143 return f32Value; 144 } 145 146 if (exp == 0x001F) { 147 if (v & 0x03FF) { 148 // this is a NaN 149 f32Bits |= 0x7FFFFFFF; 150 } else { 151 // this is -inf or +inf 152 f32Bits |= 0x7F800000; 153 } 154 return f32Value; 155 } 156 157 f32Bits |= uint32_t(exp + (-15 + 127)) << 23; 158 f32Bits |= uint32_t(v & 0x03FF) << 13; 159 160 return f32Value; 161 } 162 163 // These routines come from angle/common/mathutil.h 164 // They are copied here to remove the dependency on ANGLE headers 165 // included from mathutil.h 166 MOZ_ALWAYS_INLINE uint16_t packToFloat11(float fp32) { 167 const unsigned int float32MantissaMask = 0x7FFFFF; 168 const unsigned int float32ExponentMask = 0x7F800000; 169 const unsigned int float32SignMask = 0x80000000; 170 const unsigned int float32ValueMask = ~float32SignMask; 171 const unsigned int float32ExponentFirstBit = 23; 172 const unsigned int float32ExponentBias = 127; 173 174 const unsigned short float11Max = 0x7BF; 175 const unsigned short float11MantissaMask = 0x3F; 176 const unsigned short float11ExponentMask = 0x7C0; 177 const unsigned short float11BitMask = 0x7FF; 178 const unsigned int float11ExponentBias = 14; 179 180 const unsigned int float32Maxfloat11 = 0x477E0000; 181 const unsigned int float32Minfloat11 = 0x38800000; 182 183 const unsigned int float32Bits = BitwiseCast<unsigned int>(fp32); 184 const bool float32Sign = (float32Bits & float32SignMask) == float32SignMask; 185 186 unsigned int float32Val = float32Bits & float32ValueMask; 187 188 if ((float32Val & float32ExponentMask) == float32ExponentMask) { 189 // INF or NAN 190 if ((float32Val & float32MantissaMask) != 0) { 191 return float11ExponentMask | (((float32Val >> 17) | (float32Val >> 11) | 192 (float32Val >> 6) | (float32Val)) & 193 float11MantissaMask); 194 } else if (float32Sign) { 195 // -INF is clamped to 0 since float11 is positive only 196 return 0; 197 } else { 198 return float11ExponentMask; 199 } 200 } else if (float32Sign) { 201 // float11 is positive only, so clamp to zero 202 return 0; 203 } else if (float32Val > float32Maxfloat11) { 204 // The number is too large to be represented as a float11, set to max 205 return float11Max; 206 } else { 207 if (float32Val < float32Minfloat11) { 208 // The number is too small to be represented as a normalized float11 209 // Convert it to a denormalized value. 210 const unsigned int shift = (float32ExponentBias - float11ExponentBias) - 211 (float32Val >> float32ExponentFirstBit); 212 float32Val = ((1 << float32ExponentFirstBit) | 213 (float32Val & float32MantissaMask)) >> 214 shift; 215 } else { 216 // Rebias the exponent to represent the value as a normalized float11 217 float32Val += 0xC8000000; 218 } 219 220 return ((float32Val + 0xFFFF + ((float32Val >> 17) & 1)) >> 17) & 221 float11BitMask; 222 } 223 } 224 225 MOZ_ALWAYS_INLINE uint16_t packToFloat10(float fp32) { 226 const unsigned int float32MantissaMask = 0x7FFFFF; 227 const unsigned int float32ExponentMask = 0x7F800000; 228 const unsigned int float32SignMask = 0x80000000; 229 const unsigned int float32ValueMask = ~float32SignMask; 230 const unsigned int float32ExponentFirstBit = 23; 231 const unsigned int float32ExponentBias = 127; 232 233 const unsigned short float10Max = 0x3DF; 234 const unsigned short float10MantissaMask = 0x1F; 235 const unsigned short float10ExponentMask = 0x3E0; 236 const unsigned short float10BitMask = 0x3FF; 237 const unsigned int float10ExponentBias = 14; 238 239 const unsigned int float32Maxfloat10 = 0x477C0000; 240 const unsigned int float32Minfloat10 = 0x38800000; 241 242 const unsigned int float32Bits = BitwiseCast<unsigned int>(fp32); 243 const bool float32Sign = (float32Bits & float32SignMask) == float32SignMask; 244 245 unsigned int float32Val = float32Bits & float32ValueMask; 246 247 if ((float32Val & float32ExponentMask) == float32ExponentMask) { 248 // INF or NAN 249 if ((float32Val & float32MantissaMask) != 0) { 250 return float10ExponentMask | (((float32Val >> 18) | (float32Val >> 13) | 251 (float32Val >> 3) | (float32Val)) & 252 float10MantissaMask); 253 } else if (float32Sign) { 254 // -INF is clamped to 0 since float11 is positive only 255 return 0; 256 } else { 257 return float10ExponentMask; 258 } 259 } else if (float32Sign) { 260 // float10 is positive only, so clamp to zero 261 return 0; 262 } else if (float32Val > float32Maxfloat10) { 263 // The number is too large to be represented as a float11, set to max 264 return float10Max; 265 } else { 266 if (float32Val < float32Minfloat10) { 267 // The number is too small to be represented as a normalized float11 268 // Convert it to a denormalized value. 269 const unsigned int shift = (float32ExponentBias - float10ExponentBias) - 270 (float32Val >> float32ExponentFirstBit); 271 float32Val = ((1 << float32ExponentFirstBit) | 272 (float32Val & float32MantissaMask)) >> 273 shift; 274 } else { 275 // Rebias the exponent to represent the value as a normalized float11 276 float32Val += 0xC8000000; 277 } 278 279 return ((float32Val + 0x1FFFF + ((float32Val >> 18) & 1)) >> 18) & 280 float10BitMask; 281 } 282 } 283 284 enum class WebGLTexelPremultiplicationOp : int { 285 None, 286 Premultiply, 287 Unpremultiply 288 }; 289 290 namespace WebGLTexelConversions { 291 292 template <WebGLTexelFormat Format> 293 struct IsFloatFormat { 294 static const bool Value = 295 Format == WebGLTexelFormat::A32F || Format == WebGLTexelFormat::R32F || 296 Format == WebGLTexelFormat::RA32F || Format == WebGLTexelFormat::RG32F || 297 Format == WebGLTexelFormat::RGB11F11F10F || 298 Format == WebGLTexelFormat::RGB32F || Format == WebGLTexelFormat::RGBA32F; 299 }; 300 301 template <WebGLTexelFormat Format> 302 struct IsHalfFloatFormat { 303 static const bool Value = 304 Format == WebGLTexelFormat::A16F || Format == WebGLTexelFormat::R16F || 305 Format == WebGLTexelFormat::RA16F || Format == WebGLTexelFormat::RG16F || 306 Format == WebGLTexelFormat::RGB16F || Format == WebGLTexelFormat::RGBA16F; 307 }; 308 309 template <WebGLTexelFormat Format> 310 struct Is16bppFormat { 311 static const bool Value = Format == WebGLTexelFormat::RGB565 || 312 Format == WebGLTexelFormat::RGBA4444 || 313 Format == WebGLTexelFormat::RGBA5551; 314 }; 315 316 template <WebGLTexelFormat Format, bool IsFloat = IsFloatFormat<Format>::Value, 317 bool Is16bpp = Is16bppFormat<Format>::Value, 318 bool IsHalfFloat = IsHalfFloatFormat<Format>::Value> 319 struct DataTypeForFormat { 320 using Type = uint8_t; 321 }; 322 323 template <WebGLTexelFormat Format> 324 struct DataTypeForFormat<Format, true, false, false> { 325 using Type = float; 326 }; 327 328 template <WebGLTexelFormat Format> 329 struct DataTypeForFormat<Format, false, true, false> { 330 using Type = uint16_t; 331 }; 332 333 template <WebGLTexelFormat Format> 334 struct DataTypeForFormat<Format, false, false, true> { 335 using Type = uint16_t; 336 }; 337 338 template <> 339 struct DataTypeForFormat<WebGLTexelFormat::RGB11F11F10F, true, false, false> { 340 using Type = uint32_t; 341 }; 342 343 template <WebGLTexelFormat Format> 344 struct IntermediateFormat { 345 static const WebGLTexelFormat Value = 346 IsFloatFormat<Format>::Value ? WebGLTexelFormat::RGBA32F 347 : IsHalfFloatFormat<Format>::Value ? WebGLTexelFormat::RGBA16F 348 : WebGLTexelFormat::RGBA8; 349 }; 350 351 inline size_t TexelBytesForFormat(WebGLTexelFormat format) { 352 switch (format) { 353 case WebGLTexelFormat::A8: 354 case WebGLTexelFormat::R8: 355 return 1; 356 case WebGLTexelFormat::A16F: 357 case WebGLTexelFormat::R16F: 358 case WebGLTexelFormat::RA8: 359 case WebGLTexelFormat::RG8: 360 case WebGLTexelFormat::RGB565: 361 case WebGLTexelFormat::RGBA4444: 362 case WebGLTexelFormat::RGBA5551: 363 return 2; 364 case WebGLTexelFormat::RGB8: 365 return 3; 366 case WebGLTexelFormat::A32F: 367 case WebGLTexelFormat::R32F: 368 case WebGLTexelFormat::RA16F: 369 case WebGLTexelFormat::RG16F: 370 case WebGLTexelFormat::RGB11F11F10F: 371 case WebGLTexelFormat::RGBA8: 372 case WebGLTexelFormat::BGRX8: 373 case WebGLTexelFormat::BGRA8: 374 return 4; 375 case WebGLTexelFormat::RGB16F: 376 return 6; 377 case WebGLTexelFormat::RA32F: 378 case WebGLTexelFormat::RG32F: 379 case WebGLTexelFormat::RGBA16F: 380 return 8; 381 case WebGLTexelFormat::RGB32F: 382 return 12; 383 case WebGLTexelFormat::RGBA32F: 384 return 16; 385 default: 386 MOZ_ASSERT(false, "Unknown texel format. Coding mistake?"); 387 return 0; 388 } 389 } 390 391 MOZ_ALWAYS_INLINE bool HasAlpha(WebGLTexelFormat format) { 392 return ( 393 format == WebGLTexelFormat::A8 || format == WebGLTexelFormat::A16F || 394 format == WebGLTexelFormat::A32F || format == WebGLTexelFormat::RA8 || 395 format == WebGLTexelFormat::RA16F || format == WebGLTexelFormat::RA32F || 396 format == WebGLTexelFormat::RGBA4444 || 397 format == WebGLTexelFormat::RGBA5551 || 398 format == WebGLTexelFormat::RGBA8 || 399 format == WebGLTexelFormat::RGBA16F || 400 format == WebGLTexelFormat::RGBA32F || format == WebGLTexelFormat::BGRA8); 401 } 402 403 MOZ_ALWAYS_INLINE bool HasColor(WebGLTexelFormat format) { 404 return ( 405 format == WebGLTexelFormat::R8 || format == WebGLTexelFormat::R16F || 406 format == WebGLTexelFormat::R32F || format == WebGLTexelFormat::RA8 || 407 format == WebGLTexelFormat::RA16F || format == WebGLTexelFormat::RA32F || 408 format == WebGLTexelFormat::RG8 || format == WebGLTexelFormat::RG16F || 409 format == WebGLTexelFormat::RG32F || format == WebGLTexelFormat::RGB565 || 410 format == WebGLTexelFormat::RGB8 || 411 format == WebGLTexelFormat::RGB11F11F10F || 412 format == WebGLTexelFormat::RGB16F || 413 format == WebGLTexelFormat::RGB32F || 414 format == WebGLTexelFormat::RGBA4444 || 415 format == WebGLTexelFormat::RGBA5551 || 416 format == WebGLTexelFormat::RGBA8 || 417 format == WebGLTexelFormat::RGBA16F || 418 format == WebGLTexelFormat::RGBA32F || 419 format == WebGLTexelFormat::BGRX8 || format == WebGLTexelFormat::BGRA8); 420 } 421 422 /****** BEGIN CODE SHARED WITH WEBKIT ******/ 423 424 // the pack/unpack functions here are originally from this file: 425 // http://trac.webkit.org/browser/trunk/WebCore/platform/graphics/GraphicsContext3D.cpp 426 427 //---------------------------------------------------------------------- 428 // Pixel unpacking routines. 429 430 template <WebGLTexelFormat Format, typename SrcType, typename DstType> 431 MOZ_ALWAYS_INLINE void unpack(const SrcType* __restrict src, 432 DstType* __restrict dst) { 433 MOZ_ASSERT(false, "Unimplemented texture format conversion"); 434 } 435 436 //////////////////////////////////////////////////////////////////////////////// 437 // 1-channel formats 438 template <> 439 MOZ_ALWAYS_INLINE void unpack<WebGLTexelFormat::A8, uint8_t, uint8_t>( 440 const uint8_t* __restrict src, uint8_t* __restrict dst) { 441 dst[0] = 0; 442 dst[1] = 0; 443 dst[2] = 0; 444 dst[3] = src[0]; 445 } 446 447 template <> 448 MOZ_ALWAYS_INLINE void unpack<WebGLTexelFormat::A16F, uint16_t, uint16_t>( 449 const uint16_t* __restrict src, uint16_t* __restrict dst) { 450 dst[0] = kFloat16Value_Zero; 451 dst[1] = kFloat16Value_Zero; 452 dst[2] = kFloat16Value_Zero; 453 dst[3] = src[0]; 454 } 455 456 template <> 457 MOZ_ALWAYS_INLINE void unpack<WebGLTexelFormat::A32F, float, float>( 458 const float* __restrict src, float* __restrict dst) { 459 dst[0] = 0; 460 dst[1] = 0; 461 dst[2] = 0; 462 dst[3] = src[0]; 463 } 464 465 template <> 466 MOZ_ALWAYS_INLINE void unpack<WebGLTexelFormat::R8, uint8_t, uint8_t>( 467 const uint8_t* __restrict src, uint8_t* __restrict dst) { 468 dst[0] = src[0]; 469 dst[1] = src[0]; 470 dst[2] = src[0]; 471 dst[3] = 0xFF; 472 } 473 474 template <> 475 MOZ_ALWAYS_INLINE void unpack<WebGLTexelFormat::R16F, uint16_t, uint16_t>( 476 const uint16_t* __restrict src, uint16_t* __restrict dst) { 477 dst[0] = src[0]; 478 dst[1] = src[0]; 479 dst[2] = src[0]; 480 dst[3] = kFloat16Value_One; 481 } 482 483 template <> 484 MOZ_ALWAYS_INLINE void unpack<WebGLTexelFormat::R32F, float, float>( 485 const float* __restrict src, float* __restrict dst) { 486 dst[0] = src[0]; 487 dst[1] = src[0]; 488 dst[2] = src[0]; 489 dst[3] = 1.0f; 490 } 491 492 //////////////////////////////////////////////////////////////////////////////// 493 // 2-channel formats 494 template <> 495 MOZ_ALWAYS_INLINE void unpack<WebGLTexelFormat::RA8, uint8_t, uint8_t>( 496 const uint8_t* __restrict src, uint8_t* __restrict dst) { 497 dst[0] = src[0]; 498 dst[1] = src[0]; 499 dst[2] = src[0]; 500 dst[3] = src[1]; 501 } 502 503 template <> 504 MOZ_ALWAYS_INLINE void unpack<WebGLTexelFormat::RA16F, uint16_t, uint16_t>( 505 const uint16_t* __restrict src, uint16_t* __restrict dst) { 506 dst[0] = src[0]; 507 dst[1] = src[0]; 508 dst[2] = src[0]; 509 dst[3] = src[1]; 510 } 511 512 template <> 513 MOZ_ALWAYS_INLINE void unpack<WebGLTexelFormat::RA32F, float, float>( 514 const float* __restrict src, float* __restrict dst) { 515 dst[0] = src[0]; 516 dst[1] = src[0]; 517 dst[2] = src[0]; 518 dst[3] = src[1]; 519 } 520 521 //////////////////////////////////////////////////////////////////////////////// 522 // 3-channel formats 523 template <> 524 MOZ_ALWAYS_INLINE void unpack<WebGLTexelFormat::RGB565, uint16_t, uint8_t>( 525 const uint16_t* __restrict src, uint8_t* __restrict dst) { 526 uint16_t packedValue = src[0]; 527 uint8_t r = (packedValue >> 11) & 0x1F; 528 uint8_t g = (packedValue >> 5) & 0x3F; 529 uint8_t b = packedValue & 0x1F; 530 dst[0] = uint8_t(r << 3) | (r & 0x7); 531 dst[1] = uint8_t(g << 2) | (g & 0x3); 532 dst[2] = uint8_t(b << 3) | (b & 0x7); 533 dst[3] = 0xFF; 534 } 535 536 template <> 537 MOZ_ALWAYS_INLINE void unpack<WebGLTexelFormat::RGB8, uint8_t, uint8_t>( 538 const uint8_t* __restrict src, uint8_t* __restrict dst) { 539 dst[0] = src[0]; 540 dst[1] = src[1]; 541 dst[2] = src[2]; 542 dst[3] = 0xFF; 543 } 544 545 template <> 546 MOZ_ALWAYS_INLINE void unpack<WebGLTexelFormat::RGB16F, uint16_t, uint16_t>( 547 const uint16_t* __restrict src, uint16_t* __restrict dst) { 548 dst[0] = src[0]; 549 dst[1] = src[1]; 550 dst[2] = src[2]; 551 dst[3] = kFloat16Value_One; 552 } 553 554 template <> 555 MOZ_ALWAYS_INLINE void unpack<WebGLTexelFormat::RGB32F, float, float>( 556 const float* __restrict src, float* __restrict dst) { 557 dst[0] = src[0]; 558 dst[1] = src[1]; 559 dst[2] = src[2]; 560 dst[3] = 1.0f; 561 } 562 563 //////////////////////////////////////////////////////////////////////////////// 564 // 4-channel formats 565 template <> 566 MOZ_ALWAYS_INLINE void unpack<WebGLTexelFormat::RGBA4444, uint16_t, uint8_t>( 567 const uint16_t* __restrict src, uint8_t* __restrict dst) { 568 uint16_t packedValue = src[0]; 569 uint8_t r = (packedValue >> 12) & 0x0F; 570 uint8_t g = (packedValue >> 8) & 0x0F; 571 uint8_t b = (packedValue >> 4) & 0x0F; 572 uint8_t a = packedValue & 0x0F; 573 dst[0] = uint8_t(r << 4) | r; 574 dst[1] = uint8_t(g << 4) | g; 575 dst[2] = uint8_t(b << 4) | b; 576 dst[3] = uint8_t(a << 4) | a; 577 } 578 579 template <> 580 MOZ_ALWAYS_INLINE void unpack<WebGLTexelFormat::RGBA5551, uint16_t, uint8_t>( 581 const uint16_t* __restrict src, uint8_t* __restrict dst) { 582 uint16_t packedValue = src[0]; 583 uint8_t r = (packedValue >> 11) & 0x1F; 584 uint8_t g = (packedValue >> 6) & 0x1F; 585 uint8_t b = (packedValue >> 1) & 0x1F; 586 dst[0] = uint8_t(r << 3) | (r & 0x7); 587 dst[1] = uint8_t(g << 3) | (g & 0x7); 588 dst[2] = uint8_t(b << 3) | (b & 0x7); 589 dst[3] = (packedValue & 0x1) ? 0xFF : 0; 590 } 591 592 template <> 593 MOZ_ALWAYS_INLINE void unpack<WebGLTexelFormat::RGBA8, uint8_t, uint8_t>( 594 const uint8_t* __restrict src, uint8_t* __restrict dst) { 595 dst[0] = src[0]; 596 dst[1] = src[1]; 597 dst[2] = src[2]; 598 dst[3] = src[3]; 599 } 600 601 template <> 602 MOZ_ALWAYS_INLINE void unpack<WebGLTexelFormat::RGBA16F, uint16_t, uint16_t>( 603 const uint16_t* __restrict src, uint16_t* __restrict dst) { 604 dst[0] = src[0]; 605 dst[1] = src[1]; 606 dst[2] = src[2]; 607 dst[3] = src[3]; 608 } 609 610 template <> 611 MOZ_ALWAYS_INLINE void unpack<WebGLTexelFormat::RGBA32F, float, float>( 612 const float* __restrict src, float* __restrict dst) { 613 dst[0] = src[0]; 614 dst[1] = src[1]; 615 dst[2] = src[2]; 616 dst[3] = src[3]; 617 } 618 619 //////////////////////////////////////////////////////////////////////////////// 620 // DOM element formats 621 template <> 622 MOZ_ALWAYS_INLINE void unpack<WebGLTexelFormat::BGRX8, uint8_t, uint8_t>( 623 const uint8_t* __restrict src, uint8_t* __restrict dst) { 624 dst[0] = src[2]; 625 dst[1] = src[1]; 626 dst[2] = src[0]; 627 dst[3] = 0xFF; 628 } 629 630 template <> 631 MOZ_ALWAYS_INLINE void unpack<WebGLTexelFormat::BGRA8, uint8_t, uint8_t>( 632 const uint8_t* __restrict src, uint8_t* __restrict dst) { 633 dst[0] = src[2]; 634 dst[1] = src[1]; 635 dst[2] = src[0]; 636 dst[3] = src[3]; 637 } 638 639 //---------------------------------------------------------------------- 640 // Pixel packing routines. 641 // 642 643 template <WebGLTexelFormat Format, 644 WebGLTexelPremultiplicationOp PremultiplicationOp, typename SrcType, 645 typename DstType> 646 MOZ_ALWAYS_INLINE void pack(const SrcType* __restrict src, 647 DstType* __restrict dst) { 648 MOZ_CRASH("GFX: Unimplemented texture format conversion"); 649 } 650 651 //////////////////////////////////////////////////////////////////////////////// 652 // 1-channel formats 653 template <> 654 MOZ_ALWAYS_INLINE void 655 pack<WebGLTexelFormat::A8, WebGLTexelPremultiplicationOp::None, uint8_t, 656 uint8_t>(const uint8_t* __restrict src, uint8_t* __restrict dst) { 657 dst[0] = src[3]; 658 } 659 660 template <> 661 MOZ_ALWAYS_INLINE void 662 pack<WebGLTexelFormat::A8, WebGLTexelPremultiplicationOp::Premultiply, uint8_t, 663 uint8_t>(const uint8_t* __restrict src, uint8_t* __restrict dst) { 664 dst[0] = src[3]; 665 } 666 667 template <> 668 MOZ_ALWAYS_INLINE void 669 pack<WebGLTexelFormat::A8, WebGLTexelPremultiplicationOp::Unpremultiply, 670 uint8_t, uint8_t>(const uint8_t* __restrict src, uint8_t* __restrict dst) { 671 dst[0] = src[3]; 672 } 673 674 template <> 675 MOZ_ALWAYS_INLINE void 676 pack<WebGLTexelFormat::A16F, WebGLTexelPremultiplicationOp::None, uint16_t, 677 uint16_t>(const uint16_t* __restrict src, uint16_t* __restrict dst) { 678 dst[0] = src[3]; 679 } 680 681 template <> 682 MOZ_ALWAYS_INLINE void 683 pack<WebGLTexelFormat::A16F, WebGLTexelPremultiplicationOp::Premultiply, 684 uint16_t, uint16_t>(const uint16_t* __restrict src, 685 uint16_t* __restrict dst) { 686 dst[0] = src[3]; 687 } 688 689 template <> 690 MOZ_ALWAYS_INLINE void 691 pack<WebGLTexelFormat::A16F, WebGLTexelPremultiplicationOp::Unpremultiply, 692 uint16_t, uint16_t>(const uint16_t* __restrict src, 693 uint16_t* __restrict dst) { 694 dst[0] = src[3]; 695 } 696 697 template <> 698 MOZ_ALWAYS_INLINE void 699 pack<WebGLTexelFormat::A32F, WebGLTexelPremultiplicationOp::None, float, float>( 700 const float* __restrict src, float* __restrict dst) { 701 dst[0] = src[3]; 702 } 703 704 template <> 705 MOZ_ALWAYS_INLINE void 706 pack<WebGLTexelFormat::A32F, WebGLTexelPremultiplicationOp::Premultiply, float, 707 float>(const float* __restrict src, float* __restrict dst) { 708 dst[0] = src[3]; 709 } 710 711 template <> 712 MOZ_ALWAYS_INLINE void 713 pack<WebGLTexelFormat::A32F, WebGLTexelPremultiplicationOp::Unpremultiply, 714 float, float>(const float* __restrict src, float* __restrict dst) { 715 dst[0] = src[3]; 716 } 717 718 template <> 719 MOZ_ALWAYS_INLINE void 720 pack<WebGLTexelFormat::R8, WebGLTexelPremultiplicationOp::None, uint8_t, 721 uint8_t>(const uint8_t* __restrict src, uint8_t* __restrict dst) { 722 dst[0] = src[0]; 723 } 724 725 template <> 726 MOZ_ALWAYS_INLINE void 727 pack<WebGLTexelFormat::R8, WebGLTexelPremultiplicationOp::Premultiply, uint8_t, 728 uint8_t>(const uint8_t* __restrict src, uint8_t* __restrict dst) { 729 float scaleFactor = src[3] / 255.0f; 730 uint8_t srcR = static_cast<uint8_t>(src[0] * scaleFactor); 731 dst[0] = srcR; 732 } 733 734 template <> 735 MOZ_ALWAYS_INLINE void 736 pack<WebGLTexelFormat::R8, WebGLTexelPremultiplicationOp::Unpremultiply, 737 uint8_t, uint8_t>(const uint8_t* __restrict src, uint8_t* __restrict dst) { 738 float scaleFactor = src[3] ? 255.0f / src[3] : 1.0f; 739 uint8_t srcR = static_cast<uint8_t>(src[0] * scaleFactor); 740 dst[0] = srcR; 741 } 742 743 template <> 744 MOZ_ALWAYS_INLINE void 745 pack<WebGLTexelFormat::R16F, WebGLTexelPremultiplicationOp::None, uint16_t, 746 uint16_t>(const uint16_t* __restrict src, uint16_t* __restrict dst) { 747 dst[0] = src[0]; 748 } 749 750 template <> 751 MOZ_ALWAYS_INLINE void 752 pack<WebGLTexelFormat::R16F, WebGLTexelPremultiplicationOp::Premultiply, 753 uint16_t, uint16_t>(const uint16_t* __restrict src, 754 uint16_t* __restrict dst) { 755 float scaleFactor = unpackFromFloat16(src[3]); 756 dst[0] = packToFloat16(unpackFromFloat16(src[0]) * scaleFactor); 757 } 758 759 template <> 760 MOZ_ALWAYS_INLINE void 761 pack<WebGLTexelFormat::R16F, WebGLTexelPremultiplicationOp::Unpremultiply, 762 uint16_t, uint16_t>(const uint16_t* __restrict src, 763 uint16_t* __restrict dst) { 764 float unpackedAlpha = unpackFromFloat16(src[3]); 765 float scaleFactor = unpackedAlpha ? 1.0f / unpackedAlpha : 1.0f; 766 dst[0] = packToFloat16(unpackFromFloat16(src[0]) * scaleFactor); 767 } 768 769 template <> 770 MOZ_ALWAYS_INLINE void 771 pack<WebGLTexelFormat::R32F, WebGLTexelPremultiplicationOp::None, float, float>( 772 const float* __restrict src, float* __restrict dst) { 773 dst[0] = src[0]; 774 } 775 776 template <> 777 MOZ_ALWAYS_INLINE void 778 pack<WebGLTexelFormat::R32F, WebGLTexelPremultiplicationOp::Premultiply, float, 779 float>(const float* __restrict src, float* __restrict dst) { 780 float scaleFactor = src[3]; 781 dst[0] = src[0] * scaleFactor; 782 } 783 784 template <> 785 MOZ_ALWAYS_INLINE void 786 pack<WebGLTexelFormat::R32F, WebGLTexelPremultiplicationOp::Unpremultiply, 787 float, float>(const float* __restrict src, float* __restrict dst) { 788 float scaleFactor = src[3] ? 1.0f / src[3] : 1.0f; 789 dst[0] = src[0] * scaleFactor; 790 } 791 792 //////////////////////////////////////////////////////////////////////////////// 793 // 2-channel formats 794 template <> 795 MOZ_ALWAYS_INLINE void 796 pack<WebGLTexelFormat::RA8, WebGLTexelPremultiplicationOp::None, uint8_t, 797 uint8_t>(const uint8_t* __restrict src, uint8_t* __restrict dst) { 798 dst[0] = src[0]; 799 dst[1] = src[3]; 800 } 801 802 template <> 803 MOZ_ALWAYS_INLINE void 804 pack<WebGLTexelFormat::RA8, WebGLTexelPremultiplicationOp::Premultiply, uint8_t, 805 uint8_t>(const uint8_t* __restrict src, uint8_t* __restrict dst) { 806 float scaleFactor = src[3] / 255.0f; 807 uint8_t srcR = static_cast<uint8_t>(src[0] * scaleFactor); 808 dst[0] = srcR; 809 dst[1] = src[3]; 810 } 811 812 // FIXME: this routine is lossy and must be removed. 813 template <> 814 MOZ_ALWAYS_INLINE void 815 pack<WebGLTexelFormat::RA8, WebGLTexelPremultiplicationOp::Unpremultiply, 816 uint8_t, uint8_t>(const uint8_t* __restrict src, uint8_t* __restrict dst) { 817 float scaleFactor = src[3] ? 255.0f / src[3] : 1.0f; 818 uint8_t srcR = static_cast<uint8_t>(src[0] * scaleFactor); 819 dst[0] = srcR; 820 dst[1] = src[3]; 821 } 822 823 template <> 824 MOZ_ALWAYS_INLINE void 825 pack<WebGLTexelFormat::RA16F, WebGLTexelPremultiplicationOp::None, uint16_t, 826 uint16_t>(const uint16_t* __restrict src, uint16_t* __restrict dst) { 827 dst[0] = src[0]; 828 dst[1] = src[3]; 829 } 830 831 template <> 832 MOZ_ALWAYS_INLINE void 833 pack<WebGLTexelFormat::RA16F, WebGLTexelPremultiplicationOp::Premultiply, 834 uint16_t, uint16_t>(const uint16_t* __restrict src, 835 uint16_t* __restrict dst) { 836 float scaleFactor = unpackFromFloat16(src[3]); 837 dst[0] = packToFloat16(unpackFromFloat16(src[0]) * scaleFactor); 838 dst[1] = src[3]; 839 } 840 841 template <> 842 MOZ_ALWAYS_INLINE void 843 pack<WebGLTexelFormat::RA16F, WebGLTexelPremultiplicationOp::Unpremultiply, 844 uint16_t, uint16_t>(const uint16_t* __restrict src, 845 uint16_t* __restrict dst) { 846 float unpackedAlpha = unpackFromFloat16(src[3]); 847 float scaleFactor = unpackedAlpha ? 1.0f / unpackedAlpha : 1.0f; 848 dst[0] = packToFloat16(unpackFromFloat16(src[0]) * scaleFactor); 849 dst[1] = src[3]; 850 } 851 852 template <> 853 MOZ_ALWAYS_INLINE void pack<WebGLTexelFormat::RA32F, 854 WebGLTexelPremultiplicationOp::None, float, float>( 855 const float* __restrict src, float* __restrict dst) { 856 dst[0] = src[0]; 857 dst[1] = src[3]; 858 } 859 860 template <> 861 MOZ_ALWAYS_INLINE void 862 pack<WebGLTexelFormat::RA32F, WebGLTexelPremultiplicationOp::Premultiply, float, 863 float>(const float* __restrict src, float* __restrict dst) { 864 float scaleFactor = src[3]; 865 dst[0] = src[0] * scaleFactor; 866 dst[1] = src[3]; 867 } 868 869 template <> 870 MOZ_ALWAYS_INLINE void 871 pack<WebGLTexelFormat::RA32F, WebGLTexelPremultiplicationOp::Unpremultiply, 872 float, float>(const float* __restrict src, float* __restrict dst) { 873 float scaleFactor = src[3] ? 1.0f / src[3] : 1.0f; 874 dst[0] = src[0] * scaleFactor; 875 dst[1] = src[3]; 876 } 877 878 template <> 879 MOZ_ALWAYS_INLINE void 880 pack<WebGLTexelFormat::RG8, WebGLTexelPremultiplicationOp::None, uint8_t, 881 uint8_t>(const uint8_t* __restrict src, uint8_t* __restrict dst) { 882 dst[0] = src[0]; 883 dst[1] = src[1]; 884 } 885 886 template <> 887 MOZ_ALWAYS_INLINE void 888 pack<WebGLTexelFormat::RG8, WebGLTexelPremultiplicationOp::Premultiply, uint8_t, 889 uint8_t>(const uint8_t* __restrict src, uint8_t* __restrict dst) { 890 float scaleFactor = src[3] / 255.0f; 891 uint8_t srcR = static_cast<uint8_t>(src[0] * scaleFactor); 892 uint8_t srcG = static_cast<uint8_t>(src[1] * scaleFactor); 893 dst[0] = srcR; 894 dst[1] = srcG; 895 } 896 897 // FIXME: this routine is lossy and must be removed. 898 template <> 899 MOZ_ALWAYS_INLINE void 900 pack<WebGLTexelFormat::RG8, WebGLTexelPremultiplicationOp::Unpremultiply, 901 uint8_t, uint8_t>(const uint8_t* __restrict src, uint8_t* __restrict dst) { 902 float scaleFactor = src[3] ? 255.0f / src[3] : 1.0f; 903 uint8_t srcR = static_cast<uint8_t>(src[0] * scaleFactor); 904 uint8_t srcG = static_cast<uint8_t>(src[1] * scaleFactor); 905 dst[0] = srcR; 906 dst[1] = srcG; 907 } 908 909 template <> 910 MOZ_ALWAYS_INLINE void 911 pack<WebGLTexelFormat::RG16F, WebGLTexelPremultiplicationOp::None, uint16_t, 912 uint16_t>(const uint16_t* __restrict src, uint16_t* __restrict dst) { 913 dst[0] = src[0]; 914 dst[1] = src[1]; 915 } 916 917 template <> 918 MOZ_ALWAYS_INLINE void 919 pack<WebGLTexelFormat::RG16F, WebGLTexelPremultiplicationOp::Premultiply, 920 uint16_t, uint16_t>(const uint16_t* __restrict src, 921 uint16_t* __restrict dst) { 922 float scaleFactor = unpackFromFloat16(src[3]); 923 dst[0] = packToFloat16(unpackFromFloat16(src[0]) * scaleFactor); 924 dst[1] = packToFloat16(unpackFromFloat16(src[1]) * scaleFactor); 925 } 926 927 template <> 928 MOZ_ALWAYS_INLINE void 929 pack<WebGLTexelFormat::RG16F, WebGLTexelPremultiplicationOp::Unpremultiply, 930 uint16_t, uint16_t>(const uint16_t* __restrict src, 931 uint16_t* __restrict dst) { 932 float unpackedAlpha = unpackFromFloat16(src[3]); 933 float scaleFactor = unpackedAlpha ? 1.0f / unpackedAlpha : 1.0f; 934 dst[0] = packToFloat16(unpackFromFloat16(src[0]) * scaleFactor); 935 dst[1] = packToFloat16(unpackFromFloat16(src[1]) * scaleFactor); 936 } 937 938 template <> 939 MOZ_ALWAYS_INLINE void pack<WebGLTexelFormat::RG32F, 940 WebGLTexelPremultiplicationOp::None, float, float>( 941 const float* __restrict src, float* __restrict dst) { 942 dst[0] = src[0]; 943 dst[1] = src[1]; 944 } 945 946 template <> 947 MOZ_ALWAYS_INLINE void 948 pack<WebGLTexelFormat::RG32F, WebGLTexelPremultiplicationOp::Premultiply, float, 949 float>(const float* __restrict src, float* __restrict dst) { 950 float scaleFactor = src[3]; 951 dst[0] = src[0] * scaleFactor; 952 dst[1] = src[1] * scaleFactor; 953 } 954 955 template <> 956 MOZ_ALWAYS_INLINE void 957 pack<WebGLTexelFormat::RG32F, WebGLTexelPremultiplicationOp::Unpremultiply, 958 float, float>(const float* __restrict src, float* __restrict dst) { 959 float scaleFactor = src[3] ? 1.0f / src[3] : 1.0f; 960 dst[0] = src[0] * scaleFactor; 961 dst[1] = src[1] * scaleFactor; 962 } 963 964 //////////////////////////////////////////////////////////////////////////////// 965 // 3-channel formats 966 template <> 967 MOZ_ALWAYS_INLINE void 968 pack<WebGLTexelFormat::RGB565, WebGLTexelPremultiplicationOp::None, uint8_t, 969 uint16_t>(const uint8_t* __restrict src, uint16_t* __restrict dst) { 970 *dst = uint16_t(((src[0] & 0xF8) << 8) | ((src[1] & 0xFC) << 3) | 971 ((src[2] & 0xF8) >> 3)); 972 } 973 974 template <> 975 MOZ_ALWAYS_INLINE void 976 pack<WebGLTexelFormat::RGB565, WebGLTexelPremultiplicationOp::Premultiply, 977 uint8_t, uint16_t>(const uint8_t* __restrict src, 978 uint16_t* __restrict dst) { 979 float scaleFactor = src[3] / 255.0f; 980 uint8_t srcR = static_cast<uint8_t>(src[0] * scaleFactor); 981 uint8_t srcG = static_cast<uint8_t>(src[1] * scaleFactor); 982 uint8_t srcB = static_cast<uint8_t>(src[2] * scaleFactor); 983 *dst = uint16_t(((srcR & 0xF8) << 8) | ((srcG & 0xFC) << 3) | 984 ((srcB & 0xF8) >> 3)); 985 } 986 987 // FIXME: this routine is lossy and must be removed. 988 template <> 989 MOZ_ALWAYS_INLINE void 990 pack<WebGLTexelFormat::RGB565, WebGLTexelPremultiplicationOp::Unpremultiply, 991 uint8_t, uint16_t>(const uint8_t* __restrict src, 992 uint16_t* __restrict dst) { 993 float scaleFactor = src[3] ? 255.0f / src[3] : 1.0f; 994 uint8_t srcR = static_cast<uint8_t>(src[0] * scaleFactor); 995 uint8_t srcG = static_cast<uint8_t>(src[1] * scaleFactor); 996 uint8_t srcB = static_cast<uint8_t>(src[2] * scaleFactor); 997 *dst = uint16_t(((srcR & 0xF8) << 8) | ((srcG & 0xFC) << 3) | 998 ((srcB & 0xF8) >> 3)); 999 } 1000 1001 template <> 1002 MOZ_ALWAYS_INLINE void 1003 pack<WebGLTexelFormat::RGB8, WebGLTexelPremultiplicationOp::None, uint8_t, 1004 uint8_t>(const uint8_t* __restrict src, uint8_t* __restrict dst) { 1005 dst[0] = src[0]; 1006 dst[1] = src[1]; 1007 dst[2] = src[2]; 1008 } 1009 1010 template <> 1011 MOZ_ALWAYS_INLINE void 1012 pack<WebGLTexelFormat::RGB8, WebGLTexelPremultiplicationOp::Premultiply, 1013 uint8_t, uint8_t>(const uint8_t* __restrict src, uint8_t* __restrict dst) { 1014 float scaleFactor = src[3] / 255.0f; 1015 uint8_t srcR = static_cast<uint8_t>(src[0] * scaleFactor); 1016 uint8_t srcG = static_cast<uint8_t>(src[1] * scaleFactor); 1017 uint8_t srcB = static_cast<uint8_t>(src[2] * scaleFactor); 1018 dst[0] = srcR; 1019 dst[1] = srcG; 1020 dst[2] = srcB; 1021 } 1022 1023 template <> 1024 MOZ_ALWAYS_INLINE void 1025 pack<WebGLTexelFormat::RGB8, WebGLTexelPremultiplicationOp::Unpremultiply, 1026 uint8_t, uint8_t>(const uint8_t* __restrict src, uint8_t* __restrict dst) { 1027 float scaleFactor = src[3] ? 255.0f / src[3] : 1.0f; 1028 uint8_t srcR = static_cast<uint8_t>(src[0] * scaleFactor); 1029 uint8_t srcG = static_cast<uint8_t>(src[1] * scaleFactor); 1030 uint8_t srcB = static_cast<uint8_t>(src[2] * scaleFactor); 1031 dst[0] = srcR; 1032 dst[1] = srcG; 1033 dst[2] = srcB; 1034 } 1035 1036 template <> 1037 MOZ_ALWAYS_INLINE void 1038 pack<WebGLTexelFormat::RGB11F11F10F, WebGLTexelPremultiplicationOp::None, float, 1039 uint32_t>(const float* __restrict src, uint32_t* __restrict dst) { 1040 dst[0] = ((packToFloat11(src[0]) << 0) | (packToFloat11(src[1]) << 11) | 1041 (packToFloat10(src[2]) << 22)); 1042 } 1043 1044 template <> 1045 MOZ_ALWAYS_INLINE void 1046 pack<WebGLTexelFormat::RGB11F11F10F, WebGLTexelPremultiplicationOp::Premultiply, 1047 float, uint32_t>(const float* __restrict src, uint32_t* __restrict dst) { 1048 float scaleFactor = src[3]; 1049 dst[0] = ((packToFloat11(src[0] * scaleFactor) << 0) | 1050 (packToFloat11(src[1] * scaleFactor) << 11) | 1051 (packToFloat10(src[2] * scaleFactor) << 22)); 1052 } 1053 1054 template <> 1055 MOZ_ALWAYS_INLINE void pack<WebGLTexelFormat::RGB11F11F10F, 1056 WebGLTexelPremultiplicationOp::Unpremultiply, float, 1057 uint32_t>(const float* __restrict src, 1058 uint32_t* __restrict dst) { 1059 float scaleFactor = src[3] ? 1.0f / src[3] : 1.0f; 1060 dst[0] = ((packToFloat11(src[0] * scaleFactor) << 0) | 1061 (packToFloat11(src[1] * scaleFactor) << 11) | 1062 (packToFloat10(src[2] * scaleFactor) << 22)); 1063 } 1064 1065 template <> 1066 MOZ_ALWAYS_INLINE void 1067 pack<WebGLTexelFormat::RGB16F, WebGLTexelPremultiplicationOp::None, uint16_t, 1068 uint16_t>(const uint16_t* __restrict src, uint16_t* __restrict dst) { 1069 dst[0] = src[0]; 1070 dst[1] = src[1]; 1071 dst[2] = src[2]; 1072 } 1073 1074 template <> 1075 MOZ_ALWAYS_INLINE void 1076 pack<WebGLTexelFormat::RGB16F, WebGLTexelPremultiplicationOp::Premultiply, 1077 uint16_t, uint16_t>(const uint16_t* __restrict src, 1078 uint16_t* __restrict dst) { 1079 float scaleFactor = unpackFromFloat16(src[3]); 1080 dst[0] = packToFloat16(unpackFromFloat16(src[0]) * scaleFactor); 1081 dst[1] = packToFloat16(unpackFromFloat16(src[1]) * scaleFactor); 1082 dst[2] = packToFloat16(unpackFromFloat16(src[2]) * scaleFactor); 1083 } 1084 1085 template <> 1086 MOZ_ALWAYS_INLINE void 1087 pack<WebGLTexelFormat::RGB16F, WebGLTexelPremultiplicationOp::Unpremultiply, 1088 uint16_t, uint16_t>(const uint16_t* __restrict src, 1089 uint16_t* __restrict dst) { 1090 float unpackedAlpha = unpackFromFloat16(src[3]); 1091 float scaleFactor = unpackedAlpha ? 1.0f / unpackedAlpha : 1.0f; 1092 dst[0] = packToFloat16(unpackFromFloat16(src[0]) * scaleFactor); 1093 dst[1] = packToFloat16(unpackFromFloat16(src[1]) * scaleFactor); 1094 dst[2] = packToFloat16(unpackFromFloat16(src[2]) * scaleFactor); 1095 } 1096 1097 template <> 1098 MOZ_ALWAYS_INLINE void pack<WebGLTexelFormat::RGB32F, 1099 WebGLTexelPremultiplicationOp::None, float, float>( 1100 const float* __restrict src, float* __restrict dst) { 1101 dst[0] = src[0]; 1102 dst[1] = src[1]; 1103 dst[2] = src[2]; 1104 } 1105 1106 template <> 1107 MOZ_ALWAYS_INLINE void 1108 pack<WebGLTexelFormat::RGB32F, WebGLTexelPremultiplicationOp::Premultiply, 1109 float, float>(const float* __restrict src, float* __restrict dst) { 1110 float scaleFactor = src[3]; 1111 dst[0] = src[0] * scaleFactor; 1112 dst[1] = src[1] * scaleFactor; 1113 dst[2] = src[2] * scaleFactor; 1114 } 1115 1116 template <> 1117 MOZ_ALWAYS_INLINE void 1118 pack<WebGLTexelFormat::RGB32F, WebGLTexelPremultiplicationOp::Unpremultiply, 1119 float, float>(const float* __restrict src, float* __restrict dst) { 1120 float scaleFactor = src[3] ? 1.0f / src[3] : 1.0f; 1121 dst[0] = src[0] * scaleFactor; 1122 dst[1] = src[1] * scaleFactor; 1123 dst[2] = src[2] * scaleFactor; 1124 } 1125 1126 //////////////////////////////////////////////////////////////////////////////// 1127 // 4-channel formats 1128 template <> 1129 MOZ_ALWAYS_INLINE void 1130 pack<WebGLTexelFormat::RGBA4444, WebGLTexelPremultiplicationOp::None, uint8_t, 1131 uint16_t>(const uint8_t* __restrict src, uint16_t* __restrict dst) { 1132 *dst = uint16_t(((src[0] & 0xF0) << 8) | ((src[1] & 0xF0) << 4) | 1133 (src[2] & 0xF0) | (src[3] >> 4)); 1134 } 1135 1136 template <> 1137 MOZ_ALWAYS_INLINE void 1138 pack<WebGLTexelFormat::RGBA4444, WebGLTexelPremultiplicationOp::Premultiply, 1139 uint8_t, uint16_t>(const uint8_t* __restrict src, 1140 uint16_t* __restrict dst) { 1141 float scaleFactor = src[3] / 255.0f; 1142 uint8_t srcR = static_cast<uint8_t>(src[0] * scaleFactor); 1143 uint8_t srcG = static_cast<uint8_t>(src[1] * scaleFactor); 1144 uint8_t srcB = static_cast<uint8_t>(src[2] * scaleFactor); 1145 *dst = uint16_t(((srcR & 0xF0) << 8) | ((srcG & 0xF0) << 4) | (srcB & 0xF0) | 1146 (src[3] >> 4)); 1147 } 1148 1149 // FIXME: this routine is lossy and must be removed. 1150 template <> 1151 MOZ_ALWAYS_INLINE void 1152 pack<WebGLTexelFormat::RGBA4444, WebGLTexelPremultiplicationOp::Unpremultiply, 1153 uint8_t, uint16_t>(const uint8_t* __restrict src, 1154 uint16_t* __restrict dst) { 1155 float scaleFactor = src[3] ? 255.0f / src[3] : 1.0f; 1156 uint8_t srcR = static_cast<uint8_t>(src[0] * scaleFactor); 1157 uint8_t srcG = static_cast<uint8_t>(src[1] * scaleFactor); 1158 uint8_t srcB = static_cast<uint8_t>(src[2] * scaleFactor); 1159 *dst = uint16_t(((srcR & 0xF0) << 8) | ((srcG & 0xF0) << 4) | (srcB & 0xF0) | 1160 (src[3] >> 4)); 1161 } 1162 1163 template <> 1164 MOZ_ALWAYS_INLINE void 1165 pack<WebGLTexelFormat::RGBA5551, WebGLTexelPremultiplicationOp::None, uint8_t, 1166 uint16_t>(const uint8_t* __restrict src, uint16_t* __restrict dst) { 1167 *dst = uint16_t(((src[0] & 0xF8) << 8) | ((src[1] & 0xF8) << 3) | 1168 ((src[2] & 0xF8) >> 2) | (src[3] >> 7)); 1169 } 1170 1171 template <> 1172 MOZ_ALWAYS_INLINE void 1173 pack<WebGLTexelFormat::RGBA5551, WebGLTexelPremultiplicationOp::Premultiply, 1174 uint8_t, uint16_t>(const uint8_t* __restrict src, 1175 uint16_t* __restrict dst) { 1176 float scaleFactor = src[3] / 255.0f; 1177 uint8_t srcR = static_cast<uint8_t>(src[0] * scaleFactor); 1178 uint8_t srcG = static_cast<uint8_t>(src[1] * scaleFactor); 1179 uint8_t srcB = static_cast<uint8_t>(src[2] * scaleFactor); 1180 *dst = uint16_t(((srcR & 0xF8) << 8) | ((srcG & 0xF8) << 3) | 1181 ((srcB & 0xF8) >> 2) | (src[3] >> 7)); 1182 } 1183 1184 // FIXME: this routine is lossy and must be removed. 1185 template <> 1186 MOZ_ALWAYS_INLINE void 1187 pack<WebGLTexelFormat::RGBA5551, WebGLTexelPremultiplicationOp::Unpremultiply, 1188 uint8_t, uint16_t>(const uint8_t* __restrict src, 1189 uint16_t* __restrict dst) { 1190 float scaleFactor = src[3] ? 255.0f / src[3] : 1.0f; 1191 uint8_t srcR = static_cast<uint8_t>(src[0] * scaleFactor); 1192 uint8_t srcG = static_cast<uint8_t>(src[1] * scaleFactor); 1193 uint8_t srcB = static_cast<uint8_t>(src[2] * scaleFactor); 1194 *dst = uint16_t(((srcR & 0xF8) << 8) | ((srcG & 0xF8) << 3) | 1195 ((srcB & 0xF8) >> 2) | (src[3] >> 7)); 1196 } 1197 1198 template <> 1199 MOZ_ALWAYS_INLINE void 1200 pack<WebGLTexelFormat::RGBA8, WebGLTexelPremultiplicationOp::None, uint8_t, 1201 uint8_t>(const uint8_t* __restrict src, uint8_t* __restrict dst) { 1202 dst[0] = src[0]; 1203 dst[1] = src[1]; 1204 dst[2] = src[2]; 1205 dst[3] = src[3]; 1206 } 1207 1208 template <> 1209 MOZ_ALWAYS_INLINE void 1210 pack<WebGLTexelFormat::RGBA8, WebGLTexelPremultiplicationOp::Premultiply, 1211 uint8_t, uint8_t>(const uint8_t* __restrict src, uint8_t* __restrict dst) { 1212 float scaleFactor = src[3] / 255.0f; 1213 uint8_t srcR = static_cast<uint8_t>(src[0] * scaleFactor); 1214 uint8_t srcG = static_cast<uint8_t>(src[1] * scaleFactor); 1215 uint8_t srcB = static_cast<uint8_t>(src[2] * scaleFactor); 1216 dst[0] = srcR; 1217 dst[1] = srcG; 1218 dst[2] = srcB; 1219 dst[3] = src[3]; 1220 } 1221 1222 // FIXME: this routine is lossy and must be removed. 1223 template <> 1224 MOZ_ALWAYS_INLINE void 1225 pack<WebGLTexelFormat::RGBA8, WebGLTexelPremultiplicationOp::Unpremultiply, 1226 uint8_t, uint8_t>(const uint8_t* __restrict src, uint8_t* __restrict dst) { 1227 float scaleFactor = src[3] ? 255.0f / src[3] : 1.0f; 1228 uint8_t srcR = static_cast<uint8_t>(src[0] * scaleFactor); 1229 uint8_t srcG = static_cast<uint8_t>(src[1] * scaleFactor); 1230 uint8_t srcB = static_cast<uint8_t>(src[2] * scaleFactor); 1231 dst[0] = srcR; 1232 dst[1] = srcG; 1233 dst[2] = srcB; 1234 dst[3] = src[3]; 1235 } 1236 1237 template <> 1238 MOZ_ALWAYS_INLINE void 1239 pack<WebGLTexelFormat::BGRA8, WebGLTexelPremultiplicationOp::None, uint8_t, 1240 uint8_t>(const uint8_t* __restrict src, uint8_t* __restrict dst) { 1241 dst[0] = src[2]; 1242 dst[1] = src[1]; 1243 dst[2] = src[0]; 1244 dst[3] = src[3]; 1245 } 1246 1247 template <> 1248 MOZ_ALWAYS_INLINE void 1249 pack<WebGLTexelFormat::BGRA8, WebGLTexelPremultiplicationOp::Premultiply, 1250 uint8_t, uint8_t>(const uint8_t* __restrict src, uint8_t* __restrict dst) { 1251 float scaleFactor = src[3] / 255.0f; 1252 uint8_t srcR = static_cast<uint8_t>(src[0] * scaleFactor); 1253 uint8_t srcG = static_cast<uint8_t>(src[1] * scaleFactor); 1254 uint8_t srcB = static_cast<uint8_t>(src[2] * scaleFactor); 1255 dst[0] = srcB; 1256 dst[1] = srcG; 1257 dst[2] = srcR; 1258 dst[3] = src[3]; 1259 } 1260 1261 // FIXME: this routine is lossy and must be removed. 1262 template <> 1263 MOZ_ALWAYS_INLINE void 1264 pack<WebGLTexelFormat::BGRA8, WebGLTexelPremultiplicationOp::Unpremultiply, 1265 uint8_t, uint8_t>(const uint8_t* __restrict src, uint8_t* __restrict dst) { 1266 float scaleFactor = src[3] ? 255.0f / src[3] : 1.0f; 1267 uint8_t srcR = static_cast<uint8_t>(src[0] * scaleFactor); 1268 uint8_t srcG = static_cast<uint8_t>(src[1] * scaleFactor); 1269 uint8_t srcB = static_cast<uint8_t>(src[2] * scaleFactor); 1270 dst[0] = srcB; 1271 dst[1] = srcG; 1272 dst[2] = srcR; 1273 dst[3] = src[3]; 1274 } 1275 1276 template <> 1277 MOZ_ALWAYS_INLINE void 1278 pack<WebGLTexelFormat::RGBA16F, WebGLTexelPremultiplicationOp::None, uint16_t, 1279 uint16_t>(const uint16_t* __restrict src, uint16_t* __restrict dst) { 1280 dst[0] = src[0]; 1281 dst[1] = src[1]; 1282 dst[2] = src[2]; 1283 dst[3] = src[3]; 1284 } 1285 1286 template <> 1287 MOZ_ALWAYS_INLINE void 1288 pack<WebGLTexelFormat::RGBA16F, WebGLTexelPremultiplicationOp::Premultiply, 1289 uint16_t, uint16_t>(const uint16_t* __restrict src, 1290 uint16_t* __restrict dst) { 1291 float scaleFactor = unpackFromFloat16(src[3]); 1292 dst[0] = packToFloat16(unpackFromFloat16(src[0]) * scaleFactor); 1293 dst[1] = packToFloat16(unpackFromFloat16(src[1]) * scaleFactor); 1294 dst[2] = packToFloat16(unpackFromFloat16(src[2]) * scaleFactor); 1295 dst[3] = src[3]; 1296 } 1297 1298 template <> 1299 MOZ_ALWAYS_INLINE void 1300 pack<WebGLTexelFormat::RGBA16F, WebGLTexelPremultiplicationOp::Unpremultiply, 1301 uint16_t, uint16_t>(const uint16_t* __restrict src, 1302 uint16_t* __restrict dst) { 1303 float unpackedAlpha = unpackFromFloat16(src[3]); 1304 float scaleFactor = unpackedAlpha ? 1.0f / unpackedAlpha : 1.0f; 1305 dst[0] = packToFloat16(unpackFromFloat16(src[0]) * scaleFactor); 1306 dst[1] = packToFloat16(unpackFromFloat16(src[1]) * scaleFactor); 1307 dst[2] = packToFloat16(unpackFromFloat16(src[2]) * scaleFactor); 1308 dst[3] = src[3]; 1309 } 1310 1311 template <> 1312 MOZ_ALWAYS_INLINE void pack<WebGLTexelFormat::RGBA32F, 1313 WebGLTexelPremultiplicationOp::None, float, float>( 1314 const float* __restrict src, float* __restrict dst) { 1315 dst[0] = src[0]; 1316 dst[1] = src[1]; 1317 dst[2] = src[2]; 1318 dst[3] = src[3]; 1319 } 1320 1321 template <> 1322 MOZ_ALWAYS_INLINE void 1323 pack<WebGLTexelFormat::RGBA32F, WebGLTexelPremultiplicationOp::Premultiply, 1324 float, float>(const float* __restrict src, float* __restrict dst) { 1325 float scaleFactor = src[3]; 1326 dst[0] = src[0] * scaleFactor; 1327 dst[1] = src[1] * scaleFactor; 1328 dst[2] = src[2] * scaleFactor; 1329 dst[3] = src[3]; 1330 } 1331 1332 template <> 1333 MOZ_ALWAYS_INLINE void 1334 pack<WebGLTexelFormat::RGBA32F, WebGLTexelPremultiplicationOp::Unpremultiply, 1335 float, float>(const float* __restrict src, float* __restrict dst) { 1336 float scaleFactor = src[3] ? 1.0f / src[3] : 1.0f; 1337 dst[0] = src[0] * scaleFactor; 1338 dst[1] = src[1] * scaleFactor; 1339 dst[2] = src[2] * scaleFactor; 1340 dst[3] = src[3]; 1341 } 1342 1343 /****** END CODE SHARED WITH WEBKIT ******/ 1344 1345 template <typename SrcType, typename DstType> 1346 MOZ_ALWAYS_INLINE void convertType(const SrcType* __restrict src, 1347 DstType* __restrict dst) { 1348 MOZ_ASSERT(false, "Unimplemented texture format conversion"); 1349 // Default construct dst values, ensuring they are *some* value. 1350 dst[0] = DstType(); 1351 dst[1] = DstType(); 1352 dst[2] = DstType(); 1353 dst[3] = DstType(); 1354 } 1355 1356 template <> 1357 MOZ_ALWAYS_INLINE void convertType<uint8_t, uint8_t>( 1358 const uint8_t* __restrict src, uint8_t* __restrict dst) { 1359 dst[0] = src[0]; 1360 dst[1] = src[1]; 1361 dst[2] = src[2]; 1362 dst[3] = src[3]; 1363 } 1364 1365 template <> 1366 MOZ_ALWAYS_INLINE void convertType<uint16_t, uint16_t>( 1367 const uint16_t* __restrict src, uint16_t* __restrict dst) { 1368 dst[0] = src[0]; 1369 dst[1] = src[1]; 1370 dst[2] = src[2]; 1371 dst[3] = src[3]; 1372 } 1373 1374 template <> 1375 MOZ_ALWAYS_INLINE void convertType<float, float>(const float* __restrict src, 1376 float* __restrict dst) { 1377 dst[0] = src[0]; 1378 dst[1] = src[1]; 1379 dst[2] = src[2]; 1380 dst[3] = src[3]; 1381 } 1382 1383 template <> 1384 MOZ_ALWAYS_INLINE void convertType<uint8_t, float>( 1385 const uint8_t* __restrict src, float* __restrict dst) { 1386 const float scaleFactor = 1.f / 255.0f; 1387 dst[0] = src[0] * scaleFactor; 1388 dst[1] = src[1] * scaleFactor; 1389 dst[2] = src[2] * scaleFactor; 1390 dst[3] = src[3] * scaleFactor; 1391 } 1392 1393 template <> 1394 MOZ_ALWAYS_INLINE void convertType<float, uint8_t>(const float* __restrict src, 1395 uint8_t* __restrict dst) { 1396 const float scaleFactor = 255.0f; 1397 dst[0] = uint8_t(src[0] * scaleFactor); 1398 dst[1] = uint8_t(src[1] * scaleFactor); 1399 dst[2] = uint8_t(src[2] * scaleFactor); 1400 dst[3] = uint8_t(src[3] * scaleFactor); 1401 } 1402 1403 template <> 1404 MOZ_ALWAYS_INLINE void convertType<uint16_t, float>( 1405 const uint16_t* __restrict src, float* __restrict dst) { 1406 dst[0] = unpackFromFloat16(src[0]); 1407 dst[1] = unpackFromFloat16(src[1]); 1408 dst[2] = unpackFromFloat16(src[2]); 1409 dst[3] = unpackFromFloat16(src[3]); 1410 } 1411 1412 template <> 1413 MOZ_ALWAYS_INLINE void convertType<float, uint16_t>(const float* __restrict src, 1414 uint16_t* __restrict dst) { 1415 dst[0] = packToFloat16(src[0]); 1416 dst[1] = packToFloat16(src[1]); 1417 dst[2] = packToFloat16(src[2]); 1418 dst[3] = packToFloat16(src[3]); 1419 } 1420 1421 template <> 1422 MOZ_ALWAYS_INLINE void convertType<uint8_t, uint16_t>( 1423 const uint8_t* __restrict src, uint16_t* __restrict dst) { 1424 const float scaleFactor = 1.f / 255.0f; 1425 dst[0] = packToFloat16(src[0] * scaleFactor); 1426 dst[1] = packToFloat16(src[1] * scaleFactor); 1427 dst[2] = packToFloat16(src[2] * scaleFactor); 1428 dst[3] = packToFloat16(src[3] * scaleFactor); 1429 } 1430 1431 } // end namespace WebGLTexelConversions 1432 1433 } // end namespace mozilla 1434 1435 #endif // WEBGLTEXELCONVERSIONS_H_