Bug 1886946: Remove incorrect assertion that buffer is not-pinned. r=sfink
[gecko.git] / dom / canvas / WebGLTexelConversions.h
blobfdc0cbd0c89d3d5b9bcc1c3916df92c2394312cb
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 bool* out_wasTrivial);
53 //////////////////////////////////////////////////////////////////////////////////////////
55 // single precision float
56 // seeeeeeeemmmmmmmmmmmmmmmmmmmmmmm
58 // half precision float
59 // seeeeemmmmmmmmmm
61 // IEEE 16bits floating point:
62 const uint16_t kFloat16Value_Zero = 0x0000; // = 0000000000000000b
63 const uint16_t kFloat16Value_One = 0x3C00; // = 0011110000000000b
64 const uint16_t kFloat16Value_Infinity = 0x7C00; // = 0111110000000000b
65 const uint16_t kFloat16Value_NaN = 0x7FFF; // = 011111yyyyyyyyyyb (nonzero y)
67 MOZ_ALWAYS_INLINE uint16_t packToFloat16(float v) {
68 union {
69 float f32Value;
70 uint32_t f32Bits;
73 f32Value = v;
75 // pull the sign from v into f16bits
76 uint16_t f16Bits = uint16_t(f32Bits >> 16) & 0x8000;
77 const uint32_t mantissa = f32Bits & 0x7FFFFF;
78 const uint32_t exp = (f32Bits >> 23) & 0xFF;
80 // Adapted from: OpenGL ES 2.0 Programming Guide Appx.
81 // Converting Float to Half-Float
82 // 143 = 255 - 127 + 15
83 // = sp_max - sp_bias + hp_bias
84 if (exp >= 143) {
85 if (mantissa && exp == 0xFF) {
86 // Single precision was NaN
87 return f16Bits | kFloat16Value_NaN;
88 } else {
89 // Outside range, store as infinity
90 return f16Bits | kFloat16Value_Infinity;
94 // too small, try to make a denormalized number
95 // 112 = 255 - 127 - (15 + 1)
96 // = sp_max - sp_bias - (hp_bias + 1)
97 if (exp <= 112) {
98 return f16Bits | uint16_t(mantissa >> (14 + 112 - exp));
101 f16Bits |= uint16_t(exp - 112) << 10;
102 f16Bits |= uint16_t(mantissa >> 13) & 0x03FF;
104 return f16Bits;
107 MOZ_ALWAYS_INLINE float unpackFromFloat16(uint16_t v) {
108 union {
109 float f32Value;
110 uint32_t f32Bits;
113 // grab sign bit
114 f32Bits = uint32_t(v & 0x8000) << 16;
115 uint16_t exp = (v >> 10) & 0x001F;
116 uint16_t mantissa = v & 0x03FF;
118 if (!exp) {
119 // Handle denormalized numbers
120 // Adapted from: OpenGL ES 2.0 Programming Guide Appx.
121 // Converting Float to Half-Float
122 if (mantissa) {
123 exp = 112; // See packToFloat16
124 mantissa <<= 1;
125 // For every leading zero, decrement the exponent
126 // and shift the mantissa to the left
127 while ((mantissa & (1 << 10)) == 0) {
128 mantissa <<= 1;
129 --exp;
131 mantissa &= 0x03FF;
133 f32Bits |= (exp << 23) | (mantissa << 13);
135 // Denormalized number
136 return f32Value;
139 // +/- zero
140 return f32Value;
143 if (exp == 0x001F) {
144 if (v & 0x03FF) {
145 // this is a NaN
146 f32Bits |= 0x7FFFFFFF;
147 } else {
148 // this is -inf or +inf
149 f32Bits |= 0x7F800000;
151 return f32Value;
154 f32Bits |= uint32_t(exp + (-15 + 127)) << 23;
155 f32Bits |= uint32_t(v & 0x03FF) << 13;
157 return f32Value;
160 // These routines come from angle/common/mathutil.h
161 // They are copied here to remove the dependency on ANGLE headers
162 // included from mathutil.h
163 MOZ_ALWAYS_INLINE uint16_t packToFloat11(float fp32) {
164 const unsigned int float32MantissaMask = 0x7FFFFF;
165 const unsigned int float32ExponentMask = 0x7F800000;
166 const unsigned int float32SignMask = 0x80000000;
167 const unsigned int float32ValueMask = ~float32SignMask;
168 const unsigned int float32ExponentFirstBit = 23;
169 const unsigned int float32ExponentBias = 127;
171 const unsigned short float11Max = 0x7BF;
172 const unsigned short float11MantissaMask = 0x3F;
173 const unsigned short float11ExponentMask = 0x7C0;
174 const unsigned short float11BitMask = 0x7FF;
175 const unsigned int float11ExponentBias = 14;
177 const unsigned int float32Maxfloat11 = 0x477E0000;
178 const unsigned int float32Minfloat11 = 0x38800000;
180 const unsigned int float32Bits = BitwiseCast<unsigned int>(fp32);
181 const bool float32Sign = (float32Bits & float32SignMask) == float32SignMask;
183 unsigned int float32Val = float32Bits & float32ValueMask;
185 if ((float32Val & float32ExponentMask) == float32ExponentMask) {
186 // INF or NAN
187 if ((float32Val & float32MantissaMask) != 0) {
188 return float11ExponentMask | (((float32Val >> 17) | (float32Val >> 11) |
189 (float32Val >> 6) | (float32Val)) &
190 float11MantissaMask);
191 } else if (float32Sign) {
192 // -INF is clamped to 0 since float11 is positive only
193 return 0;
194 } else {
195 return float11ExponentMask;
197 } else if (float32Sign) {
198 // float11 is positive only, so clamp to zero
199 return 0;
200 } else if (float32Val > float32Maxfloat11) {
201 // The number is too large to be represented as a float11, set to max
202 return float11Max;
203 } else {
204 if (float32Val < float32Minfloat11) {
205 // The number is too small to be represented as a normalized float11
206 // Convert it to a denormalized value.
207 const unsigned int shift = (float32ExponentBias - float11ExponentBias) -
208 (float32Val >> float32ExponentFirstBit);
209 float32Val = ((1 << float32ExponentFirstBit) |
210 (float32Val & float32MantissaMask)) >>
211 shift;
212 } else {
213 // Rebias the exponent to represent the value as a normalized float11
214 float32Val += 0xC8000000;
217 return ((float32Val + 0xFFFF + ((float32Val >> 17) & 1)) >> 17) &
218 float11BitMask;
222 MOZ_ALWAYS_INLINE uint16_t packToFloat10(float fp32) {
223 const unsigned int float32MantissaMask = 0x7FFFFF;
224 const unsigned int float32ExponentMask = 0x7F800000;
225 const unsigned int float32SignMask = 0x80000000;
226 const unsigned int float32ValueMask = ~float32SignMask;
227 const unsigned int float32ExponentFirstBit = 23;
228 const unsigned int float32ExponentBias = 127;
230 const unsigned short float10Max = 0x3DF;
231 const unsigned short float10MantissaMask = 0x1F;
232 const unsigned short float10ExponentMask = 0x3E0;
233 const unsigned short float10BitMask = 0x3FF;
234 const unsigned int float10ExponentBias = 14;
236 const unsigned int float32Maxfloat10 = 0x477C0000;
237 const unsigned int float32Minfloat10 = 0x38800000;
239 const unsigned int float32Bits = BitwiseCast<unsigned int>(fp32);
240 const bool float32Sign = (float32Bits & float32SignMask) == float32SignMask;
242 unsigned int float32Val = float32Bits & float32ValueMask;
244 if ((float32Val & float32ExponentMask) == float32ExponentMask) {
245 // INF or NAN
246 if ((float32Val & float32MantissaMask) != 0) {
247 return float10ExponentMask | (((float32Val >> 18) | (float32Val >> 13) |
248 (float32Val >> 3) | (float32Val)) &
249 float10MantissaMask);
250 } else if (float32Sign) {
251 // -INF is clamped to 0 since float11 is positive only
252 return 0;
253 } else {
254 return float10ExponentMask;
256 } else if (float32Sign) {
257 // float10 is positive only, so clamp to zero
258 return 0;
259 } else if (float32Val > float32Maxfloat10) {
260 // The number is too large to be represented as a float11, set to max
261 return float10Max;
262 } else {
263 if (float32Val < float32Minfloat10) {
264 // The number is too small to be represented as a normalized float11
265 // Convert it to a denormalized value.
266 const unsigned int shift = (float32ExponentBias - float10ExponentBias) -
267 (float32Val >> float32ExponentFirstBit);
268 float32Val = ((1 << float32ExponentFirstBit) |
269 (float32Val & float32MantissaMask)) >>
270 shift;
271 } else {
272 // Rebias the exponent to represent the value as a normalized float11
273 float32Val += 0xC8000000;
276 return ((float32Val + 0x1FFFF + ((float32Val >> 18) & 1)) >> 18) &
277 float10BitMask;
281 enum class WebGLTexelPremultiplicationOp : int {
282 None,
283 Premultiply,
284 Unpremultiply
287 namespace WebGLTexelConversions {
289 template <WebGLTexelFormat Format>
290 struct IsFloatFormat {
291 static const bool Value =
292 Format == WebGLTexelFormat::A32F || Format == WebGLTexelFormat::R32F ||
293 Format == WebGLTexelFormat::RA32F || Format == WebGLTexelFormat::RG32F ||
294 Format == WebGLTexelFormat::RGB11F11F10F ||
295 Format == WebGLTexelFormat::RGB32F || Format == WebGLTexelFormat::RGBA32F;
298 template <WebGLTexelFormat Format>
299 struct IsHalfFloatFormat {
300 static const bool Value =
301 Format == WebGLTexelFormat::A16F || Format == WebGLTexelFormat::R16F ||
302 Format == WebGLTexelFormat::RA16F || Format == WebGLTexelFormat::RG16F ||
303 Format == WebGLTexelFormat::RGB16F || Format == WebGLTexelFormat::RGBA16F;
306 template <WebGLTexelFormat Format>
307 struct Is16bppFormat {
308 static const bool Value = Format == WebGLTexelFormat::RGB565 ||
309 Format == WebGLTexelFormat::RGBA4444 ||
310 Format == WebGLTexelFormat::RGBA5551;
313 template <WebGLTexelFormat Format, bool IsFloat = IsFloatFormat<Format>::Value,
314 bool Is16bpp = Is16bppFormat<Format>::Value,
315 bool IsHalfFloat = IsHalfFloatFormat<Format>::Value>
316 struct DataTypeForFormat {
317 using Type = uint8_t;
320 template <WebGLTexelFormat Format>
321 struct DataTypeForFormat<Format, true, false, false> {
322 using Type = float;
325 template <WebGLTexelFormat Format>
326 struct DataTypeForFormat<Format, false, true, false> {
327 using Type = uint16_t;
330 template <WebGLTexelFormat Format>
331 struct DataTypeForFormat<Format, false, false, true> {
332 using Type = uint16_t;
335 template <>
336 struct DataTypeForFormat<WebGLTexelFormat::RGB11F11F10F, true, false, false> {
337 using Type = uint32_t;
340 template <WebGLTexelFormat Format>
341 struct IntermediateFormat {
342 static const WebGLTexelFormat Value =
343 IsFloatFormat<Format>::Value ? WebGLTexelFormat::RGBA32F
344 : IsHalfFloatFormat<Format>::Value ? WebGLTexelFormat::RGBA16F
345 : WebGLTexelFormat::RGBA8;
348 inline size_t TexelBytesForFormat(WebGLTexelFormat format) {
349 switch (format) {
350 case WebGLTexelFormat::A8:
351 case WebGLTexelFormat::R8:
352 return 1;
353 case WebGLTexelFormat::A16F:
354 case WebGLTexelFormat::R16F:
355 case WebGLTexelFormat::RA8:
356 case WebGLTexelFormat::RG8:
357 case WebGLTexelFormat::RGB565:
358 case WebGLTexelFormat::RGBA4444:
359 case WebGLTexelFormat::RGBA5551:
360 return 2;
361 case WebGLTexelFormat::RGB8:
362 return 3;
363 case WebGLTexelFormat::A32F:
364 case WebGLTexelFormat::R32F:
365 case WebGLTexelFormat::RA16F:
366 case WebGLTexelFormat::RG16F:
367 case WebGLTexelFormat::RGB11F11F10F:
368 case WebGLTexelFormat::RGBA8:
369 case WebGLTexelFormat::BGRX8:
370 case WebGLTexelFormat::BGRA8:
371 return 4;
372 case WebGLTexelFormat::RGB16F:
373 return 6;
374 case WebGLTexelFormat::RA32F:
375 case WebGLTexelFormat::RG32F:
376 case WebGLTexelFormat::RGBA16F:
377 return 8;
378 case WebGLTexelFormat::RGB32F:
379 return 12;
380 case WebGLTexelFormat::RGBA32F:
381 return 16;
382 default:
383 MOZ_ASSERT(false, "Unknown texel format. Coding mistake?");
384 return 0;
388 MOZ_ALWAYS_INLINE bool HasAlpha(WebGLTexelFormat format) {
389 return (
390 format == WebGLTexelFormat::A8 || format == WebGLTexelFormat::A16F ||
391 format == WebGLTexelFormat::A32F || format == WebGLTexelFormat::RA8 ||
392 format == WebGLTexelFormat::RA16F || format == WebGLTexelFormat::RA32F ||
393 format == WebGLTexelFormat::RGBA4444 ||
394 format == WebGLTexelFormat::RGBA5551 ||
395 format == WebGLTexelFormat::RGBA8 ||
396 format == WebGLTexelFormat::RGBA16F ||
397 format == WebGLTexelFormat::RGBA32F || format == WebGLTexelFormat::BGRA8);
400 MOZ_ALWAYS_INLINE bool HasColor(WebGLTexelFormat format) {
401 return (
402 format == WebGLTexelFormat::R8 || format == WebGLTexelFormat::R16F ||
403 format == WebGLTexelFormat::R32F || format == WebGLTexelFormat::RA8 ||
404 format == WebGLTexelFormat::RA16F || format == WebGLTexelFormat::RA32F ||
405 format == WebGLTexelFormat::RG8 || format == WebGLTexelFormat::RG16F ||
406 format == WebGLTexelFormat::RG32F || format == WebGLTexelFormat::RGB565 ||
407 format == WebGLTexelFormat::RGB8 ||
408 format == WebGLTexelFormat::RGB11F11F10F ||
409 format == WebGLTexelFormat::RGB16F ||
410 format == WebGLTexelFormat::RGB32F ||
411 format == WebGLTexelFormat::RGBA4444 ||
412 format == WebGLTexelFormat::RGBA5551 ||
413 format == WebGLTexelFormat::RGBA8 ||
414 format == WebGLTexelFormat::RGBA16F ||
415 format == WebGLTexelFormat::RGBA32F ||
416 format == WebGLTexelFormat::BGRX8 || format == WebGLTexelFormat::BGRA8);
419 /****** BEGIN CODE SHARED WITH WEBKIT ******/
421 // the pack/unpack functions here are originally from this file:
422 // http://trac.webkit.org/browser/trunk/WebCore/platform/graphics/GraphicsContext3D.cpp
424 //----------------------------------------------------------------------
425 // Pixel unpacking routines.
427 template <WebGLTexelFormat Format, typename SrcType, typename DstType>
428 MOZ_ALWAYS_INLINE void unpack(const SrcType* __restrict src,
429 DstType* __restrict dst) {
430 MOZ_ASSERT(false, "Unimplemented texture format conversion");
433 ////////////////////////////////////////////////////////////////////////////////
434 // 1-channel formats
435 template <>
436 MOZ_ALWAYS_INLINE void unpack<WebGLTexelFormat::A8, uint8_t, uint8_t>(
437 const uint8_t* __restrict src, uint8_t* __restrict dst) {
438 dst[0] = 0;
439 dst[1] = 0;
440 dst[2] = 0;
441 dst[3] = src[0];
444 template <>
445 MOZ_ALWAYS_INLINE void unpack<WebGLTexelFormat::A16F, uint16_t, uint16_t>(
446 const uint16_t* __restrict src, uint16_t* __restrict dst) {
447 dst[0] = kFloat16Value_Zero;
448 dst[1] = kFloat16Value_Zero;
449 dst[2] = kFloat16Value_Zero;
450 dst[3] = src[0];
453 template <>
454 MOZ_ALWAYS_INLINE void unpack<WebGLTexelFormat::A32F, float, float>(
455 const float* __restrict src, float* __restrict dst) {
456 dst[0] = 0;
457 dst[1] = 0;
458 dst[2] = 0;
459 dst[3] = src[0];
462 template <>
463 MOZ_ALWAYS_INLINE void unpack<WebGLTexelFormat::R8, uint8_t, uint8_t>(
464 const uint8_t* __restrict src, uint8_t* __restrict dst) {
465 dst[0] = src[0];
466 dst[1] = src[0];
467 dst[2] = src[0];
468 dst[3] = 0xFF;
471 template <>
472 MOZ_ALWAYS_INLINE void unpack<WebGLTexelFormat::R16F, uint16_t, uint16_t>(
473 const uint16_t* __restrict src, uint16_t* __restrict dst) {
474 dst[0] = src[0];
475 dst[1] = src[0];
476 dst[2] = src[0];
477 dst[3] = kFloat16Value_One;
480 template <>
481 MOZ_ALWAYS_INLINE void unpack<WebGLTexelFormat::R32F, float, float>(
482 const float* __restrict src, float* __restrict dst) {
483 dst[0] = src[0];
484 dst[1] = src[0];
485 dst[2] = src[0];
486 dst[3] = 1.0f;
489 ////////////////////////////////////////////////////////////////////////////////
490 // 2-channel formats
491 template <>
492 MOZ_ALWAYS_INLINE void unpack<WebGLTexelFormat::RA8, uint8_t, uint8_t>(
493 const uint8_t* __restrict src, uint8_t* __restrict dst) {
494 dst[0] = src[0];
495 dst[1] = src[0];
496 dst[2] = src[0];
497 dst[3] = src[1];
500 template <>
501 MOZ_ALWAYS_INLINE void unpack<WebGLTexelFormat::RA16F, uint16_t, uint16_t>(
502 const uint16_t* __restrict src, uint16_t* __restrict dst) {
503 dst[0] = src[0];
504 dst[1] = src[0];
505 dst[2] = src[0];
506 dst[3] = src[1];
509 template <>
510 MOZ_ALWAYS_INLINE void unpack<WebGLTexelFormat::RA32F, float, float>(
511 const float* __restrict src, float* __restrict dst) {
512 dst[0] = src[0];
513 dst[1] = src[0];
514 dst[2] = src[0];
515 dst[3] = src[1];
518 ////////////////////////////////////////////////////////////////////////////////
519 // 3-channel formats
520 template <>
521 MOZ_ALWAYS_INLINE void unpack<WebGLTexelFormat::RGB565, uint16_t, uint8_t>(
522 const uint16_t* __restrict src, uint8_t* __restrict dst) {
523 uint16_t packedValue = src[0];
524 uint8_t r = (packedValue >> 11) & 0x1F;
525 uint8_t g = (packedValue >> 5) & 0x3F;
526 uint8_t b = packedValue & 0x1F;
527 dst[0] = uint8_t(r << 3) | (r & 0x7);
528 dst[1] = uint8_t(g << 2) | (g & 0x3);
529 dst[2] = uint8_t(b << 3) | (b & 0x7);
530 dst[3] = 0xFF;
533 template <>
534 MOZ_ALWAYS_INLINE void unpack<WebGLTexelFormat::RGB8, uint8_t, uint8_t>(
535 const uint8_t* __restrict src, uint8_t* __restrict dst) {
536 dst[0] = src[0];
537 dst[1] = src[1];
538 dst[2] = src[2];
539 dst[3] = 0xFF;
542 template <>
543 MOZ_ALWAYS_INLINE void unpack<WebGLTexelFormat::RGB16F, uint16_t, uint16_t>(
544 const uint16_t* __restrict src, uint16_t* __restrict dst) {
545 dst[0] = src[0];
546 dst[1] = src[1];
547 dst[2] = src[2];
548 dst[3] = kFloat16Value_One;
551 template <>
552 MOZ_ALWAYS_INLINE void unpack<WebGLTexelFormat::RGB32F, float, float>(
553 const float* __restrict src, float* __restrict dst) {
554 dst[0] = src[0];
555 dst[1] = src[1];
556 dst[2] = src[2];
557 dst[3] = 1.0f;
560 ////////////////////////////////////////////////////////////////////////////////
561 // 4-channel formats
562 template <>
563 MOZ_ALWAYS_INLINE void unpack<WebGLTexelFormat::RGBA4444, uint16_t, uint8_t>(
564 const uint16_t* __restrict src, uint8_t* __restrict dst) {
565 uint16_t packedValue = src[0];
566 uint8_t r = (packedValue >> 12) & 0x0F;
567 uint8_t g = (packedValue >> 8) & 0x0F;
568 uint8_t b = (packedValue >> 4) & 0x0F;
569 uint8_t a = packedValue & 0x0F;
570 dst[0] = uint8_t(r << 4) | r;
571 dst[1] = uint8_t(g << 4) | g;
572 dst[2] = uint8_t(b << 4) | b;
573 dst[3] = uint8_t(a << 4) | a;
576 template <>
577 MOZ_ALWAYS_INLINE void unpack<WebGLTexelFormat::RGBA5551, uint16_t, uint8_t>(
578 const uint16_t* __restrict src, uint8_t* __restrict dst) {
579 uint16_t packedValue = src[0];
580 uint8_t r = (packedValue >> 11) & 0x1F;
581 uint8_t g = (packedValue >> 6) & 0x1F;
582 uint8_t b = (packedValue >> 1) & 0x1F;
583 dst[0] = uint8_t(r << 3) | (r & 0x7);
584 dst[1] = uint8_t(g << 3) | (g & 0x7);
585 dst[2] = uint8_t(b << 3) | (b & 0x7);
586 dst[3] = (packedValue & 0x1) ? 0xFF : 0;
589 template <>
590 MOZ_ALWAYS_INLINE void unpack<WebGLTexelFormat::RGBA8, uint8_t, uint8_t>(
591 const uint8_t* __restrict src, uint8_t* __restrict dst) {
592 dst[0] = src[0];
593 dst[1] = src[1];
594 dst[2] = src[2];
595 dst[3] = src[3];
598 template <>
599 MOZ_ALWAYS_INLINE void unpack<WebGLTexelFormat::RGBA16F, uint16_t, uint16_t>(
600 const uint16_t* __restrict src, uint16_t* __restrict dst) {
601 dst[0] = src[0];
602 dst[1] = src[1];
603 dst[2] = src[2];
604 dst[3] = src[3];
607 template <>
608 MOZ_ALWAYS_INLINE void unpack<WebGLTexelFormat::RGBA32F, float, float>(
609 const float* __restrict src, float* __restrict dst) {
610 dst[0] = src[0];
611 dst[1] = src[1];
612 dst[2] = src[2];
613 dst[3] = src[3];
616 ////////////////////////////////////////////////////////////////////////////////
617 // DOM element formats
618 template <>
619 MOZ_ALWAYS_INLINE void unpack<WebGLTexelFormat::BGRX8, uint8_t, uint8_t>(
620 const uint8_t* __restrict src, uint8_t* __restrict dst) {
621 dst[0] = src[2];
622 dst[1] = src[1];
623 dst[2] = src[0];
624 dst[3] = 0xFF;
627 template <>
628 MOZ_ALWAYS_INLINE void unpack<WebGLTexelFormat::BGRA8, uint8_t, uint8_t>(
629 const uint8_t* __restrict src, uint8_t* __restrict dst) {
630 dst[0] = src[2];
631 dst[1] = src[1];
632 dst[2] = src[0];
633 dst[3] = src[3];
636 //----------------------------------------------------------------------
637 // Pixel packing routines.
640 template <WebGLTexelFormat Format,
641 WebGLTexelPremultiplicationOp PremultiplicationOp, typename SrcType,
642 typename DstType>
643 MOZ_ALWAYS_INLINE void pack(const SrcType* __restrict src,
644 DstType* __restrict dst) {
645 MOZ_CRASH("GFX: Unimplemented texture format conversion");
648 ////////////////////////////////////////////////////////////////////////////////
649 // 1-channel formats
650 template <>
651 MOZ_ALWAYS_INLINE void
652 pack<WebGLTexelFormat::A8, WebGLTexelPremultiplicationOp::None, uint8_t,
653 uint8_t>(const uint8_t* __restrict src, uint8_t* __restrict dst) {
654 dst[0] = src[3];
657 template <>
658 MOZ_ALWAYS_INLINE void
659 pack<WebGLTexelFormat::A8, WebGLTexelPremultiplicationOp::Premultiply, uint8_t,
660 uint8_t>(const uint8_t* __restrict src, uint8_t* __restrict dst) {
661 dst[0] = src[3];
664 template <>
665 MOZ_ALWAYS_INLINE void
666 pack<WebGLTexelFormat::A8, WebGLTexelPremultiplicationOp::Unpremultiply,
667 uint8_t, uint8_t>(const uint8_t* __restrict src, uint8_t* __restrict dst) {
668 dst[0] = src[3];
671 template <>
672 MOZ_ALWAYS_INLINE void
673 pack<WebGLTexelFormat::A16F, WebGLTexelPremultiplicationOp::None, uint16_t,
674 uint16_t>(const uint16_t* __restrict src, uint16_t* __restrict dst) {
675 dst[0] = src[3];
678 template <>
679 MOZ_ALWAYS_INLINE void
680 pack<WebGLTexelFormat::A16F, WebGLTexelPremultiplicationOp::Premultiply,
681 uint16_t, uint16_t>(const uint16_t* __restrict src,
682 uint16_t* __restrict dst) {
683 dst[0] = src[3];
686 template <>
687 MOZ_ALWAYS_INLINE void
688 pack<WebGLTexelFormat::A16F, WebGLTexelPremultiplicationOp::Unpremultiply,
689 uint16_t, uint16_t>(const uint16_t* __restrict src,
690 uint16_t* __restrict dst) {
691 dst[0] = src[3];
694 template <>
695 MOZ_ALWAYS_INLINE void
696 pack<WebGLTexelFormat::A32F, WebGLTexelPremultiplicationOp::None, float, float>(
697 const float* __restrict src, float* __restrict dst) {
698 dst[0] = src[3];
701 template <>
702 MOZ_ALWAYS_INLINE void
703 pack<WebGLTexelFormat::A32F, WebGLTexelPremultiplicationOp::Premultiply, float,
704 float>(const float* __restrict src, float* __restrict dst) {
705 dst[0] = src[3];
708 template <>
709 MOZ_ALWAYS_INLINE void
710 pack<WebGLTexelFormat::A32F, WebGLTexelPremultiplicationOp::Unpremultiply,
711 float, float>(const float* __restrict src, float* __restrict dst) {
712 dst[0] = src[3];
715 template <>
716 MOZ_ALWAYS_INLINE void
717 pack<WebGLTexelFormat::R8, WebGLTexelPremultiplicationOp::None, uint8_t,
718 uint8_t>(const uint8_t* __restrict src, uint8_t* __restrict dst) {
719 dst[0] = src[0];
722 template <>
723 MOZ_ALWAYS_INLINE void
724 pack<WebGLTexelFormat::R8, WebGLTexelPremultiplicationOp::Premultiply, uint8_t,
725 uint8_t>(const uint8_t* __restrict src, uint8_t* __restrict dst) {
726 float scaleFactor = src[3] / 255.0f;
727 uint8_t srcR = static_cast<uint8_t>(src[0] * scaleFactor);
728 dst[0] = srcR;
731 template <>
732 MOZ_ALWAYS_INLINE void
733 pack<WebGLTexelFormat::R8, WebGLTexelPremultiplicationOp::Unpremultiply,
734 uint8_t, uint8_t>(const uint8_t* __restrict src, uint8_t* __restrict dst) {
735 float scaleFactor = src[3] ? 255.0f / src[3] : 1.0f;
736 uint8_t srcR = static_cast<uint8_t>(src[0] * scaleFactor);
737 dst[0] = srcR;
740 template <>
741 MOZ_ALWAYS_INLINE void
742 pack<WebGLTexelFormat::R16F, WebGLTexelPremultiplicationOp::None, uint16_t,
743 uint16_t>(const uint16_t* __restrict src, uint16_t* __restrict dst) {
744 dst[0] = src[0];
747 template <>
748 MOZ_ALWAYS_INLINE void
749 pack<WebGLTexelFormat::R16F, WebGLTexelPremultiplicationOp::Premultiply,
750 uint16_t, uint16_t>(const uint16_t* __restrict src,
751 uint16_t* __restrict dst) {
752 float scaleFactor = unpackFromFloat16(src[3]);
753 dst[0] = packToFloat16(unpackFromFloat16(src[0]) * scaleFactor);
756 template <>
757 MOZ_ALWAYS_INLINE void
758 pack<WebGLTexelFormat::R16F, WebGLTexelPremultiplicationOp::Unpremultiply,
759 uint16_t, uint16_t>(const uint16_t* __restrict src,
760 uint16_t* __restrict dst) {
761 float unpackedAlpha = unpackFromFloat16(src[3]);
762 float scaleFactor = unpackedAlpha ? 1.0f / unpackedAlpha : 1.0f;
763 dst[0] = packToFloat16(unpackFromFloat16(src[0]) * scaleFactor);
766 template <>
767 MOZ_ALWAYS_INLINE void
768 pack<WebGLTexelFormat::R32F, WebGLTexelPremultiplicationOp::None, float, float>(
769 const float* __restrict src, float* __restrict dst) {
770 dst[0] = src[0];
773 template <>
774 MOZ_ALWAYS_INLINE void
775 pack<WebGLTexelFormat::R32F, WebGLTexelPremultiplicationOp::Premultiply, float,
776 float>(const float* __restrict src, float* __restrict dst) {
777 float scaleFactor = src[3];
778 dst[0] = src[0] * scaleFactor;
781 template <>
782 MOZ_ALWAYS_INLINE void
783 pack<WebGLTexelFormat::R32F, WebGLTexelPremultiplicationOp::Unpremultiply,
784 float, float>(const float* __restrict src, float* __restrict dst) {
785 float scaleFactor = src[3] ? 1.0f / src[3] : 1.0f;
786 dst[0] = src[0] * scaleFactor;
789 ////////////////////////////////////////////////////////////////////////////////
790 // 2-channel formats
791 template <>
792 MOZ_ALWAYS_INLINE void
793 pack<WebGLTexelFormat::RA8, WebGLTexelPremultiplicationOp::None, uint8_t,
794 uint8_t>(const uint8_t* __restrict src, uint8_t* __restrict dst) {
795 dst[0] = src[0];
796 dst[1] = src[3];
799 template <>
800 MOZ_ALWAYS_INLINE void
801 pack<WebGLTexelFormat::RA8, WebGLTexelPremultiplicationOp::Premultiply, uint8_t,
802 uint8_t>(const uint8_t* __restrict src, uint8_t* __restrict dst) {
803 float scaleFactor = src[3] / 255.0f;
804 uint8_t srcR = static_cast<uint8_t>(src[0] * scaleFactor);
805 dst[0] = srcR;
806 dst[1] = src[3];
809 // FIXME: this routine is lossy and must be removed.
810 template <>
811 MOZ_ALWAYS_INLINE void
812 pack<WebGLTexelFormat::RA8, WebGLTexelPremultiplicationOp::Unpremultiply,
813 uint8_t, uint8_t>(const uint8_t* __restrict src, uint8_t* __restrict dst) {
814 float scaleFactor = src[3] ? 255.0f / src[3] : 1.0f;
815 uint8_t srcR = static_cast<uint8_t>(src[0] * scaleFactor);
816 dst[0] = srcR;
817 dst[1] = src[3];
820 template <>
821 MOZ_ALWAYS_INLINE void
822 pack<WebGLTexelFormat::RA16F, WebGLTexelPremultiplicationOp::None, uint16_t,
823 uint16_t>(const uint16_t* __restrict src, uint16_t* __restrict dst) {
824 dst[0] = src[0];
825 dst[1] = src[3];
828 template <>
829 MOZ_ALWAYS_INLINE void
830 pack<WebGLTexelFormat::RA16F, WebGLTexelPremultiplicationOp::Premultiply,
831 uint16_t, uint16_t>(const uint16_t* __restrict src,
832 uint16_t* __restrict dst) {
833 float scaleFactor = unpackFromFloat16(src[3]);
834 dst[0] = packToFloat16(unpackFromFloat16(src[0]) * scaleFactor);
835 dst[1] = src[3];
838 template <>
839 MOZ_ALWAYS_INLINE void
840 pack<WebGLTexelFormat::RA16F, WebGLTexelPremultiplicationOp::Unpremultiply,
841 uint16_t, uint16_t>(const uint16_t* __restrict src,
842 uint16_t* __restrict dst) {
843 float unpackedAlpha = unpackFromFloat16(src[3]);
844 float scaleFactor = unpackedAlpha ? 1.0f / unpackedAlpha : 1.0f;
845 dst[0] = packToFloat16(unpackFromFloat16(src[0]) * scaleFactor);
846 dst[1] = src[3];
849 template <>
850 MOZ_ALWAYS_INLINE void pack<WebGLTexelFormat::RA32F,
851 WebGLTexelPremultiplicationOp::None, float, float>(
852 const float* __restrict src, float* __restrict dst) {
853 dst[0] = src[0];
854 dst[1] = src[3];
857 template <>
858 MOZ_ALWAYS_INLINE void
859 pack<WebGLTexelFormat::RA32F, WebGLTexelPremultiplicationOp::Premultiply, float,
860 float>(const float* __restrict src, float* __restrict dst) {
861 float scaleFactor = src[3];
862 dst[0] = src[0] * scaleFactor;
863 dst[1] = src[3];
866 template <>
867 MOZ_ALWAYS_INLINE void
868 pack<WebGLTexelFormat::RA32F, WebGLTexelPremultiplicationOp::Unpremultiply,
869 float, float>(const float* __restrict src, float* __restrict dst) {
870 float scaleFactor = src[3] ? 1.0f / src[3] : 1.0f;
871 dst[0] = src[0] * scaleFactor;
872 dst[1] = src[3];
875 template <>
876 MOZ_ALWAYS_INLINE void
877 pack<WebGLTexelFormat::RG8, WebGLTexelPremultiplicationOp::None, uint8_t,
878 uint8_t>(const uint8_t* __restrict src, uint8_t* __restrict dst) {
879 dst[0] = src[0];
880 dst[1] = src[1];
883 template <>
884 MOZ_ALWAYS_INLINE void
885 pack<WebGLTexelFormat::RG8, WebGLTexelPremultiplicationOp::Premultiply, uint8_t,
886 uint8_t>(const uint8_t* __restrict src, uint8_t* __restrict dst) {
887 float scaleFactor = src[3] / 255.0f;
888 uint8_t srcR = static_cast<uint8_t>(src[0] * scaleFactor);
889 uint8_t srcG = static_cast<uint8_t>(src[1] * scaleFactor);
890 dst[0] = srcR;
891 dst[1] = srcG;
894 // FIXME: this routine is lossy and must be removed.
895 template <>
896 MOZ_ALWAYS_INLINE void
897 pack<WebGLTexelFormat::RG8, WebGLTexelPremultiplicationOp::Unpremultiply,
898 uint8_t, uint8_t>(const uint8_t* __restrict src, uint8_t* __restrict dst) {
899 float scaleFactor = src[3] ? 255.0f / src[3] : 1.0f;
900 uint8_t srcR = static_cast<uint8_t>(src[0] * scaleFactor);
901 uint8_t srcG = static_cast<uint8_t>(src[1] * scaleFactor);
902 dst[0] = srcR;
903 dst[1] = srcG;
906 template <>
907 MOZ_ALWAYS_INLINE void
908 pack<WebGLTexelFormat::RG16F, WebGLTexelPremultiplicationOp::None, uint16_t,
909 uint16_t>(const uint16_t* __restrict src, uint16_t* __restrict dst) {
910 dst[0] = src[0];
911 dst[1] = src[1];
914 template <>
915 MOZ_ALWAYS_INLINE void
916 pack<WebGLTexelFormat::RG16F, WebGLTexelPremultiplicationOp::Premultiply,
917 uint16_t, uint16_t>(const uint16_t* __restrict src,
918 uint16_t* __restrict dst) {
919 float scaleFactor = unpackFromFloat16(src[3]);
920 dst[0] = packToFloat16(unpackFromFloat16(src[0]) * scaleFactor);
921 dst[1] = packToFloat16(unpackFromFloat16(src[1]) * scaleFactor);
924 template <>
925 MOZ_ALWAYS_INLINE void
926 pack<WebGLTexelFormat::RG16F, WebGLTexelPremultiplicationOp::Unpremultiply,
927 uint16_t, uint16_t>(const uint16_t* __restrict src,
928 uint16_t* __restrict dst) {
929 float unpackedAlpha = unpackFromFloat16(src[3]);
930 float scaleFactor = unpackedAlpha ? 1.0f / unpackedAlpha : 1.0f;
931 dst[0] = packToFloat16(unpackFromFloat16(src[0]) * scaleFactor);
932 dst[1] = packToFloat16(unpackFromFloat16(src[1]) * scaleFactor);
935 template <>
936 MOZ_ALWAYS_INLINE void pack<WebGLTexelFormat::RG32F,
937 WebGLTexelPremultiplicationOp::None, float, float>(
938 const float* __restrict src, float* __restrict dst) {
939 dst[0] = src[0];
940 dst[1] = src[1];
943 template <>
944 MOZ_ALWAYS_INLINE void
945 pack<WebGLTexelFormat::RG32F, WebGLTexelPremultiplicationOp::Premultiply, float,
946 float>(const float* __restrict src, float* __restrict dst) {
947 float scaleFactor = src[3];
948 dst[0] = src[0] * scaleFactor;
949 dst[1] = src[1] * scaleFactor;
952 template <>
953 MOZ_ALWAYS_INLINE void
954 pack<WebGLTexelFormat::RG32F, WebGLTexelPremultiplicationOp::Unpremultiply,
955 float, float>(const float* __restrict src, float* __restrict dst) {
956 float scaleFactor = src[3] ? 1.0f / src[3] : 1.0f;
957 dst[0] = src[0] * scaleFactor;
958 dst[1] = src[1] * scaleFactor;
961 ////////////////////////////////////////////////////////////////////////////////
962 // 3-channel formats
963 template <>
964 MOZ_ALWAYS_INLINE void
965 pack<WebGLTexelFormat::RGB565, WebGLTexelPremultiplicationOp::None, uint8_t,
966 uint16_t>(const uint8_t* __restrict src, uint16_t* __restrict dst) {
967 *dst = uint16_t(((src[0] & 0xF8) << 8) | ((src[1] & 0xFC) << 3) |
968 ((src[2] & 0xF8) >> 3));
971 template <>
972 MOZ_ALWAYS_INLINE void
973 pack<WebGLTexelFormat::RGB565, WebGLTexelPremultiplicationOp::Premultiply,
974 uint8_t, uint16_t>(const uint8_t* __restrict src,
975 uint16_t* __restrict dst) {
976 float scaleFactor = src[3] / 255.0f;
977 uint8_t srcR = static_cast<uint8_t>(src[0] * scaleFactor);
978 uint8_t srcG = static_cast<uint8_t>(src[1] * scaleFactor);
979 uint8_t srcB = static_cast<uint8_t>(src[2] * scaleFactor);
980 *dst = uint16_t(((srcR & 0xF8) << 8) | ((srcG & 0xFC) << 3) |
981 ((srcB & 0xF8) >> 3));
984 // FIXME: this routine is lossy and must be removed.
985 template <>
986 MOZ_ALWAYS_INLINE void
987 pack<WebGLTexelFormat::RGB565, WebGLTexelPremultiplicationOp::Unpremultiply,
988 uint8_t, uint16_t>(const uint8_t* __restrict src,
989 uint16_t* __restrict dst) {
990 float scaleFactor = src[3] ? 255.0f / src[3] : 1.0f;
991 uint8_t srcR = static_cast<uint8_t>(src[0] * scaleFactor);
992 uint8_t srcG = static_cast<uint8_t>(src[1] * scaleFactor);
993 uint8_t srcB = static_cast<uint8_t>(src[2] * scaleFactor);
994 *dst = uint16_t(((srcR & 0xF8) << 8) | ((srcG & 0xFC) << 3) |
995 ((srcB & 0xF8) >> 3));
998 template <>
999 MOZ_ALWAYS_INLINE void
1000 pack<WebGLTexelFormat::RGB8, WebGLTexelPremultiplicationOp::None, uint8_t,
1001 uint8_t>(const uint8_t* __restrict src, uint8_t* __restrict dst) {
1002 dst[0] = src[0];
1003 dst[1] = src[1];
1004 dst[2] = src[2];
1007 template <>
1008 MOZ_ALWAYS_INLINE void
1009 pack<WebGLTexelFormat::RGB8, WebGLTexelPremultiplicationOp::Premultiply,
1010 uint8_t, uint8_t>(const uint8_t* __restrict src, uint8_t* __restrict dst) {
1011 float scaleFactor = src[3] / 255.0f;
1012 uint8_t srcR = static_cast<uint8_t>(src[0] * scaleFactor);
1013 uint8_t srcG = static_cast<uint8_t>(src[1] * scaleFactor);
1014 uint8_t srcB = static_cast<uint8_t>(src[2] * scaleFactor);
1015 dst[0] = srcR;
1016 dst[1] = srcG;
1017 dst[2] = srcB;
1020 template <>
1021 MOZ_ALWAYS_INLINE void
1022 pack<WebGLTexelFormat::RGB8, WebGLTexelPremultiplicationOp::Unpremultiply,
1023 uint8_t, uint8_t>(const uint8_t* __restrict src, uint8_t* __restrict dst) {
1024 float scaleFactor = src[3] ? 255.0f / src[3] : 1.0f;
1025 uint8_t srcR = static_cast<uint8_t>(src[0] * scaleFactor);
1026 uint8_t srcG = static_cast<uint8_t>(src[1] * scaleFactor);
1027 uint8_t srcB = static_cast<uint8_t>(src[2] * scaleFactor);
1028 dst[0] = srcR;
1029 dst[1] = srcG;
1030 dst[2] = srcB;
1033 template <>
1034 MOZ_ALWAYS_INLINE void
1035 pack<WebGLTexelFormat::RGB11F11F10F, WebGLTexelPremultiplicationOp::None, float,
1036 uint32_t>(const float* __restrict src, uint32_t* __restrict dst) {
1037 dst[0] = ((packToFloat11(src[0]) << 0) | (packToFloat11(src[1]) << 11) |
1038 (packToFloat10(src[2]) << 22));
1041 template <>
1042 MOZ_ALWAYS_INLINE void
1043 pack<WebGLTexelFormat::RGB11F11F10F, WebGLTexelPremultiplicationOp::Premultiply,
1044 float, uint32_t>(const float* __restrict src, uint32_t* __restrict dst) {
1045 float scaleFactor = src[3];
1046 dst[0] = ((packToFloat11(src[0] * scaleFactor) << 0) |
1047 (packToFloat11(src[1] * scaleFactor) << 11) |
1048 (packToFloat10(src[2] * scaleFactor) << 22));
1051 template <>
1052 MOZ_ALWAYS_INLINE void pack<WebGLTexelFormat::RGB11F11F10F,
1053 WebGLTexelPremultiplicationOp::Unpremultiply, float,
1054 uint32_t>(const float* __restrict src,
1055 uint32_t* __restrict dst) {
1056 float scaleFactor = src[3] ? 1.0f / src[3] : 1.0f;
1057 dst[0] = ((packToFloat11(src[0] * scaleFactor) << 0) |
1058 (packToFloat11(src[1] * scaleFactor) << 11) |
1059 (packToFloat10(src[2] * scaleFactor) << 22));
1062 template <>
1063 MOZ_ALWAYS_INLINE void
1064 pack<WebGLTexelFormat::RGB16F, WebGLTexelPremultiplicationOp::None, uint16_t,
1065 uint16_t>(const uint16_t* __restrict src, uint16_t* __restrict dst) {
1066 dst[0] = src[0];
1067 dst[1] = src[1];
1068 dst[2] = src[2];
1071 template <>
1072 MOZ_ALWAYS_INLINE void
1073 pack<WebGLTexelFormat::RGB16F, WebGLTexelPremultiplicationOp::Premultiply,
1074 uint16_t, uint16_t>(const uint16_t* __restrict src,
1075 uint16_t* __restrict dst) {
1076 float scaleFactor = unpackFromFloat16(src[3]);
1077 dst[0] = packToFloat16(unpackFromFloat16(src[0]) * scaleFactor);
1078 dst[1] = packToFloat16(unpackFromFloat16(src[1]) * scaleFactor);
1079 dst[2] = packToFloat16(unpackFromFloat16(src[2]) * scaleFactor);
1082 template <>
1083 MOZ_ALWAYS_INLINE void
1084 pack<WebGLTexelFormat::RGB16F, WebGLTexelPremultiplicationOp::Unpremultiply,
1085 uint16_t, uint16_t>(const uint16_t* __restrict src,
1086 uint16_t* __restrict dst) {
1087 float unpackedAlpha = unpackFromFloat16(src[3]);
1088 float scaleFactor = unpackedAlpha ? 1.0f / unpackedAlpha : 1.0f;
1089 dst[0] = packToFloat16(unpackFromFloat16(src[0]) * scaleFactor);
1090 dst[1] = packToFloat16(unpackFromFloat16(src[1]) * scaleFactor);
1091 dst[2] = packToFloat16(unpackFromFloat16(src[2]) * scaleFactor);
1094 template <>
1095 MOZ_ALWAYS_INLINE void pack<WebGLTexelFormat::RGB32F,
1096 WebGLTexelPremultiplicationOp::None, float, float>(
1097 const float* __restrict src, float* __restrict dst) {
1098 dst[0] = src[0];
1099 dst[1] = src[1];
1100 dst[2] = src[2];
1103 template <>
1104 MOZ_ALWAYS_INLINE void
1105 pack<WebGLTexelFormat::RGB32F, WebGLTexelPremultiplicationOp::Premultiply,
1106 float, float>(const float* __restrict src, float* __restrict dst) {
1107 float scaleFactor = src[3];
1108 dst[0] = src[0] * scaleFactor;
1109 dst[1] = src[1] * scaleFactor;
1110 dst[2] = src[2] * scaleFactor;
1113 template <>
1114 MOZ_ALWAYS_INLINE void
1115 pack<WebGLTexelFormat::RGB32F, WebGLTexelPremultiplicationOp::Unpremultiply,
1116 float, float>(const float* __restrict src, float* __restrict dst) {
1117 float scaleFactor = src[3] ? 1.0f / src[3] : 1.0f;
1118 dst[0] = src[0] * scaleFactor;
1119 dst[1] = src[1] * scaleFactor;
1120 dst[2] = src[2] * scaleFactor;
1123 ////////////////////////////////////////////////////////////////////////////////
1124 // 4-channel formats
1125 template <>
1126 MOZ_ALWAYS_INLINE void
1127 pack<WebGLTexelFormat::RGBA4444, WebGLTexelPremultiplicationOp::None, uint8_t,
1128 uint16_t>(const uint8_t* __restrict src, uint16_t* __restrict dst) {
1129 *dst = uint16_t(((src[0] & 0xF0) << 8) | ((src[1] & 0xF0) << 4) |
1130 (src[2] & 0xF0) | (src[3] >> 4));
1133 template <>
1134 MOZ_ALWAYS_INLINE void
1135 pack<WebGLTexelFormat::RGBA4444, WebGLTexelPremultiplicationOp::Premultiply,
1136 uint8_t, uint16_t>(const uint8_t* __restrict src,
1137 uint16_t* __restrict dst) {
1138 float scaleFactor = src[3] / 255.0f;
1139 uint8_t srcR = static_cast<uint8_t>(src[0] * scaleFactor);
1140 uint8_t srcG = static_cast<uint8_t>(src[1] * scaleFactor);
1141 uint8_t srcB = static_cast<uint8_t>(src[2] * scaleFactor);
1142 *dst = uint16_t(((srcR & 0xF0) << 8) | ((srcG & 0xF0) << 4) | (srcB & 0xF0) |
1143 (src[3] >> 4));
1146 // FIXME: this routine is lossy and must be removed.
1147 template <>
1148 MOZ_ALWAYS_INLINE void
1149 pack<WebGLTexelFormat::RGBA4444, WebGLTexelPremultiplicationOp::Unpremultiply,
1150 uint8_t, uint16_t>(const uint8_t* __restrict src,
1151 uint16_t* __restrict dst) {
1152 float scaleFactor = src[3] ? 255.0f / src[3] : 1.0f;
1153 uint8_t srcR = static_cast<uint8_t>(src[0] * scaleFactor);
1154 uint8_t srcG = static_cast<uint8_t>(src[1] * scaleFactor);
1155 uint8_t srcB = static_cast<uint8_t>(src[2] * scaleFactor);
1156 *dst = uint16_t(((srcR & 0xF0) << 8) | ((srcG & 0xF0) << 4) | (srcB & 0xF0) |
1157 (src[3] >> 4));
1160 template <>
1161 MOZ_ALWAYS_INLINE void
1162 pack<WebGLTexelFormat::RGBA5551, WebGLTexelPremultiplicationOp::None, uint8_t,
1163 uint16_t>(const uint8_t* __restrict src, uint16_t* __restrict dst) {
1164 *dst = uint16_t(((src[0] & 0xF8) << 8) | ((src[1] & 0xF8) << 3) |
1165 ((src[2] & 0xF8) >> 2) | (src[3] >> 7));
1168 template <>
1169 MOZ_ALWAYS_INLINE void
1170 pack<WebGLTexelFormat::RGBA5551, WebGLTexelPremultiplicationOp::Premultiply,
1171 uint8_t, uint16_t>(const uint8_t* __restrict src,
1172 uint16_t* __restrict dst) {
1173 float scaleFactor = src[3] / 255.0f;
1174 uint8_t srcR = static_cast<uint8_t>(src[0] * scaleFactor);
1175 uint8_t srcG = static_cast<uint8_t>(src[1] * scaleFactor);
1176 uint8_t srcB = static_cast<uint8_t>(src[2] * scaleFactor);
1177 *dst = uint16_t(((srcR & 0xF8) << 8) | ((srcG & 0xF8) << 3) |
1178 ((srcB & 0xF8) >> 2) | (src[3] >> 7));
1181 // FIXME: this routine is lossy and must be removed.
1182 template <>
1183 MOZ_ALWAYS_INLINE void
1184 pack<WebGLTexelFormat::RGBA5551, WebGLTexelPremultiplicationOp::Unpremultiply,
1185 uint8_t, uint16_t>(const uint8_t* __restrict src,
1186 uint16_t* __restrict dst) {
1187 float scaleFactor = src[3] ? 255.0f / src[3] : 1.0f;
1188 uint8_t srcR = static_cast<uint8_t>(src[0] * scaleFactor);
1189 uint8_t srcG = static_cast<uint8_t>(src[1] * scaleFactor);
1190 uint8_t srcB = static_cast<uint8_t>(src[2] * scaleFactor);
1191 *dst = uint16_t(((srcR & 0xF8) << 8) | ((srcG & 0xF8) << 3) |
1192 ((srcB & 0xF8) >> 2) | (src[3] >> 7));
1195 template <>
1196 MOZ_ALWAYS_INLINE void
1197 pack<WebGLTexelFormat::RGBA8, WebGLTexelPremultiplicationOp::None, uint8_t,
1198 uint8_t>(const uint8_t* __restrict src, uint8_t* __restrict dst) {
1199 dst[0] = src[0];
1200 dst[1] = src[1];
1201 dst[2] = src[2];
1202 dst[3] = src[3];
1205 template <>
1206 MOZ_ALWAYS_INLINE void
1207 pack<WebGLTexelFormat::RGBA8, WebGLTexelPremultiplicationOp::Premultiply,
1208 uint8_t, uint8_t>(const uint8_t* __restrict src, uint8_t* __restrict dst) {
1209 float scaleFactor = src[3] / 255.0f;
1210 uint8_t srcR = static_cast<uint8_t>(src[0] * scaleFactor);
1211 uint8_t srcG = static_cast<uint8_t>(src[1] * scaleFactor);
1212 uint8_t srcB = static_cast<uint8_t>(src[2] * scaleFactor);
1213 dst[0] = srcR;
1214 dst[1] = srcG;
1215 dst[2] = srcB;
1216 dst[3] = src[3];
1219 // FIXME: this routine is lossy and must be removed.
1220 template <>
1221 MOZ_ALWAYS_INLINE void
1222 pack<WebGLTexelFormat::RGBA8, WebGLTexelPremultiplicationOp::Unpremultiply,
1223 uint8_t, uint8_t>(const uint8_t* __restrict src, uint8_t* __restrict dst) {
1224 float scaleFactor = src[3] ? 255.0f / src[3] : 1.0f;
1225 uint8_t srcR = static_cast<uint8_t>(src[0] * scaleFactor);
1226 uint8_t srcG = static_cast<uint8_t>(src[1] * scaleFactor);
1227 uint8_t srcB = static_cast<uint8_t>(src[2] * scaleFactor);
1228 dst[0] = srcR;
1229 dst[1] = srcG;
1230 dst[2] = srcB;
1231 dst[3] = src[3];
1234 template <>
1235 MOZ_ALWAYS_INLINE void
1236 pack<WebGLTexelFormat::BGRA8, WebGLTexelPremultiplicationOp::None, uint8_t,
1237 uint8_t>(const uint8_t* __restrict src, uint8_t* __restrict dst) {
1238 dst[0] = src[2];
1239 dst[1] = src[1];
1240 dst[2] = src[0];
1241 dst[3] = src[3];
1244 template <>
1245 MOZ_ALWAYS_INLINE void
1246 pack<WebGLTexelFormat::BGRA8, WebGLTexelPremultiplicationOp::Premultiply,
1247 uint8_t, uint8_t>(const uint8_t* __restrict src, uint8_t* __restrict dst) {
1248 float scaleFactor = src[3] / 255.0f;
1249 uint8_t srcR = static_cast<uint8_t>(src[0] * scaleFactor);
1250 uint8_t srcG = static_cast<uint8_t>(src[1] * scaleFactor);
1251 uint8_t srcB = static_cast<uint8_t>(src[2] * scaleFactor);
1252 dst[0] = srcB;
1253 dst[1] = srcG;
1254 dst[2] = srcR;
1255 dst[3] = src[3];
1258 // FIXME: this routine is lossy and must be removed.
1259 template <>
1260 MOZ_ALWAYS_INLINE void
1261 pack<WebGLTexelFormat::BGRA8, WebGLTexelPremultiplicationOp::Unpremultiply,
1262 uint8_t, uint8_t>(const uint8_t* __restrict src, uint8_t* __restrict dst) {
1263 float scaleFactor = src[3] ? 255.0f / src[3] : 1.0f;
1264 uint8_t srcR = static_cast<uint8_t>(src[0] * scaleFactor);
1265 uint8_t srcG = static_cast<uint8_t>(src[1] * scaleFactor);
1266 uint8_t srcB = static_cast<uint8_t>(src[2] * scaleFactor);
1267 dst[0] = srcB;
1268 dst[1] = srcG;
1269 dst[2] = srcR;
1270 dst[3] = src[3];
1273 template <>
1274 MOZ_ALWAYS_INLINE void
1275 pack<WebGLTexelFormat::RGBA16F, WebGLTexelPremultiplicationOp::None, uint16_t,
1276 uint16_t>(const uint16_t* __restrict src, uint16_t* __restrict dst) {
1277 dst[0] = src[0];
1278 dst[1] = src[1];
1279 dst[2] = src[2];
1280 dst[3] = src[3];
1283 template <>
1284 MOZ_ALWAYS_INLINE void
1285 pack<WebGLTexelFormat::RGBA16F, WebGLTexelPremultiplicationOp::Premultiply,
1286 uint16_t, uint16_t>(const uint16_t* __restrict src,
1287 uint16_t* __restrict dst) {
1288 float scaleFactor = unpackFromFloat16(src[3]);
1289 dst[0] = packToFloat16(unpackFromFloat16(src[0]) * scaleFactor);
1290 dst[1] = packToFloat16(unpackFromFloat16(src[1]) * scaleFactor);
1291 dst[2] = packToFloat16(unpackFromFloat16(src[2]) * scaleFactor);
1292 dst[3] = src[3];
1295 template <>
1296 MOZ_ALWAYS_INLINE void
1297 pack<WebGLTexelFormat::RGBA16F, WebGLTexelPremultiplicationOp::Unpremultiply,
1298 uint16_t, uint16_t>(const uint16_t* __restrict src,
1299 uint16_t* __restrict dst) {
1300 float unpackedAlpha = unpackFromFloat16(src[3]);
1301 float scaleFactor = unpackedAlpha ? 1.0f / unpackedAlpha : 1.0f;
1302 dst[0] = packToFloat16(unpackFromFloat16(src[0]) * scaleFactor);
1303 dst[1] = packToFloat16(unpackFromFloat16(src[1]) * scaleFactor);
1304 dst[2] = packToFloat16(unpackFromFloat16(src[2]) * scaleFactor);
1305 dst[3] = src[3];
1308 template <>
1309 MOZ_ALWAYS_INLINE void pack<WebGLTexelFormat::RGBA32F,
1310 WebGLTexelPremultiplicationOp::None, float, float>(
1311 const float* __restrict src, float* __restrict dst) {
1312 dst[0] = src[0];
1313 dst[1] = src[1];
1314 dst[2] = src[2];
1315 dst[3] = src[3];
1318 template <>
1319 MOZ_ALWAYS_INLINE void
1320 pack<WebGLTexelFormat::RGBA32F, WebGLTexelPremultiplicationOp::Premultiply,
1321 float, float>(const float* __restrict src, float* __restrict dst) {
1322 float scaleFactor = src[3];
1323 dst[0] = src[0] * scaleFactor;
1324 dst[1] = src[1] * scaleFactor;
1325 dst[2] = src[2] * scaleFactor;
1326 dst[3] = src[3];
1329 template <>
1330 MOZ_ALWAYS_INLINE void
1331 pack<WebGLTexelFormat::RGBA32F, WebGLTexelPremultiplicationOp::Unpremultiply,
1332 float, float>(const float* __restrict src, float* __restrict dst) {
1333 float scaleFactor = src[3] ? 1.0f / src[3] : 1.0f;
1334 dst[0] = src[0] * scaleFactor;
1335 dst[1] = src[1] * scaleFactor;
1336 dst[2] = src[2] * scaleFactor;
1337 dst[3] = src[3];
1340 /****** END CODE SHARED WITH WEBKIT ******/
1342 template <typename SrcType, typename DstType>
1343 MOZ_ALWAYS_INLINE void convertType(const SrcType* __restrict src,
1344 DstType* __restrict dst) {
1345 MOZ_ASSERT(false, "Unimplemented texture format conversion");
1348 template <>
1349 MOZ_ALWAYS_INLINE void convertType<uint8_t, uint8_t>(
1350 const uint8_t* __restrict src, uint8_t* __restrict dst) {
1351 dst[0] = src[0];
1352 dst[1] = src[1];
1353 dst[2] = src[2];
1354 dst[3] = src[3];
1357 template <>
1358 MOZ_ALWAYS_INLINE void convertType<uint16_t, uint16_t>(
1359 const uint16_t* __restrict src, uint16_t* __restrict dst) {
1360 dst[0] = src[0];
1361 dst[1] = src[1];
1362 dst[2] = src[2];
1363 dst[3] = src[3];
1366 template <>
1367 MOZ_ALWAYS_INLINE void convertType<float, float>(const float* __restrict src,
1368 float* __restrict dst) {
1369 dst[0] = src[0];
1370 dst[1] = src[1];
1371 dst[2] = src[2];
1372 dst[3] = src[3];
1375 template <>
1376 MOZ_ALWAYS_INLINE void convertType<uint8_t, float>(
1377 const uint8_t* __restrict src, float* __restrict dst) {
1378 const float scaleFactor = 1.f / 255.0f;
1379 dst[0] = src[0] * scaleFactor;
1380 dst[1] = src[1] * scaleFactor;
1381 dst[2] = src[2] * scaleFactor;
1382 dst[3] = src[3] * scaleFactor;
1385 template <>
1386 MOZ_ALWAYS_INLINE void convertType<uint8_t, uint16_t>(
1387 const uint8_t* __restrict src, uint16_t* __restrict dst) {
1388 const float scaleFactor = 1.f / 255.0f;
1389 dst[0] = packToFloat16(src[0] * scaleFactor);
1390 dst[1] = packToFloat16(src[1] * scaleFactor);
1391 dst[2] = packToFloat16(src[2] * scaleFactor);
1392 dst[3] = packToFloat16(src[3] * scaleFactor);
1395 } // end namespace WebGLTexelConversions
1397 } // end namespace mozilla
1399 #endif // WEBGLTEXELCONVERSIONS_H_