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:
ResourceSerial()24     constexpr ResourceSerial() : mValue(kDirty) {}
ResourceSerial(uintptr_t value)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 
dirty()29     void dirty() { mValue = kDirty; }
clear()30     void clear() { mValue = kEmpty; }
31 
valid()32     constexpr bool valid() const { return mValue != kEmpty && mValue != kDirty; }
empty()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:
Serial()45     constexpr Serial() : mValue(kInvalid) {}
46     constexpr Serial(const Serial &other) = default;
47     Serial &operator=(const Serial &other) = default;
48 
Infinite()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.
getValue()71     constexpr uint64_t getValue() const { return mValue; }
valid()72     constexpr bool valid() const { return mValue != kInvalid; }
73 
74   private:
75     template <typename T>
76     friend class SerialFactoryBase;
Serial(uint64_t value)77     constexpr explicit Serial(uint64_t value) : mValue(value) {}
78     uint64_t mValue;
79     static constexpr uint64_t kInvalid = 0;
80 };
81 
82 // Used as default/initial serial
83 static constexpr Serial kZeroSerial = Serial();
84 
85 template <typename SerialBaseType>
86 class SerialFactoryBase final : angle::NonCopyable
87 {
88   public:
SerialFactoryBase()89     SerialFactoryBase() : mSerial(1) {}
90 
generate()91     Serial generate()
92     {
93         ASSERT(mSerial + 1 > mSerial);
94         return Serial(mSerial++);
95     }
96 
97   private:
98     SerialBaseType mSerial;
99 };
100 
101 using SerialFactory       = SerialFactoryBase<uint64_t>;
102 using AtomicSerialFactory = SerialFactoryBase<std::atomic<uint64_t>>;
103 }  // namespace rx
104 
105 #endif  // LIBANGLE_RENDERER_SERIAL_UTILS_H_
106