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