Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/dom/canvas/WebGLTexelConversions.h
Line
Count
Source (jump to first uncovered line)
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
packToFloat16(float v)
65
0
{
66
0
    union {
67
0
        float f32Value;
68
0
        uint32_t f32Bits;
69
0
    };
70
0
71
0
    f32Value = v;
72
0
73
0
    // 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
0
78
0
    // Adapted from: OpenGL ES 2.0 Programming Guide Appx.
79
0
    // Converting Float to Half-Float
80
0
    // 143 = 255 - 127 + 15
81
0
    //     = sp_max - sp_bias + hp_bias
82
0
    if (exp >= 143) {
83
0
        if (mantissa && exp == 0xFF) {
84
0
            // Single precision was NaN
85
0
            return f16Bits | kFloat16Value_NaN;
86
0
        } else {
87
0
            // Outside range, store as infinity
88
0
            return f16Bits | kFloat16Value_Infinity;
89
0
        }
90
0
    }
91
0
92
0
    // too small, try to make a denormalized number
93
0
    // 112 = 255 - 127 - (15 + 1)
94
0
    //     = sp_max - sp_bias - (hp_bias + 1)
95
0
    if (exp <= 112) {
96
0
        return f16Bits | uint16_t(mantissa >> (14 + 112 - exp));
97
0
    }
98
0
99
0
    f16Bits |= uint16_t(exp - 112) << 10;
100
0
    f16Bits |= uint16_t(mantissa >> 13) & 0x03FF;
101
0
102
0
    return f16Bits;
103
0
}
104
105
MOZ_ALWAYS_INLINE float
106
unpackFromFloat16(uint16_t v)
107
0
{
108
0
    union {
109
0
        float f32Value;
110
0
        uint32_t f32Bits;
111
0
    };
112
0
113
0
    // 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
0
118
0
    if (!exp) {
119
0
        // Handle denormalized numbers
120
0
        // Adapted from: OpenGL ES 2.0 Programming Guide Appx.
121
0
        // Converting Float to Half-Float
122
0
        if (mantissa) {
123
0
            exp = 112; // See packToFloat16
124
0
            mantissa <<= 1;
125
0
            // For every leading zero, decrement the exponent
126
0
            // and shift the mantissa to the left
127
0
            while ((mantissa & (1 << 10)) == 0) {
128
0
                mantissa <<= 1;
129
0
                --exp;
130
0
            }
131
0
            mantissa &= 0x03FF;
132
0
133
0
            f32Bits |= (exp << 23) | (mantissa << 13);
134
0
135
0
            // Denormalized number
136
0
            return f32Value;
137
0
        }
138
0
139
0
        // +/- zero
140
0
        return f32Value;
141
0
    }
142
0
143
0
    if (exp == 0x001F) {
144
0
        if (v & 0x03FF) {
145
0
            // this is a NaN
146
0
            f32Bits |= 0x7FFFFFFF;
147
0
        } else {
148
0
            // this is -inf or +inf
149
0
            f32Bits |= 0x7F800000;
150
0
        }
151
0
        return f32Value;
152
0
    }
153
0
154
0
    f32Bits |= uint32_t(exp + (-15 + 127)) << 23;
155
0
    f32Bits |= uint32_t(v & 0x03FF) << 13;
156
0
157
0
    return f32Value;
158
0
}
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
packToFloat11(float fp32)
165
0
{
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
0
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
0
179
0
    const unsigned int float32Maxfloat11 = 0x477E0000;
180
0
    const unsigned int float32Minfloat11 = 0x38800000;
181
0
182
0
    const unsigned int float32Bits = BitwiseCast<unsigned int>(fp32);
183
0
    const bool float32Sign = (float32Bits & float32SignMask) == float32SignMask;
184
0
185
0
    unsigned int float32Val = float32Bits & float32ValueMask;
186
0
187
0
    if ((float32Val & float32ExponentMask) == float32ExponentMask)
188
0
    {
189
0
        // INF or NAN
190
0
        if ((float32Val & float32MantissaMask) != 0)
191
0
        {
192
0
            return float11ExponentMask | (((float32Val >> 17) | (float32Val >> 11) | (float32Val >> 6) | (float32Val)) & float11MantissaMask);
193
0
        }
194
0
        else if (float32Sign)
195
0
        {
196
0
            // -INF is clamped to 0 since float11 is positive only
197
0
            return 0;
198
0
        }
199
0
        else
200
0
        {
201
0
            return float11ExponentMask;
202
0
        }
203
0
    }
204
0
    else if (float32Sign)
205
0
    {
206
0
        // float11 is positive only, so clamp to zero
207
0
        return 0;
208
0
    }
209
0
    else if (float32Val > float32Maxfloat11)
210
0
    {
211
0
        // The number is too large to be represented as a float11, set to max
212
0
        return float11Max;
213
0
    }
214
0
    else
215
0
    {
216
0
        if (float32Val < float32Minfloat11)
217
0
        {
218
0
            // The number is too small to be represented as a normalized float11
219
0
            // 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
0
        }
223
0
        else
224
0
        {
225
0
            // Rebias the exponent to represent the value as a normalized float11
226
0
            float32Val += 0xC8000000;
227
0
        }
228
0
229
0
        return ((float32Val + 0xFFFF + ((float32Val >> 17) & 1)) >> 17) & float11BitMask;
230
0
    }
231
0
}
232
233
MOZ_ALWAYS_INLINE uint16_t
234
packToFloat10(float fp32)
235
0
{
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
0
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
0
249
0
    const unsigned int float32Maxfloat10 = 0x477C0000;
250
0
    const unsigned int float32Minfloat10 = 0x38800000;
251
0
252
0
    const unsigned int float32Bits = BitwiseCast<unsigned int>(fp32);
253
0
    const bool float32Sign = (float32Bits & float32SignMask) == float32SignMask;
254
0
255
0
    unsigned int float32Val = float32Bits & float32ValueMask;
256
0
257
0
    if ((float32Val & float32ExponentMask) == float32ExponentMask)
258
0
    {
259
0
        // INF or NAN
260
0
        if ((float32Val & float32MantissaMask) != 0)
261
0
        {
262
0
            return float10ExponentMask | (((float32Val >> 18) | (float32Val >> 13) | (float32Val >> 3) | (float32Val)) & float10MantissaMask);
263
0
        }
264
0
        else if (float32Sign)
265
0
        {
266
0
            // -INF is clamped to 0 since float11 is positive only
267
0
            return 0;
268
0
        }
269
0
        else
270
0
        {
271
0
            return float10ExponentMask;
272
0
        }
273
0
    }
274
0
    else if (float32Sign)
275
0
    {
276
0
        // float10 is positive only, so clamp to zero
277
0
        return 0;
278
0
    }
279
0
    else if (float32Val > float32Maxfloat10)
280
0
    {
281
0
        // The number is too large to be represented as a float11, set to max
282
0
        return float10Max;
283
0
    }
284
0
    else
285
0
    {
286
0
        if (float32Val < float32Minfloat10)
287
0
        {
288
0
            // The number is too small to be represented as a normalized float11
289
0
            // 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
0
        }
293
0
        else
294
0
        {
295
0
            // Rebias the exponent to represent the value as a normalized float11
296
0
            float32Val += 0xC8000000;
297
0
        }
298
0
299
0
        return ((float32Val + 0x1FFFF + ((float32Val >> 18) & 1)) >> 18) & float10BitMask;
300
0
    }
301
0
}
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
0
    case WebGLTexelFormat::A8:
392
0
    case WebGLTexelFormat::R8:
393
0
        return 1;
394
0
    case WebGLTexelFormat::A16F:
395
0
    case WebGLTexelFormat::R16F:
396
0
    case WebGLTexelFormat::RA8:
397
0
    case WebGLTexelFormat::RG8:
398
0
    case WebGLTexelFormat::RGB565:
399
0
    case WebGLTexelFormat::RGBA4444:
400
0
    case WebGLTexelFormat::RGBA5551:
401
0
        return 2;
402
0
    case WebGLTexelFormat::RGB8:
403
0
        return 3;
404
0
    case WebGLTexelFormat::A32F:
405
0
    case WebGLTexelFormat::R32F:
406
0
    case WebGLTexelFormat::RA16F:
407
0
    case WebGLTexelFormat::RG16F:
408
0
    case WebGLTexelFormat::RGB11F11F10F:
409
0
    case WebGLTexelFormat::RGBA8:
410
0
    case WebGLTexelFormat::BGRX8:
411
0
    case WebGLTexelFormat::BGRA8:
412
0
        return 4;
413
0
    case WebGLTexelFormat::RGB16F:
414
0
        return 6;
415
0
    case WebGLTexelFormat::RA32F:
416
0
    case WebGLTexelFormat::RG32F:
417
0
    case WebGLTexelFormat::RGBA16F:
418
0
        return 8;
419
0
    case WebGLTexelFormat::RGB32F:
420
0
        return 12;
421
0
    case WebGLTexelFormat::RGBA32F:
422
0
        return 16;
423
0
    default:
424
0
        MOZ_ASSERT(false, "Unknown texel format. Coding mistake?");
425
0
        return 0;
426
0
    }
427
0
}
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
0
}
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
0
}
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
unpack<WebGLTexelFormat::A8, uint8_t, uint8_t>(const uint8_t* __restrict src, uint8_t* __restrict dst)
488
0
{
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
unpack<WebGLTexelFormat::A16F, uint16_t, uint16_t>(const uint16_t* __restrict src, uint16_t* __restrict dst)
497
0
{
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
unpack<WebGLTexelFormat::A32F, float, float>(const float* __restrict src, float* __restrict dst)
506
0
{
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
unpack<WebGLTexelFormat::R8, uint8_t, uint8_t>(const uint8_t* __restrict src, uint8_t* __restrict dst)
515
0
{
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
unpack<WebGLTexelFormat::R16F, uint16_t, uint16_t>(const uint16_t* __restrict src, uint16_t* __restrict dst)
524
0
{
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
unpack<WebGLTexelFormat::R32F, float, float>(const float* __restrict src, float* __restrict dst)
533
0
{
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
unpack<WebGLTexelFormat::RA8, uint8_t, uint8_t>(const uint8_t* __restrict src, uint8_t* __restrict dst)
544
0
{
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
unpack<WebGLTexelFormat::RA16F, uint16_t, uint16_t>(const uint16_t* __restrict src, uint16_t* __restrict dst)
553
0
{
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
unpack<WebGLTexelFormat::RA32F, float, float>(const float* __restrict src, float* __restrict dst)
562
0
{
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
unpack<WebGLTexelFormat::RGB565, uint16_t, uint8_t>(const uint16_t* __restrict src, uint8_t* __restrict dst)
573
0
{
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
unpack<WebGLTexelFormat::RGB8, uint8_t, uint8_t>(const uint8_t* __restrict src, uint8_t* __restrict dst)
586
0
{
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
unpack<WebGLTexelFormat::RGB16F, uint16_t, uint16_t>(const uint16_t* __restrict src, uint16_t* __restrict dst)
595
0
{
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
unpack<WebGLTexelFormat::RGB32F, float, float>(const float* __restrict src, float* __restrict dst)
604
0
{
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
unpack<WebGLTexelFormat::RGBA4444, uint16_t, uint8_t>(const uint16_t* __restrict src, uint8_t* __restrict dst)
615
0
{
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
unpack<WebGLTexelFormat::RGBA5551, uint16_t, uint8_t>(const uint16_t* __restrict src, uint8_t* __restrict dst)
629
0
{
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
unpack<WebGLTexelFormat::RGBA8, uint8_t, uint8_t>(const uint8_t* __restrict src, uint8_t* __restrict dst)
642
0
{
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
unpack<WebGLTexelFormat::RGBA16F, uint16_t, uint16_t>(const uint16_t* __restrict src, uint16_t* __restrict dst)
651
0
{
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
unpack<WebGLTexelFormat::RGBA32F, float, float>(const float* __restrict src, float* __restrict dst)
660
0
{
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
unpack<WebGLTexelFormat::BGRX8, uint8_t, uint8_t>(const uint8_t* __restrict src, uint8_t* __restrict dst)
671
0
{
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
unpack<WebGLTexelFormat::BGRA8, uint8_t, uint8_t>(const uint8_t* __restrict src, uint8_t* __restrict dst)
680
0
{
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
pack<WebGLTexelFormat::A8, WebGLTexelPremultiplicationOp::None, uint8_t, uint8_t>(const uint8_t* __restrict src, uint8_t* __restrict dst)
706
0
{
707
0
    dst[0] = src[3];
708
0
}
709
710
template<> MOZ_ALWAYS_INLINE void
711
pack<WebGLTexelFormat::A8, WebGLTexelPremultiplicationOp::Premultiply, uint8_t, uint8_t>(const uint8_t* __restrict src, uint8_t* __restrict dst)
712
0
{
713
0
    dst[0] = src[3];
714
0
}
715
716
template<> MOZ_ALWAYS_INLINE void
717
pack<WebGLTexelFormat::A8, WebGLTexelPremultiplicationOp::Unpremultiply, uint8_t, uint8_t>(const uint8_t* __restrict src, uint8_t* __restrict dst)
718
0
{
719
0
    dst[0] = src[3];
720
0
}
721
722
template<> MOZ_ALWAYS_INLINE void
723
pack<WebGLTexelFormat::A16F, WebGLTexelPremultiplicationOp::None, uint16_t, uint16_t>(const uint16_t* __restrict src, uint16_t* __restrict dst)
724
0
{
725
0
    dst[0] = src[3];
726
0
}
727
728
template<> MOZ_ALWAYS_INLINE void
729
pack<WebGLTexelFormat::A16F, WebGLTexelPremultiplicationOp::Premultiply, uint16_t, uint16_t>(const uint16_t* __restrict src, uint16_t* __restrict dst)
730
0
{
731
0
    dst[0] = src[3];
732
0
}
733
734
template<> MOZ_ALWAYS_INLINE void
735
pack<WebGLTexelFormat::A16F, WebGLTexelPremultiplicationOp::Unpremultiply, uint16_t, uint16_t>(const uint16_t* __restrict src, uint16_t* __restrict dst)
736
0
{
737
0
    dst[0] = src[3];
738
0
}
739
740
template<> MOZ_ALWAYS_INLINE void
741
pack<WebGLTexelFormat::A32F, WebGLTexelPremultiplicationOp::None, float, float>(const float* __restrict src, float* __restrict dst)
742
0
{
743
0
    dst[0] = src[3];
744
0
}
745
746
template<> MOZ_ALWAYS_INLINE void
747
pack<WebGLTexelFormat::A32F, WebGLTexelPremultiplicationOp::Premultiply, float, float>(const float* __restrict src, float* __restrict dst)
748
0
{
749
0
    dst[0] = src[3];
750
0
}
751
752
template<> MOZ_ALWAYS_INLINE void
753
pack<WebGLTexelFormat::A32F, WebGLTexelPremultiplicationOp::Unpremultiply, float, float>(const float* __restrict src, float* __restrict dst)
754
0
{
755
0
    dst[0] = src[3];
756
0
}
757
758
template<> MOZ_ALWAYS_INLINE void
759
pack<WebGLTexelFormat::R8, WebGLTexelPremultiplicationOp::None, uint8_t, uint8_t>(const uint8_t* __restrict src, uint8_t* __restrict dst)
760
0
{
761
0
    dst[0] = src[0];
762
0
}
763
764
template<> MOZ_ALWAYS_INLINE void
765
pack<WebGLTexelFormat::R8, WebGLTexelPremultiplicationOp::Premultiply, uint8_t, uint8_t>(const uint8_t* __restrict src, uint8_t* __restrict dst)
766
0
{
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
pack<WebGLTexelFormat::R8, WebGLTexelPremultiplicationOp::Unpremultiply, uint8_t, uint8_t>(const uint8_t* __restrict src, uint8_t* __restrict dst)
774
0
{
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
pack<WebGLTexelFormat::R16F, WebGLTexelPremultiplicationOp::None, uint16_t, uint16_t>(const uint16_t* __restrict src, uint16_t* __restrict dst)
782
0
{
783
0
    dst[0] = src[0];
784
0
}
785
786
template<> MOZ_ALWAYS_INLINE void
787
pack<WebGLTexelFormat::R16F, WebGLTexelPremultiplicationOp::Premultiply, uint16_t, uint16_t>(const uint16_t* __restrict src, uint16_t* __restrict dst)
788
0
{
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
pack<WebGLTexelFormat::R16F, WebGLTexelPremultiplicationOp::Unpremultiply, uint16_t, uint16_t>(const uint16_t* __restrict src, uint16_t* __restrict dst)
795
0
{
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
pack<WebGLTexelFormat::R32F, WebGLTexelPremultiplicationOp::None, float, float>(const float* __restrict src, float* __restrict dst)
803
0
{
804
0
    dst[0] = src[0];
805
0
}
806
807
template<> MOZ_ALWAYS_INLINE void
808
pack<WebGLTexelFormat::R32F, WebGLTexelPremultiplicationOp::Premultiply, float, float>(const float* __restrict src, float* __restrict dst)
809
0
{
810
0
    float scaleFactor = src[3];
811
0
    dst[0] = src[0] * scaleFactor;
812
0
}
813
814
template<> MOZ_ALWAYS_INLINE void
815
pack<WebGLTexelFormat::R32F, WebGLTexelPremultiplicationOp::Unpremultiply, float, float>(const float* __restrict src, float* __restrict dst)
816
0
{
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
pack<WebGLTexelFormat::RA8, WebGLTexelPremultiplicationOp::None, uint8_t, uint8_t>(const uint8_t* __restrict src, uint8_t* __restrict dst)
825
0
{
826
0
    dst[0] = src[0];
827
0
    dst[1] = src[3];
828
0
}
829
830
template<> MOZ_ALWAYS_INLINE void
831
pack<WebGLTexelFormat::RA8, WebGLTexelPremultiplicationOp::Premultiply, uint8_t, uint8_t>(const uint8_t* __restrict src, uint8_t* __restrict dst)
832
0
{
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
pack<WebGLTexelFormat::RA8, WebGLTexelPremultiplicationOp::Unpremultiply, uint8_t, uint8_t>(const uint8_t* __restrict src, uint8_t* __restrict dst)
842
0
{
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
pack<WebGLTexelFormat::RA16F, WebGLTexelPremultiplicationOp::None, uint16_t, uint16_t>(const uint16_t* __restrict src, uint16_t* __restrict dst)
851
0
{
852
0
    dst[0] = src[0];
853
0
    dst[1] = src[3];
854
0
}
855
856
template<> MOZ_ALWAYS_INLINE void
857
pack<WebGLTexelFormat::RA16F, WebGLTexelPremultiplicationOp::Premultiply, uint16_t, uint16_t>(const uint16_t* __restrict src, uint16_t* __restrict dst)
858
0
{
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
pack<WebGLTexelFormat::RA16F, WebGLTexelPremultiplicationOp::Unpremultiply, uint16_t, uint16_t>(const uint16_t* __restrict src, uint16_t* __restrict dst)
866
0
{
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
pack<WebGLTexelFormat::RA32F, WebGLTexelPremultiplicationOp::None, float, float>(const float* __restrict src, float* __restrict dst)
875
0
{
876
0
    dst[0] = src[0];
877
0
    dst[1] = src[3];
878
0
}
879
880
template<> MOZ_ALWAYS_INLINE void
881
pack<WebGLTexelFormat::RA32F, WebGLTexelPremultiplicationOp::Premultiply, float, float>(const float* __restrict src, float* __restrict dst)
882
0
{
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
pack<WebGLTexelFormat::RA32F, WebGLTexelPremultiplicationOp::Unpremultiply, float, float>(const float* __restrict src, float* __restrict dst)
890
0
{
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
pack<WebGLTexelFormat::RG8, WebGLTexelPremultiplicationOp::None, uint8_t, uint8_t>(const uint8_t* __restrict src, uint8_t* __restrict dst)
898
0
{
899
0
    dst[0] = src[0];
900
0
    dst[1] = src[1];
901
0
}
902
903
template<> MOZ_ALWAYS_INLINE void
904
pack<WebGLTexelFormat::RG8, WebGLTexelPremultiplicationOp::Premultiply, uint8_t, uint8_t>(const uint8_t* __restrict src, uint8_t* __restrict dst)
905
0
{
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
pack<WebGLTexelFormat::RG8, WebGLTexelPremultiplicationOp::Unpremultiply, uint8_t, uint8_t>(const uint8_t* __restrict src, uint8_t* __restrict dst)
916
0
{
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
pack<WebGLTexelFormat::RG16F, WebGLTexelPremultiplicationOp::None, uint16_t, uint16_t>(const uint16_t* __restrict src, uint16_t* __restrict dst)
926
0
{
927
0
    dst[0] = src[0];
928
0
    dst[1] = src[1];
929
0
}
930
931
template<> MOZ_ALWAYS_INLINE void
932
pack<WebGLTexelFormat::RG16F, WebGLTexelPremultiplicationOp::Premultiply, uint16_t, uint16_t>(const uint16_t* __restrict src, uint16_t* __restrict dst)
933
0
{
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
pack<WebGLTexelFormat::RG16F, WebGLTexelPremultiplicationOp::Unpremultiply, uint16_t, uint16_t>(const uint16_t* __restrict src, uint16_t* __restrict dst)
941
0
{
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
pack<WebGLTexelFormat::RG32F, WebGLTexelPremultiplicationOp::None, float, float>(const float* __restrict src, float* __restrict dst)
950
0
{
951
0
    dst[0] = src[0];
952
0
    dst[1] = src[1];
953
0
}
954
955
template<> MOZ_ALWAYS_INLINE void
956
pack<WebGLTexelFormat::RG32F, WebGLTexelPremultiplicationOp::Premultiply, float, float>(const float* __restrict src, float* __restrict dst)
957
0
{
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
pack<WebGLTexelFormat::RG32F, WebGLTexelPremultiplicationOp::Unpremultiply, float, float>(const float* __restrict src, float* __restrict dst)
965
0
{
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
pack<WebGLTexelFormat::RGB565, WebGLTexelPremultiplicationOp::None, uint8_t, uint16_t>(const uint8_t* __restrict src, uint16_t* __restrict dst)
975
0
{
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
pack<WebGLTexelFormat::RGB565, WebGLTexelPremultiplicationOp::Premultiply, uint8_t, uint16_t>(const uint8_t* __restrict src, uint16_t* __restrict dst)
983
0
{
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
pack<WebGLTexelFormat::RGB565, WebGLTexelPremultiplicationOp::Unpremultiply, uint8_t, uint16_t>(const uint8_t* __restrict src, uint16_t* __restrict dst)
996
0
{
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
pack<WebGLTexelFormat::RGB8, WebGLTexelPremultiplicationOp::None, uint8_t, uint8_t>(const uint8_t* __restrict src, uint8_t* __restrict dst)
1008
0
{
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
pack<WebGLTexelFormat::RGB8, WebGLTexelPremultiplicationOp::Premultiply, uint8_t, uint8_t>(const uint8_t* __restrict src, uint8_t* __restrict dst)
1016
0
{
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
pack<WebGLTexelFormat::RGB8, WebGLTexelPremultiplicationOp::Unpremultiply, uint8_t, uint8_t>(const uint8_t* __restrict src, uint8_t* __restrict dst)
1028
0
{
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
pack<WebGLTexelFormat::RGB11F11F10F, WebGLTexelPremultiplicationOp::None, float, uint32_t>(const float* __restrict src, uint32_t* __restrict dst)
1040
0
{
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
pack<WebGLTexelFormat::RGB11F11F10F, WebGLTexelPremultiplicationOp::Premultiply, float, uint32_t>(const float* __restrict src, uint32_t* __restrict dst)
1048
0
{
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
pack<WebGLTexelFormat::RGB11F11F10F, WebGLTexelPremultiplicationOp::Unpremultiply, float, uint32_t>(const float* __restrict src, uint32_t* __restrict dst)
1057
0
{
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
pack<WebGLTexelFormat::RGB16F, WebGLTexelPremultiplicationOp::None, uint16_t, uint16_t>(const uint16_t* __restrict src, uint16_t* __restrict dst)
1066
0
{
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
pack<WebGLTexelFormat::RGB16F, WebGLTexelPremultiplicationOp::Premultiply, uint16_t, uint16_t>(const uint16_t* __restrict src, uint16_t* __restrict dst)
1074
0
{
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
pack<WebGLTexelFormat::RGB16F, WebGLTexelPremultiplicationOp::Unpremultiply, uint16_t, uint16_t>(const uint16_t* __restrict src, uint16_t* __restrict dst)
1083
0
{
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
pack<WebGLTexelFormat::RGB32F, WebGLTexelPremultiplicationOp::None, float, float>(const float* __restrict src, float* __restrict dst)
1093
0
{
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
pack<WebGLTexelFormat::RGB32F, WebGLTexelPremultiplicationOp::Premultiply, float, float>(const float* __restrict src, float* __restrict dst)
1101
0
{
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
pack<WebGLTexelFormat::RGB32F, WebGLTexelPremultiplicationOp::Unpremultiply, float, float>(const float* __restrict src, float* __restrict dst)
1110
0
{
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
pack<WebGLTexelFormat::RGBA4444, WebGLTexelPremultiplicationOp::None, uint8_t, uint16_t>(const uint8_t* __restrict src, uint16_t* __restrict dst)
1121
0
{
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
pack<WebGLTexelFormat::RGBA4444, WebGLTexelPremultiplicationOp::Premultiply, uint8_t, uint16_t>(const uint8_t* __restrict src, uint16_t* __restrict dst)
1130
0
{
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
pack<WebGLTexelFormat::RGBA4444, WebGLTexelPremultiplicationOp::Unpremultiply, uint8_t, uint16_t>(const uint8_t* __restrict src, uint16_t* __restrict dst)
1144
0
{
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
pack<WebGLTexelFormat::RGBA5551, WebGLTexelPremultiplicationOp::None, uint8_t, uint16_t>(const uint8_t* __restrict src, uint16_t* __restrict dst)
1157
0
{
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
pack<WebGLTexelFormat::RGBA5551, WebGLTexelPremultiplicationOp::Premultiply, uint8_t, uint16_t>(const uint8_t* __restrict src, uint16_t* __restrict dst)
1166
0
{
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
pack<WebGLTexelFormat::RGBA5551, WebGLTexelPremultiplicationOp::Unpremultiply, uint8_t, uint16_t>(const uint8_t* __restrict src, uint16_t* __restrict dst)
1180
0
{
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
pack<WebGLTexelFormat::RGBA8, WebGLTexelPremultiplicationOp::None, uint8_t, uint8_t>(const uint8_t* __restrict src, uint8_t* __restrict dst)
1193
0
{
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
pack<WebGLTexelFormat::RGBA8, WebGLTexelPremultiplicationOp::Premultiply, uint8_t, uint8_t>(const uint8_t* __restrict src, uint8_t* __restrict dst)
1202
0
{
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
pack<WebGLTexelFormat::RGBA8, WebGLTexelPremultiplicationOp::Unpremultiply, uint8_t, uint8_t>(const uint8_t* __restrict src, uint8_t* __restrict dst)
1216
0
{
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
pack<WebGLTexelFormat::RGBA16F, WebGLTexelPremultiplicationOp::None, uint16_t, uint16_t>(const uint16_t* __restrict src, uint16_t* __restrict dst)
1229
0
{
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
pack<WebGLTexelFormat::RGBA16F, WebGLTexelPremultiplicationOp::Premultiply, uint16_t, uint16_t>(const uint16_t* __restrict src, uint16_t* __restrict dst)
1238
0
{
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
pack<WebGLTexelFormat::RGBA16F, WebGLTexelPremultiplicationOp::Unpremultiply, uint16_t, uint16_t>(const uint16_t* __restrict src, uint16_t* __restrict dst)
1248
0
{
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
pack<WebGLTexelFormat::RGBA32F, WebGLTexelPremultiplicationOp::None, float, float>(const float* __restrict src, float* __restrict dst)
1259
0
{
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
pack<WebGLTexelFormat::RGBA32F, WebGLTexelPremultiplicationOp::Premultiply, float, float>(const float* __restrict src, float* __restrict dst)
1268
0
{
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
pack<WebGLTexelFormat::RGBA32F, WebGLTexelPremultiplicationOp::Unpremultiply, float, float>(const float* __restrict src, float* __restrict dst)
1278
0
{
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
0
{
1291
0
    MOZ_ASSERT(false, "Unimplemented texture format conversion");
1292
0
}
Unexecuted instantiation: void mozilla::WebGLTexelConversions::convertType<unsigned short, unsigned char>(unsigned short const*, unsigned char*)
Unexecuted instantiation: void mozilla::WebGLTexelConversions::convertType<unsigned short, float>(unsigned short const*, float*)
Unexecuted instantiation: void mozilla::WebGLTexelConversions::convertType<float, unsigned char>(float const*, unsigned char*)
Unexecuted instantiation: void mozilla::WebGLTexelConversions::convertType<float, unsigned short>(float const*, unsigned short*)
1293
1294
template<> MOZ_ALWAYS_INLINE void
1295
convertType<uint8_t, uint8_t>(const uint8_t* __restrict src, uint8_t* __restrict dst)
1296
0
{
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
convertType<uint16_t, uint16_t>(const uint16_t* __restrict src, uint16_t* __restrict dst)
1305
0
{
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
convertType<float, float>(const float* __restrict src, float* __restrict dst)
1314
0
{
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
convertType<uint8_t, float>(const uint8_t* __restrict src, float* __restrict dst)
1323
0
{
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
convertType<uint8_t, uint16_t>(const uint8_t* __restrict src, uint16_t* __restrict dst)
1333
0
{
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_