tor-browser

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

angleutils.h (17784B)


      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 // angleutils.h: Common ANGLE utilities.
      8 
      9 #ifndef COMMON_ANGLEUTILS_H_
     10 #define COMMON_ANGLEUTILS_H_
     11 
     12 #include "common/platform.h"
     13 
     14 #if defined(ANGLE_USE_ABSEIL)
     15 #    include "absl/container/flat_hash_map.h"
     16 #    include "absl/container/flat_hash_set.h"
     17 #endif  // defined(ANGLE_USE_ABSEIL)
     18 
     19 #if defined(ANGLE_WITH_LSAN)
     20 #    include <sanitizer/lsan_interface.h>
     21 #endif  // defined(ANGLE_WITH_LSAN)
     22 
     23 #include <climits>
     24 #include <cstdarg>
     25 #include <cstddef>
     26 #include <fstream>
     27 #include <mutex>
     28 #include <set>
     29 #include <sstream>
     30 #include <string>
     31 #include <unordered_map>
     32 #include <unordered_set>
     33 #include <vector>
     34 
     35 // A helper class to disallow copy and assignment operators
     36 namespace angle
     37 {
     38 
     39 #if defined(ANGLE_ENABLE_D3D9) || defined(ANGLE_ENABLE_D3D11)
     40 using Microsoft::WRL::ComPtr;
     41 #endif  // defined(ANGLE_ENABLE_D3D9) || defined(ANGLE_ENABLE_D3D11)
     42 
     43 #if defined(ANGLE_USE_ABSEIL)
     44 template <typename Key, typename T, class Hash = absl::container_internal::hash_default_hash<Key>>
     45 using HashMap = absl::flat_hash_map<Key, T, Hash>;
     46 template <typename Key, class Hash = absl::container_internal::hash_default_hash<Key>>
     47 using HashSet = absl::flat_hash_set<Key, Hash>;
     48 #else
     49 template <typename Key, typename T, class Hash = std::hash<Key>>
     50 using HashMap = std::unordered_map<Key, T, Hash>;
     51 template <typename Key, class Hash = std::hash<Key>>
     52 using HashSet = std::unordered_set<Key, Hash>;
     53 #endif  // defined(ANGLE_USE_ABSEIL)
     54 
     55 class NonCopyable
     56 {
     57  protected:
     58    constexpr NonCopyable() = default;
     59    ~NonCopyable()          = default;
     60 
     61  private:
     62    NonCopyable(const NonCopyable &)    = delete;
     63    void operator=(const NonCopyable &) = delete;
     64 };
     65 
     66 extern const uintptr_t DirtyPointer;
     67 
     68 struct SaveFileHelper
     69 {
     70  public:
     71    // We always use ios::binary to avoid inconsistent line endings when captured on Linux vs Win.
     72    SaveFileHelper(const std::string &filePathIn);
     73    ~SaveFileHelper();
     74 
     75    template <typename T>
     76    SaveFileHelper &operator<<(const T &value)
     77    {
     78        mOfs << value;
     79        checkError();
     80        return *this;
     81    }
     82 
     83    void write(const uint8_t *data, size_t size);
     84 
     85  private:
     86    void checkError();
     87 
     88    std::ofstream mOfs;
     89    std::string mFilePath;
     90 };
     91 
     92 // AMD_performance_monitor helpers.
     93 constexpr char kPerfMonitorExtensionName[] = "GL_AMD_performance_monitor";
     94 
     95 struct PerfMonitorCounter
     96 {
     97    PerfMonitorCounter();
     98    ~PerfMonitorCounter();
     99 
    100    std::string name;
    101    uint64_t value;
    102 };
    103 using PerfMonitorCounters = std::vector<PerfMonitorCounter>;
    104 
    105 struct PerfMonitorCounterGroup
    106 {
    107    PerfMonitorCounterGroup();
    108    ~PerfMonitorCounterGroup();
    109 
    110    std::string name;
    111    PerfMonitorCounters counters;
    112 };
    113 using PerfMonitorCounterGroups = std::vector<PerfMonitorCounterGroup>;
    114 
    115 uint32_t GetPerfMonitorCounterIndex(const PerfMonitorCounters &counters, const std::string &name);
    116 const PerfMonitorCounter &GetPerfMonitorCounter(const PerfMonitorCounters &counters,
    117                                                const std::string &name);
    118 PerfMonitorCounter &GetPerfMonitorCounter(PerfMonitorCounters &counters, const std::string &name);
    119 uint32_t GetPerfMonitorCounterGroupIndex(const PerfMonitorCounterGroups &groups,
    120                                         const std::string &name);
    121 const PerfMonitorCounterGroup &GetPerfMonitorCounterGroup(const PerfMonitorCounterGroups &groups,
    122                                                          const std::string &name);
    123 PerfMonitorCounterGroup &GetPerfMonitorCounterGroup(PerfMonitorCounterGroups &groups,
    124                                                    const std::string &name);
    125 
    126 struct PerfMonitorTriplet
    127 {
    128    uint32_t group;
    129    uint32_t counter;
    130    uint64_t value;
    131 };
    132 
    133 #define ANGLE_VK_PERF_COUNTERS_X(FN)               \
    134    FN(commandQueueSubmitCallsTotal)               \
    135    FN(commandQueueSubmitCallsPerFrame)            \
    136    FN(vkQueueSubmitCallsTotal)                    \
    137    FN(vkQueueSubmitCallsPerFrame)                 \
    138    FN(renderPasses)                               \
    139    FN(writeDescriptorSets)                        \
    140    FN(flushedOutsideRenderPassCommandBuffers)     \
    141    FN(swapchainResolveInSubpass)                  \
    142    FN(swapchainResolveOutsideSubpass)             \
    143    FN(resolveImageCommands)                       \
    144    FN(colorLoadOpClears)                          \
    145    FN(colorLoadOpLoads)                           \
    146    FN(colorLoadOpNones)                           \
    147    FN(colorStoreOpStores)                         \
    148    FN(colorStoreOpNones)                          \
    149    FN(colorClearAttachments)                      \
    150    FN(depthLoadOpClears)                          \
    151    FN(depthLoadOpLoads)                           \
    152    FN(depthLoadOpNones)                           \
    153    FN(depthStoreOpStores)                         \
    154    FN(depthStoreOpNones)                          \
    155    FN(depthClearAttachments)                      \
    156    FN(stencilLoadOpClears)                        \
    157    FN(stencilLoadOpLoads)                         \
    158    FN(stencilLoadOpNones)                         \
    159    FN(stencilStoreOpStores)                       \
    160    FN(stencilStoreOpNones)                        \
    161    FN(stencilClearAttachments)                    \
    162    FN(colorAttachmentUnresolves)                  \
    163    FN(depthAttachmentUnresolves)                  \
    164    FN(stencilAttachmentUnresolves)                \
    165    FN(colorAttachmentResolves)                    \
    166    FN(depthAttachmentResolves)                    \
    167    FN(stencilAttachmentResolves)                  \
    168    FN(readOnlyDepthStencilRenderPasses)           \
    169    FN(pipelineCreationCacheHits)                  \
    170    FN(pipelineCreationCacheMisses)                \
    171    FN(pipelineCreationTotalCacheHitsDurationNs)   \
    172    FN(pipelineCreationTotalCacheMissesDurationNs) \
    173    FN(descriptorSetAllocations)                   \
    174    FN(descriptorSetCacheTotalSize)                \
    175    FN(descriptorSetCacheKeySizeBytes)             \
    176    FN(uniformsAndXfbDescriptorSetCacheHits)       \
    177    FN(uniformsAndXfbDescriptorSetCacheMisses)     \
    178    FN(uniformsAndXfbDescriptorSetCacheTotalSize)  \
    179    FN(textureDescriptorSetCacheHits)              \
    180    FN(textureDescriptorSetCacheMisses)            \
    181    FN(textureDescriptorSetCacheTotalSize)         \
    182    FN(shaderResourcesDescriptorSetCacheHits)      \
    183    FN(mutableTexturesUploaded)                    \
    184    FN(shaderResourcesDescriptorSetCacheMisses)    \
    185    FN(shaderResourcesDescriptorSetCacheTotalSize) \
    186    FN(buffersGhosted)                             \
    187    FN(vertexArraySyncStateCalls)                  \
    188    FN(allocateNewBufferBlockCalls)                \
    189    FN(dynamicBufferAllocations)                   \
    190    FN(framebufferCacheSize)
    191 
    192 #define ANGLE_DECLARE_PERF_COUNTER(COUNTER) uint64_t COUNTER;
    193 
    194 struct VulkanPerfCounters
    195 {
    196    ANGLE_VK_PERF_COUNTERS_X(ANGLE_DECLARE_PERF_COUNTER)
    197 };
    198 
    199 #undef ANGLE_DECLARE_PERF_COUNTER
    200 
    201 }  // namespace angle
    202 
    203 template <typename T, size_t N>
    204 constexpr inline size_t ArraySize(T (&)[N])
    205 {
    206    return N;
    207 }
    208 
    209 template <typename T>
    210 class WrappedArray final : angle::NonCopyable
    211 {
    212  public:
    213    template <size_t N>
    214    constexpr WrappedArray(const T (&data)[N]) : mArray(&data[0]), mSize(N)
    215    {}
    216 
    217    constexpr WrappedArray() : mArray(nullptr), mSize(0) {}
    218    constexpr WrappedArray(const T *data, size_t size) : mArray(data), mSize(size) {}
    219 
    220    WrappedArray(WrappedArray &&other) : WrappedArray()
    221    {
    222        std::swap(mArray, other.mArray);
    223        std::swap(mSize, other.mSize);
    224    }
    225 
    226    ~WrappedArray() {}
    227 
    228    constexpr const T *get() const { return mArray; }
    229    constexpr size_t size() const { return mSize; }
    230 
    231  private:
    232    const T *mArray;
    233    size_t mSize;
    234 };
    235 
    236 template <typename T, unsigned int N>
    237 void SafeRelease(T (&resourceBlock)[N])
    238 {
    239    for (unsigned int i = 0; i < N; i++)
    240    {
    241        SafeRelease(resourceBlock[i]);
    242    }
    243 }
    244 
    245 template <typename T>
    246 void SafeRelease(T &resource)
    247 {
    248    if (resource)
    249    {
    250        resource->Release();
    251        resource = nullptr;
    252    }
    253 }
    254 
    255 template <typename T>
    256 void SafeDelete(T *&resource)
    257 {
    258    delete resource;
    259    resource = nullptr;
    260 }
    261 
    262 template <typename T>
    263 void SafeDeleteContainer(T &resource)
    264 {
    265    for (auto &element : resource)
    266    {
    267        SafeDelete(element);
    268    }
    269    resource.clear();
    270 }
    271 
    272 template <typename T>
    273 void SafeDeleteArray(T *&resource)
    274 {
    275    delete[] resource;
    276    resource = nullptr;
    277 }
    278 
    279 // Provide a less-than function for comparing structs
    280 // Note: struct memory must be initialized to zero, because of packing gaps
    281 template <typename T>
    282 inline bool StructLessThan(const T &a, const T &b)
    283 {
    284    return (memcmp(&a, &b, sizeof(T)) < 0);
    285 }
    286 
    287 // Provide a less-than function for comparing structs
    288 // Note: struct memory must be initialized to zero, because of packing gaps
    289 template <typename T>
    290 inline bool StructEquals(const T &a, const T &b)
    291 {
    292    return (memcmp(&a, &b, sizeof(T)) == 0);
    293 }
    294 
    295 template <typename T>
    296 inline void StructZero(T *obj)
    297 {
    298    memset(obj, 0, sizeof(T));
    299 }
    300 
    301 template <typename T>
    302 inline bool IsMaskFlagSet(T mask, T flag)
    303 {
    304    // Handles multibit flags as well
    305    return (mask & flag) == flag;
    306 }
    307 
    308 inline const char *MakeStaticString(const std::string &str)
    309 {
    310    // On the heap so that no destructor runs on application exit.
    311    static std::set<std::string> *strings = new std::set<std::string>;
    312    std::set<std::string>::iterator it    = strings->find(str);
    313    if (it != strings->end())
    314    {
    315        return it->c_str();
    316    }
    317 
    318    return strings->insert(str).first->c_str();
    319 }
    320 
    321 std::string ArrayString(unsigned int i);
    322 
    323 // Indices are stored in vectors with the outermost index in the back. In the output of the function
    324 // the indices are reversed.
    325 std::string ArrayIndexString(const std::vector<unsigned int> &indices);
    326 
    327 inline std::string Str(int i)
    328 {
    329    std::stringstream strstr;
    330    strstr << i;
    331    return strstr.str();
    332 }
    333 
    334 template <typename T>
    335 std::string ToString(const T &value)
    336 {
    337    std::ostringstream o;
    338    o << value;
    339    return o.str();
    340 }
    341 
    342 inline bool IsLittleEndian()
    343 {
    344    constexpr uint32_t kEndiannessTest = 1;
    345    const bool isLittleEndian          = *reinterpret_cast<const uint8_t *>(&kEndiannessTest) == 1;
    346    return isLittleEndian;
    347 }
    348 
    349 // Helper class to use a mutex with the control of boolean.
    350 class ConditionalMutex final : angle::NonCopyable
    351 {
    352  public:
    353    ConditionalMutex() : mUseMutex(true) {}
    354    void init(bool useMutex) { mUseMutex = useMutex; }
    355    void lock()
    356    {
    357        if (mUseMutex)
    358        {
    359            mMutex.lock();
    360        }
    361    }
    362    void unlock()
    363    {
    364        if (mUseMutex)
    365        {
    366            mMutex.unlock();
    367        }
    368    }
    369 
    370  private:
    371    std::mutex mMutex;
    372    bool mUseMutex;
    373 };
    374 
    375 // snprintf is not defined with MSVC prior to to msvc14
    376 #if defined(_MSC_VER) && _MSC_VER < 1900
    377 #    define snprintf _snprintf
    378 #endif
    379 
    380 #define GL_A1RGB5_ANGLEX 0x6AC5
    381 #define GL_BGRX8_ANGLEX 0x6ABA
    382 #define GL_BGR565_ANGLEX 0x6ABB
    383 #define GL_BGRA4_ANGLEX 0x6ABC
    384 #define GL_BGR5_A1_ANGLEX 0x6ABD
    385 #define GL_INT_64_ANGLEX 0x6ABE
    386 #define GL_UINT_64_ANGLEX 0x6ABF
    387 #define GL_BGRA8_SRGB_ANGLEX 0x6AC0
    388 #define GL_BGR10_A2_ANGLEX 0x6AF9
    389 
    390 // These are fake formats used to fit typeless D3D textures that can be bound to EGL pbuffers into
    391 // the format system (for extension EGL_ANGLE_d3d_texture_client_buffer):
    392 #define GL_RGBA8_TYPELESS_ANGLEX 0x6AC1
    393 #define GL_RGBA8_TYPELESS_SRGB_ANGLEX 0x6AC2
    394 #define GL_BGRA8_TYPELESS_ANGLEX 0x6AC3
    395 #define GL_BGRA8_TYPELESS_SRGB_ANGLEX 0x6AC4
    396 
    397 #define GL_R8_SSCALED_ANGLEX 0x6AC6
    398 #define GL_RG8_SSCALED_ANGLEX 0x6AC7
    399 #define GL_RGB8_SSCALED_ANGLEX 0x6AC8
    400 #define GL_RGBA8_SSCALED_ANGLEX 0x6AC9
    401 #define GL_R8_USCALED_ANGLEX 0x6ACA
    402 #define GL_RG8_USCALED_ANGLEX 0x6ACB
    403 #define GL_RGB8_USCALED_ANGLEX 0x6ACC
    404 #define GL_RGBA8_USCALED_ANGLEX 0x6ACD
    405 
    406 #define GL_R16_SSCALED_ANGLEX 0x6ACE
    407 #define GL_RG16_SSCALED_ANGLEX 0x6ACF
    408 #define GL_RGB16_SSCALED_ANGLEX 0x6AD0
    409 #define GL_RGBA16_SSCALED_ANGLEX 0x6AD1
    410 #define GL_R16_USCALED_ANGLEX 0x6AD2
    411 #define GL_RG16_USCALED_ANGLEX 0x6AD3
    412 #define GL_RGB16_USCALED_ANGLEX 0x6AD4
    413 #define GL_RGBA16_USCALED_ANGLEX 0x6AD5
    414 
    415 #define GL_R32_SSCALED_ANGLEX 0x6AD6
    416 #define GL_RG32_SSCALED_ANGLEX 0x6AD7
    417 #define GL_RGB32_SSCALED_ANGLEX 0x6AD8
    418 #define GL_RGBA32_SSCALED_ANGLEX 0x6AD9
    419 #define GL_R32_USCALED_ANGLEX 0x6ADA
    420 #define GL_RG32_USCALED_ANGLEX 0x6ADB
    421 #define GL_RGB32_USCALED_ANGLEX 0x6ADC
    422 #define GL_RGBA32_USCALED_ANGLEX 0x6ADD
    423 
    424 #define GL_R32_SNORM_ANGLEX 0x6ADE
    425 #define GL_RG32_SNORM_ANGLEX 0x6ADF
    426 #define GL_RGB32_SNORM_ANGLEX 0x6AE0
    427 #define GL_RGBA32_SNORM_ANGLEX 0x6AE1
    428 #define GL_R32_UNORM_ANGLEX 0x6AE2
    429 #define GL_RG32_UNORM_ANGLEX 0x6AE3
    430 #define GL_RGB32_UNORM_ANGLEX 0x6AE4
    431 #define GL_RGBA32_UNORM_ANGLEX 0x6AE5
    432 
    433 #define GL_R32_FIXED_ANGLEX 0x6AE6
    434 #define GL_RG32_FIXED_ANGLEX 0x6AE7
    435 #define GL_RGB32_FIXED_ANGLEX 0x6AE8
    436 #define GL_RGBA32_FIXED_ANGLEX 0x6AE9
    437 
    438 #define GL_RGB10_A2_SINT_ANGLEX 0x6AEA
    439 #define GL_RGB10_A2_SNORM_ANGLEX 0x6AEB
    440 #define GL_RGB10_A2_SSCALED_ANGLEX 0x6AEC
    441 #define GL_RGB10_A2_USCALED_ANGLEX 0x6AED
    442 
    443 // EXT_texture_type_2_10_10_10_REV
    444 #define GL_RGB10_UNORM_ANGLEX 0x6AEE
    445 
    446 // These are fake formats for OES_vertex_type_10_10_10_2
    447 #define GL_A2_RGB10_UNORM_ANGLEX 0x6AEF
    448 #define GL_A2_RGB10_SNORM_ANGLEX 0x6AF0
    449 #define GL_A2_RGB10_USCALED_ANGLEX 0x6AF1
    450 #define GL_A2_RGB10_SSCALED_ANGLEX 0x6AF2
    451 #define GL_X2_RGB10_UINT_ANGLEX 0x6AF3
    452 #define GL_X2_RGB10_SINT_ANGLEX 0x6AF4
    453 #define GL_X2_RGB10_USCALED_ANGLEX 0x6AF5
    454 #define GL_X2_RGB10_SSCALED_ANGLEX 0x6AF6
    455 #define GL_X2_RGB10_UNORM_ANGLEX 0x6AF7
    456 #define GL_X2_RGB10_SNORM_ANGLEX 0x6AF8
    457 
    458 #define ANGLE_CHECK_GL_ALLOC(context, result) \
    459    ANGLE_CHECK(context, result, "Failed to allocate host memory", GL_OUT_OF_MEMORY)
    460 
    461 #define ANGLE_CHECK_GL_MATH(context, result) \
    462    ANGLE_CHECK(context, result, "Integer overflow.", GL_INVALID_OPERATION)
    463 
    464 #define ANGLE_GL_UNREACHABLE(context) \
    465    UNREACHABLE();                    \
    466    ANGLE_CHECK(context, false, "Unreachable Code.", GL_INVALID_OPERATION)
    467 
    468 #if defined(ANGLE_WITH_LSAN)
    469 #    define ANGLE_SCOPED_DISABLE_LSAN() __lsan::ScopedDisabler lsanDisabler
    470 #else
    471 #    define ANGLE_SCOPED_DISABLE_LSAN()
    472 #endif
    473 
    474 #if defined(ANGLE_WITH_MSAN)
    475 class MsanScopedDisableInterceptorChecks final : angle::NonCopyable
    476 {
    477  public:
    478    MsanScopedDisableInterceptorChecks() { __msan_scoped_disable_interceptor_checks(); }
    479    ~MsanScopedDisableInterceptorChecks() { __msan_scoped_enable_interceptor_checks(); }
    480 };
    481 #    define ANGLE_SCOPED_DISABLE_MSAN() \
    482        MsanScopedDisableInterceptorChecks msanScopedDisableInterceptorChecks
    483 #else
    484 #    define ANGLE_SCOPED_DISABLE_MSAN()
    485 #endif
    486 
    487 // The ANGLE_NO_SANITIZE_MEMORY macro suppresses MemorySanitizer checks for
    488 // use-of-uninitialized-data. It can be used to decorate functions with known
    489 // false positives.
    490 #ifdef __clang__
    491 #    define ANGLE_NO_SANITIZE_MEMORY __attribute__((no_sanitize_memory))
    492 #else
    493 #    define ANGLE_NO_SANITIZE_MEMORY
    494 #endif
    495 
    496 // Similar to the above, but for thread sanitization.
    497 #ifdef __clang__
    498 #    define ANGLE_NO_SANITIZE_THREAD __attribute__((no_sanitize_thread))
    499 #else
    500 #    define ANGLE_NO_SANITIZE_THREAD
    501 #endif
    502 
    503 // The below inlining code lifted from V8.
    504 #if defined(__clang__) || (defined(__GNUC__) && defined(__has_attribute))
    505 #    define ANGLE_HAS_ATTRIBUTE_ALWAYS_INLINE (__has_attribute(always_inline))
    506 #    define ANGLE_HAS___FORCEINLINE 0
    507 #elif defined(_MSC_VER)
    508 #    define ANGLE_HAS_ATTRIBUTE_ALWAYS_INLINE 0
    509 #    define ANGLE_HAS___FORCEINLINE 1
    510 #else
    511 #    define ANGLE_HAS_ATTRIBUTE_ALWAYS_INLINE 0
    512 #    define ANGLE_HAS___FORCEINLINE 0
    513 #endif
    514 
    515 #if defined(NDEBUG) && ANGLE_HAS_ATTRIBUTE_ALWAYS_INLINE
    516 #    define ANGLE_INLINE inline __attribute__((always_inline))
    517 #elif defined(NDEBUG) && ANGLE_HAS___FORCEINLINE
    518 #    define ANGLE_INLINE __forceinline
    519 #else
    520 #    define ANGLE_INLINE inline
    521 #endif
    522 
    523 #if defined(__clang__) || (defined(__GNUC__) && defined(__has_attribute))
    524 #    if __has_attribute(noinline)
    525 #        define ANGLE_NOINLINE __attribute__((noinline))
    526 #    else
    527 #        define ANGLE_NOINLINE
    528 #    endif
    529 #elif defined(_MSC_VER)
    530 #    define ANGLE_NOINLINE __declspec(noinline)
    531 #else
    532 #    define ANGLE_NOINLINE
    533 #endif
    534 
    535 #if defined(__clang__) || (defined(__GNUC__) && defined(__has_attribute))
    536 #    if __has_attribute(format)
    537 #        define ANGLE_FORMAT_PRINTF(fmt, args) __attribute__((format(__printf__, fmt, args)))
    538 #    else
    539 #        define ANGLE_FORMAT_PRINTF(fmt, args)
    540 #    endif
    541 #else
    542 #    define ANGLE_FORMAT_PRINTF(fmt, args)
    543 #endif
    544 
    545 ANGLE_FORMAT_PRINTF(1, 0)
    546 size_t FormatStringIntoVector(const char *fmt, va_list vararg, std::vector<char> &buffer);
    547 
    548 // Format messes up the # inside the macro.
    549 // clang-format off
    550 #ifndef ANGLE_STRINGIFY
    551 #    define ANGLE_STRINGIFY(x) #x
    552 #endif
    553 // clang-format on
    554 
    555 #ifndef ANGLE_MACRO_STRINGIFY
    556 #    define ANGLE_MACRO_STRINGIFY(x) ANGLE_STRINGIFY(x)
    557 #endif
    558 
    559 #if __has_cpp_attribute(clang::require_constant_initialization)
    560 #    define ANGLE_REQUIRE_CONSTANT_INIT [[clang::require_constant_initialization]]
    561 #else
    562 #    define ANGLE_REQUIRE_CONSTANT_INIT
    563 #endif  // __has_cpp_attribute(require_constant_initialization)
    564 
    565 // Compiler configs.
    566 inline bool IsASan()
    567 {
    568 #if defined(ANGLE_WITH_ASAN)
    569    return true;
    570 #else
    571    return false;
    572 #endif  // defined(ANGLE_WITH_ASAN)
    573 }
    574 
    575 inline bool IsMSan()
    576 {
    577 #if defined(ANGLE_WITH_MSAN)
    578    return true;
    579 #else
    580    return false;
    581 #endif  // defined(ANGLE_WITH_MSAN)
    582 }
    583 
    584 inline bool IsTSan()
    585 {
    586 #if defined(ANGLE_WITH_TSAN)
    587    return true;
    588 #else
    589    return false;
    590 #endif  // defined(ANGLE_WITH_TSAN)
    591 }
    592 
    593 inline bool IsUBSan()
    594 {
    595 #if defined(ANGLE_WITH_UBSAN)
    596    return true;
    597 #else
    598    return false;
    599 #endif  // defined(ANGLE_WITH_UBSAN)
    600 }
    601 #endif  // COMMON_ANGLEUTILS_H_