serial_utils.h (3985B)
1 // 2 // Copyright 2019 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 // serial_utils: 7 // Utilities for generating unique IDs for resources in ANGLE. 8 // 9 10 #ifndef LIBANGLE_RENDERER_SERIAL_UTILS_H_ 11 #define LIBANGLE_RENDERER_SERIAL_UTILS_H_ 12 13 #include <atomic> 14 #include <limits> 15 16 #include "common/angleutils.h" 17 #include "common/debug.h" 18 19 namespace rx 20 { 21 class ResourceSerial 22 { 23 public: 24 constexpr ResourceSerial() : mValue(kDirty) {} 25 explicit constexpr ResourceSerial(uintptr_t value) : mValue(value) {} 26 constexpr bool operator==(ResourceSerial other) const { return mValue == other.mValue; } 27 constexpr bool operator!=(ResourceSerial other) const { return mValue != other.mValue; } 28 29 void dirty() { mValue = kDirty; } 30 void clear() { mValue = kEmpty; } 31 32 constexpr bool valid() const { return mValue != kEmpty && mValue != kDirty; } 33 constexpr bool empty() const { return mValue == kEmpty; } 34 35 private: 36 constexpr static uintptr_t kDirty = std::numeric_limits<uintptr_t>::max(); 37 constexpr static uintptr_t kEmpty = 0; 38 39 uintptr_t mValue; 40 }; 41 42 class Serial final 43 { 44 public: 45 constexpr Serial() : mValue(kInvalid) {} 46 constexpr Serial(const Serial &other) = default; 47 Serial &operator=(const Serial &other) = default; 48 49 static constexpr Serial Infinite() { return Serial(std::numeric_limits<uint64_t>::max()); } 50 51 constexpr bool operator==(const Serial &other) const 52 { 53 return mValue != kInvalid && mValue == other.mValue; 54 } 55 constexpr bool operator==(uint32_t value) const 56 { 57 return mValue != kInvalid && mValue == static_cast<uint64_t>(value); 58 } 59 constexpr bool operator!=(const Serial &other) const 60 { 61 return mValue == kInvalid || mValue != other.mValue; 62 } 63 constexpr bool operator>(const Serial &other) const { return mValue > other.mValue; } 64 constexpr bool operator>=(const Serial &other) const { return mValue >= other.mValue; } 65 constexpr bool operator<(const Serial &other) const { return mValue < other.mValue; } 66 constexpr bool operator<=(const Serial &other) const { return mValue <= other.mValue; } 67 68 constexpr bool operator<(uint32_t value) const { return mValue < static_cast<uint64_t>(value); } 69 70 // Useful for serialization. 71 constexpr uint64_t getValue() const { return mValue; } 72 constexpr bool valid() const { return mValue != kInvalid; } 73 74 private: 75 template <typename T> 76 friend class SerialFactoryBase; 77 friend class AtomicQueueSerial; 78 constexpr explicit Serial(uint64_t value) : mValue(value) {} 79 uint64_t mValue; 80 static constexpr uint64_t kInvalid = 0; 81 }; 82 83 // Defines class to track the queue serial that can be load/store from multiple threads atomically. 84 class AtomicQueueSerial final 85 { 86 public: 87 constexpr AtomicQueueSerial() : mValue(kInvalid) { ASSERT(mValue.is_lock_free()); } 88 AtomicQueueSerial &operator=(const Serial &other) 89 { 90 mValue.store(other.mValue, std::memory_order_release); 91 return *this; 92 } 93 Serial getSerial() const { return Serial(mValue.load(std::memory_order_consume)); } 94 95 private: 96 std::atomic<uint64_t> mValue; 97 static constexpr uint64_t kInvalid = 0; 98 }; 99 100 // Used as default/initial serial 101 static constexpr Serial kZeroSerial = Serial(); 102 103 template <typename SerialBaseType> 104 class SerialFactoryBase final : angle::NonCopyable 105 { 106 public: 107 SerialFactoryBase() : mSerial(1) {} 108 109 Serial generate() 110 { 111 uint64_t current = mSerial++; 112 ASSERT(mSerial > current); // Integer overflow 113 return Serial(current); 114 } 115 116 private: 117 SerialBaseType mSerial; 118 }; 119 120 using SerialFactory = SerialFactoryBase<uint64_t>; 121 using AtomicSerialFactory = SerialFactoryBase<std::atomic<uint64_t>>; 122 using RenderPassSerialFactory = SerialFactoryBase<uint64_t>; 123 124 } // namespace rx 125 126 #endif // LIBANGLE_RENDERER_SERIAL_UTILS_H_