LCOV - code coverage report
Current view: top level - dom/canvas - WebGLTexelConversions.h (source / functions) Hit Total Coverage
Test: output.info Lines: 0 686 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 98 0.0 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.13