tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

mathutil.h (43593B)


      1 //
      2 // Copyright 2002 The ANGLE Project Authors. All rights reserved.
      3 // Use of this source code is governed by a BSD-style license that can be
      4 // found in the LICENSE file.
      5 //
      6 
      7 // mathutil.h: Math and bit manipulation functions.
      8 
      9 #ifndef COMMON_MATHUTIL_H_
     10 #define COMMON_MATHUTIL_H_
     11 
     12 #include <math.h>
     13 #include <stdint.h>
     14 #include <stdlib.h>
     15 #include <string.h>
     16 #include <algorithm>
     17 #include <limits>
     18 
     19 #include <anglebase/numerics/safe_math.h>
     20 
     21 #include "common/debug.h"
     22 #include "common/platform.h"
     23 
     24 namespace angle
     25 {
     26 using base::CheckedNumeric;
     27 using base::IsValueInRangeForNumericType;
     28 }  // namespace angle
     29 
     30 namespace gl
     31 {
     32 
     33 const unsigned int Float32One   = 0x3F800000;
     34 const unsigned short Float16One = 0x3C00;
     35 
     36 template <typename T>
     37 inline constexpr bool isPow2(T x)
     38 {
     39    static_assert(std::is_integral<T>::value, "isPow2 must be called on an integer type.");
     40    return (x & (x - 1)) == 0 && (x != 0);
     41 }
     42 
     43 template <typename T>
     44 inline int log2(T x)
     45 {
     46    static_assert(std::is_integral<T>::value, "log2 must be called on an integer type.");
     47    int r = 0;
     48    while ((x >> r) > 1)
     49        r++;
     50    return r;
     51 }
     52 
     53 inline unsigned int ceilPow2(unsigned int x)
     54 {
     55    if (x != 0)
     56        x--;
     57    x |= x >> 1;
     58    x |= x >> 2;
     59    x |= x >> 4;
     60    x |= x >> 8;
     61    x |= x >> 16;
     62    x++;
     63 
     64    return x;
     65 }
     66 
     67 template <typename DestT, typename SrcT>
     68 inline DestT clampCast(SrcT value)
     69 {
     70    // For floating-point types with denormalization, min returns the minimum positive normalized
     71    // value. To find the value that has no values less than it, use numeric_limits::lowest.
     72    constexpr const long double destLo =
     73        static_cast<long double>(std::numeric_limits<DestT>::lowest());
     74    constexpr const long double destHi =
     75        static_cast<long double>(std::numeric_limits<DestT>::max());
     76    constexpr const long double srcLo =
     77        static_cast<long double>(std::numeric_limits<SrcT>::lowest());
     78    constexpr long double srcHi = static_cast<long double>(std::numeric_limits<SrcT>::max());
     79 
     80    if (destHi < srcHi)
     81    {
     82        DestT destMax = std::numeric_limits<DestT>::max();
     83        if (value >= static_cast<SrcT>(destMax))
     84        {
     85            return destMax;
     86        }
     87    }
     88 
     89    if (destLo > srcLo)
     90    {
     91        DestT destLow = std::numeric_limits<DestT>::lowest();
     92        if (value <= static_cast<SrcT>(destLow))
     93        {
     94            return destLow;
     95        }
     96    }
     97 
     98    return static_cast<DestT>(value);
     99 }
    100 
    101 // Specialize clampCast for bool->int conversion to avoid MSVS 2015 performance warning when the max
    102 // value is casted to the source type.
    103 template <>
    104 inline unsigned int clampCast(bool value)
    105 {
    106    return static_cast<unsigned int>(value);
    107 }
    108 
    109 template <>
    110 inline int clampCast(bool value)
    111 {
    112    return static_cast<int>(value);
    113 }
    114 
    115 template <typename T, typename MIN, typename MAX>
    116 inline T clamp(T x, MIN min, MAX max)
    117 {
    118    // Since NaNs fail all comparison tests, a NaN value will default to min
    119    return x > min ? (x > max ? max : x) : min;
    120 }
    121 
    122 template <typename T>
    123 T clampForBitCount(T value, size_t bitCount)
    124 {
    125    static_assert(std::numeric_limits<T>::is_integer, "T must be an integer.");
    126 
    127    if (bitCount == 0)
    128    {
    129        constexpr T kZero = 0;
    130        return kZero;
    131    }
    132    ASSERT(bitCount <= sizeof(T) * 8);
    133 
    134    constexpr bool kIsSigned = std::numeric_limits<T>::is_signed;
    135    ASSERT((bitCount > 1) || !kIsSigned);
    136 
    137    T min = 0;
    138    T max = 0;
    139    if (bitCount == sizeof(T) * 8)
    140    {
    141        min = std::numeric_limits<T>::min();
    142        max = std::numeric_limits<T>::max();
    143    }
    144    else
    145    {
    146        constexpr T kOne = 1;
    147        min              = (kIsSigned) ? -1 * (kOne << (bitCount - 1)) : 0;
    148        max              = (kIsSigned) ? (kOne << (bitCount - 1)) - 1 : (kOne << bitCount) - 1;
    149    }
    150 
    151    return gl::clamp(value, min, max);
    152 }
    153 
    154 inline float clamp01(float x)
    155 {
    156    return clamp(x, 0.0f, 1.0f);
    157 }
    158 
    159 template <const int n>
    160 inline unsigned int unorm(float x)
    161 {
    162    const unsigned int max = 0xFFFFFFFF >> (32 - n);
    163 
    164    if (x > 1)
    165    {
    166        return max;
    167    }
    168    else if (x < 0)
    169    {
    170        return 0;
    171    }
    172    else
    173    {
    174        return (unsigned int)(max * x + 0.5f);
    175    }
    176 }
    177 
    178 inline bool supportsSSE2()
    179 {
    180 #if defined(ANGLE_USE_SSE)
    181    static bool checked  = false;
    182    static bool supports = false;
    183 
    184    if (checked)
    185    {
    186        return supports;
    187    }
    188 
    189 #    if defined(ANGLE_PLATFORM_WINDOWS) && !defined(_M_ARM) && !defined(_M_ARM64)
    190    {
    191        int info[4];
    192        __cpuid(info, 0);
    193 
    194        if (info[0] >= 1)
    195        {
    196            __cpuid(info, 1);
    197 
    198            supports = (info[3] >> 26) & 1;
    199        }
    200    }
    201 #    endif  // defined(ANGLE_PLATFORM_WINDOWS) && !defined(_M_ARM) && !defined(_M_ARM64)
    202    checked = true;
    203    return supports;
    204 #else  // defined(ANGLE_USE_SSE)
    205    return false;
    206 #endif
    207 }
    208 
    209 template <typename destType, typename sourceType>
    210 destType bitCast(const sourceType &source)
    211 {
    212    size_t copySize = std::min(sizeof(destType), sizeof(sourceType));
    213    destType output;
    214    memcpy(&output, &source, copySize);
    215    return output;
    216 }
    217 
    218 // https://stackoverflow.com/a/37581284
    219 template <typename T>
    220 static constexpr double normalize(T value)
    221 {
    222    return value < 0 ? -static_cast<double>(value) / std::numeric_limits<T>::min()
    223                     : static_cast<double>(value) / std::numeric_limits<T>::max();
    224 }
    225 
    226 inline unsigned short float32ToFloat16(float fp32)
    227 {
    228    unsigned int fp32i = bitCast<unsigned int>(fp32);
    229    unsigned int sign  = (fp32i & 0x80000000) >> 16;
    230    unsigned int abs   = fp32i & 0x7FFFFFFF;
    231 
    232    if (abs > 0x7F800000)
    233    {  // NaN
    234        return 0x7FFF;
    235    }
    236    else if (abs > 0x47FFEFFF)
    237    {  // Infinity
    238        return static_cast<uint16_t>(sign | 0x7C00);
    239    }
    240    else if (abs < 0x38800000)  // Denormal
    241    {
    242        unsigned int mantissa = (abs & 0x007FFFFF) | 0x00800000;
    243        int e                 = 113 - (abs >> 23);
    244 
    245        if (e < 24)
    246        {
    247            abs = mantissa >> e;
    248        }
    249        else
    250        {
    251            abs = 0;
    252        }
    253 
    254        return static_cast<unsigned short>(sign | (abs + 0x00000FFF + ((abs >> 13) & 1)) >> 13);
    255    }
    256    else
    257    {
    258        return static_cast<unsigned short>(
    259            sign | (abs + 0xC8000000 + 0x00000FFF + ((abs >> 13) & 1)) >> 13);
    260    }
    261 }
    262 
    263 float float16ToFloat32(unsigned short h);
    264 
    265 unsigned int convertRGBFloatsTo999E5(float red, float green, float blue);
    266 void convert999E5toRGBFloats(unsigned int input, float *red, float *green, float *blue);
    267 
    268 inline unsigned short float32ToFloat11(float fp32)
    269 {
    270    const unsigned int float32MantissaMask     = 0x7FFFFF;
    271    const unsigned int float32ExponentMask     = 0x7F800000;
    272    const unsigned int float32SignMask         = 0x80000000;
    273    const unsigned int float32ValueMask        = ~float32SignMask;
    274    const unsigned int float32ExponentFirstBit = 23;
    275    const unsigned int float32ExponentBias     = 127;
    276 
    277    const unsigned short float11Max          = 0x7BF;
    278    const unsigned short float11MantissaMask = 0x3F;
    279    const unsigned short float11ExponentMask = 0x7C0;
    280    const unsigned short float11BitMask      = 0x7FF;
    281    const unsigned int float11ExponentBias   = 14;
    282 
    283    const unsigned int float32Maxfloat11       = 0x477E0000;
    284    const unsigned int float32MinNormfloat11   = 0x38800000;
    285    const unsigned int float32MinDenormfloat11 = 0x35000080;
    286 
    287    const unsigned int float32Bits = bitCast<unsigned int>(fp32);
    288    const bool float32Sign         = (float32Bits & float32SignMask) == float32SignMask;
    289 
    290    unsigned int float32Val = float32Bits & float32ValueMask;
    291 
    292    if ((float32Val & float32ExponentMask) == float32ExponentMask)
    293    {
    294        // INF or NAN
    295        if ((float32Val & float32MantissaMask) != 0)
    296        {
    297            return float11ExponentMask |
    298                   (((float32Val >> 17) | (float32Val >> 11) | (float32Val >> 6) | (float32Val)) &
    299                    float11MantissaMask);
    300        }
    301        else if (float32Sign)
    302        {
    303            // -INF is clamped to 0 since float11 is positive only
    304            return 0;
    305        }
    306        else
    307        {
    308            return float11ExponentMask;
    309        }
    310    }
    311    else if (float32Sign)
    312    {
    313        // float11 is positive only, so clamp to zero
    314        return 0;
    315    }
    316    else if (float32Val > float32Maxfloat11)
    317    {
    318        // The number is too large to be represented as a float11, set to max
    319        return float11Max;
    320    }
    321    else if (float32Val < float32MinDenormfloat11)
    322    {
    323        // The number is too small to be represented as a denormalized float11, set to 0
    324        return 0;
    325    }
    326    else
    327    {
    328        if (float32Val < float32MinNormfloat11)
    329        {
    330            // The number is too small to be represented as a normalized float11
    331            // Convert it to a denormalized value.
    332            const unsigned int shift = (float32ExponentBias - float11ExponentBias) -
    333                                       (float32Val >> float32ExponentFirstBit);
    334            ASSERT(shift < 32);
    335            float32Val =
    336                ((1 << float32ExponentFirstBit) | (float32Val & float32MantissaMask)) >> shift;
    337        }
    338        else
    339        {
    340            // Rebias the exponent to represent the value as a normalized float11
    341            float32Val += 0xC8000000;
    342        }
    343 
    344        return ((float32Val + 0xFFFF + ((float32Val >> 17) & 1)) >> 17) & float11BitMask;
    345    }
    346 }
    347 
    348 inline unsigned short float32ToFloat10(float fp32)
    349 {
    350    const unsigned int float32MantissaMask     = 0x7FFFFF;
    351    const unsigned int float32ExponentMask     = 0x7F800000;
    352    const unsigned int float32SignMask         = 0x80000000;
    353    const unsigned int float32ValueMask        = ~float32SignMask;
    354    const unsigned int float32ExponentFirstBit = 23;
    355    const unsigned int float32ExponentBias     = 127;
    356 
    357    const unsigned short float10Max          = 0x3DF;
    358    const unsigned short float10MantissaMask = 0x1F;
    359    const unsigned short float10ExponentMask = 0x3E0;
    360    const unsigned short float10BitMask      = 0x3FF;
    361    const unsigned int float10ExponentBias   = 14;
    362 
    363    const unsigned int float32Maxfloat10       = 0x477C0000;
    364    const unsigned int float32MinNormfloat10   = 0x38800000;
    365    const unsigned int float32MinDenormfloat10 = 0x35800040;
    366 
    367    const unsigned int float32Bits = bitCast<unsigned int>(fp32);
    368    const bool float32Sign         = (float32Bits & float32SignMask) == float32SignMask;
    369 
    370    unsigned int float32Val = float32Bits & float32ValueMask;
    371 
    372    if ((float32Val & float32ExponentMask) == float32ExponentMask)
    373    {
    374        // INF or NAN
    375        if ((float32Val & float32MantissaMask) != 0)
    376        {
    377            return float10ExponentMask |
    378                   (((float32Val >> 18) | (float32Val >> 13) | (float32Val >> 3) | (float32Val)) &
    379                    float10MantissaMask);
    380        }
    381        else if (float32Sign)
    382        {
    383            // -INF is clamped to 0 since float10 is positive only
    384            return 0;
    385        }
    386        else
    387        {
    388            return float10ExponentMask;
    389        }
    390    }
    391    else if (float32Sign)
    392    {
    393        // float10 is positive only, so clamp to zero
    394        return 0;
    395    }
    396    else if (float32Val > float32Maxfloat10)
    397    {
    398        // The number is too large to be represented as a float10, set to max
    399        return float10Max;
    400    }
    401    else if (float32Val < float32MinDenormfloat10)
    402    {
    403        // The number is too small to be represented as a denormalized float10, set to 0
    404        return 0;
    405    }
    406    else
    407    {
    408        if (float32Val < float32MinNormfloat10)
    409        {
    410            // The number is too small to be represented as a normalized float10
    411            // Convert it to a denormalized value.
    412            const unsigned int shift = (float32ExponentBias - float10ExponentBias) -
    413                                       (float32Val >> float32ExponentFirstBit);
    414            ASSERT(shift < 32);
    415            float32Val =
    416                ((1 << float32ExponentFirstBit) | (float32Val & float32MantissaMask)) >> shift;
    417        }
    418        else
    419        {
    420            // Rebias the exponent to represent the value as a normalized float10
    421            float32Val += 0xC8000000;
    422        }
    423 
    424        return ((float32Val + 0x1FFFF + ((float32Val >> 18) & 1)) >> 18) & float10BitMask;
    425    }
    426 }
    427 
    428 inline float float11ToFloat32(unsigned short fp11)
    429 {
    430    unsigned short exponent = (fp11 >> 6) & 0x1F;
    431    unsigned short mantissa = fp11 & 0x3F;
    432 
    433    if (exponent == 0x1F)
    434    {
    435        // INF or NAN
    436        return bitCast<float>(0x7f800000 | (mantissa << 17));
    437    }
    438    else
    439    {
    440        if (exponent != 0)
    441        {
    442            // normalized
    443        }
    444        else if (mantissa != 0)
    445        {
    446            // The value is denormalized
    447            exponent = 1;
    448 
    449            do
    450            {
    451                exponent--;
    452                mantissa <<= 1;
    453            } while ((mantissa & 0x40) == 0);
    454 
    455            mantissa = mantissa & 0x3F;
    456        }
    457        else  // The value is zero
    458        {
    459            exponent = static_cast<unsigned short>(-112);
    460        }
    461 
    462        return bitCast<float>(((exponent + 112) << 23) | (mantissa << 17));
    463    }
    464 }
    465 
    466 inline float float10ToFloat32(unsigned short fp10)
    467 {
    468    unsigned short exponent = (fp10 >> 5) & 0x1F;
    469    unsigned short mantissa = fp10 & 0x1F;
    470 
    471    if (exponent == 0x1F)
    472    {
    473        // INF or NAN
    474        return bitCast<float>(0x7f800000 | (mantissa << 17));
    475    }
    476    else
    477    {
    478        if (exponent != 0)
    479        {
    480            // normalized
    481        }
    482        else if (mantissa != 0)
    483        {
    484            // The value is denormalized
    485            exponent = 1;
    486 
    487            do
    488            {
    489                exponent--;
    490                mantissa <<= 1;
    491            } while ((mantissa & 0x20) == 0);
    492 
    493            mantissa = mantissa & 0x1F;
    494        }
    495        else  // The value is zero
    496        {
    497            exponent = static_cast<unsigned short>(-112);
    498        }
    499 
    500        return bitCast<float>(((exponent + 112) << 23) | (mantissa << 18));
    501    }
    502 }
    503 
    504 // Converts to and from float and 16.16 fixed point format.
    505 inline float ConvertFixedToFloat(int32_t fixedInput)
    506 {
    507    return static_cast<float>(fixedInput) / 65536.0f;
    508 }
    509 
    510 inline uint32_t ConvertFloatToFixed(float floatInput)
    511 {
    512    static constexpr uint32_t kHighest = 32767 * 65536 + 65535;
    513    static constexpr uint32_t kLowest  = static_cast<uint32_t>(-32768 * 65536 + 65535);
    514 
    515    if (floatInput > 32767.65535)
    516    {
    517        return kHighest;
    518    }
    519    else if (floatInput < -32768.65535)
    520    {
    521        return kLowest;
    522    }
    523    else
    524    {
    525        return static_cast<uint32_t>(floatInput * 65536);
    526    }
    527 }
    528 
    529 template <typename T>
    530 inline float normalizedToFloat(T input)
    531 {
    532    static_assert(std::numeric_limits<T>::is_integer, "T must be an integer.");
    533 
    534    if (sizeof(T) > 2)
    535    {
    536        // float has only a 23 bit mantissa, so we need to do the calculation in double precision
    537        constexpr double inverseMax = 1.0 / std::numeric_limits<T>::max();
    538        return static_cast<float>(input * inverseMax);
    539    }
    540    else
    541    {
    542        constexpr float inverseMax = 1.0f / std::numeric_limits<T>::max();
    543        return input * inverseMax;
    544    }
    545 }
    546 
    547 template <unsigned int inputBitCount, typename T>
    548 inline float normalizedToFloat(T input)
    549 {
    550    static_assert(std::numeric_limits<T>::is_integer, "T must be an integer.");
    551    static_assert(inputBitCount < (sizeof(T) * 8), "T must have more bits than inputBitCount.");
    552    ASSERT((input & ~((1 << inputBitCount) - 1)) == 0);
    553 
    554    if (inputBitCount > 23)
    555    {
    556        // float has only a 23 bit mantissa, so we need to do the calculation in double precision
    557        constexpr double inverseMax = 1.0 / ((1 << inputBitCount) - 1);
    558        return static_cast<float>(input * inverseMax);
    559    }
    560    else
    561    {
    562        constexpr float inverseMax = 1.0f / ((1 << inputBitCount) - 1);
    563        return input * inverseMax;
    564    }
    565 }
    566 
    567 template <typename T>
    568 inline T floatToNormalized(float input)
    569 {
    570    if constexpr (sizeof(T) > 2)
    571    {
    572        // float has only a 23 bit mantissa, so we need to do the calculation in double precision
    573        return static_cast<T>(std::numeric_limits<T>::max() * static_cast<double>(input) + 0.5);
    574    }
    575    else
    576    {
    577        return static_cast<T>(std::numeric_limits<T>::max() * input + 0.5f);
    578    }
    579 }
    580 
    581 template <unsigned int outputBitCount, typename T>
    582 inline T floatToNormalized(float input)
    583 {
    584    static_assert(outputBitCount < (sizeof(T) * 8), "T must have more bits than outputBitCount.");
    585 
    586    if (outputBitCount > 23)
    587    {
    588        // float has only a 23 bit mantissa, so we need to do the calculation in double precision
    589        return static_cast<T>(((1 << outputBitCount) - 1) * static_cast<double>(input) + 0.5);
    590    }
    591    else
    592    {
    593        return static_cast<T>(((1 << outputBitCount) - 1) * input + 0.5f);
    594    }
    595 }
    596 
    597 template <unsigned int inputBitCount, unsigned int inputBitStart, typename T>
    598 inline T getShiftedData(T input)
    599 {
    600    static_assert(inputBitCount + inputBitStart <= (sizeof(T) * 8),
    601                  "T must have at least as many bits as inputBitCount + inputBitStart.");
    602    const T mask = (1 << inputBitCount) - 1;
    603    return (input >> inputBitStart) & mask;
    604 }
    605 
    606 template <unsigned int inputBitCount, unsigned int inputBitStart, typename T>
    607 inline T shiftData(T input)
    608 {
    609    static_assert(inputBitCount + inputBitStart <= (sizeof(T) * 8),
    610                  "T must have at least as many bits as inputBitCount + inputBitStart.");
    611    const T mask = (1 << inputBitCount) - 1;
    612    return (input & mask) << inputBitStart;
    613 }
    614 
    615 inline unsigned int CountLeadingZeros(uint32_t x)
    616 {
    617    // Use binary search to find the amount of leading zeros.
    618    unsigned int zeros = 32u;
    619    uint32_t y;
    620 
    621    y = x >> 16u;
    622    if (y != 0)
    623    {
    624        zeros = zeros - 16u;
    625        x     = y;
    626    }
    627    y = x >> 8u;
    628    if (y != 0)
    629    {
    630        zeros = zeros - 8u;
    631        x     = y;
    632    }
    633    y = x >> 4u;
    634    if (y != 0)
    635    {
    636        zeros = zeros - 4u;
    637        x     = y;
    638    }
    639    y = x >> 2u;
    640    if (y != 0)
    641    {
    642        zeros = zeros - 2u;
    643        x     = y;
    644    }
    645    y = x >> 1u;
    646    if (y != 0)
    647    {
    648        return zeros - 2u;
    649    }
    650    return zeros - x;
    651 }
    652 
    653 inline unsigned char average(unsigned char a, unsigned char b)
    654 {
    655    return ((a ^ b) >> 1) + (a & b);
    656 }
    657 
    658 inline signed char average(signed char a, signed char b)
    659 {
    660    return ((short)a + (short)b) / 2;
    661 }
    662 
    663 inline unsigned short average(unsigned short a, unsigned short b)
    664 {
    665    return ((a ^ b) >> 1) + (a & b);
    666 }
    667 
    668 inline signed short average(signed short a, signed short b)
    669 {
    670    return ((int)a + (int)b) / 2;
    671 }
    672 
    673 inline unsigned int average(unsigned int a, unsigned int b)
    674 {
    675    return ((a ^ b) >> 1) + (a & b);
    676 }
    677 
    678 inline int average(int a, int b)
    679 {
    680    long long average = (static_cast<long long>(a) + static_cast<long long>(b)) / 2LL;
    681    return static_cast<int>(average);
    682 }
    683 
    684 inline float average(float a, float b)
    685 {
    686    return (a + b) * 0.5f;
    687 }
    688 
    689 inline unsigned short averageHalfFloat(unsigned short a, unsigned short b)
    690 {
    691    return float32ToFloat16((float16ToFloat32(a) + float16ToFloat32(b)) * 0.5f);
    692 }
    693 
    694 inline unsigned int averageFloat11(unsigned int a, unsigned int b)
    695 {
    696    return float32ToFloat11((float11ToFloat32(static_cast<unsigned short>(a)) +
    697                             float11ToFloat32(static_cast<unsigned short>(b))) *
    698                            0.5f);
    699 }
    700 
    701 inline unsigned int averageFloat10(unsigned int a, unsigned int b)
    702 {
    703    return float32ToFloat10((float10ToFloat32(static_cast<unsigned short>(a)) +
    704                             float10ToFloat32(static_cast<unsigned short>(b))) *
    705                            0.5f);
    706 }
    707 
    708 template <typename T>
    709 class Range
    710 {
    711  public:
    712    Range() {}
    713    Range(T lo, T hi) : mLow(lo), mHigh(hi) {}
    714 
    715    T length() const { return (empty() ? 0 : (mHigh - mLow)); }
    716 
    717    bool intersects(Range<T> other)
    718    {
    719        if (mLow <= other.mLow)
    720        {
    721            return other.mLow < mHigh;
    722        }
    723        else
    724        {
    725            return mLow < other.mHigh;
    726        }
    727    }
    728 
    729    // Assumes that end is non-inclusive.. for example, extending to 5 will make "end" 6.
    730    void extend(T value)
    731    {
    732        mLow  = value < mLow ? value : mLow;
    733        mHigh = value >= mHigh ? (value + 1) : mHigh;
    734    }
    735 
    736    bool empty() const { return mHigh <= mLow; }
    737 
    738    bool contains(T value) const { return value >= mLow && value < mHigh; }
    739 
    740    class Iterator final
    741    {
    742      public:
    743        Iterator(T value) : mCurrent(value) {}
    744 
    745        Iterator &operator++()
    746        {
    747            mCurrent++;
    748            return *this;
    749        }
    750        bool operator==(const Iterator &other) const { return mCurrent == other.mCurrent; }
    751        bool operator!=(const Iterator &other) const { return mCurrent != other.mCurrent; }
    752        T operator*() const { return mCurrent; }
    753 
    754      private:
    755        T mCurrent;
    756    };
    757 
    758    Iterator begin() const { return Iterator(mLow); }
    759 
    760    Iterator end() const { return Iterator(mHigh); }
    761 
    762    T low() const { return mLow; }
    763    T high() const { return mHigh; }
    764 
    765    void invalidate()
    766    {
    767        mLow  = std::numeric_limits<T>::max();
    768        mHigh = std::numeric_limits<T>::min();
    769    }
    770 
    771  private:
    772    T mLow;
    773    T mHigh;
    774 };
    775 
    776 typedef Range<int> RangeI;
    777 typedef Range<unsigned int> RangeUI;
    778 
    779 struct IndexRange
    780 {
    781    struct Undefined
    782    {};
    783    IndexRange(Undefined) {}
    784    IndexRange() : IndexRange(0, 0, 0) {}
    785    IndexRange(size_t start_, size_t end_, size_t vertexIndexCount_)
    786        : start(start_), end(end_), vertexIndexCount(vertexIndexCount_)
    787    {
    788        ASSERT(start <= end);
    789    }
    790 
    791    // Number of vertices in the range.
    792    size_t vertexCount() const { return (end - start) + 1; }
    793 
    794    // Inclusive range of indices that are not primitive restart
    795    size_t start;
    796    size_t end;
    797 
    798    // Number of non-primitive restart indices
    799    size_t vertexIndexCount;
    800 };
    801 
    802 // Combine a floating-point value representing a mantissa (x) and an integer exponent (exp) into a
    803 // floating-point value. As in GLSL ldexp() built-in.
    804 inline float Ldexp(float x, int exp)
    805 {
    806    if (exp > 128)
    807    {
    808        return std::numeric_limits<float>::infinity();
    809    }
    810    if (exp < -126)
    811    {
    812        return 0.0f;
    813    }
    814    double result = static_cast<double>(x) * std::pow(2.0, static_cast<double>(exp));
    815    return static_cast<float>(result);
    816 }
    817 
    818 // First, both normalized floating-point values are converted into 16-bit integer values.
    819 // Then, the results are packed into the returned 32-bit unsigned integer.
    820 // The first float value will be written to the least significant bits of the output;
    821 // the last float value will be written to the most significant bits.
    822 // The conversion of each value to fixed point is done as follows :
    823 // packSnorm2x16 : round(clamp(c, -1, +1) * 32767.0)
    824 inline uint32_t packSnorm2x16(float f1, float f2)
    825 {
    826    int16_t leastSignificantBits = static_cast<int16_t>(roundf(clamp(f1, -1.0f, 1.0f) * 32767.0f));
    827    int16_t mostSignificantBits  = static_cast<int16_t>(roundf(clamp(f2, -1.0f, 1.0f) * 32767.0f));
    828    return static_cast<uint32_t>(mostSignificantBits) << 16 |
    829           (static_cast<uint32_t>(leastSignificantBits) & 0xFFFF);
    830 }
    831 
    832 // First, unpacks a single 32-bit unsigned integer u into a pair of 16-bit unsigned integers. Then,
    833 // each component is converted to a normalized floating-point value to generate the returned two
    834 // float values. The first float value will be extracted from the least significant bits of the
    835 // input; the last float value will be extracted from the most-significant bits. The conversion for
    836 // unpacked fixed-point value to floating point is done as follows: unpackSnorm2x16 : clamp(f /
    837 // 32767.0, -1, +1)
    838 inline void unpackSnorm2x16(uint32_t u, float *f1, float *f2)
    839 {
    840    int16_t leastSignificantBits = static_cast<int16_t>(u & 0xFFFF);
    841    int16_t mostSignificantBits  = static_cast<int16_t>(u >> 16);
    842    *f1 = clamp(static_cast<float>(leastSignificantBits) / 32767.0f, -1.0f, 1.0f);
    843    *f2 = clamp(static_cast<float>(mostSignificantBits) / 32767.0f, -1.0f, 1.0f);
    844 }
    845 
    846 // First, both normalized floating-point values are converted into 16-bit integer values.
    847 // Then, the results are packed into the returned 32-bit unsigned integer.
    848 // The first float value will be written to the least significant bits of the output;
    849 // the last float value will be written to the most significant bits.
    850 // The conversion of each value to fixed point is done as follows:
    851 // packUnorm2x16 : round(clamp(c, 0, +1) * 65535.0)
    852 inline uint32_t packUnorm2x16(float f1, float f2)
    853 {
    854    uint16_t leastSignificantBits = static_cast<uint16_t>(roundf(clamp(f1, 0.0f, 1.0f) * 65535.0f));
    855    uint16_t mostSignificantBits  = static_cast<uint16_t>(roundf(clamp(f2, 0.0f, 1.0f) * 65535.0f));
    856    return static_cast<uint32_t>(mostSignificantBits) << 16 |
    857           static_cast<uint32_t>(leastSignificantBits);
    858 }
    859 
    860 // First, unpacks a single 32-bit unsigned integer u into a pair of 16-bit unsigned integers. Then,
    861 // each component is converted to a normalized floating-point value to generate the returned two
    862 // float values. The first float value will be extracted from the least significant bits of the
    863 // input; the last float value will be extracted from the most-significant bits. The conversion for
    864 // unpacked fixed-point value to floating point is done as follows: unpackUnorm2x16 : f / 65535.0
    865 inline void unpackUnorm2x16(uint32_t u, float *f1, float *f2)
    866 {
    867    uint16_t leastSignificantBits = static_cast<uint16_t>(u & 0xFFFF);
    868    uint16_t mostSignificantBits  = static_cast<uint16_t>(u >> 16);
    869    *f1                           = static_cast<float>(leastSignificantBits) / 65535.0f;
    870    *f2                           = static_cast<float>(mostSignificantBits) / 65535.0f;
    871 }
    872 
    873 // Helper functions intended to be used only here.
    874 namespace priv
    875 {
    876 
    877 inline uint8_t ToPackedUnorm8(float f)
    878 {
    879    return static_cast<uint8_t>(roundf(clamp(f, 0.0f, 1.0f) * 255.0f));
    880 }
    881 
    882 inline int8_t ToPackedSnorm8(float f)
    883 {
    884    return static_cast<int8_t>(roundf(clamp(f, -1.0f, 1.0f) * 127.0f));
    885 }
    886 
    887 }  // namespace priv
    888 
    889 // Packs 4 normalized unsigned floating-point values to a single 32-bit unsigned integer. Works
    890 // similarly to packUnorm2x16. The floats are clamped to the range 0.0 to 1.0, and written to the
    891 // unsigned integer starting from the least significant bits.
    892 inline uint32_t PackUnorm4x8(float f1, float f2, float f3, float f4)
    893 {
    894    uint8_t bits[4];
    895    bits[0]         = priv::ToPackedUnorm8(f1);
    896    bits[1]         = priv::ToPackedUnorm8(f2);
    897    bits[2]         = priv::ToPackedUnorm8(f3);
    898    bits[3]         = priv::ToPackedUnorm8(f4);
    899    uint32_t result = 0u;
    900    for (int i = 0; i < 4; ++i)
    901    {
    902        int shift = i * 8;
    903        result |= (static_cast<uint32_t>(bits[i]) << shift);
    904    }
    905    return result;
    906 }
    907 
    908 // Unpacks 4 normalized unsigned floating-point values from a single 32-bit unsigned integer into f.
    909 // Works similarly to unpackUnorm2x16. The floats are unpacked starting from the least significant
    910 // bits.
    911 inline void UnpackUnorm4x8(uint32_t u, float *f)
    912 {
    913    for (int i = 0; i < 4; ++i)
    914    {
    915        int shift    = i * 8;
    916        uint8_t bits = static_cast<uint8_t>((u >> shift) & 0xFF);
    917        f[i]         = static_cast<float>(bits) / 255.0f;
    918    }
    919 }
    920 
    921 // Packs 4 normalized signed floating-point values to a single 32-bit unsigned integer. The floats
    922 // are clamped to the range -1.0 to 1.0, and written to the unsigned integer starting from the least
    923 // significant bits.
    924 inline uint32_t PackSnorm4x8(float f1, float f2, float f3, float f4)
    925 {
    926    int8_t bits[4];
    927    bits[0]         = priv::ToPackedSnorm8(f1);
    928    bits[1]         = priv::ToPackedSnorm8(f2);
    929    bits[2]         = priv::ToPackedSnorm8(f3);
    930    bits[3]         = priv::ToPackedSnorm8(f4);
    931    uint32_t result = 0u;
    932    for (int i = 0; i < 4; ++i)
    933    {
    934        int shift = i * 8;
    935        result |= ((static_cast<uint32_t>(bits[i]) & 0xFF) << shift);
    936    }
    937    return result;
    938 }
    939 
    940 // Unpacks 4 normalized signed floating-point values from a single 32-bit unsigned integer into f.
    941 // Works similarly to unpackSnorm2x16. The floats are unpacked starting from the least significant
    942 // bits, and clamped to the range -1.0 to 1.0.
    943 inline void UnpackSnorm4x8(uint32_t u, float *f)
    944 {
    945    for (int i = 0; i < 4; ++i)
    946    {
    947        int shift   = i * 8;
    948        int8_t bits = static_cast<int8_t>((u >> shift) & 0xFF);
    949        f[i]        = clamp(static_cast<float>(bits) / 127.0f, -1.0f, 1.0f);
    950    }
    951 }
    952 
    953 // Returns an unsigned integer obtained by converting the two floating-point values to the 16-bit
    954 // floating-point representation found in the OpenGL ES Specification, and then packing these
    955 // two 16-bit integers into a 32-bit unsigned integer.
    956 // f1: The 16 least-significant bits of the result;
    957 // f2: The 16 most-significant bits.
    958 inline uint32_t packHalf2x16(float f1, float f2)
    959 {
    960    uint16_t leastSignificantBits = static_cast<uint16_t>(float32ToFloat16(f1));
    961    uint16_t mostSignificantBits  = static_cast<uint16_t>(float32ToFloat16(f2));
    962    return static_cast<uint32_t>(mostSignificantBits) << 16 |
    963           static_cast<uint32_t>(leastSignificantBits);
    964 }
    965 
    966 // Returns two floating-point values obtained by unpacking a 32-bit unsigned integer into a pair of
    967 // 16-bit values, interpreting those values as 16-bit floating-point numbers according to the OpenGL
    968 // ES Specification, and converting them to 32-bit floating-point values. The first float value is
    969 // obtained from the 16 least-significant bits of u; the second component is obtained from the 16
    970 // most-significant bits of u.
    971 inline void unpackHalf2x16(uint32_t u, float *f1, float *f2)
    972 {
    973    uint16_t leastSignificantBits = static_cast<uint16_t>(u & 0xFFFF);
    974    uint16_t mostSignificantBits  = static_cast<uint16_t>(u >> 16);
    975 
    976    *f1 = float16ToFloat32(leastSignificantBits);
    977    *f2 = float16ToFloat32(mostSignificantBits);
    978 }
    979 
    980 inline uint8_t sRGBToLinear(uint8_t srgbValue)
    981 {
    982    float value = srgbValue / 255.0f;
    983    if (value <= 0.04045f)
    984    {
    985        value = value / 12.92f;
    986    }
    987    else
    988    {
    989        value = std::pow((value + 0.055f) / 1.055f, 2.4f);
    990    }
    991    return static_cast<uint8_t>(clamp(value * 255.0f + 0.5f, 0.0f, 255.0f));
    992 }
    993 
    994 inline uint8_t linearToSRGB(uint8_t linearValue)
    995 {
    996    float value = linearValue / 255.0f;
    997    if (value <= 0.0f)
    998    {
    999        value = 0.0f;
   1000    }
   1001    else if (value < 0.0031308f)
   1002    {
   1003        value = value * 12.92f;
   1004    }
   1005    else if (value < 1.0f)
   1006    {
   1007        value = std::pow(value, 0.41666f) * 1.055f - 0.055f;
   1008    }
   1009    else
   1010    {
   1011        value = 1.0f;
   1012    }
   1013    return static_cast<uint8_t>(clamp(value * 255.0f + 0.5f, 0.0f, 255.0f));
   1014 }
   1015 
   1016 // Reverse the order of the bits.
   1017 inline uint32_t BitfieldReverse(uint32_t value)
   1018 {
   1019    // TODO(oetuaho@nvidia.com): Optimize this if needed. There don't seem to be compiler intrinsics
   1020    // for this, and right now it's not used in performance-critical paths.
   1021    uint32_t result = 0u;
   1022    for (size_t j = 0u; j < 32u; ++j)
   1023    {
   1024        result |= (((value >> j) & 1u) << (31u - j));
   1025    }
   1026    return result;
   1027 }
   1028 
   1029 // Count the 1 bits.
   1030 #if defined(_MSC_VER) && !defined(__clang__)
   1031 #    if defined(_M_IX86) || defined(_M_X64)
   1032 namespace priv
   1033 {
   1034 // Check POPCNT instruction support and cache the result.
   1035 // https://docs.microsoft.com/en-us/cpp/intrinsics/popcnt16-popcnt-popcnt64#remarks
   1036 static const bool kHasPopcnt = [] {
   1037    int info[4];
   1038    __cpuid(&info[0], 1);
   1039    return static_cast<bool>(info[2] & 0x800000);
   1040 }();
   1041 }  // namespace priv
   1042 
   1043 // Polyfills for x86/x64 CPUs without POPCNT.
   1044 // https://graphics.stanford.edu/~seander/bithacks.html#CountBitsSetParallel
   1045 inline int BitCountPolyfill(uint32_t bits)
   1046 {
   1047    bits = bits - ((bits >> 1) & 0x55555555);
   1048    bits = (bits & 0x33333333) + ((bits >> 2) & 0x33333333);
   1049    bits = ((bits + (bits >> 4) & 0x0F0F0F0F) * 0x01010101) >> 24;
   1050    return static_cast<int>(bits);
   1051 }
   1052 
   1053 inline int BitCountPolyfill(uint64_t bits)
   1054 {
   1055    bits = bits - ((bits >> 1) & 0x5555555555555555ull);
   1056    bits = (bits & 0x3333333333333333ull) + ((bits >> 2) & 0x3333333333333333ull);
   1057    bits = ((bits + (bits >> 4) & 0x0F0F0F0F0F0F0F0Full) * 0x0101010101010101ull) >> 56;
   1058    return static_cast<int>(bits);
   1059 }
   1060 
   1061 inline int BitCount(uint32_t bits)
   1062 {
   1063    if (priv::kHasPopcnt)
   1064    {
   1065        return static_cast<int>(__popcnt(bits));
   1066    }
   1067    return BitCountPolyfill(bits);
   1068 }
   1069 
   1070 inline int BitCount(uint64_t bits)
   1071 {
   1072    if (priv::kHasPopcnt)
   1073    {
   1074 #        if defined(_M_X64)
   1075        return static_cast<int>(__popcnt64(bits));
   1076 #        else   // x86
   1077        return static_cast<int>(__popcnt(static_cast<uint32_t>(bits >> 32)) +
   1078                                __popcnt(static_cast<uint32_t>(bits)));
   1079 #        endif  // defined(_M_X64)
   1080    }
   1081    return BitCountPolyfill(bits);
   1082 }
   1083 
   1084 #    elif defined(_M_ARM) || defined(_M_ARM64)
   1085 
   1086 // MSVC's _CountOneBits* intrinsics are not defined for ARM64, moreover they do not use dedicated
   1087 // NEON instructions.
   1088 
   1089 inline int BitCount(uint32_t bits)
   1090 {
   1091    // cast bits to 8x8 datatype and use VCNT on it
   1092    const uint8x8_t vsum = vcnt_u8(vcreate_u8(static_cast<uint64_t>(bits)));
   1093 
   1094    // pairwise sums: 8x8 -> 16x4 -> 32x2
   1095    return static_cast<int>(vget_lane_u32(vpaddl_u16(vpaddl_u8(vsum)), 0));
   1096 }
   1097 
   1098 inline int BitCount(uint64_t bits)
   1099 {
   1100    // cast bits to 8x8 datatype and use VCNT on it
   1101    const uint8x8_t vsum = vcnt_u8(vcreate_u8(bits));
   1102 
   1103    // pairwise sums: 8x8 -> 16x4 -> 32x2 -> 64x1
   1104    return static_cast<int>(vget_lane_u64(vpaddl_u32(vpaddl_u16(vpaddl_u8(vsum))), 0));
   1105 }
   1106 #    endif  // defined(_M_IX86) || defined(_M_X64)
   1107 #endif      // defined(_MSC_VER) && !defined(__clang__)
   1108 
   1109 #if defined(ANGLE_PLATFORM_POSIX) || defined(__clang__)
   1110 inline int BitCount(uint32_t bits)
   1111 {
   1112    return __builtin_popcount(bits);
   1113 }
   1114 
   1115 inline int BitCount(uint64_t bits)
   1116 {
   1117    return __builtin_popcountll(bits);
   1118 }
   1119 #endif  // defined(ANGLE_PLATFORM_POSIX) || defined(__clang__)
   1120 
   1121 inline int BitCount(uint8_t bits)
   1122 {
   1123    return BitCount(static_cast<uint32_t>(bits));
   1124 }
   1125 
   1126 inline int BitCount(uint16_t bits)
   1127 {
   1128    return BitCount(static_cast<uint32_t>(bits));
   1129 }
   1130 
   1131 #if defined(ANGLE_PLATFORM_WINDOWS)
   1132 // Return the index of the least significant bit set. Indexing is such that bit 0 is the least
   1133 // significant bit. Implemented for different bit widths on different platforms.
   1134 inline unsigned long ScanForward(uint32_t bits)
   1135 {
   1136    ASSERT(bits != 0u);
   1137    unsigned long firstBitIndex = 0ul;
   1138    unsigned char ret           = _BitScanForward(&firstBitIndex, bits);
   1139    ASSERT(ret != 0u);
   1140    return firstBitIndex;
   1141 }
   1142 
   1143 inline unsigned long ScanForward(uint64_t bits)
   1144 {
   1145    ASSERT(bits != 0u);
   1146    unsigned long firstBitIndex = 0ul;
   1147 #    if defined(ANGLE_IS_64_BIT_CPU)
   1148    unsigned char ret = _BitScanForward64(&firstBitIndex, bits);
   1149 #    else
   1150    unsigned char ret;
   1151    if (static_cast<uint32_t>(bits) == 0)
   1152    {
   1153        ret = _BitScanForward(&firstBitIndex, static_cast<uint32_t>(bits >> 32));
   1154        firstBitIndex += 32ul;
   1155    }
   1156    else
   1157    {
   1158        ret = _BitScanForward(&firstBitIndex, static_cast<uint32_t>(bits));
   1159    }
   1160 #    endif  // defined(ANGLE_IS_64_BIT_CPU)
   1161    ASSERT(ret != 0u);
   1162    return firstBitIndex;
   1163 }
   1164 
   1165 // Return the index of the most significant bit set. Indexing is such that bit 0 is the least
   1166 // significant bit.
   1167 inline unsigned long ScanReverse(uint32_t bits)
   1168 {
   1169    ASSERT(bits != 0u);
   1170    unsigned long lastBitIndex = 0ul;
   1171    unsigned char ret          = _BitScanReverse(&lastBitIndex, bits);
   1172    ASSERT(ret != 0u);
   1173    return lastBitIndex;
   1174 }
   1175 
   1176 inline unsigned long ScanReverse(uint64_t bits)
   1177 {
   1178    ASSERT(bits != 0u);
   1179    unsigned long lastBitIndex = 0ul;
   1180 #    if defined(ANGLE_IS_64_BIT_CPU)
   1181    unsigned char ret = _BitScanReverse64(&lastBitIndex, bits);
   1182 #    else
   1183    unsigned char ret;
   1184    if (static_cast<uint32_t>(bits >> 32) == 0)
   1185    {
   1186        ret = _BitScanReverse(&lastBitIndex, static_cast<uint32_t>(bits));
   1187    }
   1188    else
   1189    {
   1190        ret = _BitScanReverse(&lastBitIndex, static_cast<uint32_t>(bits >> 32));
   1191        lastBitIndex += 32ul;
   1192    }
   1193 #    endif  // defined(ANGLE_IS_64_BIT_CPU)
   1194    ASSERT(ret != 0u);
   1195    return lastBitIndex;
   1196 }
   1197 #endif  // defined(ANGLE_PLATFORM_WINDOWS)
   1198 
   1199 #if defined(ANGLE_PLATFORM_POSIX)
   1200 inline unsigned long ScanForward(uint32_t bits)
   1201 {
   1202    ASSERT(bits != 0u);
   1203    return static_cast<unsigned long>(__builtin_ctz(bits));
   1204 }
   1205 
   1206 inline unsigned long ScanForward(uint64_t bits)
   1207 {
   1208    ASSERT(bits != 0u);
   1209 #    if defined(ANGLE_IS_64_BIT_CPU)
   1210    return static_cast<unsigned long>(__builtin_ctzll(bits));
   1211 #    else
   1212    return static_cast<unsigned long>(static_cast<uint32_t>(bits) == 0
   1213                                          ? __builtin_ctz(static_cast<uint32_t>(bits >> 32)) + 32
   1214                                          : __builtin_ctz(static_cast<uint32_t>(bits)));
   1215 #    endif  // defined(ANGLE_IS_64_BIT_CPU)
   1216 }
   1217 
   1218 inline unsigned long ScanReverse(uint32_t bits)
   1219 {
   1220    ASSERT(bits != 0u);
   1221    return static_cast<unsigned long>(sizeof(uint32_t) * CHAR_BIT - 1 - __builtin_clz(bits));
   1222 }
   1223 
   1224 inline unsigned long ScanReverse(uint64_t bits)
   1225 {
   1226    ASSERT(bits != 0u);
   1227 #    if defined(ANGLE_IS_64_BIT_CPU)
   1228    return static_cast<unsigned long>(sizeof(uint64_t) * CHAR_BIT - 1 - __builtin_clzll(bits));
   1229 #    else
   1230    if (static_cast<uint32_t>(bits >> 32) == 0)
   1231    {
   1232        return sizeof(uint32_t) * CHAR_BIT - 1 - __builtin_clz(static_cast<uint32_t>(bits));
   1233    }
   1234    else
   1235    {
   1236        return sizeof(uint32_t) * CHAR_BIT - 1 - __builtin_clz(static_cast<uint32_t>(bits >> 32)) +
   1237               32;
   1238    }
   1239 #    endif  // defined(ANGLE_IS_64_BIT_CPU)
   1240 }
   1241 #endif  // defined(ANGLE_PLATFORM_POSIX)
   1242 
   1243 inline unsigned long ScanForward(uint8_t bits)
   1244 {
   1245    return ScanForward(static_cast<uint32_t>(bits));
   1246 }
   1247 
   1248 inline unsigned long ScanForward(uint16_t bits)
   1249 {
   1250    return ScanForward(static_cast<uint32_t>(bits));
   1251 }
   1252 
   1253 inline unsigned long ScanReverse(uint8_t bits)
   1254 {
   1255    return ScanReverse(static_cast<uint32_t>(bits));
   1256 }
   1257 
   1258 inline unsigned long ScanReverse(uint16_t bits)
   1259 {
   1260    return ScanReverse(static_cast<uint32_t>(bits));
   1261 }
   1262 
   1263 // Returns -1 on 0, otherwise the index of the least significant 1 bit as in GLSL.
   1264 template <typename T>
   1265 int FindLSB(T bits)
   1266 {
   1267    static_assert(std::is_integral<T>::value, "must be integral type.");
   1268    if (bits == 0u)
   1269    {
   1270        return -1;
   1271    }
   1272    else
   1273    {
   1274        return static_cast<int>(ScanForward(bits));
   1275    }
   1276 }
   1277 
   1278 // Returns -1 on 0, otherwise the index of the most significant 1 bit as in GLSL.
   1279 template <typename T>
   1280 int FindMSB(T bits)
   1281 {
   1282    static_assert(std::is_integral<T>::value, "must be integral type.");
   1283    if (bits == 0u)
   1284    {
   1285        return -1;
   1286    }
   1287    else
   1288    {
   1289        return static_cast<int>(ScanReverse(bits));
   1290    }
   1291 }
   1292 
   1293 // Returns whether the argument is Not a Number.
   1294 // IEEE 754 single precision NaN representation: Exponent(8 bits) - 255, Mantissa(23 bits) -
   1295 // non-zero.
   1296 inline bool isNaN(float f)
   1297 {
   1298    // Exponent mask: ((1u << 8) - 1u) << 23 = 0x7f800000u
   1299    // Mantissa mask: ((1u << 23) - 1u) = 0x7fffffu
   1300    return ((bitCast<uint32_t>(f) & 0x7f800000u) == 0x7f800000u) &&
   1301           (bitCast<uint32_t>(f) & 0x7fffffu);
   1302 }
   1303 
   1304 // Returns whether the argument is infinity.
   1305 // IEEE 754 single precision infinity representation: Exponent(8 bits) - 255, Mantissa(23 bits) -
   1306 // zero.
   1307 inline bool isInf(float f)
   1308 {
   1309    // Exponent mask: ((1u << 8) - 1u) << 23 = 0x7f800000u
   1310    // Mantissa mask: ((1u << 23) - 1u) = 0x7fffffu
   1311    return ((bitCast<uint32_t>(f) & 0x7f800000u) == 0x7f800000u) &&
   1312           !(bitCast<uint32_t>(f) & 0x7fffffu);
   1313 }
   1314 
   1315 namespace priv
   1316 {
   1317 template <unsigned int N, unsigned int R>
   1318 struct iSquareRoot
   1319 {
   1320    static constexpr unsigned int solve()
   1321    {
   1322        return (R * R > N)
   1323                   ? 0
   1324                   : ((R * R == N) ? R : static_cast<unsigned int>(iSquareRoot<N, R + 1>::value));
   1325    }
   1326    enum Result
   1327    {
   1328        value = iSquareRoot::solve()
   1329    };
   1330 };
   1331 
   1332 template <unsigned int N>
   1333 struct iSquareRoot<N, N>
   1334 {
   1335    enum result
   1336    {
   1337        value = N
   1338    };
   1339 };
   1340 
   1341 }  // namespace priv
   1342 
   1343 template <unsigned int N>
   1344 constexpr unsigned int iSquareRoot()
   1345 {
   1346    return priv::iSquareRoot<N, 1>::value;
   1347 }
   1348 
   1349 // Sum, difference and multiplication operations for signed ints that wrap on 32-bit overflow.
   1350 //
   1351 // Unsigned types are defined to do arithmetic modulo 2^n in C++. For signed types, overflow
   1352 // behavior is undefined.
   1353 
   1354 template <typename T>
   1355 inline T WrappingSum(T lhs, T rhs)
   1356 {
   1357    uint32_t lhsUnsigned = static_cast<uint32_t>(lhs);
   1358    uint32_t rhsUnsigned = static_cast<uint32_t>(rhs);
   1359    return static_cast<T>(lhsUnsigned + rhsUnsigned);
   1360 }
   1361 
   1362 template <typename T>
   1363 inline T WrappingDiff(T lhs, T rhs)
   1364 {
   1365    uint32_t lhsUnsigned = static_cast<uint32_t>(lhs);
   1366    uint32_t rhsUnsigned = static_cast<uint32_t>(rhs);
   1367    return static_cast<T>(lhsUnsigned - rhsUnsigned);
   1368 }
   1369 
   1370 inline int32_t WrappingMul(int32_t lhs, int32_t rhs)
   1371 {
   1372    int64_t lhsWide = static_cast<int64_t>(lhs);
   1373    int64_t rhsWide = static_cast<int64_t>(rhs);
   1374    // The multiplication is guaranteed not to overflow.
   1375    int64_t resultWide = lhsWide * rhsWide;
   1376    // Implement the desired wrapping behavior by masking out the high-order 32 bits.
   1377    resultWide = resultWide & 0xffffffffLL;
   1378    // Casting to a narrower signed type is fine since the casted value is representable in the
   1379    // narrower type.
   1380    return static_cast<int32_t>(resultWide);
   1381 }
   1382 
   1383 inline float scaleScreenDimensionToNdc(float dimensionScreen, float viewportDimension)
   1384 {
   1385    return 2.0f * dimensionScreen / viewportDimension;
   1386 }
   1387 
   1388 inline float scaleScreenCoordinateToNdc(float coordinateScreen, float viewportDimension)
   1389 {
   1390    float halfShifted = coordinateScreen / viewportDimension;
   1391    return 2.0f * (halfShifted - 0.5f);
   1392 }
   1393 
   1394 }  // namespace gl
   1395 
   1396 namespace rx
   1397 {
   1398 
   1399 template <typename T>
   1400 T roundUp(const T value, const T alignment)
   1401 {
   1402    auto temp = value + alignment - static_cast<T>(1);
   1403    return temp - temp % alignment;
   1404 }
   1405 
   1406 template <typename T>
   1407 constexpr T roundUpPow2(const T value, const T alignment)
   1408 {
   1409    ASSERT(gl::isPow2(alignment));
   1410    return (value + alignment - 1) & ~(alignment - 1);
   1411 }
   1412 
   1413 template <typename T>
   1414 constexpr T roundDownPow2(const T value, const T alignment)
   1415 {
   1416    ASSERT(gl::isPow2(alignment));
   1417    return value & ~(alignment - 1);
   1418 }
   1419 
   1420 template <typename T>
   1421 angle::CheckedNumeric<T> CheckedRoundUp(const T value, const T alignment)
   1422 {
   1423    angle::CheckedNumeric<T> checkedValue(value);
   1424    angle::CheckedNumeric<T> checkedAlignment(alignment);
   1425    return roundUp(checkedValue, checkedAlignment);
   1426 }
   1427 
   1428 inline constexpr unsigned int UnsignedCeilDivide(unsigned int value, unsigned int divisor)
   1429 {
   1430    unsigned int divided = value / divisor;
   1431    return (divided + ((value % divisor == 0) ? 0 : 1));
   1432 }
   1433 
   1434 #if defined(__has_builtin)
   1435 #    define ANGLE_HAS_BUILTIN(x) __has_builtin(x)
   1436 #else
   1437 #    define ANGLE_HAS_BUILTIN(x) 0
   1438 #endif
   1439 
   1440 #if defined(_MSC_VER)
   1441 
   1442 #    define ANGLE_ROTL(x, y) _rotl(x, y)
   1443 #    define ANGLE_ROTL64(x, y) _rotl64(x, y)
   1444 #    define ANGLE_ROTR16(x, y) _rotr16(x, y)
   1445 
   1446 #elif defined(__clang__) && ANGLE_HAS_BUILTIN(__builtin_rotateleft32) && \
   1447    ANGLE_HAS_BUILTIN(__builtin_rotateleft64) && ANGLE_HAS_BUILTIN(__builtin_rotateright16)
   1448 
   1449 #    define ANGLE_ROTL(x, y) __builtin_rotateleft32(x, y)
   1450 #    define ANGLE_ROTL64(x, y) __builtin_rotateleft64(x, y)
   1451 #    define ANGLE_ROTR16(x, y) __builtin_rotateright16(x, y)
   1452 
   1453 #else
   1454 
   1455 inline uint32_t RotL(uint32_t x, int8_t r)
   1456 {
   1457    return (x << r) | (x >> (32 - r));
   1458 }
   1459 
   1460 inline uint64_t RotL64(uint64_t x, int8_t r)
   1461 {
   1462    return (x << r) | (x >> (64 - r));
   1463 }
   1464 
   1465 inline uint16_t RotR16(uint16_t x, int8_t r)
   1466 {
   1467    return (x >> r) | (x << (16 - r));
   1468 }
   1469 
   1470 #    define ANGLE_ROTL(x, y) ::rx::RotL(x, y)
   1471 #    define ANGLE_ROTL64(x, y) ::rx::RotL64(x, y)
   1472 #    define ANGLE_ROTR16(x, y) ::rx::RotR16(x, y)
   1473 
   1474 #endif  // namespace rx
   1475 
   1476 constexpr unsigned int Log2(unsigned int bytes)
   1477 {
   1478    return bytes == 1 ? 0 : (1 + Log2(bytes / 2));
   1479 }
   1480 }  // namespace rx
   1481 
   1482 #endif  // COMMON_MATHUTIL_H_