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