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