Thu, 15 Jan 2015 21:03:48 +0100
Integrate friendly tips from Tor colleagues to make (or not) 4.5 alpha 3;
This includes removal of overloaded (but unused) methods, and addition of
a overlooked call to DataStruct::SetData(nsISupports, uint32_t, bool.)
michael@0 | 1 | /* |
michael@0 | 2 | * Copyright (C) 2010 Apple Inc. All rights reserved. |
michael@0 | 3 | * Copyright (C) 2010 Google Inc. All rights reserved. |
michael@0 | 4 | * Copyright (C) 2010 Mozilla Corporation. All rights reserved. |
michael@0 | 5 | * |
michael@0 | 6 | * Redistribution and use in source and binary forms, with or without |
michael@0 | 7 | * modification, are permitted provided that the following conditions |
michael@0 | 8 | * are met: |
michael@0 | 9 | * 1. Redistributions of source code must retain the above copyright |
michael@0 | 10 | * notice, this list of conditions and the following disclaimer. |
michael@0 | 11 | * 2. Redistributions in binary form must reproduce the above copyright |
michael@0 | 12 | * notice, this list of conditions and the following disclaimer in the |
michael@0 | 13 | * documentation and/or other materials provided with the distribution. |
michael@0 | 14 | * |
michael@0 | 15 | * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY |
michael@0 | 16 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
michael@0 | 17 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
michael@0 | 18 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR |
michael@0 | 19 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
michael@0 | 20 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
michael@0 | 21 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
michael@0 | 22 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY |
michael@0 | 23 | * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
michael@0 | 24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
michael@0 | 25 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
michael@0 | 26 | */ |
michael@0 | 27 | |
michael@0 | 28 | #ifndef WEBGLTEXELCONVERSIONS_H_ |
michael@0 | 29 | #define WEBGLTEXELCONVERSIONS_H_ |
michael@0 | 30 | |
michael@0 | 31 | #ifdef __SUNPRO_CC |
michael@0 | 32 | #define __restrict |
michael@0 | 33 | #endif |
michael@0 | 34 | |
michael@0 | 35 | #include "WebGLTypes.h" |
michael@0 | 36 | #include <stdint.h> |
michael@0 | 37 | #include "mozilla/Attributes.h" |
michael@0 | 38 | |
michael@0 | 39 | namespace mozilla { |
michael@0 | 40 | |
michael@0 | 41 | // single precision float |
michael@0 | 42 | // seeeeeeeemmmmmmmmmmmmmmmmmmmmmmm |
michael@0 | 43 | |
michael@0 | 44 | // half precision float |
michael@0 | 45 | // seeeeemmmmmmmmmm |
michael@0 | 46 | |
michael@0 | 47 | // IEEE 16bits floating point: |
michael@0 | 48 | const uint16_t kFloat16Value_Zero = 0x0000; // = 0000000000000000b |
michael@0 | 49 | const uint16_t kFloat16Value_One = 0x3C00; // = 0011110000000000b |
michael@0 | 50 | const uint16_t kFloat16Value_Infinity = 0x7C00; // = 0111110000000000b |
michael@0 | 51 | const uint16_t kFloat16Value_NaN = 0x7FFF; // = 011111yyyyyyyyyyb (nonzero y) |
michael@0 | 52 | |
michael@0 | 53 | MOZ_ALWAYS_INLINE uint16_t |
michael@0 | 54 | packToFloat16(float v) |
michael@0 | 55 | { |
michael@0 | 56 | union { |
michael@0 | 57 | float f32Value; |
michael@0 | 58 | uint32_t f32Bits; |
michael@0 | 59 | }; |
michael@0 | 60 | |
michael@0 | 61 | f32Value = v; |
michael@0 | 62 | |
michael@0 | 63 | // pull the sign from v into f16bits |
michael@0 | 64 | uint16_t f16Bits = uint16_t(f32Bits >> 16) & 0x8000; |
michael@0 | 65 | |
michael@0 | 66 | // handle +/- 0 |
michael@0 | 67 | if ((f32Bits & 0x7FFFFFFF) == 0x00000000) { |
michael@0 | 68 | return f16Bits; |
michael@0 | 69 | } |
michael@0 | 70 | |
michael@0 | 71 | // handle NaN |
michael@0 | 72 | if (f32Value != f32Value) { |
michael@0 | 73 | return f16Bits | kFloat16Value_NaN; |
michael@0 | 74 | } |
michael@0 | 75 | |
michael@0 | 76 | int32_t exp = int32_t(f32Bits >> 23) - 127; |
michael@0 | 77 | |
michael@0 | 78 | // too small, we clamp it to -0 or +0 |
michael@0 | 79 | if (exp < -14) { |
michael@0 | 80 | return f16Bits; |
michael@0 | 81 | } |
michael@0 | 82 | |
michael@0 | 83 | // too big, we clamp it to -inf/+inf |
michael@0 | 84 | if (exp > 15) { |
michael@0 | 85 | return f16Bits | kFloat16Value_Infinity; |
michael@0 | 86 | } |
michael@0 | 87 | |
michael@0 | 88 | f16Bits |= uint16_t(exp + 15) << 10; |
michael@0 | 89 | f16Bits |= uint16_t(f32Bits >> 13) & 0x03FF; |
michael@0 | 90 | |
michael@0 | 91 | return f16Bits; |
michael@0 | 92 | } |
michael@0 | 93 | |
michael@0 | 94 | MOZ_ALWAYS_INLINE float |
michael@0 | 95 | unpackFromFloat16(uint16_t v) |
michael@0 | 96 | { |
michael@0 | 97 | union |
michael@0 | 98 | { |
michael@0 | 99 | float f32Value; |
michael@0 | 100 | uint32_t f32Bits; |
michael@0 | 101 | }; |
michael@0 | 102 | |
michael@0 | 103 | // grab sign bit |
michael@0 | 104 | f32Bits = uint32_t(v & 0x8000) << 16; |
michael@0 | 105 | |
michael@0 | 106 | if ((v & 0x7FFF) == 0x0000) { |
michael@0 | 107 | // +0 or -0 |
michael@0 | 108 | return f32Value; |
michael@0 | 109 | } |
michael@0 | 110 | |
michael@0 | 111 | uint16_t exp = (v >> 10) & 0x001F; |
michael@0 | 112 | if (exp == 0x001F) { |
michael@0 | 113 | if (v & 0x03FF) { |
michael@0 | 114 | // this is a NaN |
michael@0 | 115 | f32Bits |= 0x7FFFFFFF; |
michael@0 | 116 | } else { |
michael@0 | 117 | // this is -inf or +inf |
michael@0 | 118 | f32Bits |= 0x7F800000; |
michael@0 | 119 | } |
michael@0 | 120 | return f32Value; |
michael@0 | 121 | } |
michael@0 | 122 | |
michael@0 | 123 | f32Bits |= uint32_t(exp + (-15 + 127)) << 10; |
michael@0 | 124 | f32Bits |= uint32_t(v & 0x03FF) << 13; |
michael@0 | 125 | |
michael@0 | 126 | return f32Value; |
michael@0 | 127 | } |
michael@0 | 128 | |
michael@0 | 129 | MOZ_BEGIN_ENUM_CLASS(WebGLTexelPremultiplicationOp, int) |
michael@0 | 130 | None, |
michael@0 | 131 | Premultiply, |
michael@0 | 132 | Unpremultiply |
michael@0 | 133 | MOZ_END_ENUM_CLASS(WebGLTexelPremultiplicationOp) |
michael@0 | 134 | |
michael@0 | 135 | namespace WebGLTexelConversions { |
michael@0 | 136 | |
michael@0 | 137 | template<MOZ_ENUM_CLASS_ENUM_TYPE(WebGLTexelFormat) Format> |
michael@0 | 138 | struct IsFloatFormat |
michael@0 | 139 | { |
michael@0 | 140 | static const bool Value = |
michael@0 | 141 | Format == WebGLTexelFormat::RGBA32F || |
michael@0 | 142 | Format == WebGLTexelFormat::RGB32F || |
michael@0 | 143 | Format == WebGLTexelFormat::RA32F || |
michael@0 | 144 | Format == WebGLTexelFormat::R32F || |
michael@0 | 145 | Format == WebGLTexelFormat::A32F; |
michael@0 | 146 | }; |
michael@0 | 147 | |
michael@0 | 148 | template<MOZ_ENUM_CLASS_ENUM_TYPE(WebGLTexelFormat) Format> |
michael@0 | 149 | struct IsHalfFloatFormat |
michael@0 | 150 | { |
michael@0 | 151 | static const bool Value = |
michael@0 | 152 | Format == WebGLTexelFormat::RGBA16F || |
michael@0 | 153 | Format == WebGLTexelFormat::RGB16F || |
michael@0 | 154 | Format == WebGLTexelFormat::RA16F || |
michael@0 | 155 | Format == WebGLTexelFormat::R16F || |
michael@0 | 156 | Format == WebGLTexelFormat::A16F; |
michael@0 | 157 | }; |
michael@0 | 158 | |
michael@0 | 159 | template<MOZ_ENUM_CLASS_ENUM_TYPE(WebGLTexelFormat) Format> |
michael@0 | 160 | struct Is16bppFormat |
michael@0 | 161 | { |
michael@0 | 162 | static const bool Value = |
michael@0 | 163 | Format == WebGLTexelFormat::RGBA4444 || |
michael@0 | 164 | Format == WebGLTexelFormat::RGBA5551 || |
michael@0 | 165 | Format == WebGLTexelFormat::RGB565; |
michael@0 | 166 | }; |
michael@0 | 167 | |
michael@0 | 168 | template<MOZ_ENUM_CLASS_ENUM_TYPE(WebGLTexelFormat) Format, |
michael@0 | 169 | bool IsFloat = IsFloatFormat<Format>::Value, |
michael@0 | 170 | bool Is16bpp = Is16bppFormat<Format>::Value, |
michael@0 | 171 | bool IsHalfFloat = IsHalfFloatFormat<Format>::Value> |
michael@0 | 172 | struct DataTypeForFormat |
michael@0 | 173 | { |
michael@0 | 174 | typedef uint8_t Type; |
michael@0 | 175 | }; |
michael@0 | 176 | |
michael@0 | 177 | template<MOZ_ENUM_CLASS_ENUM_TYPE(WebGLTexelFormat) Format> |
michael@0 | 178 | struct DataTypeForFormat<Format, true, false, false> |
michael@0 | 179 | { |
michael@0 | 180 | typedef float Type; |
michael@0 | 181 | }; |
michael@0 | 182 | |
michael@0 | 183 | template<MOZ_ENUM_CLASS_ENUM_TYPE(WebGLTexelFormat) Format> |
michael@0 | 184 | struct DataTypeForFormat<Format, false, true, false> |
michael@0 | 185 | { |
michael@0 | 186 | typedef uint16_t Type; |
michael@0 | 187 | }; |
michael@0 | 188 | |
michael@0 | 189 | template<MOZ_ENUM_CLASS_ENUM_TYPE(WebGLTexelFormat) Format> |
michael@0 | 190 | struct DataTypeForFormat<Format, false, false, true> |
michael@0 | 191 | { |
michael@0 | 192 | typedef uint16_t Type; |
michael@0 | 193 | }; |
michael@0 | 194 | |
michael@0 | 195 | template<MOZ_ENUM_CLASS_ENUM_TYPE(WebGLTexelFormat) Format> |
michael@0 | 196 | struct IntermediateFormat |
michael@0 | 197 | { |
michael@0 | 198 | static const MOZ_ENUM_CLASS_ENUM_TYPE(WebGLTexelFormat) Value |
michael@0 | 199 | = IsFloatFormat<Format>::Value |
michael@0 | 200 | ? WebGLTexelFormat::RGBA32F |
michael@0 | 201 | : IsHalfFloatFormat<Format>::Value ? WebGLTexelFormat::RGBA16F |
michael@0 | 202 | : WebGLTexelFormat::RGBA8; |
michael@0 | 203 | }; |
michael@0 | 204 | |
michael@0 | 205 | inline GLenum |
michael@0 | 206 | GLFormatForTexelFormat(WebGLTexelFormat format) { |
michael@0 | 207 | switch (format) { |
michael@0 | 208 | case WebGLTexelFormat::R8: return LOCAL_GL_LUMINANCE; |
michael@0 | 209 | case WebGLTexelFormat::A8: return LOCAL_GL_ALPHA; |
michael@0 | 210 | case WebGLTexelFormat::RA8: return LOCAL_GL_LUMINANCE_ALPHA; |
michael@0 | 211 | case WebGLTexelFormat::RGBA5551: return LOCAL_GL_RGBA; |
michael@0 | 212 | case WebGLTexelFormat::RGBA4444: return LOCAL_GL_RGBA; |
michael@0 | 213 | case WebGLTexelFormat::RGB565: return LOCAL_GL_RGB; |
michael@0 | 214 | case WebGLTexelFormat::D16: return LOCAL_GL_DEPTH_COMPONENT; |
michael@0 | 215 | case WebGLTexelFormat::RGB8: return LOCAL_GL_RGB; |
michael@0 | 216 | case WebGLTexelFormat::RGBA8: return LOCAL_GL_RGBA; |
michael@0 | 217 | case WebGLTexelFormat::BGRA8: return LOCAL_GL_BGRA; |
michael@0 | 218 | case WebGLTexelFormat::BGRX8: return LOCAL_GL_BGR; |
michael@0 | 219 | case WebGLTexelFormat::R32F: return LOCAL_GL_LUMINANCE; |
michael@0 | 220 | case WebGLTexelFormat::A32F: return LOCAL_GL_ALPHA; |
michael@0 | 221 | case WebGLTexelFormat::D32: return LOCAL_GL_DEPTH_COMPONENT; |
michael@0 | 222 | case WebGLTexelFormat::D24S8: return LOCAL_GL_DEPTH_STENCIL; |
michael@0 | 223 | case WebGLTexelFormat::RA32F: return LOCAL_GL_LUMINANCE_ALPHA; |
michael@0 | 224 | case WebGLTexelFormat::RGB32F: return LOCAL_GL_RGB; |
michael@0 | 225 | case WebGLTexelFormat::RGBA32F: return LOCAL_GL_RGBA; |
michael@0 | 226 | case WebGLTexelFormat::R16F: return LOCAL_GL_LUMINANCE; |
michael@0 | 227 | case WebGLTexelFormat::A16F: return LOCAL_GL_ALPHA; |
michael@0 | 228 | case WebGLTexelFormat::RA16F: return LOCAL_GL_LUMINANCE_ALPHA; |
michael@0 | 229 | case WebGLTexelFormat::RGB16F: return LOCAL_GL_RGB; |
michael@0 | 230 | case WebGLTexelFormat::RGBA16F: return LOCAL_GL_RGBA; |
michael@0 | 231 | default: |
michael@0 | 232 | MOZ_CRASH("Unknown texel format. Coding mistake?"); |
michael@0 | 233 | return LOCAL_GL_INVALID_ENUM; |
michael@0 | 234 | } |
michael@0 | 235 | } |
michael@0 | 236 | |
michael@0 | 237 | inline size_t TexelBytesForFormat(WebGLTexelFormat format) { |
michael@0 | 238 | switch (format) { |
michael@0 | 239 | case WebGLTexelFormat::R8: |
michael@0 | 240 | case WebGLTexelFormat::A8: |
michael@0 | 241 | return 1; |
michael@0 | 242 | case WebGLTexelFormat::RA8: |
michael@0 | 243 | case WebGLTexelFormat::RGBA5551: |
michael@0 | 244 | case WebGLTexelFormat::RGBA4444: |
michael@0 | 245 | case WebGLTexelFormat::RGB565: |
michael@0 | 246 | case WebGLTexelFormat::R16F: |
michael@0 | 247 | case WebGLTexelFormat::A16F: |
michael@0 | 248 | case WebGLTexelFormat::D16: |
michael@0 | 249 | return 2; |
michael@0 | 250 | case WebGLTexelFormat::RGB8: |
michael@0 | 251 | return 3; |
michael@0 | 252 | case WebGLTexelFormat::RGBA8: |
michael@0 | 253 | case WebGLTexelFormat::BGRA8: |
michael@0 | 254 | case WebGLTexelFormat::BGRX8: |
michael@0 | 255 | case WebGLTexelFormat::R32F: |
michael@0 | 256 | case WebGLTexelFormat::A32F: |
michael@0 | 257 | case WebGLTexelFormat::D32: |
michael@0 | 258 | case WebGLTexelFormat::D24S8: |
michael@0 | 259 | case WebGLTexelFormat::RA16F: |
michael@0 | 260 | return 4; |
michael@0 | 261 | case WebGLTexelFormat::RGB16F: |
michael@0 | 262 | return 6; |
michael@0 | 263 | case WebGLTexelFormat::RGBA16F: |
michael@0 | 264 | case WebGLTexelFormat::RA32F: |
michael@0 | 265 | return 8; |
michael@0 | 266 | case WebGLTexelFormat::RGB32F: |
michael@0 | 267 | return 12; |
michael@0 | 268 | case WebGLTexelFormat::RGBA32F: |
michael@0 | 269 | return 16; |
michael@0 | 270 | default: |
michael@0 | 271 | MOZ_ASSERT(false, "Unknown texel format. Coding mistake?"); |
michael@0 | 272 | return 0; |
michael@0 | 273 | } |
michael@0 | 274 | } |
michael@0 | 275 | |
michael@0 | 276 | MOZ_ALWAYS_INLINE bool HasAlpha(WebGLTexelFormat format) { |
michael@0 | 277 | return format == WebGLTexelFormat::A8 || |
michael@0 | 278 | format == WebGLTexelFormat::A16F || |
michael@0 | 279 | format == WebGLTexelFormat::A32F || |
michael@0 | 280 | format == WebGLTexelFormat::RA8 || |
michael@0 | 281 | format == WebGLTexelFormat::RA16F || |
michael@0 | 282 | format == WebGLTexelFormat::RA32F || |
michael@0 | 283 | format == WebGLTexelFormat::RGBA8 || |
michael@0 | 284 | format == WebGLTexelFormat::BGRA8 || |
michael@0 | 285 | format == WebGLTexelFormat::RGBA16F || |
michael@0 | 286 | format == WebGLTexelFormat::RGBA32F || |
michael@0 | 287 | format == WebGLTexelFormat::RGBA4444 || |
michael@0 | 288 | format == WebGLTexelFormat::RGBA5551; |
michael@0 | 289 | } |
michael@0 | 290 | |
michael@0 | 291 | MOZ_ALWAYS_INLINE bool HasColor(WebGLTexelFormat format) { |
michael@0 | 292 | return format == WebGLTexelFormat::R8 || |
michael@0 | 293 | format == WebGLTexelFormat::R16F || |
michael@0 | 294 | format == WebGLTexelFormat::R32F || |
michael@0 | 295 | format == WebGLTexelFormat::RA8 || |
michael@0 | 296 | format == WebGLTexelFormat::RA16F || |
michael@0 | 297 | format == WebGLTexelFormat::RA32F || |
michael@0 | 298 | format == WebGLTexelFormat::RGB8 || |
michael@0 | 299 | format == WebGLTexelFormat::BGRX8 || |
michael@0 | 300 | format == WebGLTexelFormat::RGB565 || |
michael@0 | 301 | format == WebGLTexelFormat::RGB16F || |
michael@0 | 302 | format == WebGLTexelFormat::RGB32F || |
michael@0 | 303 | format == WebGLTexelFormat::RGBA8 || |
michael@0 | 304 | format == WebGLTexelFormat::BGRA8 || |
michael@0 | 305 | format == WebGLTexelFormat::RGBA16F || |
michael@0 | 306 | format == WebGLTexelFormat::RGBA32F || |
michael@0 | 307 | format == WebGLTexelFormat::RGBA4444 || |
michael@0 | 308 | format == WebGLTexelFormat::RGBA5551; |
michael@0 | 309 | } |
michael@0 | 310 | |
michael@0 | 311 | |
michael@0 | 312 | /****** BEGIN CODE SHARED WITH WEBKIT ******/ |
michael@0 | 313 | |
michael@0 | 314 | // the pack/unpack functions here are originally from this file: |
michael@0 | 315 | // http://trac.webkit.org/browser/trunk/WebCore/platform/graphics/GraphicsContext3D.cpp |
michael@0 | 316 | |
michael@0 | 317 | //---------------------------------------------------------------------- |
michael@0 | 318 | // Pixel unpacking routines. |
michael@0 | 319 | |
michael@0 | 320 | template<MOZ_ENUM_CLASS_ENUM_TYPE(WebGLTexelFormat) Format, typename SrcType, typename DstType> |
michael@0 | 321 | MOZ_ALWAYS_INLINE void |
michael@0 | 322 | unpack(const SrcType* __restrict src, |
michael@0 | 323 | DstType* __restrict dst) |
michael@0 | 324 | { |
michael@0 | 325 | MOZ_ASSERT(false, "Unimplemented texture format conversion"); |
michael@0 | 326 | } |
michael@0 | 327 | |
michael@0 | 328 | template<> MOZ_ALWAYS_INLINE void |
michael@0 | 329 | unpack<WebGLTexelFormat::RGBA8, uint8_t, uint8_t>(const uint8_t* __restrict src, uint8_t* __restrict dst) |
michael@0 | 330 | { |
michael@0 | 331 | dst[0] = src[0]; |
michael@0 | 332 | dst[1] = src[1]; |
michael@0 | 333 | dst[2] = src[2]; |
michael@0 | 334 | dst[3] = src[3]; |
michael@0 | 335 | } |
michael@0 | 336 | |
michael@0 | 337 | template<> MOZ_ALWAYS_INLINE void |
michael@0 | 338 | unpack<WebGLTexelFormat::RGB8, uint8_t, uint8_t>(const uint8_t* __restrict src, uint8_t* __restrict dst) |
michael@0 | 339 | { |
michael@0 | 340 | dst[0] = src[0]; |
michael@0 | 341 | dst[1] = src[1]; |
michael@0 | 342 | dst[2] = src[2]; |
michael@0 | 343 | dst[3] = 0xFF; |
michael@0 | 344 | } |
michael@0 | 345 | |
michael@0 | 346 | template<> MOZ_ALWAYS_INLINE void |
michael@0 | 347 | unpack<WebGLTexelFormat::BGRA8, uint8_t, uint8_t>(const uint8_t* __restrict src, uint8_t* __restrict dst) |
michael@0 | 348 | { |
michael@0 | 349 | dst[0] = src[2]; |
michael@0 | 350 | dst[1] = src[1]; |
michael@0 | 351 | dst[2] = src[0]; |
michael@0 | 352 | dst[3] = src[3]; |
michael@0 | 353 | } |
michael@0 | 354 | |
michael@0 | 355 | template<> MOZ_ALWAYS_INLINE void |
michael@0 | 356 | unpack<WebGLTexelFormat::BGRX8, uint8_t, uint8_t>(const uint8_t* __restrict src, uint8_t* __restrict dst) |
michael@0 | 357 | { |
michael@0 | 358 | dst[0] = src[2]; |
michael@0 | 359 | dst[1] = src[1]; |
michael@0 | 360 | dst[2] = src[0]; |
michael@0 | 361 | dst[3] = 0xFF; |
michael@0 | 362 | } |
michael@0 | 363 | |
michael@0 | 364 | template<> MOZ_ALWAYS_INLINE void |
michael@0 | 365 | unpack<WebGLTexelFormat::RGBA5551, uint16_t, uint8_t>(const uint16_t* __restrict src, uint8_t* __restrict dst) |
michael@0 | 366 | { |
michael@0 | 367 | uint16_t packedValue = src[0]; |
michael@0 | 368 | uint8_t r = (packedValue >> 11) & 0x1F; |
michael@0 | 369 | uint8_t g = (packedValue >> 6) & 0x1F; |
michael@0 | 370 | uint8_t b = (packedValue >> 1) & 0x1F; |
michael@0 | 371 | dst[0] = (r << 3) | (r & 0x7); |
michael@0 | 372 | dst[1] = (g << 3) | (g & 0x7); |
michael@0 | 373 | dst[2] = (b << 3) | (b & 0x7); |
michael@0 | 374 | dst[3] = (packedValue & 0x1) ? 0xFF : 0; |
michael@0 | 375 | } |
michael@0 | 376 | |
michael@0 | 377 | template<> MOZ_ALWAYS_INLINE void |
michael@0 | 378 | unpack<WebGLTexelFormat::RGBA4444, uint16_t, uint8_t>(const uint16_t* __restrict src, uint8_t* __restrict dst) |
michael@0 | 379 | { |
michael@0 | 380 | uint16_t packedValue = src[0]; |
michael@0 | 381 | uint8_t r = (packedValue >> 12) & 0x0F; |
michael@0 | 382 | uint8_t g = (packedValue >> 8) & 0x0F; |
michael@0 | 383 | uint8_t b = (packedValue >> 4) & 0x0F; |
michael@0 | 384 | uint8_t a = packedValue & 0x0F; |
michael@0 | 385 | dst[0] = (r << 4) | r; |
michael@0 | 386 | dst[1] = (g << 4) | g; |
michael@0 | 387 | dst[2] = (b << 4) | b; |
michael@0 | 388 | dst[3] = (a << 4) | a; |
michael@0 | 389 | } |
michael@0 | 390 | |
michael@0 | 391 | template<> MOZ_ALWAYS_INLINE void |
michael@0 | 392 | unpack<WebGLTexelFormat::RGB565, uint16_t, uint8_t>(const uint16_t* __restrict src, uint8_t* __restrict dst) |
michael@0 | 393 | { |
michael@0 | 394 | uint16_t packedValue = src[0]; |
michael@0 | 395 | uint8_t r = (packedValue >> 11) & 0x1F; |
michael@0 | 396 | uint8_t g = (packedValue >> 5) & 0x3F; |
michael@0 | 397 | uint8_t b = packedValue & 0x1F; |
michael@0 | 398 | dst[0] = (r << 3) | (r & 0x7); |
michael@0 | 399 | dst[1] = (g << 2) | (g & 0x3); |
michael@0 | 400 | dst[2] = (b << 3) | (b & 0x7); |
michael@0 | 401 | dst[3] = 0xFF; |
michael@0 | 402 | } |
michael@0 | 403 | |
michael@0 | 404 | template<> MOZ_ALWAYS_INLINE void |
michael@0 | 405 | unpack<WebGLTexelFormat::R8, uint8_t, uint8_t>(const uint8_t* __restrict src, uint8_t* __restrict dst) |
michael@0 | 406 | { |
michael@0 | 407 | dst[0] = src[0]; |
michael@0 | 408 | dst[1] = src[0]; |
michael@0 | 409 | dst[2] = src[0]; |
michael@0 | 410 | dst[3] = 0xFF; |
michael@0 | 411 | } |
michael@0 | 412 | |
michael@0 | 413 | template<> MOZ_ALWAYS_INLINE void |
michael@0 | 414 | unpack<WebGLTexelFormat::RA8, uint8_t, uint8_t>(const uint8_t* __restrict src, uint8_t* __restrict dst) |
michael@0 | 415 | { |
michael@0 | 416 | dst[0] = src[0]; |
michael@0 | 417 | dst[1] = src[0]; |
michael@0 | 418 | dst[2] = src[0]; |
michael@0 | 419 | dst[3] = src[1]; |
michael@0 | 420 | } |
michael@0 | 421 | |
michael@0 | 422 | template<> MOZ_ALWAYS_INLINE void |
michael@0 | 423 | unpack<WebGLTexelFormat::A8, uint8_t, uint8_t>(const uint8_t* __restrict src, uint8_t* __restrict dst) |
michael@0 | 424 | { |
michael@0 | 425 | dst[0] = 0; |
michael@0 | 426 | dst[1] = 0; |
michael@0 | 427 | dst[2] = 0; |
michael@0 | 428 | dst[3] = src[0]; |
michael@0 | 429 | } |
michael@0 | 430 | |
michael@0 | 431 | template<> MOZ_ALWAYS_INLINE void |
michael@0 | 432 | unpack<WebGLTexelFormat::RGBA32F, float, float>(const float* __restrict src, float* __restrict dst) |
michael@0 | 433 | { |
michael@0 | 434 | dst[0] = src[0]; |
michael@0 | 435 | dst[1] = src[1]; |
michael@0 | 436 | dst[2] = src[2]; |
michael@0 | 437 | dst[3] = src[3]; |
michael@0 | 438 | } |
michael@0 | 439 | |
michael@0 | 440 | template<> MOZ_ALWAYS_INLINE void |
michael@0 | 441 | unpack<WebGLTexelFormat::RGB32F, float, float>(const float* __restrict src, float* __restrict dst) |
michael@0 | 442 | { |
michael@0 | 443 | dst[0] = src[0]; |
michael@0 | 444 | dst[1] = src[1]; |
michael@0 | 445 | dst[2] = src[2]; |
michael@0 | 446 | dst[3] = 1.0f; |
michael@0 | 447 | } |
michael@0 | 448 | |
michael@0 | 449 | template<> MOZ_ALWAYS_INLINE void |
michael@0 | 450 | unpack<WebGLTexelFormat::R32F, float, float>(const float* __restrict src, float* __restrict dst) |
michael@0 | 451 | { |
michael@0 | 452 | dst[0] = src[0]; |
michael@0 | 453 | dst[1] = src[0]; |
michael@0 | 454 | dst[2] = src[0]; |
michael@0 | 455 | dst[3] = 1.0f; |
michael@0 | 456 | } |
michael@0 | 457 | |
michael@0 | 458 | template<> MOZ_ALWAYS_INLINE void |
michael@0 | 459 | unpack<WebGLTexelFormat::RA32F, float, float>(const float* __restrict src, float* __restrict dst) |
michael@0 | 460 | { |
michael@0 | 461 | dst[0] = src[0]; |
michael@0 | 462 | dst[1] = src[0]; |
michael@0 | 463 | dst[2] = src[0]; |
michael@0 | 464 | dst[3] = src[1]; |
michael@0 | 465 | } |
michael@0 | 466 | |
michael@0 | 467 | template<> MOZ_ALWAYS_INLINE void |
michael@0 | 468 | unpack<WebGLTexelFormat::A32F, float, float>(const float* __restrict src, float* __restrict dst) |
michael@0 | 469 | { |
michael@0 | 470 | dst[0] = 0; |
michael@0 | 471 | dst[1] = 0; |
michael@0 | 472 | dst[2] = 0; |
michael@0 | 473 | dst[3] = src[0]; |
michael@0 | 474 | } |
michael@0 | 475 | |
michael@0 | 476 | template<> MOZ_ALWAYS_INLINE void |
michael@0 | 477 | unpack<WebGLTexelFormat::RGBA16F, uint16_t, uint16_t>(const uint16_t* __restrict src, uint16_t* __restrict dst) |
michael@0 | 478 | { |
michael@0 | 479 | dst[0] = src[0]; |
michael@0 | 480 | dst[1] = src[1]; |
michael@0 | 481 | dst[2] = src[2]; |
michael@0 | 482 | dst[3] = src[3]; |
michael@0 | 483 | } |
michael@0 | 484 | |
michael@0 | 485 | template<> MOZ_ALWAYS_INLINE void |
michael@0 | 486 | unpack<WebGLTexelFormat::RGB16F, uint16_t, uint16_t>(const uint16_t* __restrict src, uint16_t* __restrict dst) |
michael@0 | 487 | { |
michael@0 | 488 | dst[0] = src[0]; |
michael@0 | 489 | dst[1] = src[1]; |
michael@0 | 490 | dst[2] = src[2]; |
michael@0 | 491 | dst[3] = kFloat16Value_One; |
michael@0 | 492 | } |
michael@0 | 493 | |
michael@0 | 494 | template<> MOZ_ALWAYS_INLINE void |
michael@0 | 495 | unpack<WebGLTexelFormat::R16F, uint16_t, uint16_t>(const uint16_t* __restrict src, uint16_t* __restrict dst) |
michael@0 | 496 | { |
michael@0 | 497 | dst[0] = src[0]; |
michael@0 | 498 | dst[1] = src[0]; |
michael@0 | 499 | dst[2] = src[0]; |
michael@0 | 500 | dst[3] = kFloat16Value_One; |
michael@0 | 501 | } |
michael@0 | 502 | |
michael@0 | 503 | template<> MOZ_ALWAYS_INLINE void |
michael@0 | 504 | unpack<WebGLTexelFormat::RA16F, uint16_t, uint16_t>(const uint16_t* __restrict src, uint16_t* __restrict dst) |
michael@0 | 505 | { |
michael@0 | 506 | dst[0] = src[0]; |
michael@0 | 507 | dst[1] = src[0]; |
michael@0 | 508 | dst[2] = src[0]; |
michael@0 | 509 | dst[3] = src[1]; |
michael@0 | 510 | } |
michael@0 | 511 | |
michael@0 | 512 | template<> MOZ_ALWAYS_INLINE void |
michael@0 | 513 | unpack<WebGLTexelFormat::A16F, uint16_t, uint16_t>(const uint16_t* __restrict src, uint16_t* __restrict dst) |
michael@0 | 514 | { |
michael@0 | 515 | dst[0] = kFloat16Value_Zero; |
michael@0 | 516 | dst[1] = kFloat16Value_Zero; |
michael@0 | 517 | dst[2] = kFloat16Value_Zero; |
michael@0 | 518 | dst[3] = src[0]; |
michael@0 | 519 | } |
michael@0 | 520 | |
michael@0 | 521 | //---------------------------------------------------------------------- |
michael@0 | 522 | // Pixel packing routines. |
michael@0 | 523 | // |
michael@0 | 524 | |
michael@0 | 525 | template<MOZ_ENUM_CLASS_ENUM_TYPE(WebGLTexelFormat) Format, |
michael@0 | 526 | MOZ_ENUM_CLASS_ENUM_TYPE(WebGLTexelPremultiplicationOp) PremultiplicationOp, |
michael@0 | 527 | typename SrcType, |
michael@0 | 528 | typename DstType> |
michael@0 | 529 | MOZ_ALWAYS_INLINE void |
michael@0 | 530 | pack(const SrcType* __restrict src, |
michael@0 | 531 | DstType* __restrict dst) |
michael@0 | 532 | { |
michael@0 | 533 | MOZ_ASSERT(false, "Unimplemented texture format conversion"); |
michael@0 | 534 | } |
michael@0 | 535 | |
michael@0 | 536 | template<> MOZ_ALWAYS_INLINE void |
michael@0 | 537 | pack<WebGLTexelFormat::A8, WebGLTexelPremultiplicationOp::None, uint8_t, uint8_t>(const uint8_t* __restrict src, uint8_t* __restrict dst) |
michael@0 | 538 | { |
michael@0 | 539 | dst[0] = src[3]; |
michael@0 | 540 | } |
michael@0 | 541 | |
michael@0 | 542 | template<> MOZ_ALWAYS_INLINE void |
michael@0 | 543 | pack<WebGLTexelFormat::A8, WebGLTexelPremultiplicationOp::Premultiply, uint8_t, uint8_t>(const uint8_t* __restrict src, uint8_t* __restrict dst) |
michael@0 | 544 | { |
michael@0 | 545 | dst[0] = src[3]; |
michael@0 | 546 | } |
michael@0 | 547 | |
michael@0 | 548 | template<> MOZ_ALWAYS_INLINE void |
michael@0 | 549 | pack<WebGLTexelFormat::A8, WebGLTexelPremultiplicationOp::Unpremultiply, uint8_t, uint8_t>(const uint8_t* __restrict src, uint8_t* __restrict dst) |
michael@0 | 550 | { |
michael@0 | 551 | dst[0] = src[3]; |
michael@0 | 552 | } |
michael@0 | 553 | |
michael@0 | 554 | template<> MOZ_ALWAYS_INLINE void |
michael@0 | 555 | pack<WebGLTexelFormat::R8, WebGLTexelPremultiplicationOp::None, uint8_t, uint8_t>(const uint8_t* __restrict src, uint8_t* __restrict dst) |
michael@0 | 556 | { |
michael@0 | 557 | dst[0] = src[0]; |
michael@0 | 558 | } |
michael@0 | 559 | |
michael@0 | 560 | template<> MOZ_ALWAYS_INLINE void |
michael@0 | 561 | pack<WebGLTexelFormat::R8, WebGLTexelPremultiplicationOp::Premultiply, uint8_t, uint8_t>(const uint8_t* __restrict src, uint8_t* __restrict dst) |
michael@0 | 562 | { |
michael@0 | 563 | float scaleFactor = src[3] / 255.0f; |
michael@0 | 564 | uint8_t srcR = static_cast<uint8_t>(src[0] * scaleFactor); |
michael@0 | 565 | dst[0] = srcR; |
michael@0 | 566 | } |
michael@0 | 567 | |
michael@0 | 568 | template<> MOZ_ALWAYS_INLINE void |
michael@0 | 569 | pack<WebGLTexelFormat::R8, WebGLTexelPremultiplicationOp::Unpremultiply, uint8_t, uint8_t>(const uint8_t* __restrict src, uint8_t* __restrict dst) |
michael@0 | 570 | { |
michael@0 | 571 | float scaleFactor = src[3] ? 255.0f / src[3] : 1.0f; |
michael@0 | 572 | uint8_t srcR = static_cast<uint8_t>(src[0] * scaleFactor); |
michael@0 | 573 | dst[0] = srcR; |
michael@0 | 574 | } |
michael@0 | 575 | |
michael@0 | 576 | template<> MOZ_ALWAYS_INLINE void |
michael@0 | 577 | pack<WebGLTexelFormat::RA8, WebGLTexelPremultiplicationOp::None, uint8_t, uint8_t>(const uint8_t* __restrict src, uint8_t* __restrict dst) |
michael@0 | 578 | { |
michael@0 | 579 | dst[0] = src[0]; |
michael@0 | 580 | dst[1] = src[3]; |
michael@0 | 581 | } |
michael@0 | 582 | |
michael@0 | 583 | template<> MOZ_ALWAYS_INLINE void |
michael@0 | 584 | pack<WebGLTexelFormat::RA8, WebGLTexelPremultiplicationOp::Premultiply, uint8_t, uint8_t>(const uint8_t* __restrict src, uint8_t* __restrict dst) |
michael@0 | 585 | { |
michael@0 | 586 | float scaleFactor = src[3] / 255.0f; |
michael@0 | 587 | uint8_t srcR = static_cast<uint8_t>(src[0] * scaleFactor); |
michael@0 | 588 | dst[0] = srcR; |
michael@0 | 589 | dst[1] = src[3]; |
michael@0 | 590 | } |
michael@0 | 591 | |
michael@0 | 592 | // FIXME: this routine is lossy and must be removed. |
michael@0 | 593 | template<> MOZ_ALWAYS_INLINE void |
michael@0 | 594 | pack<WebGLTexelFormat::RA8, WebGLTexelPremultiplicationOp::Unpremultiply, uint8_t, uint8_t>(const uint8_t* __restrict src, uint8_t* __restrict dst) |
michael@0 | 595 | { |
michael@0 | 596 | float scaleFactor = src[3] ? 255.0f / src[3] : 1.0f; |
michael@0 | 597 | uint8_t srcR = static_cast<uint8_t>(src[0] * scaleFactor); |
michael@0 | 598 | dst[0] = srcR; |
michael@0 | 599 | dst[1] = src[3]; |
michael@0 | 600 | } |
michael@0 | 601 | |
michael@0 | 602 | template<> MOZ_ALWAYS_INLINE void |
michael@0 | 603 | pack<WebGLTexelFormat::RGB8, WebGLTexelPremultiplicationOp::None, uint8_t, uint8_t>(const uint8_t* __restrict src, uint8_t* __restrict dst) |
michael@0 | 604 | { |
michael@0 | 605 | dst[0] = src[0]; |
michael@0 | 606 | dst[1] = src[1]; |
michael@0 | 607 | dst[2] = src[2]; |
michael@0 | 608 | } |
michael@0 | 609 | |
michael@0 | 610 | template<> MOZ_ALWAYS_INLINE void |
michael@0 | 611 | pack<WebGLTexelFormat::RGB8, WebGLTexelPremultiplicationOp::Premultiply, uint8_t, uint8_t>(const uint8_t* __restrict src, uint8_t* __restrict dst) |
michael@0 | 612 | { |
michael@0 | 613 | float scaleFactor = src[3] / 255.0f; |
michael@0 | 614 | uint8_t srcR = static_cast<uint8_t>(src[0] * scaleFactor); |
michael@0 | 615 | uint8_t srcG = static_cast<uint8_t>(src[1] * scaleFactor); |
michael@0 | 616 | uint8_t srcB = static_cast<uint8_t>(src[2] * scaleFactor); |
michael@0 | 617 | dst[0] = srcR; |
michael@0 | 618 | dst[1] = srcG; |
michael@0 | 619 | dst[2] = srcB; |
michael@0 | 620 | } |
michael@0 | 621 | |
michael@0 | 622 | template<> MOZ_ALWAYS_INLINE void |
michael@0 | 623 | pack<WebGLTexelFormat::RGB8, WebGLTexelPremultiplicationOp::Unpremultiply, uint8_t, uint8_t>(const uint8_t* __restrict src, uint8_t* __restrict dst) |
michael@0 | 624 | { |
michael@0 | 625 | float scaleFactor = src[3] ? 255.0f / src[3] : 1.0f; |
michael@0 | 626 | uint8_t srcR = static_cast<uint8_t>(src[0] * scaleFactor); |
michael@0 | 627 | uint8_t srcG = static_cast<uint8_t>(src[1] * scaleFactor); |
michael@0 | 628 | uint8_t srcB = static_cast<uint8_t>(src[2] * scaleFactor); |
michael@0 | 629 | dst[0] = srcR; |
michael@0 | 630 | dst[1] = srcG; |
michael@0 | 631 | dst[2] = srcB; |
michael@0 | 632 | } |
michael@0 | 633 | |
michael@0 | 634 | template<> MOZ_ALWAYS_INLINE void |
michael@0 | 635 | pack<WebGLTexelFormat::RGBA8, WebGLTexelPremultiplicationOp::None, uint8_t, uint8_t>(const uint8_t* __restrict src, uint8_t* __restrict dst) |
michael@0 | 636 | { |
michael@0 | 637 | dst[0] = src[0]; |
michael@0 | 638 | dst[1] = src[1]; |
michael@0 | 639 | dst[2] = src[2]; |
michael@0 | 640 | dst[3] = src[3]; |
michael@0 | 641 | } |
michael@0 | 642 | |
michael@0 | 643 | template<> MOZ_ALWAYS_INLINE void |
michael@0 | 644 | pack<WebGLTexelFormat::RGBA8, WebGLTexelPremultiplicationOp::Premultiply, uint8_t, uint8_t>(const uint8_t* __restrict src, uint8_t* __restrict dst) |
michael@0 | 645 | { |
michael@0 | 646 | float scaleFactor = src[3] / 255.0f; |
michael@0 | 647 | uint8_t srcR = static_cast<uint8_t>(src[0] * scaleFactor); |
michael@0 | 648 | uint8_t srcG = static_cast<uint8_t>(src[1] * scaleFactor); |
michael@0 | 649 | uint8_t srcB = static_cast<uint8_t>(src[2] * scaleFactor); |
michael@0 | 650 | dst[0] = srcR; |
michael@0 | 651 | dst[1] = srcG; |
michael@0 | 652 | dst[2] = srcB; |
michael@0 | 653 | dst[3] = src[3]; |
michael@0 | 654 | } |
michael@0 | 655 | |
michael@0 | 656 | // FIXME: this routine is lossy and must be removed. |
michael@0 | 657 | template<> MOZ_ALWAYS_INLINE void |
michael@0 | 658 | pack<WebGLTexelFormat::RGBA8, WebGLTexelPremultiplicationOp::Unpremultiply, uint8_t, uint8_t>(const uint8_t* __restrict src, uint8_t* __restrict dst) |
michael@0 | 659 | { |
michael@0 | 660 | float scaleFactor = src[3] ? 255.0f / src[3] : 1.0f; |
michael@0 | 661 | uint8_t srcR = static_cast<uint8_t>(src[0] * scaleFactor); |
michael@0 | 662 | uint8_t srcG = static_cast<uint8_t>(src[1] * scaleFactor); |
michael@0 | 663 | uint8_t srcB = static_cast<uint8_t>(src[2] * scaleFactor); |
michael@0 | 664 | dst[0] = srcR; |
michael@0 | 665 | dst[1] = srcG; |
michael@0 | 666 | dst[2] = srcB; |
michael@0 | 667 | dst[3] = src[3]; |
michael@0 | 668 | } |
michael@0 | 669 | |
michael@0 | 670 | template<> MOZ_ALWAYS_INLINE void |
michael@0 | 671 | pack<WebGLTexelFormat::RGBA4444, WebGLTexelPremultiplicationOp::None, uint8_t, uint16_t>(const uint8_t* __restrict src, uint16_t* __restrict dst) |
michael@0 | 672 | { |
michael@0 | 673 | *dst = ( ((src[0] & 0xF0) << 8) |
michael@0 | 674 | | ((src[1] & 0xF0) << 4) |
michael@0 | 675 | | (src[2] & 0xF0) |
michael@0 | 676 | | (src[3] >> 4) ); |
michael@0 | 677 | } |
michael@0 | 678 | |
michael@0 | 679 | template<> MOZ_ALWAYS_INLINE void |
michael@0 | 680 | pack<WebGLTexelFormat::RGBA4444, WebGLTexelPremultiplicationOp::Premultiply, uint8_t, uint16_t>(const uint8_t* __restrict src, uint16_t* __restrict dst) |
michael@0 | 681 | { |
michael@0 | 682 | float scaleFactor = src[3] / 255.0f; |
michael@0 | 683 | uint8_t srcR = static_cast<uint8_t>(src[0] * scaleFactor); |
michael@0 | 684 | uint8_t srcG = static_cast<uint8_t>(src[1] * scaleFactor); |
michael@0 | 685 | uint8_t srcB = static_cast<uint8_t>(src[2] * scaleFactor); |
michael@0 | 686 | *dst = ( ((srcR & 0xF0) << 8) |
michael@0 | 687 | | ((srcG & 0xF0) << 4) |
michael@0 | 688 | | (srcB & 0xF0) |
michael@0 | 689 | | (src[3] >> 4)); |
michael@0 | 690 | } |
michael@0 | 691 | |
michael@0 | 692 | // FIXME: this routine is lossy and must be removed. |
michael@0 | 693 | template<> MOZ_ALWAYS_INLINE void |
michael@0 | 694 | pack<WebGLTexelFormat::RGBA4444, WebGLTexelPremultiplicationOp::Unpremultiply, uint8_t, uint16_t>(const uint8_t* __restrict src, uint16_t* __restrict dst) |
michael@0 | 695 | { |
michael@0 | 696 | float scaleFactor = src[3] ? 255.0f / src[3] : 1.0f; |
michael@0 | 697 | uint8_t srcR = static_cast<uint8_t>(src[0] * scaleFactor); |
michael@0 | 698 | uint8_t srcG = static_cast<uint8_t>(src[1] * scaleFactor); |
michael@0 | 699 | uint8_t srcB = static_cast<uint8_t>(src[2] * scaleFactor); |
michael@0 | 700 | *dst = ( ((srcR & 0xF0) << 8) |
michael@0 | 701 | | ((srcG & 0xF0) << 4) |
michael@0 | 702 | | (srcB & 0xF0) |
michael@0 | 703 | | (src[3] >> 4)); |
michael@0 | 704 | } |
michael@0 | 705 | |
michael@0 | 706 | template<> MOZ_ALWAYS_INLINE void |
michael@0 | 707 | pack<WebGLTexelFormat::RGBA5551, WebGLTexelPremultiplicationOp::None, uint8_t, uint16_t>(const uint8_t* __restrict src, uint16_t* __restrict dst) |
michael@0 | 708 | { |
michael@0 | 709 | *dst = ( ((src[0] & 0xF8) << 8) |
michael@0 | 710 | | ((src[1] & 0xF8) << 3) |
michael@0 | 711 | | ((src[2] & 0xF8) >> 2) |
michael@0 | 712 | | (src[3] >> 7)); |
michael@0 | 713 | } |
michael@0 | 714 | |
michael@0 | 715 | template<> MOZ_ALWAYS_INLINE void |
michael@0 | 716 | pack<WebGLTexelFormat::RGBA5551, WebGLTexelPremultiplicationOp::Premultiply, uint8_t, uint16_t>(const uint8_t* __restrict src, uint16_t* __restrict dst) |
michael@0 | 717 | { |
michael@0 | 718 | float scaleFactor = src[3] / 255.0f; |
michael@0 | 719 | uint8_t srcR = static_cast<uint8_t>(src[0] * scaleFactor); |
michael@0 | 720 | uint8_t srcG = static_cast<uint8_t>(src[1] * scaleFactor); |
michael@0 | 721 | uint8_t srcB = static_cast<uint8_t>(src[2] * scaleFactor); |
michael@0 | 722 | *dst = ( ((srcR & 0xF8) << 8) |
michael@0 | 723 | | ((srcG & 0xF8) << 3) |
michael@0 | 724 | | ((srcB & 0xF8) >> 2) |
michael@0 | 725 | | (src[3] >> 7)); |
michael@0 | 726 | } |
michael@0 | 727 | |
michael@0 | 728 | // FIXME: this routine is lossy and must be removed. |
michael@0 | 729 | template<> MOZ_ALWAYS_INLINE void |
michael@0 | 730 | pack<WebGLTexelFormat::RGBA5551, WebGLTexelPremultiplicationOp::Unpremultiply, uint8_t, uint16_t>(const uint8_t* __restrict src, uint16_t* __restrict dst) |
michael@0 | 731 | { |
michael@0 | 732 | float scaleFactor = src[3] ? 255.0f / src[3] : 1.0f; |
michael@0 | 733 | uint8_t srcR = static_cast<uint8_t>(src[0] * scaleFactor); |
michael@0 | 734 | uint8_t srcG = static_cast<uint8_t>(src[1] * scaleFactor); |
michael@0 | 735 | uint8_t srcB = static_cast<uint8_t>(src[2] * scaleFactor); |
michael@0 | 736 | *dst = ( ((srcR & 0xF8) << 8) |
michael@0 | 737 | | ((srcG & 0xF8) << 3) |
michael@0 | 738 | | ((srcB & 0xF8) >> 2) |
michael@0 | 739 | | (src[3] >> 7)); |
michael@0 | 740 | } |
michael@0 | 741 | |
michael@0 | 742 | template<> MOZ_ALWAYS_INLINE void |
michael@0 | 743 | pack<WebGLTexelFormat::RGB565, WebGLTexelPremultiplicationOp::None, uint8_t, uint16_t>(const uint8_t* __restrict src, uint16_t* __restrict dst) |
michael@0 | 744 | { |
michael@0 | 745 | *dst = ( ((src[0] & 0xF8) << 8) |
michael@0 | 746 | | ((src[1] & 0xFC) << 3) |
michael@0 | 747 | | ((src[2] & 0xF8) >> 3)); |
michael@0 | 748 | } |
michael@0 | 749 | |
michael@0 | 750 | template<> MOZ_ALWAYS_INLINE void |
michael@0 | 751 | pack<WebGLTexelFormat::RGB565, WebGLTexelPremultiplicationOp::Premultiply, uint8_t, uint16_t>(const uint8_t* __restrict src, uint16_t* __restrict dst) |
michael@0 | 752 | { |
michael@0 | 753 | float scaleFactor = src[3] / 255.0f; |
michael@0 | 754 | uint8_t srcR = static_cast<uint8_t>(src[0] * scaleFactor); |
michael@0 | 755 | uint8_t srcG = static_cast<uint8_t>(src[1] * scaleFactor); |
michael@0 | 756 | uint8_t srcB = static_cast<uint8_t>(src[2] * scaleFactor); |
michael@0 | 757 | *dst = ( ((srcR & 0xF8) << 8) |
michael@0 | 758 | | ((srcG & 0xFC) << 3) |
michael@0 | 759 | | ((srcB & 0xF8) >> 3)); |
michael@0 | 760 | } |
michael@0 | 761 | |
michael@0 | 762 | // FIXME: this routine is lossy and must be removed. |
michael@0 | 763 | template<> MOZ_ALWAYS_INLINE void |
michael@0 | 764 | pack<WebGLTexelFormat::RGB565, WebGLTexelPremultiplicationOp::Unpremultiply, uint8_t, uint16_t>(const uint8_t* __restrict src, uint16_t* __restrict dst) |
michael@0 | 765 | { |
michael@0 | 766 | float scaleFactor = src[3] ? 255.0f / src[3] : 1.0f; |
michael@0 | 767 | uint8_t srcR = static_cast<uint8_t>(src[0] * scaleFactor); |
michael@0 | 768 | uint8_t srcG = static_cast<uint8_t>(src[1] * scaleFactor); |
michael@0 | 769 | uint8_t srcB = static_cast<uint8_t>(src[2] * scaleFactor); |
michael@0 | 770 | *dst = ( ((srcR & 0xF8) << 8) |
michael@0 | 771 | | ((srcG & 0xFC) << 3) |
michael@0 | 772 | | ((srcB & 0xF8) >> 3)); |
michael@0 | 773 | } |
michael@0 | 774 | |
michael@0 | 775 | template<> MOZ_ALWAYS_INLINE void |
michael@0 | 776 | pack<WebGLTexelFormat::RGB32F, WebGLTexelPremultiplicationOp::None, float, float>(const float* __restrict src, float* __restrict dst) |
michael@0 | 777 | { |
michael@0 | 778 | dst[0] = src[0]; |
michael@0 | 779 | dst[1] = src[1]; |
michael@0 | 780 | dst[2] = src[2]; |
michael@0 | 781 | } |
michael@0 | 782 | |
michael@0 | 783 | template<> MOZ_ALWAYS_INLINE void |
michael@0 | 784 | pack<WebGLTexelFormat::RGB32F, WebGLTexelPremultiplicationOp::Premultiply, float, float>(const float* __restrict src, float* __restrict dst) |
michael@0 | 785 | { |
michael@0 | 786 | float scaleFactor = src[3]; |
michael@0 | 787 | dst[0] = src[0] * scaleFactor; |
michael@0 | 788 | dst[1] = src[1] * scaleFactor; |
michael@0 | 789 | dst[2] = src[2] * scaleFactor; |
michael@0 | 790 | } |
michael@0 | 791 | |
michael@0 | 792 | template<> MOZ_ALWAYS_INLINE void |
michael@0 | 793 | pack<WebGLTexelFormat::RGBA32F, WebGLTexelPremultiplicationOp::None, float, float>(const float* __restrict src, float* __restrict dst) |
michael@0 | 794 | { |
michael@0 | 795 | dst[0] = src[0]; |
michael@0 | 796 | dst[1] = src[1]; |
michael@0 | 797 | dst[2] = src[2]; |
michael@0 | 798 | dst[3] = src[3]; |
michael@0 | 799 | } |
michael@0 | 800 | |
michael@0 | 801 | template<> MOZ_ALWAYS_INLINE void |
michael@0 | 802 | pack<WebGLTexelFormat::RGBA32F, WebGLTexelPremultiplicationOp::Premultiply, float, float>(const float* __restrict src, float* __restrict dst) |
michael@0 | 803 | { |
michael@0 | 804 | float scaleFactor = src[3]; |
michael@0 | 805 | dst[0] = src[0] * scaleFactor; |
michael@0 | 806 | dst[1] = src[1] * scaleFactor; |
michael@0 | 807 | dst[2] = src[2] * scaleFactor; |
michael@0 | 808 | dst[3] = src[3]; |
michael@0 | 809 | } |
michael@0 | 810 | |
michael@0 | 811 | template<> MOZ_ALWAYS_INLINE void |
michael@0 | 812 | pack<WebGLTexelFormat::A32F, WebGLTexelPremultiplicationOp::None, float, float>(const float* __restrict src, float* __restrict dst) |
michael@0 | 813 | { |
michael@0 | 814 | dst[0] = src[3]; |
michael@0 | 815 | } |
michael@0 | 816 | |
michael@0 | 817 | template<> MOZ_ALWAYS_INLINE void |
michael@0 | 818 | pack<WebGLTexelFormat::A32F, WebGLTexelPremultiplicationOp::Premultiply, float, float>(const float* __restrict src, float* __restrict dst) |
michael@0 | 819 | { |
michael@0 | 820 | dst[0] = src[3]; |
michael@0 | 821 | } |
michael@0 | 822 | |
michael@0 | 823 | template<> MOZ_ALWAYS_INLINE void |
michael@0 | 824 | pack<WebGLTexelFormat::R32F, WebGLTexelPremultiplicationOp::None, float, float>(const float* __restrict src, float* __restrict dst) |
michael@0 | 825 | { |
michael@0 | 826 | dst[0] = src[0]; |
michael@0 | 827 | } |
michael@0 | 828 | |
michael@0 | 829 | template<> MOZ_ALWAYS_INLINE void |
michael@0 | 830 | pack<WebGLTexelFormat::R32F, WebGLTexelPremultiplicationOp::Premultiply, float, float>(const float* __restrict src, float* __restrict dst) |
michael@0 | 831 | { |
michael@0 | 832 | float scaleFactor = src[3]; |
michael@0 | 833 | dst[0] = src[0] * scaleFactor; |
michael@0 | 834 | } |
michael@0 | 835 | |
michael@0 | 836 | template<> MOZ_ALWAYS_INLINE void |
michael@0 | 837 | pack<WebGLTexelFormat::RA32F, WebGLTexelPremultiplicationOp::None, float, float>(const float* __restrict src, float* __restrict dst) |
michael@0 | 838 | { |
michael@0 | 839 | dst[0] = src[0]; |
michael@0 | 840 | dst[1] = src[3]; |
michael@0 | 841 | } |
michael@0 | 842 | |
michael@0 | 843 | template<> MOZ_ALWAYS_INLINE void |
michael@0 | 844 | pack<WebGLTexelFormat::RA32F, WebGLTexelPremultiplicationOp::Premultiply, float, float>(const float* __restrict src, float* __restrict dst) |
michael@0 | 845 | { |
michael@0 | 846 | float scaleFactor = src[3]; |
michael@0 | 847 | dst[0] = src[0] * scaleFactor; |
michael@0 | 848 | dst[1] = scaleFactor; |
michael@0 | 849 | } |
michael@0 | 850 | |
michael@0 | 851 | template<> MOZ_ALWAYS_INLINE void |
michael@0 | 852 | pack<WebGLTexelFormat::RGB16F, WebGLTexelPremultiplicationOp::None, uint16_t, uint16_t>(const uint16_t* __restrict src, uint16_t* __restrict dst) |
michael@0 | 853 | { |
michael@0 | 854 | dst[0] = src[0]; |
michael@0 | 855 | dst[1] = src[1]; |
michael@0 | 856 | dst[2] = src[2]; |
michael@0 | 857 | } |
michael@0 | 858 | |
michael@0 | 859 | template<> MOZ_ALWAYS_INLINE void |
michael@0 | 860 | pack<WebGLTexelFormat::RGB16F, WebGLTexelPremultiplicationOp::Premultiply, uint16_t, uint16_t>(const uint16_t* __restrict src, uint16_t* __restrict dst) |
michael@0 | 861 | { |
michael@0 | 862 | float scaleFactor = unpackFromFloat16(src[3]); |
michael@0 | 863 | dst[0] = packToFloat16(unpackFromFloat16(src[0]) * scaleFactor); |
michael@0 | 864 | dst[1] = packToFloat16(unpackFromFloat16(src[1]) * scaleFactor); |
michael@0 | 865 | dst[2] = packToFloat16(unpackFromFloat16(src[2]) * scaleFactor); |
michael@0 | 866 | } |
michael@0 | 867 | |
michael@0 | 868 | template<> MOZ_ALWAYS_INLINE void |
michael@0 | 869 | pack<WebGLTexelFormat::RGBA16F, WebGLTexelPremultiplicationOp::None, uint16_t, uint16_t>(const uint16_t* __restrict src, uint16_t* __restrict dst) |
michael@0 | 870 | { |
michael@0 | 871 | dst[0] = src[0]; |
michael@0 | 872 | dst[1] = src[1]; |
michael@0 | 873 | dst[2] = src[2]; |
michael@0 | 874 | dst[3] = src[3]; |
michael@0 | 875 | } |
michael@0 | 876 | |
michael@0 | 877 | template<> MOZ_ALWAYS_INLINE void |
michael@0 | 878 | pack<WebGLTexelFormat::RGBA16F, WebGLTexelPremultiplicationOp::Premultiply, uint16_t, uint16_t>(const uint16_t* __restrict src, uint16_t* __restrict dst) |
michael@0 | 879 | { |
michael@0 | 880 | float scaleFactor = unpackFromFloat16(src[3]); |
michael@0 | 881 | dst[0] = packToFloat16(unpackFromFloat16(src[0]) * scaleFactor); |
michael@0 | 882 | dst[1] = packToFloat16(unpackFromFloat16(src[1]) * scaleFactor); |
michael@0 | 883 | dst[2] = packToFloat16(unpackFromFloat16(src[2]) * scaleFactor); |
michael@0 | 884 | dst[3] = src[3]; |
michael@0 | 885 | } |
michael@0 | 886 | |
michael@0 | 887 | template<> MOZ_ALWAYS_INLINE void |
michael@0 | 888 | pack<WebGLTexelFormat::A16F, WebGLTexelPremultiplicationOp::None, uint16_t, uint16_t>(const uint16_t* __restrict src, uint16_t* __restrict dst) |
michael@0 | 889 | { |
michael@0 | 890 | dst[0] = src[3]; |
michael@0 | 891 | } |
michael@0 | 892 | |
michael@0 | 893 | template<> MOZ_ALWAYS_INLINE void |
michael@0 | 894 | pack<WebGLTexelFormat::A16F, WebGLTexelPremultiplicationOp::Premultiply, uint16_t, uint16_t>(const uint16_t* __restrict src, uint16_t* __restrict dst) |
michael@0 | 895 | { |
michael@0 | 896 | dst[0] = src[3]; |
michael@0 | 897 | } |
michael@0 | 898 | |
michael@0 | 899 | template<> MOZ_ALWAYS_INLINE void |
michael@0 | 900 | pack<WebGLTexelFormat::R16F, WebGLTexelPremultiplicationOp::None, uint16_t, uint16_t>(const uint16_t* __restrict src, uint16_t* __restrict dst) |
michael@0 | 901 | { |
michael@0 | 902 | dst[0] = src[0]; |
michael@0 | 903 | } |
michael@0 | 904 | |
michael@0 | 905 | template<> MOZ_ALWAYS_INLINE void |
michael@0 | 906 | pack<WebGLTexelFormat::R16F, WebGLTexelPremultiplicationOp::Premultiply, uint16_t, uint16_t>(const uint16_t* __restrict src, uint16_t* __restrict dst) |
michael@0 | 907 | { |
michael@0 | 908 | float scaleFactor = unpackFromFloat16(src[3]); |
michael@0 | 909 | dst[0] = packToFloat16(unpackFromFloat16(src[0]) * scaleFactor); |
michael@0 | 910 | } |
michael@0 | 911 | |
michael@0 | 912 | template<> MOZ_ALWAYS_INLINE void |
michael@0 | 913 | pack<WebGLTexelFormat::RA16F, WebGLTexelPremultiplicationOp::None, uint16_t, uint16_t>(const uint16_t* __restrict src, uint16_t* __restrict dst) |
michael@0 | 914 | { |
michael@0 | 915 | dst[0] = src[0]; |
michael@0 | 916 | dst[1] = src[3]; |
michael@0 | 917 | } |
michael@0 | 918 | |
michael@0 | 919 | template<> MOZ_ALWAYS_INLINE void |
michael@0 | 920 | pack<WebGLTexelFormat::RA16F, WebGLTexelPremultiplicationOp::Premultiply, uint16_t, uint16_t>(const uint16_t* __restrict src, uint16_t* __restrict dst) |
michael@0 | 921 | { |
michael@0 | 922 | float scaleFactor = unpackFromFloat16(src[3]); |
michael@0 | 923 | dst[0] = packToFloat16(unpackFromFloat16(src[0]) * scaleFactor); |
michael@0 | 924 | dst[1] = scaleFactor; |
michael@0 | 925 | } |
michael@0 | 926 | |
michael@0 | 927 | /****** END CODE SHARED WITH WEBKIT ******/ |
michael@0 | 928 | |
michael@0 | 929 | template<typename SrcType, typename DstType> MOZ_ALWAYS_INLINE void |
michael@0 | 930 | convertType(const SrcType* __restrict src, DstType* __restrict dst) |
michael@0 | 931 | { |
michael@0 | 932 | MOZ_ASSERT(false, "Unimplemented texture format conversion"); |
michael@0 | 933 | } |
michael@0 | 934 | |
michael@0 | 935 | template<> MOZ_ALWAYS_INLINE void |
michael@0 | 936 | convertType<uint8_t, uint8_t>(const uint8_t* __restrict src, uint8_t* __restrict dst) |
michael@0 | 937 | { |
michael@0 | 938 | dst[0] = src[0]; |
michael@0 | 939 | dst[1] = src[1]; |
michael@0 | 940 | dst[2] = src[2]; |
michael@0 | 941 | dst[3] = src[3]; |
michael@0 | 942 | } |
michael@0 | 943 | |
michael@0 | 944 | template<> MOZ_ALWAYS_INLINE void |
michael@0 | 945 | convertType<uint16_t, uint16_t>(const uint16_t* __restrict src, uint16_t* __restrict dst) |
michael@0 | 946 | { |
michael@0 | 947 | dst[0] = src[0]; |
michael@0 | 948 | dst[1] = src[1]; |
michael@0 | 949 | dst[2] = src[2]; |
michael@0 | 950 | dst[3] = src[3]; |
michael@0 | 951 | } |
michael@0 | 952 | |
michael@0 | 953 | template<> MOZ_ALWAYS_INLINE void |
michael@0 | 954 | convertType<float, float>(const float* __restrict src, float* __restrict dst) |
michael@0 | 955 | { |
michael@0 | 956 | dst[0] = src[0]; |
michael@0 | 957 | dst[1] = src[1]; |
michael@0 | 958 | dst[2] = src[2]; |
michael@0 | 959 | dst[3] = src[3]; |
michael@0 | 960 | } |
michael@0 | 961 | |
michael@0 | 962 | template<> MOZ_ALWAYS_INLINE void |
michael@0 | 963 | convertType<uint8_t, float>(const uint8_t* __restrict src, float* __restrict dst) |
michael@0 | 964 | { |
michael@0 | 965 | const float scaleFactor = 1.f / 255.0f; |
michael@0 | 966 | dst[0] = src[0] * scaleFactor; |
michael@0 | 967 | dst[1] = src[1] * scaleFactor; |
michael@0 | 968 | dst[2] = src[2] * scaleFactor; |
michael@0 | 969 | dst[3] = src[3] * scaleFactor; |
michael@0 | 970 | } |
michael@0 | 971 | |
michael@0 | 972 | template<> MOZ_ALWAYS_INLINE void |
michael@0 | 973 | convertType<uint8_t, uint16_t>(const uint8_t* __restrict src, uint16_t* __restrict dst) |
michael@0 | 974 | { |
michael@0 | 975 | const float scaleFactor = 1.f / 255.0f; |
michael@0 | 976 | dst[0] = packToFloat16(src[0] * scaleFactor); |
michael@0 | 977 | dst[1] = packToFloat16(src[1] * scaleFactor); |
michael@0 | 978 | dst[2] = packToFloat16(src[2] * scaleFactor); |
michael@0 | 979 | dst[3] = packToFloat16(src[3] * scaleFactor); |
michael@0 | 980 | } |
michael@0 | 981 | |
michael@0 | 982 | } // end namespace WebGLTexelConversions |
michael@0 | 983 | |
michael@0 | 984 | } // end namespace mozilla |
michael@0 | 985 | |
michael@0 | 986 | #endif // WEBGLTEXELCONVERSIONS_H_ |