Thu, 15 Jan 2015 21:03:48 +0100
Integrate friendly tips from Tor colleagues to make (or not) 4.5 alpha 3;
This includes removal of overloaded (but unused) methods, and addition of
a overlooked call to DataStruct::SetData(nsISupports, uint32_t, bool.)
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 */
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"
39 namespace mozilla {
41 // single precision float
42 // seeeeeeeemmmmmmmmmmmmmmmmmmmmmmm
44 // half precision float
45 // seeeeemmmmmmmmmm
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)
55 {
56 union {
57 float f32Value;
58 uint32_t f32Bits;
59 };
61 f32Value = v;
63 // pull the sign from v into f16bits
64 uint16_t f16Bits = uint16_t(f32Bits >> 16) & 0x8000;
66 // handle +/- 0
67 if ((f32Bits & 0x7FFFFFFF) == 0x00000000) {
68 return f16Bits;
69 }
71 // handle NaN
72 if (f32Value != f32Value) {
73 return f16Bits | kFloat16Value_NaN;
74 }
76 int32_t exp = int32_t(f32Bits >> 23) - 127;
78 // too small, we clamp it to -0 or +0
79 if (exp < -14) {
80 return f16Bits;
81 }
83 // too big, we clamp it to -inf/+inf
84 if (exp > 15) {
85 return f16Bits | kFloat16Value_Infinity;
86 }
88 f16Bits |= uint16_t(exp + 15) << 10;
89 f16Bits |= uint16_t(f32Bits >> 13) & 0x03FF;
91 return f16Bits;
92 }
94 MOZ_ALWAYS_INLINE float
95 unpackFromFloat16(uint16_t v)
96 {
97 union
98 {
99 float f32Value;
100 uint32_t f32Bits;
101 };
103 // grab sign bit
104 f32Bits = uint32_t(v & 0x8000) << 16;
106 if ((v & 0x7FFF) == 0x0000) {
107 // +0 or -0
108 return f32Value;
109 }
111 uint16_t exp = (v >> 10) & 0x001F;
112 if (exp == 0x001F) {
113 if (v & 0x03FF) {
114 // this is a NaN
115 f32Bits |= 0x7FFFFFFF;
116 } else {
117 // this is -inf or +inf
118 f32Bits |= 0x7F800000;
119 }
120 return f32Value;
121 }
123 f32Bits |= uint32_t(exp + (-15 + 127)) << 10;
124 f32Bits |= uint32_t(v & 0x03FF) << 13;
126 return f32Value;
127 }
129 MOZ_BEGIN_ENUM_CLASS(WebGLTexelPremultiplicationOp, int)
130 None,
131 Premultiply,
132 Unpremultiply
133 MOZ_END_ENUM_CLASS(WebGLTexelPremultiplicationOp)
135 namespace WebGLTexelConversions {
137 template<MOZ_ENUM_CLASS_ENUM_TYPE(WebGLTexelFormat) Format>
138 struct IsFloatFormat
139 {
140 static const bool Value =
141 Format == WebGLTexelFormat::RGBA32F ||
142 Format == WebGLTexelFormat::RGB32F ||
143 Format == WebGLTexelFormat::RA32F ||
144 Format == WebGLTexelFormat::R32F ||
145 Format == WebGLTexelFormat::A32F;
146 };
148 template<MOZ_ENUM_CLASS_ENUM_TYPE(WebGLTexelFormat) Format>
149 struct IsHalfFloatFormat
150 {
151 static const bool Value =
152 Format == WebGLTexelFormat::RGBA16F ||
153 Format == WebGLTexelFormat::RGB16F ||
154 Format == WebGLTexelFormat::RA16F ||
155 Format == WebGLTexelFormat::R16F ||
156 Format == WebGLTexelFormat::A16F;
157 };
159 template<MOZ_ENUM_CLASS_ENUM_TYPE(WebGLTexelFormat) Format>
160 struct Is16bppFormat
161 {
162 static const bool Value =
163 Format == WebGLTexelFormat::RGBA4444 ||
164 Format == WebGLTexelFormat::RGBA5551 ||
165 Format == WebGLTexelFormat::RGB565;
166 };
168 template<MOZ_ENUM_CLASS_ENUM_TYPE(WebGLTexelFormat) Format,
169 bool IsFloat = IsFloatFormat<Format>::Value,
170 bool Is16bpp = Is16bppFormat<Format>::Value,
171 bool IsHalfFloat = IsHalfFloatFormat<Format>::Value>
172 struct DataTypeForFormat
173 {
174 typedef uint8_t Type;
175 };
177 template<MOZ_ENUM_CLASS_ENUM_TYPE(WebGLTexelFormat) Format>
178 struct DataTypeForFormat<Format, true, false, false>
179 {
180 typedef float Type;
181 };
183 template<MOZ_ENUM_CLASS_ENUM_TYPE(WebGLTexelFormat) Format>
184 struct DataTypeForFormat<Format, false, true, false>
185 {
186 typedef uint16_t Type;
187 };
189 template<MOZ_ENUM_CLASS_ENUM_TYPE(WebGLTexelFormat) Format>
190 struct DataTypeForFormat<Format, false, false, true>
191 {
192 typedef uint16_t Type;
193 };
195 template<MOZ_ENUM_CLASS_ENUM_TYPE(WebGLTexelFormat) Format>
196 struct IntermediateFormat
197 {
198 static const MOZ_ENUM_CLASS_ENUM_TYPE(WebGLTexelFormat) Value
199 = IsFloatFormat<Format>::Value
200 ? WebGLTexelFormat::RGBA32F
201 : IsHalfFloatFormat<Format>::Value ? WebGLTexelFormat::RGBA16F
202 : WebGLTexelFormat::RGBA8;
203 };
205 inline GLenum
206 GLFormatForTexelFormat(WebGLTexelFormat format) {
207 switch (format) {
208 case WebGLTexelFormat::R8: return LOCAL_GL_LUMINANCE;
209 case WebGLTexelFormat::A8: return LOCAL_GL_ALPHA;
210 case WebGLTexelFormat::RA8: return LOCAL_GL_LUMINANCE_ALPHA;
211 case WebGLTexelFormat::RGBA5551: return LOCAL_GL_RGBA;
212 case WebGLTexelFormat::RGBA4444: return LOCAL_GL_RGBA;
213 case WebGLTexelFormat::RGB565: return LOCAL_GL_RGB;
214 case WebGLTexelFormat::D16: return LOCAL_GL_DEPTH_COMPONENT;
215 case WebGLTexelFormat::RGB8: return LOCAL_GL_RGB;
216 case WebGLTexelFormat::RGBA8: return LOCAL_GL_RGBA;
217 case WebGLTexelFormat::BGRA8: return LOCAL_GL_BGRA;
218 case WebGLTexelFormat::BGRX8: return LOCAL_GL_BGR;
219 case WebGLTexelFormat::R32F: return LOCAL_GL_LUMINANCE;
220 case WebGLTexelFormat::A32F: return LOCAL_GL_ALPHA;
221 case WebGLTexelFormat::D32: return LOCAL_GL_DEPTH_COMPONENT;
222 case WebGLTexelFormat::D24S8: return LOCAL_GL_DEPTH_STENCIL;
223 case WebGLTexelFormat::RA32F: return LOCAL_GL_LUMINANCE_ALPHA;
224 case WebGLTexelFormat::RGB32F: return LOCAL_GL_RGB;
225 case WebGLTexelFormat::RGBA32F: return LOCAL_GL_RGBA;
226 case WebGLTexelFormat::R16F: return LOCAL_GL_LUMINANCE;
227 case WebGLTexelFormat::A16F: return LOCAL_GL_ALPHA;
228 case WebGLTexelFormat::RA16F: return LOCAL_GL_LUMINANCE_ALPHA;
229 case WebGLTexelFormat::RGB16F: return LOCAL_GL_RGB;
230 case WebGLTexelFormat::RGBA16F: return LOCAL_GL_RGBA;
231 default:
232 MOZ_CRASH("Unknown texel format. Coding mistake?");
233 return LOCAL_GL_INVALID_ENUM;
234 }
235 }
237 inline size_t TexelBytesForFormat(WebGLTexelFormat format) {
238 switch (format) {
239 case WebGLTexelFormat::R8:
240 case WebGLTexelFormat::A8:
241 return 1;
242 case WebGLTexelFormat::RA8:
243 case WebGLTexelFormat::RGBA5551:
244 case WebGLTexelFormat::RGBA4444:
245 case WebGLTexelFormat::RGB565:
246 case WebGLTexelFormat::R16F:
247 case WebGLTexelFormat::A16F:
248 case WebGLTexelFormat::D16:
249 return 2;
250 case WebGLTexelFormat::RGB8:
251 return 3;
252 case WebGLTexelFormat::RGBA8:
253 case WebGLTexelFormat::BGRA8:
254 case WebGLTexelFormat::BGRX8:
255 case WebGLTexelFormat::R32F:
256 case WebGLTexelFormat::A32F:
257 case WebGLTexelFormat::D32:
258 case WebGLTexelFormat::D24S8:
259 case WebGLTexelFormat::RA16F:
260 return 4;
261 case WebGLTexelFormat::RGB16F:
262 return 6;
263 case WebGLTexelFormat::RGBA16F:
264 case WebGLTexelFormat::RA32F:
265 return 8;
266 case WebGLTexelFormat::RGB32F:
267 return 12;
268 case WebGLTexelFormat::RGBA32F:
269 return 16;
270 default:
271 MOZ_ASSERT(false, "Unknown texel format. Coding mistake?");
272 return 0;
273 }
274 }
276 MOZ_ALWAYS_INLINE bool HasAlpha(WebGLTexelFormat format) {
277 return format == WebGLTexelFormat::A8 ||
278 format == WebGLTexelFormat::A16F ||
279 format == WebGLTexelFormat::A32F ||
280 format == WebGLTexelFormat::RA8 ||
281 format == WebGLTexelFormat::RA16F ||
282 format == WebGLTexelFormat::RA32F ||
283 format == WebGLTexelFormat::RGBA8 ||
284 format == WebGLTexelFormat::BGRA8 ||
285 format == WebGLTexelFormat::RGBA16F ||
286 format == WebGLTexelFormat::RGBA32F ||
287 format == WebGLTexelFormat::RGBA4444 ||
288 format == WebGLTexelFormat::RGBA5551;
289 }
291 MOZ_ALWAYS_INLINE bool HasColor(WebGLTexelFormat format) {
292 return format == WebGLTexelFormat::R8 ||
293 format == WebGLTexelFormat::R16F ||
294 format == WebGLTexelFormat::R32F ||
295 format == WebGLTexelFormat::RA8 ||
296 format == WebGLTexelFormat::RA16F ||
297 format == WebGLTexelFormat::RA32F ||
298 format == WebGLTexelFormat::RGB8 ||
299 format == WebGLTexelFormat::BGRX8 ||
300 format == WebGLTexelFormat::RGB565 ||
301 format == WebGLTexelFormat::RGB16F ||
302 format == WebGLTexelFormat::RGB32F ||
303 format == WebGLTexelFormat::RGBA8 ||
304 format == WebGLTexelFormat::BGRA8 ||
305 format == WebGLTexelFormat::RGBA16F ||
306 format == WebGLTexelFormat::RGBA32F ||
307 format == WebGLTexelFormat::RGBA4444 ||
308 format == WebGLTexelFormat::RGBA5551;
309 }
312 /****** BEGIN CODE SHARED WITH WEBKIT ******/
314 // the pack/unpack functions here are originally from this file:
315 // http://trac.webkit.org/browser/trunk/WebCore/platform/graphics/GraphicsContext3D.cpp
317 //----------------------------------------------------------------------
318 // Pixel unpacking routines.
320 template<MOZ_ENUM_CLASS_ENUM_TYPE(WebGLTexelFormat) Format, typename SrcType, typename DstType>
321 MOZ_ALWAYS_INLINE void
322 unpack(const SrcType* __restrict src,
323 DstType* __restrict dst)
324 {
325 MOZ_ASSERT(false, "Unimplemented texture format conversion");
326 }
328 template<> MOZ_ALWAYS_INLINE void
329 unpack<WebGLTexelFormat::RGBA8, uint8_t, uint8_t>(const uint8_t* __restrict src, uint8_t* __restrict dst)
330 {
331 dst[0] = src[0];
332 dst[1] = src[1];
333 dst[2] = src[2];
334 dst[3] = src[3];
335 }
337 template<> MOZ_ALWAYS_INLINE void
338 unpack<WebGLTexelFormat::RGB8, uint8_t, uint8_t>(const uint8_t* __restrict src, uint8_t* __restrict dst)
339 {
340 dst[0] = src[0];
341 dst[1] = src[1];
342 dst[2] = src[2];
343 dst[3] = 0xFF;
344 }
346 template<> MOZ_ALWAYS_INLINE void
347 unpack<WebGLTexelFormat::BGRA8, uint8_t, uint8_t>(const uint8_t* __restrict src, uint8_t* __restrict dst)
348 {
349 dst[0] = src[2];
350 dst[1] = src[1];
351 dst[2] = src[0];
352 dst[3] = src[3];
353 }
355 template<> MOZ_ALWAYS_INLINE void
356 unpack<WebGLTexelFormat::BGRX8, uint8_t, uint8_t>(const uint8_t* __restrict src, uint8_t* __restrict dst)
357 {
358 dst[0] = src[2];
359 dst[1] = src[1];
360 dst[2] = src[0];
361 dst[3] = 0xFF;
362 }
364 template<> MOZ_ALWAYS_INLINE void
365 unpack<WebGLTexelFormat::RGBA5551, uint16_t, uint8_t>(const uint16_t* __restrict src, uint8_t* __restrict dst)
366 {
367 uint16_t packedValue = src[0];
368 uint8_t r = (packedValue >> 11) & 0x1F;
369 uint8_t g = (packedValue >> 6) & 0x1F;
370 uint8_t b = (packedValue >> 1) & 0x1F;
371 dst[0] = (r << 3) | (r & 0x7);
372 dst[1] = (g << 3) | (g & 0x7);
373 dst[2] = (b << 3) | (b & 0x7);
374 dst[3] = (packedValue & 0x1) ? 0xFF : 0;
375 }
377 template<> MOZ_ALWAYS_INLINE void
378 unpack<WebGLTexelFormat::RGBA4444, uint16_t, uint8_t>(const uint16_t* __restrict src, uint8_t* __restrict dst)
379 {
380 uint16_t packedValue = src[0];
381 uint8_t r = (packedValue >> 12) & 0x0F;
382 uint8_t g = (packedValue >> 8) & 0x0F;
383 uint8_t b = (packedValue >> 4) & 0x0F;
384 uint8_t a = packedValue & 0x0F;
385 dst[0] = (r << 4) | r;
386 dst[1] = (g << 4) | g;
387 dst[2] = (b << 4) | b;
388 dst[3] = (a << 4) | a;
389 }
391 template<> MOZ_ALWAYS_INLINE void
392 unpack<WebGLTexelFormat::RGB565, uint16_t, uint8_t>(const uint16_t* __restrict src, uint8_t* __restrict dst)
393 {
394 uint16_t packedValue = src[0];
395 uint8_t r = (packedValue >> 11) & 0x1F;
396 uint8_t g = (packedValue >> 5) & 0x3F;
397 uint8_t b = packedValue & 0x1F;
398 dst[0] = (r << 3) | (r & 0x7);
399 dst[1] = (g << 2) | (g & 0x3);
400 dst[2] = (b << 3) | (b & 0x7);
401 dst[3] = 0xFF;
402 }
404 template<> MOZ_ALWAYS_INLINE void
405 unpack<WebGLTexelFormat::R8, uint8_t, uint8_t>(const uint8_t* __restrict src, uint8_t* __restrict dst)
406 {
407 dst[0] = src[0];
408 dst[1] = src[0];
409 dst[2] = src[0];
410 dst[3] = 0xFF;
411 }
413 template<> MOZ_ALWAYS_INLINE void
414 unpack<WebGLTexelFormat::RA8, uint8_t, uint8_t>(const uint8_t* __restrict src, uint8_t* __restrict dst)
415 {
416 dst[0] = src[0];
417 dst[1] = src[0];
418 dst[2] = src[0];
419 dst[3] = src[1];
420 }
422 template<> MOZ_ALWAYS_INLINE void
423 unpack<WebGLTexelFormat::A8, uint8_t, uint8_t>(const uint8_t* __restrict src, uint8_t* __restrict dst)
424 {
425 dst[0] = 0;
426 dst[1] = 0;
427 dst[2] = 0;
428 dst[3] = src[0];
429 }
431 template<> MOZ_ALWAYS_INLINE void
432 unpack<WebGLTexelFormat::RGBA32F, float, float>(const float* __restrict src, float* __restrict dst)
433 {
434 dst[0] = src[0];
435 dst[1] = src[1];
436 dst[2] = src[2];
437 dst[3] = src[3];
438 }
440 template<> MOZ_ALWAYS_INLINE void
441 unpack<WebGLTexelFormat::RGB32F, float, float>(const float* __restrict src, float* __restrict dst)
442 {
443 dst[0] = src[0];
444 dst[1] = src[1];
445 dst[2] = src[2];
446 dst[3] = 1.0f;
447 }
449 template<> MOZ_ALWAYS_INLINE void
450 unpack<WebGLTexelFormat::R32F, float, float>(const float* __restrict src, float* __restrict dst)
451 {
452 dst[0] = src[0];
453 dst[1] = src[0];
454 dst[2] = src[0];
455 dst[3] = 1.0f;
456 }
458 template<> MOZ_ALWAYS_INLINE void
459 unpack<WebGLTexelFormat::RA32F, float, float>(const float* __restrict src, float* __restrict dst)
460 {
461 dst[0] = src[0];
462 dst[1] = src[0];
463 dst[2] = src[0];
464 dst[3] = src[1];
465 }
467 template<> MOZ_ALWAYS_INLINE void
468 unpack<WebGLTexelFormat::A32F, float, float>(const float* __restrict src, float* __restrict dst)
469 {
470 dst[0] = 0;
471 dst[1] = 0;
472 dst[2] = 0;
473 dst[3] = src[0];
474 }
476 template<> MOZ_ALWAYS_INLINE void
477 unpack<WebGLTexelFormat::RGBA16F, uint16_t, uint16_t>(const uint16_t* __restrict src, uint16_t* __restrict dst)
478 {
479 dst[0] = src[0];
480 dst[1] = src[1];
481 dst[2] = src[2];
482 dst[3] = src[3];
483 }
485 template<> MOZ_ALWAYS_INLINE void
486 unpack<WebGLTexelFormat::RGB16F, uint16_t, uint16_t>(const uint16_t* __restrict src, uint16_t* __restrict dst)
487 {
488 dst[0] = src[0];
489 dst[1] = src[1];
490 dst[2] = src[2];
491 dst[3] = kFloat16Value_One;
492 }
494 template<> MOZ_ALWAYS_INLINE void
495 unpack<WebGLTexelFormat::R16F, uint16_t, uint16_t>(const uint16_t* __restrict src, uint16_t* __restrict dst)
496 {
497 dst[0] = src[0];
498 dst[1] = src[0];
499 dst[2] = src[0];
500 dst[3] = kFloat16Value_One;
501 }
503 template<> MOZ_ALWAYS_INLINE void
504 unpack<WebGLTexelFormat::RA16F, uint16_t, uint16_t>(const uint16_t* __restrict src, uint16_t* __restrict dst)
505 {
506 dst[0] = src[0];
507 dst[1] = src[0];
508 dst[2] = src[0];
509 dst[3] = src[1];
510 }
512 template<> MOZ_ALWAYS_INLINE void
513 unpack<WebGLTexelFormat::A16F, uint16_t, uint16_t>(const uint16_t* __restrict src, uint16_t* __restrict dst)
514 {
515 dst[0] = kFloat16Value_Zero;
516 dst[1] = kFloat16Value_Zero;
517 dst[2] = kFloat16Value_Zero;
518 dst[3] = src[0];
519 }
521 //----------------------------------------------------------------------
522 // Pixel packing routines.
523 //
525 template<MOZ_ENUM_CLASS_ENUM_TYPE(WebGLTexelFormat) Format,
526 MOZ_ENUM_CLASS_ENUM_TYPE(WebGLTexelPremultiplicationOp) PremultiplicationOp,
527 typename SrcType,
528 typename DstType>
529 MOZ_ALWAYS_INLINE void
530 pack(const SrcType* __restrict src,
531 DstType* __restrict dst)
532 {
533 MOZ_ASSERT(false, "Unimplemented texture format conversion");
534 }
536 template<> MOZ_ALWAYS_INLINE void
537 pack<WebGLTexelFormat::A8, WebGLTexelPremultiplicationOp::None, uint8_t, uint8_t>(const uint8_t* __restrict src, uint8_t* __restrict dst)
538 {
539 dst[0] = src[3];
540 }
542 template<> MOZ_ALWAYS_INLINE void
543 pack<WebGLTexelFormat::A8, WebGLTexelPremultiplicationOp::Premultiply, uint8_t, uint8_t>(const uint8_t* __restrict src, uint8_t* __restrict dst)
544 {
545 dst[0] = src[3];
546 }
548 template<> MOZ_ALWAYS_INLINE void
549 pack<WebGLTexelFormat::A8, WebGLTexelPremultiplicationOp::Unpremultiply, uint8_t, uint8_t>(const uint8_t* __restrict src, uint8_t* __restrict dst)
550 {
551 dst[0] = src[3];
552 }
554 template<> MOZ_ALWAYS_INLINE void
555 pack<WebGLTexelFormat::R8, WebGLTexelPremultiplicationOp::None, uint8_t, uint8_t>(const uint8_t* __restrict src, uint8_t* __restrict dst)
556 {
557 dst[0] = src[0];
558 }
560 template<> MOZ_ALWAYS_INLINE void
561 pack<WebGLTexelFormat::R8, WebGLTexelPremultiplicationOp::Premultiply, uint8_t, uint8_t>(const uint8_t* __restrict src, uint8_t* __restrict dst)
562 {
563 float scaleFactor = src[3] / 255.0f;
564 uint8_t srcR = static_cast<uint8_t>(src[0] * scaleFactor);
565 dst[0] = srcR;
566 }
568 template<> MOZ_ALWAYS_INLINE void
569 pack<WebGLTexelFormat::R8, WebGLTexelPremultiplicationOp::Unpremultiply, uint8_t, uint8_t>(const uint8_t* __restrict src, uint8_t* __restrict dst)
570 {
571 float scaleFactor = src[3] ? 255.0f / src[3] : 1.0f;
572 uint8_t srcR = static_cast<uint8_t>(src[0] * scaleFactor);
573 dst[0] = srcR;
574 }
576 template<> MOZ_ALWAYS_INLINE void
577 pack<WebGLTexelFormat::RA8, WebGLTexelPremultiplicationOp::None, uint8_t, uint8_t>(const uint8_t* __restrict src, uint8_t* __restrict dst)
578 {
579 dst[0] = src[0];
580 dst[1] = src[3];
581 }
583 template<> MOZ_ALWAYS_INLINE void
584 pack<WebGLTexelFormat::RA8, WebGLTexelPremultiplicationOp::Premultiply, uint8_t, uint8_t>(const uint8_t* __restrict src, uint8_t* __restrict dst)
585 {
586 float scaleFactor = src[3] / 255.0f;
587 uint8_t srcR = static_cast<uint8_t>(src[0] * scaleFactor);
588 dst[0] = srcR;
589 dst[1] = src[3];
590 }
592 // FIXME: this routine is lossy and must be removed.
593 template<> MOZ_ALWAYS_INLINE void
594 pack<WebGLTexelFormat::RA8, WebGLTexelPremultiplicationOp::Unpremultiply, uint8_t, uint8_t>(const uint8_t* __restrict src, uint8_t* __restrict dst)
595 {
596 float scaleFactor = src[3] ? 255.0f / src[3] : 1.0f;
597 uint8_t srcR = static_cast<uint8_t>(src[0] * scaleFactor);
598 dst[0] = srcR;
599 dst[1] = src[3];
600 }
602 template<> MOZ_ALWAYS_INLINE void
603 pack<WebGLTexelFormat::RGB8, WebGLTexelPremultiplicationOp::None, uint8_t, uint8_t>(const uint8_t* __restrict src, uint8_t* __restrict dst)
604 {
605 dst[0] = src[0];
606 dst[1] = src[1];
607 dst[2] = src[2];
608 }
610 template<> MOZ_ALWAYS_INLINE void
611 pack<WebGLTexelFormat::RGB8, WebGLTexelPremultiplicationOp::Premultiply, uint8_t, uint8_t>(const uint8_t* __restrict src, uint8_t* __restrict dst)
612 {
613 float scaleFactor = src[3] / 255.0f;
614 uint8_t srcR = static_cast<uint8_t>(src[0] * scaleFactor);
615 uint8_t srcG = static_cast<uint8_t>(src[1] * scaleFactor);
616 uint8_t srcB = static_cast<uint8_t>(src[2] * scaleFactor);
617 dst[0] = srcR;
618 dst[1] = srcG;
619 dst[2] = srcB;
620 }
622 template<> MOZ_ALWAYS_INLINE void
623 pack<WebGLTexelFormat::RGB8, WebGLTexelPremultiplicationOp::Unpremultiply, uint8_t, uint8_t>(const uint8_t* __restrict src, uint8_t* __restrict dst)
624 {
625 float scaleFactor = src[3] ? 255.0f / src[3] : 1.0f;
626 uint8_t srcR = static_cast<uint8_t>(src[0] * scaleFactor);
627 uint8_t srcG = static_cast<uint8_t>(src[1] * scaleFactor);
628 uint8_t srcB = static_cast<uint8_t>(src[2] * scaleFactor);
629 dst[0] = srcR;
630 dst[1] = srcG;
631 dst[2] = srcB;
632 }
634 template<> MOZ_ALWAYS_INLINE void
635 pack<WebGLTexelFormat::RGBA8, WebGLTexelPremultiplicationOp::None, uint8_t, uint8_t>(const uint8_t* __restrict src, uint8_t* __restrict dst)
636 {
637 dst[0] = src[0];
638 dst[1] = src[1];
639 dst[2] = src[2];
640 dst[3] = src[3];
641 }
643 template<> MOZ_ALWAYS_INLINE void
644 pack<WebGLTexelFormat::RGBA8, WebGLTexelPremultiplicationOp::Premultiply, uint8_t, uint8_t>(const uint8_t* __restrict src, uint8_t* __restrict dst)
645 {
646 float scaleFactor = src[3] / 255.0f;
647 uint8_t srcR = static_cast<uint8_t>(src[0] * scaleFactor);
648 uint8_t srcG = static_cast<uint8_t>(src[1] * scaleFactor);
649 uint8_t srcB = static_cast<uint8_t>(src[2] * scaleFactor);
650 dst[0] = srcR;
651 dst[1] = srcG;
652 dst[2] = srcB;
653 dst[3] = src[3];
654 }
656 // FIXME: this routine is lossy and must be removed.
657 template<> MOZ_ALWAYS_INLINE void
658 pack<WebGLTexelFormat::RGBA8, WebGLTexelPremultiplicationOp::Unpremultiply, uint8_t, uint8_t>(const uint8_t* __restrict src, uint8_t* __restrict dst)
659 {
660 float scaleFactor = src[3] ? 255.0f / src[3] : 1.0f;
661 uint8_t srcR = static_cast<uint8_t>(src[0] * scaleFactor);
662 uint8_t srcG = static_cast<uint8_t>(src[1] * scaleFactor);
663 uint8_t srcB = static_cast<uint8_t>(src[2] * scaleFactor);
664 dst[0] = srcR;
665 dst[1] = srcG;
666 dst[2] = srcB;
667 dst[3] = src[3];
668 }
670 template<> MOZ_ALWAYS_INLINE void
671 pack<WebGLTexelFormat::RGBA4444, WebGLTexelPremultiplicationOp::None, uint8_t, uint16_t>(const uint8_t* __restrict src, uint16_t* __restrict dst)
672 {
673 *dst = ( ((src[0] & 0xF0) << 8)
674 | ((src[1] & 0xF0) << 4)
675 | (src[2] & 0xF0)
676 | (src[3] >> 4) );
677 }
679 template<> MOZ_ALWAYS_INLINE void
680 pack<WebGLTexelFormat::RGBA4444, WebGLTexelPremultiplicationOp::Premultiply, uint8_t, uint16_t>(const uint8_t* __restrict src, uint16_t* __restrict dst)
681 {
682 float scaleFactor = src[3] / 255.0f;
683 uint8_t srcR = static_cast<uint8_t>(src[0] * scaleFactor);
684 uint8_t srcG = static_cast<uint8_t>(src[1] * scaleFactor);
685 uint8_t srcB = static_cast<uint8_t>(src[2] * scaleFactor);
686 *dst = ( ((srcR & 0xF0) << 8)
687 | ((srcG & 0xF0) << 4)
688 | (srcB & 0xF0)
689 | (src[3] >> 4));
690 }
692 // FIXME: this routine is lossy and must be removed.
693 template<> MOZ_ALWAYS_INLINE void
694 pack<WebGLTexelFormat::RGBA4444, WebGLTexelPremultiplicationOp::Unpremultiply, uint8_t, uint16_t>(const uint8_t* __restrict src, uint16_t* __restrict dst)
695 {
696 float scaleFactor = src[3] ? 255.0f / src[3] : 1.0f;
697 uint8_t srcR = static_cast<uint8_t>(src[0] * scaleFactor);
698 uint8_t srcG = static_cast<uint8_t>(src[1] * scaleFactor);
699 uint8_t srcB = static_cast<uint8_t>(src[2] * scaleFactor);
700 *dst = ( ((srcR & 0xF0) << 8)
701 | ((srcG & 0xF0) << 4)
702 | (srcB & 0xF0)
703 | (src[3] >> 4));
704 }
706 template<> MOZ_ALWAYS_INLINE void
707 pack<WebGLTexelFormat::RGBA5551, WebGLTexelPremultiplicationOp::None, uint8_t, uint16_t>(const uint8_t* __restrict src, uint16_t* __restrict dst)
708 {
709 *dst = ( ((src[0] & 0xF8) << 8)
710 | ((src[1] & 0xF8) << 3)
711 | ((src[2] & 0xF8) >> 2)
712 | (src[3] >> 7));
713 }
715 template<> MOZ_ALWAYS_INLINE void
716 pack<WebGLTexelFormat::RGBA5551, WebGLTexelPremultiplicationOp::Premultiply, uint8_t, uint16_t>(const uint8_t* __restrict src, uint16_t* __restrict dst)
717 {
718 float scaleFactor = src[3] / 255.0f;
719 uint8_t srcR = static_cast<uint8_t>(src[0] * scaleFactor);
720 uint8_t srcG = static_cast<uint8_t>(src[1] * scaleFactor);
721 uint8_t srcB = static_cast<uint8_t>(src[2] * scaleFactor);
722 *dst = ( ((srcR & 0xF8) << 8)
723 | ((srcG & 0xF8) << 3)
724 | ((srcB & 0xF8) >> 2)
725 | (src[3] >> 7));
726 }
728 // FIXME: this routine is lossy and must be removed.
729 template<> MOZ_ALWAYS_INLINE void
730 pack<WebGLTexelFormat::RGBA5551, WebGLTexelPremultiplicationOp::Unpremultiply, uint8_t, uint16_t>(const uint8_t* __restrict src, uint16_t* __restrict dst)
731 {
732 float scaleFactor = src[3] ? 255.0f / src[3] : 1.0f;
733 uint8_t srcR = static_cast<uint8_t>(src[0] * scaleFactor);
734 uint8_t srcG = static_cast<uint8_t>(src[1] * scaleFactor);
735 uint8_t srcB = static_cast<uint8_t>(src[2] * scaleFactor);
736 *dst = ( ((srcR & 0xF8) << 8)
737 | ((srcG & 0xF8) << 3)
738 | ((srcB & 0xF8) >> 2)
739 | (src[3] >> 7));
740 }
742 template<> MOZ_ALWAYS_INLINE void
743 pack<WebGLTexelFormat::RGB565, WebGLTexelPremultiplicationOp::None, uint8_t, uint16_t>(const uint8_t* __restrict src, uint16_t* __restrict dst)
744 {
745 *dst = ( ((src[0] & 0xF8) << 8)
746 | ((src[1] & 0xFC) << 3)
747 | ((src[2] & 0xF8) >> 3));
748 }
750 template<> MOZ_ALWAYS_INLINE void
751 pack<WebGLTexelFormat::RGB565, WebGLTexelPremultiplicationOp::Premultiply, uint8_t, uint16_t>(const uint8_t* __restrict src, uint16_t* __restrict dst)
752 {
753 float scaleFactor = src[3] / 255.0f;
754 uint8_t srcR = static_cast<uint8_t>(src[0] * scaleFactor);
755 uint8_t srcG = static_cast<uint8_t>(src[1] * scaleFactor);
756 uint8_t srcB = static_cast<uint8_t>(src[2] * scaleFactor);
757 *dst = ( ((srcR & 0xF8) << 8)
758 | ((srcG & 0xFC) << 3)
759 | ((srcB & 0xF8) >> 3));
760 }
762 // FIXME: this routine is lossy and must be removed.
763 template<> MOZ_ALWAYS_INLINE void
764 pack<WebGLTexelFormat::RGB565, WebGLTexelPremultiplicationOp::Unpremultiply, uint8_t, uint16_t>(const uint8_t* __restrict src, uint16_t* __restrict dst)
765 {
766 float scaleFactor = src[3] ? 255.0f / src[3] : 1.0f;
767 uint8_t srcR = static_cast<uint8_t>(src[0] * scaleFactor);
768 uint8_t srcG = static_cast<uint8_t>(src[1] * scaleFactor);
769 uint8_t srcB = static_cast<uint8_t>(src[2] * scaleFactor);
770 *dst = ( ((srcR & 0xF8) << 8)
771 | ((srcG & 0xFC) << 3)
772 | ((srcB & 0xF8) >> 3));
773 }
775 template<> MOZ_ALWAYS_INLINE void
776 pack<WebGLTexelFormat::RGB32F, WebGLTexelPremultiplicationOp::None, float, float>(const float* __restrict src, float* __restrict dst)
777 {
778 dst[0] = src[0];
779 dst[1] = src[1];
780 dst[2] = src[2];
781 }
783 template<> MOZ_ALWAYS_INLINE void
784 pack<WebGLTexelFormat::RGB32F, WebGLTexelPremultiplicationOp::Premultiply, float, float>(const float* __restrict src, float* __restrict dst)
785 {
786 float scaleFactor = src[3];
787 dst[0] = src[0] * scaleFactor;
788 dst[1] = src[1] * scaleFactor;
789 dst[2] = src[2] * scaleFactor;
790 }
792 template<> MOZ_ALWAYS_INLINE void
793 pack<WebGLTexelFormat::RGBA32F, WebGLTexelPremultiplicationOp::None, float, float>(const float* __restrict src, float* __restrict dst)
794 {
795 dst[0] = src[0];
796 dst[1] = src[1];
797 dst[2] = src[2];
798 dst[3] = src[3];
799 }
801 template<> MOZ_ALWAYS_INLINE void
802 pack<WebGLTexelFormat::RGBA32F, WebGLTexelPremultiplicationOp::Premultiply, float, float>(const float* __restrict src, float* __restrict dst)
803 {
804 float scaleFactor = src[3];
805 dst[0] = src[0] * scaleFactor;
806 dst[1] = src[1] * scaleFactor;
807 dst[2] = src[2] * scaleFactor;
808 dst[3] = src[3];
809 }
811 template<> MOZ_ALWAYS_INLINE void
812 pack<WebGLTexelFormat::A32F, WebGLTexelPremultiplicationOp::None, float, float>(const float* __restrict src, float* __restrict dst)
813 {
814 dst[0] = src[3];
815 }
817 template<> MOZ_ALWAYS_INLINE void
818 pack<WebGLTexelFormat::A32F, WebGLTexelPremultiplicationOp::Premultiply, float, float>(const float* __restrict src, float* __restrict dst)
819 {
820 dst[0] = src[3];
821 }
823 template<> MOZ_ALWAYS_INLINE void
824 pack<WebGLTexelFormat::R32F, WebGLTexelPremultiplicationOp::None, float, float>(const float* __restrict src, float* __restrict dst)
825 {
826 dst[0] = src[0];
827 }
829 template<> MOZ_ALWAYS_INLINE void
830 pack<WebGLTexelFormat::R32F, WebGLTexelPremultiplicationOp::Premultiply, float, float>(const float* __restrict src, float* __restrict dst)
831 {
832 float scaleFactor = src[3];
833 dst[0] = src[0] * scaleFactor;
834 }
836 template<> MOZ_ALWAYS_INLINE void
837 pack<WebGLTexelFormat::RA32F, WebGLTexelPremultiplicationOp::None, float, float>(const float* __restrict src, float* __restrict dst)
838 {
839 dst[0] = src[0];
840 dst[1] = src[3];
841 }
843 template<> MOZ_ALWAYS_INLINE void
844 pack<WebGLTexelFormat::RA32F, WebGLTexelPremultiplicationOp::Premultiply, float, float>(const float* __restrict src, float* __restrict dst)
845 {
846 float scaleFactor = src[3];
847 dst[0] = src[0] * scaleFactor;
848 dst[1] = scaleFactor;
849 }
851 template<> MOZ_ALWAYS_INLINE void
852 pack<WebGLTexelFormat::RGB16F, WebGLTexelPremultiplicationOp::None, uint16_t, uint16_t>(const uint16_t* __restrict src, uint16_t* __restrict dst)
853 {
854 dst[0] = src[0];
855 dst[1] = src[1];
856 dst[2] = src[2];
857 }
859 template<> MOZ_ALWAYS_INLINE void
860 pack<WebGLTexelFormat::RGB16F, WebGLTexelPremultiplicationOp::Premultiply, uint16_t, uint16_t>(const uint16_t* __restrict src, uint16_t* __restrict dst)
861 {
862 float scaleFactor = unpackFromFloat16(src[3]);
863 dst[0] = packToFloat16(unpackFromFloat16(src[0]) * scaleFactor);
864 dst[1] = packToFloat16(unpackFromFloat16(src[1]) * scaleFactor);
865 dst[2] = packToFloat16(unpackFromFloat16(src[2]) * scaleFactor);
866 }
868 template<> MOZ_ALWAYS_INLINE void
869 pack<WebGLTexelFormat::RGBA16F, WebGLTexelPremultiplicationOp::None, uint16_t, uint16_t>(const uint16_t* __restrict src, uint16_t* __restrict dst)
870 {
871 dst[0] = src[0];
872 dst[1] = src[1];
873 dst[2] = src[2];
874 dst[3] = src[3];
875 }
877 template<> MOZ_ALWAYS_INLINE void
878 pack<WebGLTexelFormat::RGBA16F, WebGLTexelPremultiplicationOp::Premultiply, uint16_t, uint16_t>(const uint16_t* __restrict src, uint16_t* __restrict dst)
879 {
880 float scaleFactor = unpackFromFloat16(src[3]);
881 dst[0] = packToFloat16(unpackFromFloat16(src[0]) * scaleFactor);
882 dst[1] = packToFloat16(unpackFromFloat16(src[1]) * scaleFactor);
883 dst[2] = packToFloat16(unpackFromFloat16(src[2]) * scaleFactor);
884 dst[3] = src[3];
885 }
887 template<> MOZ_ALWAYS_INLINE void
888 pack<WebGLTexelFormat::A16F, WebGLTexelPremultiplicationOp::None, uint16_t, uint16_t>(const uint16_t* __restrict src, uint16_t* __restrict dst)
889 {
890 dst[0] = src[3];
891 }
893 template<> MOZ_ALWAYS_INLINE void
894 pack<WebGLTexelFormat::A16F, WebGLTexelPremultiplicationOp::Premultiply, uint16_t, uint16_t>(const uint16_t* __restrict src, uint16_t* __restrict dst)
895 {
896 dst[0] = src[3];
897 }
899 template<> MOZ_ALWAYS_INLINE void
900 pack<WebGLTexelFormat::R16F, WebGLTexelPremultiplicationOp::None, uint16_t, uint16_t>(const uint16_t* __restrict src, uint16_t* __restrict dst)
901 {
902 dst[0] = src[0];
903 }
905 template<> MOZ_ALWAYS_INLINE void
906 pack<WebGLTexelFormat::R16F, WebGLTexelPremultiplicationOp::Premultiply, uint16_t, uint16_t>(const uint16_t* __restrict src, uint16_t* __restrict dst)
907 {
908 float scaleFactor = unpackFromFloat16(src[3]);
909 dst[0] = packToFloat16(unpackFromFloat16(src[0]) * scaleFactor);
910 }
912 template<> MOZ_ALWAYS_INLINE void
913 pack<WebGLTexelFormat::RA16F, WebGLTexelPremultiplicationOp::None, uint16_t, uint16_t>(const uint16_t* __restrict src, uint16_t* __restrict dst)
914 {
915 dst[0] = src[0];
916 dst[1] = src[3];
917 }
919 template<> MOZ_ALWAYS_INLINE void
920 pack<WebGLTexelFormat::RA16F, WebGLTexelPremultiplicationOp::Premultiply, uint16_t, uint16_t>(const uint16_t* __restrict src, uint16_t* __restrict dst)
921 {
922 float scaleFactor = unpackFromFloat16(src[3]);
923 dst[0] = packToFloat16(unpackFromFloat16(src[0]) * scaleFactor);
924 dst[1] = scaleFactor;
925 }
927 /****** END CODE SHARED WITH WEBKIT ******/
929 template<typename SrcType, typename DstType> MOZ_ALWAYS_INLINE void
930 convertType(const SrcType* __restrict src, DstType* __restrict dst)
931 {
932 MOZ_ASSERT(false, "Unimplemented texture format conversion");
933 }
935 template<> MOZ_ALWAYS_INLINE void
936 convertType<uint8_t, uint8_t>(const uint8_t* __restrict src, uint8_t* __restrict dst)
937 {
938 dst[0] = src[0];
939 dst[1] = src[1];
940 dst[2] = src[2];
941 dst[3] = src[3];
942 }
944 template<> MOZ_ALWAYS_INLINE void
945 convertType<uint16_t, uint16_t>(const uint16_t* __restrict src, uint16_t* __restrict dst)
946 {
947 dst[0] = src[0];
948 dst[1] = src[1];
949 dst[2] = src[2];
950 dst[3] = src[3];
951 }
953 template<> MOZ_ALWAYS_INLINE void
954 convertType<float, float>(const float* __restrict src, float* __restrict dst)
955 {
956 dst[0] = src[0];
957 dst[1] = src[1];
958 dst[2] = src[2];
959 dst[3] = src[3];
960 }
962 template<> MOZ_ALWAYS_INLINE void
963 convertType<uint8_t, float>(const uint8_t* __restrict src, float* __restrict dst)
964 {
965 const float scaleFactor = 1.f / 255.0f;
966 dst[0] = src[0] * scaleFactor;
967 dst[1] = src[1] * scaleFactor;
968 dst[2] = src[2] * scaleFactor;
969 dst[3] = src[3] * scaleFactor;
970 }
972 template<> MOZ_ALWAYS_INLINE void
973 convertType<uint8_t, uint16_t>(const uint8_t* __restrict src, uint16_t* __restrict dst)
974 {
975 const float scaleFactor = 1.f / 255.0f;
976 dst[0] = packToFloat16(src[0] * scaleFactor);
977 dst[1] = packToFloat16(src[1] * scaleFactor);
978 dst[2] = packToFloat16(src[2] * scaleFactor);
979 dst[3] = packToFloat16(src[3] * scaleFactor);
980 }
982 } // end namespace WebGLTexelConversions
984 } // end namespace mozilla
986 #endif // WEBGLTEXELCONVERSIONS_H_