blob: b51f7a3992a77f1f255b9a6f525c94abfc1a8912 [file] [log] [blame]
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001//
Geoff Langcec35902014-04-16 10:52:36 -04002// Copyright (c) 2002-2014 The ANGLE Project Authors. All rights reserved.
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003// 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
daniel@transgaming.combbf56f72010-04-20 18:52:13 +00009#ifndef COMMON_ANGLEUTILS_H_
10#define COMMON_ANGLEUTILS_H_
11
Geoff Lang44fa7592014-05-30 11:50:07 -040012#include "common/platform.h"
13
Jamie Madill55573e12014-11-25 11:21:13 -050014#include <climits>
15#include <cstdarg>
16#include <cstddef>
Geoff Langcec35902014-04-16 10:52:36 -040017#include <string>
18#include <set>
Jamie Madill53cb14d2014-07-08 15:02:35 -040019#include <sstream>
Austin Kinross922a9fb2014-10-21 14:26:33 -070020#include <vector>
Jamie Madillf386bf72013-07-08 14:02:41 -040021
Jamie Madillf0d10f82015-03-31 12:56:52 -040022// A helper class to disallow copy and assignment operators
23namespace angle
24{
25
Brian Osman63d82622017-01-06 14:05:18 -050026#if defined(ANGLE_ENABLE_D3D9) || defined(ANGLE_ENABLE_D3D11)
Jamie Madill47c0e042016-11-30 13:44:45 -050027using Microsoft::WRL::ComPtr;
Brian Osman63d82622017-01-06 14:05:18 -050028#endif // defined(ANGLE_ENABLE_D3D9) || defined(ANGLE_ENABLE_D3D11)
Jamie Madill47c0e042016-11-30 13:44:45 -050029
Jamie Madillf0d10f82015-03-31 12:56:52 -040030class NonCopyable
31{
Frank Henigmanaa7203e2017-05-03 23:32:29 -040032 protected:
Jamie Madillf0d10f82015-03-31 12:56:52 -040033 NonCopyable() = default;
34 ~NonCopyable() = default;
Frank Henigmanaa7203e2017-05-03 23:32:29 -040035
36 private:
Jamie Madillf0d10f82015-03-31 12:56:52 -040037 NonCopyable(const NonCopyable&) = delete;
38 void operator=(const NonCopyable&) = delete;
39};
40
Jamie Madillc9bdeff2016-02-08 12:36:55 -050041extern const uintptr_t DirtyPointer;
Jamie Madillfe548342017-06-19 11:13:24 -040042
43// Helper class for wrapping an onDestroy function.
44template <typename ObjT, typename ContextT>
45class UniqueObjectPointer : angle::NonCopyable
46{
47 public:
Jamie Madill4928b7c2017-06-20 12:57:39 -040048 UniqueObjectPointer(const ContextT *context) : mObject(nullptr), mContext(context) {}
Jamie Madillfe548342017-06-19 11:13:24 -040049 UniqueObjectPointer(ObjT *obj, const ContextT *context) : mObject(obj), mContext(context) {}
50 ~UniqueObjectPointer()
51 {
52 if (mObject)
53 {
54 mObject->onDestroy(mContext);
55 }
56 }
57
58 ObjT *operator->() const { return mObject; }
59
60 ObjT *release()
61 {
62 auto obj = mObject;
63 mObject = nullptr;
64 return obj;
65 }
66
Jamie Madill4928b7c2017-06-20 12:57:39 -040067 ObjT *get() const { return mObject; }
68
69 void reset(ObjT *obj)
70 {
71 if (mObject)
72 {
73 mObject->onDestroy(mContext);
74 }
75 mObject = obj;
76 }
77
Jamie Madillfe548342017-06-19 11:13:24 -040078 private:
79 ObjT *mObject;
80 const ContextT *mContext;
81};
82
Sami Väisänen46eaa942016-06-29 10:26:37 +030083} // namespace angle
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000084
Jamie Madill33ea2f92014-08-29 15:15:01 -040085template <typename T, size_t N>
Sami Väisänen46eaa942016-06-29 10:26:37 +030086constexpr inline size_t ArraySize(T (&)[N])
shannon.woods@transgaming.com6d792572013-02-28 23:07:25 +000087{
88 return N;
89}
90
Jamie Madill5978e282017-06-02 11:49:31 -040091template <typename T>
92class WrappedArray final : angle::NonCopyable
93{
94 public:
95 template <size_t N>
96 constexpr WrappedArray(const T (&data)[N]) : mArray(&data[0]), mSize(N)
97 {
98 }
99
100 constexpr WrappedArray() : mArray(nullptr), mSize(0) {}
101 constexpr WrappedArray(const T *data, size_t size) : mArray(data), mSize(size) {}
Jamie Madill92996b02017-08-17 10:39:02 -0400102
103 constexpr WrappedArray(WrappedArray &&other) : WrappedArray()
104 {
105 std::swap(mArray, other.mArray);
106 std::swap(mSize, other.mSize);
107 }
108
Jamie Madill5978e282017-06-02 11:49:31 -0400109 ~WrappedArray() {}
110
111 constexpr const T *get() const { return mArray; }
112 constexpr size_t size() const { return mSize; }
113
114 private:
115 const T *mArray;
116 size_t mSize;
117};
118
shannon.woods%transgaming.com@gtempaccount.com96224772013-04-13 03:30:18 +0000119template <typename T, unsigned int N>
120void SafeRelease(T (&resourceBlock)[N])
121{
122 for (unsigned int i = 0; i < N; i++)
123 {
124 SafeRelease(resourceBlock[i]);
125 }
126}
127
128template <typename T>
129void SafeRelease(T& resource)
130{
131 if (resource)
132 {
133 resource->Release();
Yunchao Hed7297bf2017-04-19 15:27:10 +0800134 resource = nullptr;
shannon.woods%transgaming.com@gtempaccount.com96224772013-04-13 03:30:18 +0000135 }
136}
137
Geoff Langea228632013-07-30 15:17:12 -0400138template <typename T>
Jamie Madill78a9c732016-07-15 11:22:43 -0400139void SafeDelete(T *&resource)
Geoff Langea228632013-07-30 15:17:12 -0400140{
141 delete resource;
Yunchao Hed7297bf2017-04-19 15:27:10 +0800142 resource = nullptr;
Geoff Langea228632013-07-30 15:17:12 -0400143}
144
145template <typename T>
Geoff Lang04fb89a2014-06-09 15:05:36 -0400146void SafeDeleteContainer(T& resource)
147{
Jamie Madill4e31ad52015-10-29 10:32:57 -0400148 for (auto &element : resource)
Geoff Lang04fb89a2014-06-09 15:05:36 -0400149 {
Jamie Madill4e31ad52015-10-29 10:32:57 -0400150 SafeDelete(element);
Geoff Lang04fb89a2014-06-09 15:05:36 -0400151 }
152 resource.clear();
153}
154
155template <typename T>
Geoff Langea228632013-07-30 15:17:12 -0400156void SafeDeleteArray(T*& resource)
157{
158 delete[] resource;
Yunchao Hed7297bf2017-04-19 15:27:10 +0800159 resource = nullptr;
Geoff Langea228632013-07-30 15:17:12 -0400160}
161
Jamie Madilld3f0f1e2013-09-20 13:31:08 -0400162// Provide a less-than function for comparing structs
163// Note: struct memory must be initialized to zero, because of packing gaps
164template <typename T>
165inline bool StructLessThan(const T &a, const T &b)
166{
167 return (memcmp(&a, &b, sizeof(T)) < 0);
168}
169
170// Provide a less-than function for comparing structs
171// Note: struct memory must be initialized to zero, because of packing gaps
172template <typename T>
173inline bool StructEquals(const T &a, const T &b)
174{
175 return (memcmp(&a, &b, sizeof(T)) == 0);
176}
177
178template <typename T>
179inline void StructZero(T *obj)
180{
181 memset(obj, 0, sizeof(T));
182}
183
Tibor den Ouden2221f472014-10-22 15:07:05 +0200184template <typename T>
185inline bool IsMaskFlagSet(T mask, T flag)
186{
187 // Handles multibit flags as well
188 return (mask & flag) == flag;
189}
190
Geoff Langcec35902014-04-16 10:52:36 -0400191inline const char* MakeStaticString(const std::string &str)
192{
193 static std::set<std::string> strings;
194 std::set<std::string>::iterator it = strings.find(str);
195 if (it != strings.end())
196 {
197 return it->c_str();
198 }
199
200 return strings.insert(str).first->c_str();
201}
202
Jamie Madill53cb14d2014-07-08 15:02:35 -0400203inline std::string ArrayString(unsigned int i)
204{
205 // We assume UINT_MAX and GL_INVALID_INDEX are equal
206 // See DynamicHLSL.cpp
207 if (i == UINT_MAX)
208 {
209 return "";
210 }
211
212 std::stringstream strstr;
213
214 strstr << "[";
215 strstr << i;
216 strstr << "]";
217
218 return strstr.str();
219}
220
221inline std::string Str(int i)
222{
223 std::stringstream strstr;
224 strstr << i;
225 return strstr.str();
226}
227
Austin Kinross922a9fb2014-10-21 14:26:33 -0700228size_t FormatStringIntoVector(const char *fmt, va_list vararg, std::vector<char>& buffer);
229
Shannon Woods8e7d7a32014-09-02 17:09:08 -0400230std::string FormatString(const char *fmt, va_list vararg);
231std::string FormatString(const char *fmt, ...);
Geoff Langda5777c2014-07-11 09:52:58 -0400232
Corentin Wallez054f7ed2016-09-20 17:15:59 -0400233template <typename T>
234std::string ToString(const T &value)
235{
236 std::ostringstream o;
237 o << value;
238 return o.str();
239}
240
Geoff Langdf8fafe2014-11-11 11:11:33 -0500241// snprintf is not defined with MSVC prior to to msvc14
242#if defined(_MSC_VER) && _MSC_VER < 1900
alokp@chromium.org79fb1012012-04-26 21:07:39 +0000243#define snprintf _snprintf
244#endif
245
Geoff Langaadc8f32017-08-11 17:34:44 -0400246#define GL_BGRX8_ANGLEX 0x6ABA
Jamie Madillec0b5802016-07-04 13:11:59 -0400247#define GL_BGR565_ANGLEX 0x6ABB
daniel@transgaming.com106e1f72012-10-31 18:38:36 +0000248#define GL_BGRA4_ANGLEX 0x6ABC
249#define GL_BGR5_A1_ANGLEX 0x6ABD
Jamie Madill0fda9862013-07-19 16:36:55 -0400250#define GL_INT_64_ANGLEX 0x6ABE
Jamie Madill28167c62013-08-30 13:21:10 -0400251#define GL_STRUCT_ANGLEX 0x6ABF
daniel@transgaming.com106e1f72012-10-31 18:38:36 +0000252
Geoff Lang7825f612014-11-26 16:19:41 -0500253// Hidden enum for the NULL D3D device type.
254#define EGL_PLATFORM_ANGLE_DEVICE_TYPE_NULL_ANGLE 0x6AC0
255
Jamie Madill98de8262017-05-29 13:01:02 -0400256// TODO(jmadill): Clean this up at some point.
257#define EGL_PLATFORM_ANGLE_PLATFORM_METHODS_ANGLEX 0x9999
258
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500259#define ANGLE_TRY_CHECKED_MATH(result) \
260 if (!result.IsValid()) \
261 { \
262 return gl::InternalError() << "Integer overflow."; \
Jamie Madille2e406c2016-06-02 13:04:10 -0400263 }
264
Jamie Madill44183cc2017-08-01 12:48:34 -0400265// The below inlining code lifted from V8.
jchen103c76d592017-08-03 08:47:56 +0800266#if defined(__clang__) || (defined(__GNUC__) && defined(__has_attribute))
Jamie Madill44183cc2017-08-01 12:48:34 -0400267#define ANGLE_HAS_ATTRIBUTE_ALWAYS_INLINE (__has_attribute(always_inline))
268#define ANGLE_HAS___FORCEINLINE 0
269#elif defined(_MSC_VER)
270#define ANGLE_HAS_ATTRIBUTE_ALWAYS_INLINE 0
271#define ANGLE_HAS___FORCEINLINE 1
272#else
273#define ANGLE_HAS_ATTRIBUTE_ALWAYS_INLINE 0
274#define ANGLE_HAS___FORCEINLINE 0
275#endif
276
277#if defined(NDEBUG) && ANGLE_HAS_ATTRIBUTE_ALWAYS_INLINE
278#define ANGLE_INLINE inline __attribute__((always_inline))
279#elif defined(NDEBUG) && ANGLE_HAS___FORCEINLINE
280#define ANGLE_INLINE __forceinline
281#else
282#define ANGLE_INLINE inline
283#endif
284
Jamie Madill92996b02017-08-17 10:39:02 -0400285#ifndef ANGLE_STRINGIFY
286#define ANGLE_STRINGIFY(x) #x
287#endif
288
289#ifndef ANGLE_MACRO_STRINGIFY
290#define ANGLE_MACRO_STRINGIFY(x) ANGLE_STRINGIFY(x)
291#endif
292
daniel@transgaming.combbf56f72010-04-20 18:52:13 +0000293#endif // COMMON_ANGLEUTILS_H_