tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

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_