1 //
2 // Copyright (c) 2002-2014 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 #include <climits>
15 #include <cstdarg>
16 #include <cstddef>
17 #include <string>
18 #include <set>
19 #include <sstream>
20 #include <vector>
21
22 // A helper class to disallow copy and assignment operators
23 namespace angle
24 {
25
26 #if defined(ANGLE_ENABLE_D3D9) || defined(ANGLE_ENABLE_D3D11)
27 using Microsoft::WRL::ComPtr;
28 #endif // defined(ANGLE_ENABLE_D3D9) || defined(ANGLE_ENABLE_D3D11)
29
30 class NonCopyable
31 {
32 protected:
33 NonCopyable() = default;
34 ~NonCopyable() = default;
35
36 private:
37 NonCopyable(const NonCopyable&) = delete;
38 void operator=(const NonCopyable&) = delete;
39 };
40
41 extern const uintptr_t DirtyPointer;
42
43 } // namespace angle
44
45 template <typename T, size_t N>
ArraySize(T (&)[N])46 constexpr inline size_t ArraySize(T (&)[N])
47 {
48 return N;
49 }
50
51 template <typename T>
52 class WrappedArray final : angle::NonCopyable
53 {
54 public:
55 template <size_t N>
WrappedArray(const T (& data)[N])56 constexpr WrappedArray(const T (&data)[N]) : mArray(&data[0]), mSize(N)
57 {
58 }
59
WrappedArray()60 constexpr WrappedArray() : mArray(nullptr), mSize(0) {}
WrappedArray(const T * data,size_t size)61 constexpr WrappedArray(const T *data, size_t size) : mArray(data), mSize(size) {}
62
WrappedArray(WrappedArray && other)63 WrappedArray(WrappedArray &&other) : WrappedArray()
64 {
65 std::swap(mArray, other.mArray);
66 std::swap(mSize, other.mSize);
67 }
68
~WrappedArray()69 ~WrappedArray() {}
70
get()71 constexpr const T *get() const { return mArray; }
size()72 constexpr size_t size() const { return mSize; }
73
74 private:
75 const T *mArray;
76 size_t mSize;
77 };
78
79 template <typename T, unsigned int N>
SafeRelease(T (& resourceBlock)[N])80 void SafeRelease(T (&resourceBlock)[N])
81 {
82 for (unsigned int i = 0; i < N; i++)
83 {
84 SafeRelease(resourceBlock[i]);
85 }
86 }
87
88 template <typename T>
SafeRelease(T & resource)89 void SafeRelease(T& resource)
90 {
91 if (resource)
92 {
93 resource->Release();
94 resource = nullptr;
95 }
96 }
97
98 template <typename T>
SafeDelete(T * & resource)99 void SafeDelete(T *&resource)
100 {
101 delete resource;
102 resource = nullptr;
103 }
104
105 template <typename T>
SafeDeleteContainer(T & resource)106 void SafeDeleteContainer(T& resource)
107 {
108 for (auto &element : resource)
109 {
110 SafeDelete(element);
111 }
112 resource.clear();
113 }
114
115 template <typename T>
SafeDeleteArray(T * & resource)116 void SafeDeleteArray(T*& resource)
117 {
118 delete[] resource;
119 resource = nullptr;
120 }
121
122 // Provide a less-than function for comparing structs
123 // Note: struct memory must be initialized to zero, because of packing gaps
124 template <typename T>
StructLessThan(const T & a,const T & b)125 inline bool StructLessThan(const T &a, const T &b)
126 {
127 return (memcmp(&a, &b, sizeof(T)) < 0);
128 }
129
130 // Provide a less-than function for comparing structs
131 // Note: struct memory must be initialized to zero, because of packing gaps
132 template <typename T>
StructEquals(const T & a,const T & b)133 inline bool StructEquals(const T &a, const T &b)
134 {
135 return (memcmp(&a, &b, sizeof(T)) == 0);
136 }
137
138 template <typename T>
StructZero(T * obj)139 inline void StructZero(T *obj)
140 {
141 memset(obj, 0, sizeof(T));
142 }
143
144 template <typename T>
IsMaskFlagSet(T mask,T flag)145 inline bool IsMaskFlagSet(T mask, T flag)
146 {
147 // Handles multibit flags as well
148 return (mask & flag) == flag;
149 }
150
MakeStaticString(const std::string & str)151 inline const char* MakeStaticString(const std::string &str)
152 {
153 static std::set<std::string> strings;
154 std::set<std::string>::iterator it = strings.find(str);
155 if (it != strings.end())
156 {
157 return it->c_str();
158 }
159
160 return strings.insert(str).first->c_str();
161 }
162
163 std::string ArrayString(unsigned int i);
164
165 // Indices are stored in vectors with the outermost index in the back. In the output of the function
166 // the indices are reversed.
167 std::string ArrayIndexString(const std::vector<unsigned int> &indices);
168
Str(int i)169 inline std::string Str(int i)
170 {
171 std::stringstream strstr;
172 strstr << i;
173 return strstr.str();
174 }
175
176 size_t FormatStringIntoVector(const char *fmt, va_list vararg, std::vector<char>& buffer);
177
178 std::string FormatString(const char *fmt, va_list vararg);
179 std::string FormatString(const char *fmt, ...);
180
181 template <typename T>
ToString(const T & value)182 std::string ToString(const T &value)
183 {
184 std::ostringstream o;
185 o << value;
186 return o.str();
187 }
188
189 // snprintf is not defined with MSVC prior to to msvc14
190 #if defined(_MSC_VER) && _MSC_VER < 1900
191 #define snprintf _snprintf
192 #endif
193
194 #define GL_BGRX8_ANGLEX 0x6ABA
195 #define GL_BGR565_ANGLEX 0x6ABB
196 #define GL_BGRA4_ANGLEX 0x6ABC
197 #define GL_BGR5_A1_ANGLEX 0x6ABD
198 #define GL_INT_64_ANGLEX 0x6ABE
199 #define GL_UINT_64_ANGLEX 0x6ABF
200 #define GL_BGRA8_SRGB_ANGLEX 0x6AC0
201
202 // Hidden enum for the NULL D3D device type.
203 #define EGL_PLATFORM_ANGLE_DEVICE_TYPE_NULL_ANGLE 0x6AC0
204
205 // TODO(jmadill): Clean this up at some point.
206 #define EGL_PLATFORM_ANGLE_PLATFORM_METHODS_ANGLEX 0x9999
207
208 #define ANGLE_TRY_CHECKED_MATH(result) \
209 if (!result.IsValid()) \
210 { \
211 return gl::InternalError() << "Integer overflow."; \
212 }
213
214 // The below inlining code lifted from V8.
215 #if defined(__clang__) || (defined(__GNUC__) && defined(__has_attribute))
216 #define ANGLE_HAS_ATTRIBUTE_ALWAYS_INLINE (__has_attribute(always_inline))
217 #define ANGLE_HAS___FORCEINLINE 0
218 #elif defined(_MSC_VER)
219 #define ANGLE_HAS_ATTRIBUTE_ALWAYS_INLINE 0
220 #define ANGLE_HAS___FORCEINLINE 1
221 #else
222 #define ANGLE_HAS_ATTRIBUTE_ALWAYS_INLINE 0
223 #define ANGLE_HAS___FORCEINLINE 0
224 #endif
225
226 #if defined(NDEBUG) && ANGLE_HAS_ATTRIBUTE_ALWAYS_INLINE
227 #define ANGLE_INLINE inline __attribute__((always_inline))
228 #elif defined(NDEBUG) && ANGLE_HAS___FORCEINLINE
229 #define ANGLE_INLINE __forceinline
230 #else
231 #define ANGLE_INLINE inline
232 #endif
233
234 #ifndef ANGLE_STRINGIFY
235 #define ANGLE_STRINGIFY(x) #x
236 #endif
237
238 #ifndef ANGLE_MACRO_STRINGIFY
239 #define ANGLE_MACRO_STRINGIFY(x) ANGLE_STRINGIFY(x)
240 #endif
241
242 // Detect support for C++17 [[nodiscard]]
243 #if !defined(__has_cpp_attribute)
244 #define __has_cpp_attribute(name) 0
245 #endif // !defined(__has_cpp_attribute)
246
247 #if __has_cpp_attribute(nodiscard)
248 #define ANGLE_NO_DISCARD [[nodiscard]]
249 #else
250 #define ANGLE_NO_DISCARD
251 #endif // __has_cpp_attribute(nodiscard)
252
253 #endif // COMMON_ANGLEUTILS_H_
254