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
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_
35 #include "WebGLTypes.h"
37 #include "mozilla/Attributes.h"
41 // single precision float
42 // seeeeeeeemmmmmmmmmmmmmmmmmmmmmmm
44 // half precision float
47 // IEEE 16bits floating point:
48 const uint16_t kFloat16Value_Zero
= 0x0000; // = 0000000000000000b
49 const uint16_t kFloat16Value_One
= 0x3C00; // = 0011110000000000b
50 const uint16_t kFloat16Value_Infinity
= 0x7C00; // = 0111110000000000b
51 const uint16_t kFloat16Value_NaN
= 0x7FFF; // = 011111yyyyyyyyyyb (nonzero y)
53 MOZ_ALWAYS_INLINE
uint16_t
54 packToFloat16(float v
)
63 // pull the sign from v into f16bits
64 uint16_t f16Bits
= uint16_t(f32Bits
>> 16) & 0x8000;
65 const uint32_t mantissa
= f32Bits
& 0x7FFFFF;
66 const uint32_t exp
= (f32Bits
>> 23) & 0xFF;
68 // Adapted from: OpenGL ES 2.0 Programming Guide Appx.
69 // Converting Float to Half-Float
70 // 143 = 255 - 127 + 15
71 // = sp_max - sp_bias + hp_bias
73 if (mantissa
&& exp
== 0xFF) {
74 // Single precision was NaN
75 return f16Bits
| kFloat16Value_NaN
;
77 // Outside range, store as infinity
78 return f16Bits
| kFloat16Value_Infinity
;
82 // too small, try to make a denormalized number
83 // 112 = 255 - 127 - (15 + 1)
84 // = sp_max - sp_bias - (hp_bias + 1)
86 return f16Bits
| uint16_t(mantissa
>> (14 + 112 - exp
));
89 f16Bits
|= uint16_t(exp
- 112) << 10;
90 f16Bits
|= uint16_t(mantissa
>> 13) & 0x03FF;
95 MOZ_ALWAYS_INLINE
float
96 unpackFromFloat16(uint16_t v
)
104 f32Bits
= uint32_t(v
& 0x8000) << 16;
105 uint16_t exp
= (v
>> 10) & 0x001F;
106 uint16_t mantissa
= v
& 0x03FF;
109 // Handle denormalized numbers
110 // Adapted from: OpenGL ES 2.0 Programming Guide Appx.
111 // Converting Float to Half-Float
113 exp
= 112; // See packToFloat16
115 // For every leading zero, decrement the exponent
116 // and shift the mantissa to the left
117 while ((mantissa
& (1 << 10)) == 0) {
123 f32Bits
|= (exp
<< 23) | (mantissa
<< 13);
125 // Denormalized number
136 f32Bits
|= 0x7FFFFFFF;
138 // this is -inf or +inf
139 f32Bits
|= 0x7F800000;
144 f32Bits
|= uint32_t(exp
+ (-15 + 127)) << 23;
145 f32Bits
|= uint32_t(v
& 0x03FF) << 13;
150 MOZ_BEGIN_ENUM_CLASS(WebGLTexelPremultiplicationOp
, int)
154 MOZ_END_ENUM_CLASS(WebGLTexelPremultiplicationOp
)
156 namespace WebGLTexelConversions
{
158 template<MOZ_ENUM_CLASS_ENUM_TYPE(WebGLTexelFormat
) Format
>
161 static const bool Value
=
162 Format
== WebGLTexelFormat::RGBA32F
||
163 Format
== WebGLTexelFormat::RGB32F
||
164 Format
== WebGLTexelFormat::RA32F
||
165 Format
== WebGLTexelFormat::R32F
||
166 Format
== WebGLTexelFormat::A32F
;
169 template<MOZ_ENUM_CLASS_ENUM_TYPE(WebGLTexelFormat
) Format
>
170 struct IsHalfFloatFormat
172 static const bool Value
=
173 Format
== WebGLTexelFormat::RGBA16F
||
174 Format
== WebGLTexelFormat::RGB16F
||
175 Format
== WebGLTexelFormat::RA16F
||
176 Format
== WebGLTexelFormat::R16F
||
177 Format
== WebGLTexelFormat::A16F
;
180 template<MOZ_ENUM_CLASS_ENUM_TYPE(WebGLTexelFormat
) Format
>
183 static const bool Value
=
184 Format
== WebGLTexelFormat::RGBA4444
||
185 Format
== WebGLTexelFormat::RGBA5551
||
186 Format
== WebGLTexelFormat::RGB565
;
189 template<MOZ_ENUM_CLASS_ENUM_TYPE(WebGLTexelFormat
) Format
,
190 bool IsFloat
= IsFloatFormat
<Format
>::Value
,
191 bool Is16bpp
= Is16bppFormat
<Format
>::Value
,
192 bool IsHalfFloat
= IsHalfFloatFormat
<Format
>::Value
>
193 struct DataTypeForFormat
195 typedef uint8_t Type
;
198 template<MOZ_ENUM_CLASS_ENUM_TYPE(WebGLTexelFormat
) Format
>
199 struct DataTypeForFormat
<Format
, true, false, false>
204 template<MOZ_ENUM_CLASS_ENUM_TYPE(WebGLTexelFormat
) Format
>
205 struct DataTypeForFormat
<Format
, false, true, false>
207 typedef uint16_t Type
;
210 template<MOZ_ENUM_CLASS_ENUM_TYPE(WebGLTexelFormat
) Format
>
211 struct DataTypeForFormat
<Format
, false, false, true>
213 typedef uint16_t Type
;
216 template<MOZ_ENUM_CLASS_ENUM_TYPE(WebGLTexelFormat
) Format
>
217 struct IntermediateFormat
219 static const MOZ_ENUM_CLASS_ENUM_TYPE(WebGLTexelFormat
) Value
220 = IsFloatFormat
<Format
>::Value
221 ? WebGLTexelFormat::RGBA32F
222 : IsHalfFloatFormat
<Format
>::Value
? WebGLTexelFormat::RGBA16F
223 : WebGLTexelFormat::RGBA8
;
227 GLFormatForTexelFormat(WebGLTexelFormat format
) {
229 case WebGLTexelFormat::R8
: return LOCAL_GL_LUMINANCE
;
230 case WebGLTexelFormat::A8
: return LOCAL_GL_ALPHA
;
231 case WebGLTexelFormat::RA8
: return LOCAL_GL_LUMINANCE_ALPHA
;
232 case WebGLTexelFormat::RGBA5551
: return LOCAL_GL_RGBA
;
233 case WebGLTexelFormat::RGBA4444
: return LOCAL_GL_RGBA
;
234 case WebGLTexelFormat::RGB565
: return LOCAL_GL_RGB
;
235 case WebGLTexelFormat::RGB8
: return LOCAL_GL_RGB
;
236 case WebGLTexelFormat::RGBA8
: return LOCAL_GL_RGBA
;
237 case WebGLTexelFormat::BGRA8
: return LOCAL_GL_BGRA
;
238 case WebGLTexelFormat::BGRX8
: return LOCAL_GL_BGR
;
239 case WebGLTexelFormat::R32F
: return LOCAL_GL_LUMINANCE
;
240 case WebGLTexelFormat::A32F
: return LOCAL_GL_ALPHA
;
241 case WebGLTexelFormat::RA32F
: return LOCAL_GL_LUMINANCE_ALPHA
;
242 case WebGLTexelFormat::RGB32F
: return LOCAL_GL_RGB
;
243 case WebGLTexelFormat::RGBA32F
: return LOCAL_GL_RGBA
;
244 case WebGLTexelFormat::R16F
: return LOCAL_GL_LUMINANCE
;
245 case WebGLTexelFormat::A16F
: return LOCAL_GL_ALPHA
;
246 case WebGLTexelFormat::RA16F
: return LOCAL_GL_LUMINANCE_ALPHA
;
247 case WebGLTexelFormat::RGB16F
: return LOCAL_GL_RGB
;
248 case WebGLTexelFormat::RGBA16F
: return LOCAL_GL_RGBA
;
250 MOZ_CRASH("Unknown texel format. Coding mistake?");
251 return LOCAL_GL_INVALID_ENUM
;
255 inline size_t TexelBytesForFormat(WebGLTexelFormat format
) {
257 case WebGLTexelFormat::R8
:
258 case WebGLTexelFormat::A8
:
260 case WebGLTexelFormat::RA8
:
261 case WebGLTexelFormat::RGBA5551
:
262 case WebGLTexelFormat::RGBA4444
:
263 case WebGLTexelFormat::RGB565
:
264 case WebGLTexelFormat::R16F
:
265 case WebGLTexelFormat::A16F
:
267 case WebGLTexelFormat::RGB8
:
269 case WebGLTexelFormat::RGBA8
:
270 case WebGLTexelFormat::BGRA8
:
271 case WebGLTexelFormat::BGRX8
:
272 case WebGLTexelFormat::R32F
:
273 case WebGLTexelFormat::A32F
:
274 case WebGLTexelFormat::RA16F
:
276 case WebGLTexelFormat::RGB16F
:
278 case WebGLTexelFormat::RGBA16F
:
279 case WebGLTexelFormat::RA32F
:
281 case WebGLTexelFormat::RGB32F
:
283 case WebGLTexelFormat::RGBA32F
:
286 MOZ_ASSERT(false, "Unknown texel format. Coding mistake?");
291 MOZ_ALWAYS_INLINE
bool HasAlpha(WebGLTexelFormat format
) {
292 return format
== WebGLTexelFormat::A8
||
293 format
== WebGLTexelFormat::A16F
||
294 format
== WebGLTexelFormat::A32F
||
295 format
== WebGLTexelFormat::RA8
||
296 format
== WebGLTexelFormat::RA16F
||
297 format
== WebGLTexelFormat::RA32F
||
298 format
== WebGLTexelFormat::RGBA8
||
299 format
== WebGLTexelFormat::BGRA8
||
300 format
== WebGLTexelFormat::RGBA16F
||
301 format
== WebGLTexelFormat::RGBA32F
||
302 format
== WebGLTexelFormat::RGBA4444
||
303 format
== WebGLTexelFormat::RGBA5551
;
306 MOZ_ALWAYS_INLINE
bool HasColor(WebGLTexelFormat format
) {
307 return format
== WebGLTexelFormat::R8
||
308 format
== WebGLTexelFormat::R16F
||
309 format
== WebGLTexelFormat::R32F
||
310 format
== WebGLTexelFormat::RA8
||
311 format
== WebGLTexelFormat::RA16F
||
312 format
== WebGLTexelFormat::RA32F
||
313 format
== WebGLTexelFormat::RGB8
||
314 format
== WebGLTexelFormat::BGRX8
||
315 format
== WebGLTexelFormat::RGB565
||
316 format
== WebGLTexelFormat::RGB16F
||
317 format
== WebGLTexelFormat::RGB32F
||
318 format
== WebGLTexelFormat::RGBA8
||
319 format
== WebGLTexelFormat::BGRA8
||
320 format
== WebGLTexelFormat::RGBA16F
||
321 format
== WebGLTexelFormat::RGBA32F
||
322 format
== WebGLTexelFormat::RGBA4444
||
323 format
== WebGLTexelFormat::RGBA5551
;
327 /****** BEGIN CODE SHARED WITH WEBKIT ******/
329 // the pack/unpack functions here are originally from this file:
330 // http://trac.webkit.org/browser/trunk/WebCore/platform/graphics/GraphicsContext3D.cpp
332 //----------------------------------------------------------------------
333 // Pixel unpacking routines.
335 template<MOZ_ENUM_CLASS_ENUM_TYPE(WebGLTexelFormat
) Format
, typename SrcType
, typename DstType
>
336 MOZ_ALWAYS_INLINE
void
337 unpack(const SrcType
* __restrict src
,
338 DstType
* __restrict dst
)
340 MOZ_ASSERT(false, "Unimplemented texture format conversion");
343 template<> MOZ_ALWAYS_INLINE
void
344 unpack
<WebGLTexelFormat::RGBA8
, uint8_t, uint8_t>(const uint8_t* __restrict src
, uint8_t* __restrict dst
)
352 template<> MOZ_ALWAYS_INLINE
void
353 unpack
<WebGLTexelFormat::RGB8
, uint8_t, uint8_t>(const uint8_t* __restrict src
, uint8_t* __restrict dst
)
361 template<> MOZ_ALWAYS_INLINE
void
362 unpack
<WebGLTexelFormat::BGRA8
, uint8_t, uint8_t>(const uint8_t* __restrict src
, uint8_t* __restrict dst
)
370 template<> MOZ_ALWAYS_INLINE
void
371 unpack
<WebGLTexelFormat::BGRX8
, uint8_t, uint8_t>(const uint8_t* __restrict src
, uint8_t* __restrict dst
)
379 template<> MOZ_ALWAYS_INLINE
void
380 unpack
<WebGLTexelFormat::RGBA5551
, uint16_t, uint8_t>(const uint16_t* __restrict src
, uint8_t* __restrict dst
)
382 uint16_t packedValue
= src
[0];
383 uint8_t r
= (packedValue
>> 11) & 0x1F;
384 uint8_t g
= (packedValue
>> 6) & 0x1F;
385 uint8_t b
= (packedValue
>> 1) & 0x1F;
386 dst
[0] = (r
<< 3) | (r
& 0x7);
387 dst
[1] = (g
<< 3) | (g
& 0x7);
388 dst
[2] = (b
<< 3) | (b
& 0x7);
389 dst
[3] = (packedValue
& 0x1) ? 0xFF : 0;
392 template<> MOZ_ALWAYS_INLINE
void
393 unpack
<WebGLTexelFormat::RGBA4444
, uint16_t, uint8_t>(const uint16_t* __restrict src
, uint8_t* __restrict dst
)
395 uint16_t packedValue
= src
[0];
396 uint8_t r
= (packedValue
>> 12) & 0x0F;
397 uint8_t g
= (packedValue
>> 8) & 0x0F;
398 uint8_t b
= (packedValue
>> 4) & 0x0F;
399 uint8_t a
= packedValue
& 0x0F;
400 dst
[0] = (r
<< 4) | r
;
401 dst
[1] = (g
<< 4) | g
;
402 dst
[2] = (b
<< 4) | b
;
403 dst
[3] = (a
<< 4) | a
;
406 template<> MOZ_ALWAYS_INLINE
void
407 unpack
<WebGLTexelFormat::RGB565
, uint16_t, uint8_t>(const uint16_t* __restrict src
, uint8_t* __restrict dst
)
409 uint16_t packedValue
= src
[0];
410 uint8_t r
= (packedValue
>> 11) & 0x1F;
411 uint8_t g
= (packedValue
>> 5) & 0x3F;
412 uint8_t b
= packedValue
& 0x1F;
413 dst
[0] = (r
<< 3) | (r
& 0x7);
414 dst
[1] = (g
<< 2) | (g
& 0x3);
415 dst
[2] = (b
<< 3) | (b
& 0x7);
419 template<> MOZ_ALWAYS_INLINE
void
420 unpack
<WebGLTexelFormat::R8
, uint8_t, uint8_t>(const uint8_t* __restrict src
, uint8_t* __restrict dst
)
428 template<> MOZ_ALWAYS_INLINE
void
429 unpack
<WebGLTexelFormat::RA8
, uint8_t, uint8_t>(const uint8_t* __restrict src
, uint8_t* __restrict dst
)
437 template<> MOZ_ALWAYS_INLINE
void
438 unpack
<WebGLTexelFormat::A8
, uint8_t, uint8_t>(const uint8_t* __restrict src
, uint8_t* __restrict dst
)
446 template<> MOZ_ALWAYS_INLINE
void
447 unpack
<WebGLTexelFormat::RGBA32F
, float, float>(const float* __restrict src
, float* __restrict dst
)
455 template<> MOZ_ALWAYS_INLINE
void
456 unpack
<WebGLTexelFormat::RGB32F
, float, float>(const float* __restrict src
, float* __restrict dst
)
464 template<> MOZ_ALWAYS_INLINE
void
465 unpack
<WebGLTexelFormat::R32F
, float, float>(const float* __restrict src
, float* __restrict dst
)
473 template<> MOZ_ALWAYS_INLINE
void
474 unpack
<WebGLTexelFormat::RA32F
, float, float>(const float* __restrict src
, float* __restrict dst
)
482 template<> MOZ_ALWAYS_INLINE
void
483 unpack
<WebGLTexelFormat::A32F
, float, float>(const float* __restrict src
, float* __restrict dst
)
491 template<> MOZ_ALWAYS_INLINE
void
492 unpack
<WebGLTexelFormat::RGBA16F
, uint16_t, uint16_t>(const uint16_t* __restrict src
, uint16_t* __restrict dst
)
500 template<> MOZ_ALWAYS_INLINE
void
501 unpack
<WebGLTexelFormat::RGB16F
, uint16_t, uint16_t>(const uint16_t* __restrict src
, uint16_t* __restrict dst
)
506 dst
[3] = kFloat16Value_One
;
509 template<> MOZ_ALWAYS_INLINE
void
510 unpack
<WebGLTexelFormat::R16F
, uint16_t, uint16_t>(const uint16_t* __restrict src
, uint16_t* __restrict dst
)
515 dst
[3] = kFloat16Value_One
;
518 template<> MOZ_ALWAYS_INLINE
void
519 unpack
<WebGLTexelFormat::RA16F
, uint16_t, uint16_t>(const uint16_t* __restrict src
, uint16_t* __restrict dst
)
527 template<> MOZ_ALWAYS_INLINE
void
528 unpack
<WebGLTexelFormat::A16F
, uint16_t, uint16_t>(const uint16_t* __restrict src
, uint16_t* __restrict dst
)
530 dst
[0] = kFloat16Value_Zero
;
531 dst
[1] = kFloat16Value_Zero
;
532 dst
[2] = kFloat16Value_Zero
;
536 //----------------------------------------------------------------------
537 // Pixel packing routines.
540 template<MOZ_ENUM_CLASS_ENUM_TYPE(WebGLTexelFormat
) Format
,
541 MOZ_ENUM_CLASS_ENUM_TYPE(WebGLTexelPremultiplicationOp
) PremultiplicationOp
,
544 MOZ_ALWAYS_INLINE
void
545 pack(const SrcType
* __restrict src
,
546 DstType
* __restrict dst
)
548 MOZ_ASSERT(false, "Unimplemented texture format conversion");
551 template<> MOZ_ALWAYS_INLINE
void
552 pack
<WebGLTexelFormat::A8
, WebGLTexelPremultiplicationOp::None
, uint8_t, uint8_t>(const uint8_t* __restrict src
, uint8_t* __restrict dst
)
557 template<> MOZ_ALWAYS_INLINE
void
558 pack
<WebGLTexelFormat::A8
, WebGLTexelPremultiplicationOp::Premultiply
, uint8_t, uint8_t>(const uint8_t* __restrict src
, uint8_t* __restrict dst
)
563 template<> MOZ_ALWAYS_INLINE
void
564 pack
<WebGLTexelFormat::A8
, WebGLTexelPremultiplicationOp::Unpremultiply
, uint8_t, uint8_t>(const uint8_t* __restrict src
, uint8_t* __restrict dst
)
569 template<> MOZ_ALWAYS_INLINE
void
570 pack
<WebGLTexelFormat::R8
, WebGLTexelPremultiplicationOp::None
, uint8_t, uint8_t>(const uint8_t* __restrict src
, uint8_t* __restrict dst
)
575 template<> MOZ_ALWAYS_INLINE
void
576 pack
<WebGLTexelFormat::R8
, WebGLTexelPremultiplicationOp::Premultiply
, uint8_t, uint8_t>(const uint8_t* __restrict src
, uint8_t* __restrict dst
)
578 float scaleFactor
= src
[3] / 255.0f
;
579 uint8_t srcR
= static_cast<uint8_t>(src
[0] * scaleFactor
);
583 template<> MOZ_ALWAYS_INLINE
void
584 pack
<WebGLTexelFormat::R8
, WebGLTexelPremultiplicationOp::Unpremultiply
, uint8_t, uint8_t>(const uint8_t* __restrict src
, uint8_t* __restrict dst
)
586 float scaleFactor
= src
[3] ? 255.0f
/ src
[3] : 1.0f
;
587 uint8_t srcR
= static_cast<uint8_t>(src
[0] * scaleFactor
);
591 template<> MOZ_ALWAYS_INLINE
void
592 pack
<WebGLTexelFormat::RA8
, WebGLTexelPremultiplicationOp::None
, uint8_t, uint8_t>(const uint8_t* __restrict src
, uint8_t* __restrict dst
)
598 template<> MOZ_ALWAYS_INLINE
void
599 pack
<WebGLTexelFormat::RA8
, WebGLTexelPremultiplicationOp::Premultiply
, uint8_t, uint8_t>(const uint8_t* __restrict src
, uint8_t* __restrict dst
)
601 float scaleFactor
= src
[3] / 255.0f
;
602 uint8_t srcR
= static_cast<uint8_t>(src
[0] * scaleFactor
);
607 // FIXME: this routine is lossy and must be removed.
608 template<> MOZ_ALWAYS_INLINE
void
609 pack
<WebGLTexelFormat::RA8
, WebGLTexelPremultiplicationOp::Unpremultiply
, uint8_t, uint8_t>(const uint8_t* __restrict src
, uint8_t* __restrict dst
)
611 float scaleFactor
= src
[3] ? 255.0f
/ src
[3] : 1.0f
;
612 uint8_t srcR
= static_cast<uint8_t>(src
[0] * scaleFactor
);
617 template<> MOZ_ALWAYS_INLINE
void
618 pack
<WebGLTexelFormat::RGB8
, WebGLTexelPremultiplicationOp::None
, uint8_t, uint8_t>(const uint8_t* __restrict src
, uint8_t* __restrict dst
)
625 template<> MOZ_ALWAYS_INLINE
void
626 pack
<WebGLTexelFormat::RGB8
, WebGLTexelPremultiplicationOp::Premultiply
, uint8_t, uint8_t>(const uint8_t* __restrict src
, uint8_t* __restrict dst
)
628 float scaleFactor
= src
[3] / 255.0f
;
629 uint8_t srcR
= static_cast<uint8_t>(src
[0] * scaleFactor
);
630 uint8_t srcG
= static_cast<uint8_t>(src
[1] * scaleFactor
);
631 uint8_t srcB
= static_cast<uint8_t>(src
[2] * scaleFactor
);
637 template<> MOZ_ALWAYS_INLINE
void
638 pack
<WebGLTexelFormat::RGB8
, WebGLTexelPremultiplicationOp::Unpremultiply
, uint8_t, uint8_t>(const uint8_t* __restrict src
, uint8_t* __restrict dst
)
640 float scaleFactor
= src
[3] ? 255.0f
/ src
[3] : 1.0f
;
641 uint8_t srcR
= static_cast<uint8_t>(src
[0] * scaleFactor
);
642 uint8_t srcG
= static_cast<uint8_t>(src
[1] * scaleFactor
);
643 uint8_t srcB
= static_cast<uint8_t>(src
[2] * scaleFactor
);
649 template<> MOZ_ALWAYS_INLINE
void
650 pack
<WebGLTexelFormat::RGBA8
, WebGLTexelPremultiplicationOp::None
, uint8_t, uint8_t>(const uint8_t* __restrict src
, uint8_t* __restrict dst
)
658 template<> MOZ_ALWAYS_INLINE
void
659 pack
<WebGLTexelFormat::RGBA8
, WebGLTexelPremultiplicationOp::Premultiply
, uint8_t, uint8_t>(const uint8_t* __restrict src
, uint8_t* __restrict dst
)
661 float scaleFactor
= src
[3] / 255.0f
;
662 uint8_t srcR
= static_cast<uint8_t>(src
[0] * scaleFactor
);
663 uint8_t srcG
= static_cast<uint8_t>(src
[1] * scaleFactor
);
664 uint8_t srcB
= static_cast<uint8_t>(src
[2] * scaleFactor
);
671 // FIXME: this routine is lossy and must be removed.
672 template<> MOZ_ALWAYS_INLINE
void
673 pack
<WebGLTexelFormat::RGBA8
, WebGLTexelPremultiplicationOp::Unpremultiply
, uint8_t, uint8_t>(const uint8_t* __restrict src
, uint8_t* __restrict dst
)
675 float scaleFactor
= src
[3] ? 255.0f
/ src
[3] : 1.0f
;
676 uint8_t srcR
= static_cast<uint8_t>(src
[0] * scaleFactor
);
677 uint8_t srcG
= static_cast<uint8_t>(src
[1] * scaleFactor
);
678 uint8_t srcB
= static_cast<uint8_t>(src
[2] * scaleFactor
);
685 template<> MOZ_ALWAYS_INLINE
void
686 pack
<WebGLTexelFormat::RGBA4444
, WebGLTexelPremultiplicationOp::None
, uint8_t, uint16_t>(const uint8_t* __restrict src
, uint16_t* __restrict dst
)
688 *dst
= ( ((src
[0] & 0xF0) << 8)
689 | ((src
[1] & 0xF0) << 4)
694 template<> MOZ_ALWAYS_INLINE
void
695 pack
<WebGLTexelFormat::RGBA4444
, WebGLTexelPremultiplicationOp::Premultiply
, uint8_t, uint16_t>(const uint8_t* __restrict src
, uint16_t* __restrict dst
)
697 float scaleFactor
= src
[3] / 255.0f
;
698 uint8_t srcR
= static_cast<uint8_t>(src
[0] * scaleFactor
);
699 uint8_t srcG
= static_cast<uint8_t>(src
[1] * scaleFactor
);
700 uint8_t srcB
= static_cast<uint8_t>(src
[2] * scaleFactor
);
701 *dst
= ( ((srcR
& 0xF0) << 8)
702 | ((srcG
& 0xF0) << 4)
707 // FIXME: this routine is lossy and must be removed.
708 template<> MOZ_ALWAYS_INLINE
void
709 pack
<WebGLTexelFormat::RGBA4444
, WebGLTexelPremultiplicationOp::Unpremultiply
, uint8_t, uint16_t>(const uint8_t* __restrict src
, uint16_t* __restrict dst
)
711 float scaleFactor
= src
[3] ? 255.0f
/ src
[3] : 1.0f
;
712 uint8_t srcR
= static_cast<uint8_t>(src
[0] * scaleFactor
);
713 uint8_t srcG
= static_cast<uint8_t>(src
[1] * scaleFactor
);
714 uint8_t srcB
= static_cast<uint8_t>(src
[2] * scaleFactor
);
715 *dst
= ( ((srcR
& 0xF0) << 8)
716 | ((srcG
& 0xF0) << 4)
721 template<> MOZ_ALWAYS_INLINE
void
722 pack
<WebGLTexelFormat::RGBA5551
, WebGLTexelPremultiplicationOp::None
, uint8_t, uint16_t>(const uint8_t* __restrict src
, uint16_t* __restrict dst
)
724 *dst
= ( ((src
[0] & 0xF8) << 8)
725 | ((src
[1] & 0xF8) << 3)
726 | ((src
[2] & 0xF8) >> 2)
730 template<> MOZ_ALWAYS_INLINE
void
731 pack
<WebGLTexelFormat::RGBA5551
, WebGLTexelPremultiplicationOp::Premultiply
, uint8_t, uint16_t>(const uint8_t* __restrict src
, uint16_t* __restrict dst
)
733 float scaleFactor
= src
[3] / 255.0f
;
734 uint8_t srcR
= static_cast<uint8_t>(src
[0] * scaleFactor
);
735 uint8_t srcG
= static_cast<uint8_t>(src
[1] * scaleFactor
);
736 uint8_t srcB
= static_cast<uint8_t>(src
[2] * scaleFactor
);
737 *dst
= ( ((srcR
& 0xF8) << 8)
738 | ((srcG
& 0xF8) << 3)
739 | ((srcB
& 0xF8) >> 2)
743 // FIXME: this routine is lossy and must be removed.
744 template<> MOZ_ALWAYS_INLINE
void
745 pack
<WebGLTexelFormat::RGBA5551
, WebGLTexelPremultiplicationOp::Unpremultiply
, uint8_t, uint16_t>(const uint8_t* __restrict src
, uint16_t* __restrict dst
)
747 float scaleFactor
= src
[3] ? 255.0f
/ src
[3] : 1.0f
;
748 uint8_t srcR
= static_cast<uint8_t>(src
[0] * scaleFactor
);
749 uint8_t srcG
= static_cast<uint8_t>(src
[1] * scaleFactor
);
750 uint8_t srcB
= static_cast<uint8_t>(src
[2] * scaleFactor
);
751 *dst
= ( ((srcR
& 0xF8) << 8)
752 | ((srcG
& 0xF8) << 3)
753 | ((srcB
& 0xF8) >> 2)
757 template<> MOZ_ALWAYS_INLINE
void
758 pack
<WebGLTexelFormat::RGB565
, WebGLTexelPremultiplicationOp::None
, uint8_t, uint16_t>(const uint8_t* __restrict src
, uint16_t* __restrict dst
)
760 *dst
= ( ((src
[0] & 0xF8) << 8)
761 | ((src
[1] & 0xFC) << 3)
762 | ((src
[2] & 0xF8) >> 3));
765 template<> MOZ_ALWAYS_INLINE
void
766 pack
<WebGLTexelFormat::RGB565
, WebGLTexelPremultiplicationOp::Premultiply
, uint8_t, uint16_t>(const uint8_t* __restrict src
, uint16_t* __restrict dst
)
768 float scaleFactor
= src
[3] / 255.0f
;
769 uint8_t srcR
= static_cast<uint8_t>(src
[0] * scaleFactor
);
770 uint8_t srcG
= static_cast<uint8_t>(src
[1] * scaleFactor
);
771 uint8_t srcB
= static_cast<uint8_t>(src
[2] * scaleFactor
);
772 *dst
= ( ((srcR
& 0xF8) << 8)
773 | ((srcG
& 0xFC) << 3)
774 | ((srcB
& 0xF8) >> 3));
777 // FIXME: this routine is lossy and must be removed.
778 template<> MOZ_ALWAYS_INLINE
void
779 pack
<WebGLTexelFormat::RGB565
, WebGLTexelPremultiplicationOp::Unpremultiply
, uint8_t, uint16_t>(const uint8_t* __restrict src
, uint16_t* __restrict dst
)
781 float scaleFactor
= src
[3] ? 255.0f
/ src
[3] : 1.0f
;
782 uint8_t srcR
= static_cast<uint8_t>(src
[0] * scaleFactor
);
783 uint8_t srcG
= static_cast<uint8_t>(src
[1] * scaleFactor
);
784 uint8_t srcB
= static_cast<uint8_t>(src
[2] * scaleFactor
);
785 *dst
= ( ((srcR
& 0xF8) << 8)
786 | ((srcG
& 0xFC) << 3)
787 | ((srcB
& 0xF8) >> 3));
790 template<> MOZ_ALWAYS_INLINE
void
791 pack
<WebGLTexelFormat::RGB32F
, WebGLTexelPremultiplicationOp::None
, float, float>(const float* __restrict src
, float* __restrict dst
)
798 template<> MOZ_ALWAYS_INLINE
void
799 pack
<WebGLTexelFormat::RGB32F
, WebGLTexelPremultiplicationOp::Premultiply
, float, float>(const float* __restrict src
, float* __restrict dst
)
801 float scaleFactor
= src
[3];
802 dst
[0] = src
[0] * scaleFactor
;
803 dst
[1] = src
[1] * scaleFactor
;
804 dst
[2] = src
[2] * scaleFactor
;
807 template<> MOZ_ALWAYS_INLINE
void
808 pack
<WebGLTexelFormat::RGBA32F
, WebGLTexelPremultiplicationOp::None
, float, float>(const float* __restrict src
, float* __restrict dst
)
816 template<> MOZ_ALWAYS_INLINE
void
817 pack
<WebGLTexelFormat::RGBA32F
, WebGLTexelPremultiplicationOp::Premultiply
, float, float>(const float* __restrict src
, float* __restrict dst
)
819 float scaleFactor
= src
[3];
820 dst
[0] = src
[0] * scaleFactor
;
821 dst
[1] = src
[1] * scaleFactor
;
822 dst
[2] = src
[2] * scaleFactor
;
826 template<> MOZ_ALWAYS_INLINE
void
827 pack
<WebGLTexelFormat::A32F
, WebGLTexelPremultiplicationOp::None
, float, float>(const float* __restrict src
, float* __restrict dst
)
832 template<> MOZ_ALWAYS_INLINE
void
833 pack
<WebGLTexelFormat::A32F
, WebGLTexelPremultiplicationOp::Premultiply
, float, float>(const float* __restrict src
, float* __restrict dst
)
838 template<> MOZ_ALWAYS_INLINE
void
839 pack
<WebGLTexelFormat::R32F
, WebGLTexelPremultiplicationOp::None
, float, float>(const float* __restrict src
, float* __restrict dst
)
844 template<> MOZ_ALWAYS_INLINE
void
845 pack
<WebGLTexelFormat::R32F
, WebGLTexelPremultiplicationOp::Premultiply
, float, float>(const float* __restrict src
, float* __restrict dst
)
847 float scaleFactor
= src
[3];
848 dst
[0] = src
[0] * scaleFactor
;
851 template<> MOZ_ALWAYS_INLINE
void
852 pack
<WebGLTexelFormat::RA32F
, WebGLTexelPremultiplicationOp::None
, float, float>(const float* __restrict src
, float* __restrict dst
)
858 template<> MOZ_ALWAYS_INLINE
void
859 pack
<WebGLTexelFormat::RA32F
, WebGLTexelPremultiplicationOp::Premultiply
, float, float>(const float* __restrict src
, float* __restrict dst
)
861 float scaleFactor
= src
[3];
862 dst
[0] = src
[0] * scaleFactor
;
863 dst
[1] = scaleFactor
;
866 template<> MOZ_ALWAYS_INLINE
void
867 pack
<WebGLTexelFormat::RGB16F
, WebGLTexelPremultiplicationOp::None
, uint16_t, uint16_t>(const uint16_t* __restrict src
, uint16_t* __restrict dst
)
874 template<> MOZ_ALWAYS_INLINE
void
875 pack
<WebGLTexelFormat::RGB16F
, WebGLTexelPremultiplicationOp::Premultiply
, uint16_t, uint16_t>(const uint16_t* __restrict src
, uint16_t* __restrict dst
)
877 float scaleFactor
= unpackFromFloat16(src
[3]);
878 dst
[0] = packToFloat16(unpackFromFloat16(src
[0]) * scaleFactor
);
879 dst
[1] = packToFloat16(unpackFromFloat16(src
[1]) * scaleFactor
);
880 dst
[2] = packToFloat16(unpackFromFloat16(src
[2]) * scaleFactor
);
883 template<> MOZ_ALWAYS_INLINE
void
884 pack
<WebGLTexelFormat::RGBA16F
, WebGLTexelPremultiplicationOp::None
, uint16_t, uint16_t>(const uint16_t* __restrict src
, uint16_t* __restrict dst
)
892 template<> MOZ_ALWAYS_INLINE
void
893 pack
<WebGLTexelFormat::RGBA16F
, WebGLTexelPremultiplicationOp::Premultiply
, uint16_t, uint16_t>(const uint16_t* __restrict src
, uint16_t* __restrict dst
)
895 float scaleFactor
= unpackFromFloat16(src
[3]);
896 dst
[0] = packToFloat16(unpackFromFloat16(src
[0]) * scaleFactor
);
897 dst
[1] = packToFloat16(unpackFromFloat16(src
[1]) * scaleFactor
);
898 dst
[2] = packToFloat16(unpackFromFloat16(src
[2]) * scaleFactor
);
902 template<> MOZ_ALWAYS_INLINE
void
903 pack
<WebGLTexelFormat::A16F
, WebGLTexelPremultiplicationOp::None
, uint16_t, uint16_t>(const uint16_t* __restrict src
, uint16_t* __restrict dst
)
908 template<> MOZ_ALWAYS_INLINE
void
909 pack
<WebGLTexelFormat::A16F
, WebGLTexelPremultiplicationOp::Premultiply
, uint16_t, uint16_t>(const uint16_t* __restrict src
, uint16_t* __restrict dst
)
914 template<> MOZ_ALWAYS_INLINE
void
915 pack
<WebGLTexelFormat::R16F
, WebGLTexelPremultiplicationOp::None
, uint16_t, uint16_t>(const uint16_t* __restrict src
, uint16_t* __restrict dst
)
920 template<> MOZ_ALWAYS_INLINE
void
921 pack
<WebGLTexelFormat::R16F
, WebGLTexelPremultiplicationOp::Premultiply
, uint16_t, uint16_t>(const uint16_t* __restrict src
, uint16_t* __restrict dst
)
923 float scaleFactor
= unpackFromFloat16(src
[3]);
924 dst
[0] = packToFloat16(unpackFromFloat16(src
[0]) * scaleFactor
);
927 template<> MOZ_ALWAYS_INLINE
void
928 pack
<WebGLTexelFormat::RA16F
, WebGLTexelPremultiplicationOp::None
, uint16_t, uint16_t>(const uint16_t* __restrict src
, uint16_t* __restrict dst
)
934 template<> MOZ_ALWAYS_INLINE
void
935 pack
<WebGLTexelFormat::RA16F
, WebGLTexelPremultiplicationOp::Premultiply
, uint16_t, uint16_t>(const uint16_t* __restrict src
, uint16_t* __restrict dst
)
937 float scaleFactor
= unpackFromFloat16(src
[3]);
938 dst
[0] = packToFloat16(unpackFromFloat16(src
[0]) * scaleFactor
);
939 dst
[1] = scaleFactor
;
942 /****** END CODE SHARED WITH WEBKIT ******/
944 template<typename SrcType
, typename DstType
> MOZ_ALWAYS_INLINE
void
945 convertType(const SrcType
* __restrict src
, DstType
* __restrict dst
)
947 MOZ_ASSERT(false, "Unimplemented texture format conversion");
950 template<> MOZ_ALWAYS_INLINE
void
951 convertType
<uint8_t, uint8_t>(const uint8_t* __restrict src
, uint8_t* __restrict dst
)
959 template<> MOZ_ALWAYS_INLINE
void
960 convertType
<uint16_t, uint16_t>(const uint16_t* __restrict src
, uint16_t* __restrict dst
)
968 template<> MOZ_ALWAYS_INLINE
void
969 convertType
<float, float>(const float* __restrict src
, float* __restrict dst
)
977 template<> MOZ_ALWAYS_INLINE
void
978 convertType
<uint8_t, float>(const uint8_t* __restrict src
, float* __restrict dst
)
980 const float scaleFactor
= 1.f
/ 255.0f
;
981 dst
[0] = src
[0] * scaleFactor
;
982 dst
[1] = src
[1] * scaleFactor
;
983 dst
[2] = src
[2] * scaleFactor
;
984 dst
[3] = src
[3] * scaleFactor
;
987 template<> MOZ_ALWAYS_INLINE
void
988 convertType
<uint8_t, uint16_t>(const uint8_t* __restrict src
, uint16_t* __restrict dst
)
990 const float scaleFactor
= 1.f
/ 255.0f
;
991 dst
[0] = packToFloat16(src
[0] * scaleFactor
);
992 dst
[1] = packToFloat16(src
[1] * scaleFactor
);
993 dst
[2] = packToFloat16(src
[2] * scaleFactor
);
994 dst
[3] = packToFloat16(src
[3] * scaleFactor
);
997 } // end namespace WebGLTexelConversions
999 } // end namespace mozilla
1001 #endif // WEBGLTEXELCONVERSIONS_H_