blob: 037f9e91b7d6571dccb9ad8986ba51d4dea1ac0e [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 <set>
Jamie Madill53cb14d2014-07-08 15:02:35 -040018#include <sstream>
Frank Henigman95fb2a12018-05-27 20:17:05 -040019#include <string>
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:
Olli Etuaho7b17fa12018-01-29 11:12:57 +020033 constexpr NonCopyable() = default;
Frank Henigman95fb2a12018-05-27 20:17:05 -040034 ~NonCopyable() = default;
Frank Henigmanaa7203e2017-05-03 23:32:29 -040035
36 private:
Frank Henigman95fb2a12018-05-27 20:17:05 -040037 NonCopyable(const NonCopyable &) = delete;
38 void operator=(const NonCopyable &) = delete;
Jamie Madillf0d10f82015-03-31 12:56:52 -040039};
40
Jamie Madillc9bdeff2016-02-08 12:36:55 -050041extern const uintptr_t DirtyPointer;
Jamie Madillfe548342017-06-19 11:13:24 -040042
Sami Väisänen46eaa942016-06-29 10:26:37 +030043} // namespace angle
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000044
Jamie Madill33ea2f92014-08-29 15:15:01 -040045template <typename T, size_t N>
Sami Väisänen46eaa942016-06-29 10:26:37 +030046constexpr inline size_t ArraySize(T (&)[N])
shannon.woods@transgaming.com6d792572013-02-28 23:07:25 +000047{
48 return N;
49}
50
Jamie Madill5978e282017-06-02 11:49:31 -040051template <typename T>
52class WrappedArray final : angle::NonCopyable
53{
54 public:
55 template <size_t N>
56 constexpr WrappedArray(const T (&data)[N]) : mArray(&data[0]), mSize(N)
57 {
58 }
59
60 constexpr WrappedArray() : mArray(nullptr), mSize(0) {}
61 constexpr WrappedArray(const T *data, size_t size) : mArray(data), mSize(size) {}
Jamie Madill92996b02017-08-17 10:39:02 -040062
Jamie Madill2c1183b2017-08-24 10:36:01 -070063 WrappedArray(WrappedArray &&other) : WrappedArray()
Jamie Madill92996b02017-08-17 10:39:02 -040064 {
65 std::swap(mArray, other.mArray);
66 std::swap(mSize, other.mSize);
67 }
68
Jamie Madill5978e282017-06-02 11:49:31 -040069 ~WrappedArray() {}
70
71 constexpr const T *get() const { return mArray; }
72 constexpr size_t size() const { return mSize; }
73
74 private:
75 const T *mArray;
76 size_t mSize;
77};
78
shannon.woods%transgaming.com@gtempaccount.com96224772013-04-13 03:30:18 +000079template <typename T, unsigned int N>
80void SafeRelease(T (&resourceBlock)[N])
81{
82 for (unsigned int i = 0; i < N; i++)
83 {
84 SafeRelease(resourceBlock[i]);
85 }
86}
87
88template <typename T>
Frank Henigman95fb2a12018-05-27 20:17:05 -040089void SafeRelease(T &resource)
shannon.woods%transgaming.com@gtempaccount.com96224772013-04-13 03:30:18 +000090{
91 if (resource)
92 {
93 resource->Release();
Yunchao Hed7297bf2017-04-19 15:27:10 +080094 resource = nullptr;
shannon.woods%transgaming.com@gtempaccount.com96224772013-04-13 03:30:18 +000095 }
96}
97
Geoff Langea228632013-07-30 15:17:12 -040098template <typename T>
Jamie Madill78a9c732016-07-15 11:22:43 -040099void SafeDelete(T *&resource)
Geoff Langea228632013-07-30 15:17:12 -0400100{
101 delete resource;
Yunchao Hed7297bf2017-04-19 15:27:10 +0800102 resource = nullptr;
Geoff Langea228632013-07-30 15:17:12 -0400103}
104
105template <typename T>
Frank Henigman95fb2a12018-05-27 20:17:05 -0400106void SafeDeleteContainer(T &resource)
Geoff Lang04fb89a2014-06-09 15:05:36 -0400107{
Jamie Madill4e31ad52015-10-29 10:32:57 -0400108 for (auto &element : resource)
Geoff Lang04fb89a2014-06-09 15:05:36 -0400109 {
Jamie Madill4e31ad52015-10-29 10:32:57 -0400110 SafeDelete(element);
Geoff Lang04fb89a2014-06-09 15:05:36 -0400111 }
112 resource.clear();
113}
114
115template <typename T>
Frank Henigman95fb2a12018-05-27 20:17:05 -0400116void SafeDeleteArray(T *&resource)
Geoff Langea228632013-07-30 15:17:12 -0400117{
118 delete[] resource;
Yunchao Hed7297bf2017-04-19 15:27:10 +0800119 resource = nullptr;
Geoff Langea228632013-07-30 15:17:12 -0400120}
121
Jamie Madilld3f0f1e2013-09-20 13:31:08 -0400122// Provide a less-than function for comparing structs
123// Note: struct memory must be initialized to zero, because of packing gaps
124template <typename T>
125inline 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
132template <typename T>
133inline bool StructEquals(const T &a, const T &b)
134{
135 return (memcmp(&a, &b, sizeof(T)) == 0);
136}
137
138template <typename T>
139inline void StructZero(T *obj)
140{
141 memset(obj, 0, sizeof(T));
142}
143
Tibor den Ouden2221f472014-10-22 15:07:05 +0200144template <typename T>
145inline bool IsMaskFlagSet(T mask, T flag)
146{
147 // Handles multibit flags as well
148 return (mask & flag) == flag;
149}
150
Frank Henigman95fb2a12018-05-27 20:17:05 -0400151inline const char *MakeStaticString(const std::string &str)
Geoff Langcec35902014-04-16 10:52:36 -0400152{
Nico Weber079a6bc2018-10-01 14:30:09 -0400153 // On the heap so that no destructor runs on application exit.
154 static std::set<std::string> *strings = new std::set<std::string>;
155 std::set<std::string>::iterator it = strings->find(str);
156 if (it != strings->end())
Geoff Langcec35902014-04-16 10:52:36 -0400157 {
158 return it->c_str();
159 }
160
Nico Weber079a6bc2018-10-01 14:30:09 -0400161 return strings->insert(str).first->c_str();
Geoff Langcec35902014-04-16 10:52:36 -0400162}
163
Olli Etuahoc8538042017-09-27 11:20:15 +0300164std::string ArrayString(unsigned int i);
Jamie Madill53cb14d2014-07-08 15:02:35 -0400165
Olli Etuahoc8538042017-09-27 11:20:15 +0300166// Indices are stored in vectors with the outermost index in the back. In the output of the function
167// the indices are reversed.
168std::string ArrayIndexString(const std::vector<unsigned int> &indices);
Jamie Madill53cb14d2014-07-08 15:02:35 -0400169
170inline std::string Str(int i)
171{
172 std::stringstream strstr;
173 strstr << i;
174 return strstr.str();
175}
176
Frank Henigman95fb2a12018-05-27 20:17:05 -0400177size_t FormatStringIntoVector(const char *fmt, va_list vararg, std::vector<char> &buffer);
Austin Kinross922a9fb2014-10-21 14:26:33 -0700178
Corentin Wallez054f7ed2016-09-20 17:15:59 -0400179template <typename T>
180std::string ToString(const T &value)
181{
182 std::ostringstream o;
183 o << value;
184 return o.str();
185}
186
Geoff Langdf8fafe2014-11-11 11:11:33 -0500187// snprintf is not defined with MSVC prior to to msvc14
188#if defined(_MSC_VER) && _MSC_VER < 1900
alokp@chromium.org79fb1012012-04-26 21:07:39 +0000189#define snprintf _snprintf
190#endif
191
Luc Ferron41918382018-03-13 11:37:54 -0400192#define GL_A1RGB5_ANGLEX 0x6AC5
Geoff Langaadc8f32017-08-11 17:34:44 -0400193#define GL_BGRX8_ANGLEX 0x6ABA
Jamie Madillec0b5802016-07-04 13:11:59 -0400194#define GL_BGR565_ANGLEX 0x6ABB
daniel@transgaming.com106e1f72012-10-31 18:38:36 +0000195#define GL_BGRA4_ANGLEX 0x6ABC
196#define GL_BGR5_A1_ANGLEX 0x6ABD
Jamie Madill0fda9862013-07-19 16:36:55 -0400197#define GL_INT_64_ANGLEX 0x6ABE
jchen10a99ed552017-09-22 08:10:32 +0800198#define GL_UINT_64_ANGLEX 0x6ABF
Sami Väisänen935cb7c2017-11-08 15:53:41 +0100199#define GL_BGRA8_SRGB_ANGLEX 0x6AC0
daniel@transgaming.com106e1f72012-10-31 18:38:36 +0000200
Olli Etuahod66e1932018-01-17 11:36:24 +0200201// These are dummy formats used to fit typeless D3D textures that can be bound to EGL pbuffers into
202// the format system (for extension EGL_ANGLE_d3d_texture_client_buffer):
203#define GL_RGBA8_TYPELESS_ANGLEX 0x6AC1
204#define GL_RGBA8_TYPELESS_SRGB_ANGLEX 0x6AC2
205#define GL_BGRA8_TYPELESS_ANGLEX 0x6AC3
206#define GL_BGRA8_TYPELESS_SRGB_ANGLEX 0x6AC4
207
Frank Henigman95fb2a12018-05-27 20:17:05 -0400208#define GL_R8_SSCALED_ANGLEX 0x6AC6
209#define GL_RG8_SSCALED_ANGLEX 0x6AC7
210#define GL_RGB8_SSCALED_ANGLEX 0x6AC8
211#define GL_RGBA8_SSCALED_ANGLEX 0x6AC9
212#define GL_R8_USCALED_ANGLEX 0x6ACA
213#define GL_RG8_USCALED_ANGLEX 0x6ACB
214#define GL_RGB8_USCALED_ANGLEX 0x6ACC
215#define GL_RGBA8_USCALED_ANGLEX 0x6ACD
216
217#define GL_R16_SSCALED_ANGLEX 0x6ACE
218#define GL_RG16_SSCALED_ANGLEX 0x6ACF
219#define GL_RGB16_SSCALED_ANGLEX 0x6AD0
220#define GL_RGBA16_SSCALED_ANGLEX 0x6AD1
221#define GL_R16_USCALED_ANGLEX 0x6AD2
222#define GL_RG16_USCALED_ANGLEX 0x6AD3
223#define GL_RGB16_USCALED_ANGLEX 0x6AD4
224#define GL_RGBA16_USCALED_ANGLEX 0x6AD5
225
226#define GL_R32_SSCALED_ANGLEX 0x6AD6
227#define GL_RG32_SSCALED_ANGLEX 0x6AD7
228#define GL_RGB32_SSCALED_ANGLEX 0x6AD8
229#define GL_RGBA32_SSCALED_ANGLEX 0x6AD9
230#define GL_R32_USCALED_ANGLEX 0x6ADA
231#define GL_RG32_USCALED_ANGLEX 0x6ADB
232#define GL_RGB32_USCALED_ANGLEX 0x6ADC
233#define GL_RGBA32_USCALED_ANGLEX 0x6ADD
234
235#define GL_R32_SNORM_ANGLEX 0x6ADE
236#define GL_RG32_SNORM_ANGLEX 0x6ADF
237#define GL_RGB32_SNORM_ANGLEX 0x6AE0
238#define GL_RGBA32_SNORM_ANGLEX 0x6AE1
239#define GL_R32_UNORM_ANGLEX 0x6AE2
240#define GL_RG32_UNORM_ANGLEX 0x6AE3
241#define GL_RGB32_UNORM_ANGLEX 0x6AE4
242#define GL_RGBA32_UNORM_ANGLEX 0x6AE5
243
244#define GL_R32_FIXED_ANGLEX 0x6AE6
245#define GL_RG32_FIXED_ANGLEX 0x6AE7
246#define GL_RGB32_FIXED_ANGLEX 0x6AE8
247#define GL_RGBA32_FIXED_ANGLEX 0x6AE9
248
249#define GL_RGB10_A2_SINT_ANGLEX 0x6AEA
250#define GL_RGB10_A2_SNORM_ANGLEX 0x6AEB
251#define GL_RGB10_A2_SSCALED_ANGLEX 0x6AEC
252#define GL_RGB10_A2_USCALED_ANGLEX 0x6AED
253
Jamie Madill6b873dd2018-07-12 23:56:30 -0400254// This internal enum is used to filter internal errors that are already handled.
255// TODO(jmadill): Remove this when refactor is done. http://anglebug.com/2491
256#define GL_INTERNAL_ERROR_ANGLEX 0x6AEE
257
Jamie Madillabfbc0f2018-10-09 12:48:52 -0400258#define ANGLE_CHECK_GL_ALLOC(context, result) \
259 ANGLE_CHECK(context, result, "Failed to allocate host memory", GL_OUT_OF_MEMORY)
Jamie Madille2e406c2016-06-02 13:04:10 -0400260
Jamie Madillabfbc0f2018-10-09 12:48:52 -0400261#define ANGLE_CHECK_GL_MATH(context, result) \
262 ANGLE_CHECK(context, result, "Integer overflow.", GL_INVALID_OPERATION)
Jamie Madilldec86232018-07-11 09:01:18 -0400263
Jamie Madill44183cc2017-08-01 12:48:34 -0400264// The below inlining code lifted from V8.
jchen103c76d592017-08-03 08:47:56 +0800265#if defined(__clang__) || (defined(__GNUC__) && defined(__has_attribute))
Jamie Madill44183cc2017-08-01 12:48:34 -0400266#define ANGLE_HAS_ATTRIBUTE_ALWAYS_INLINE (__has_attribute(always_inline))
267#define ANGLE_HAS___FORCEINLINE 0
268#elif defined(_MSC_VER)
269#define ANGLE_HAS_ATTRIBUTE_ALWAYS_INLINE 0
270#define ANGLE_HAS___FORCEINLINE 1
271#else
272#define ANGLE_HAS_ATTRIBUTE_ALWAYS_INLINE 0
273#define ANGLE_HAS___FORCEINLINE 0
274#endif
275
276#if defined(NDEBUG) && ANGLE_HAS_ATTRIBUTE_ALWAYS_INLINE
277#define ANGLE_INLINE inline __attribute__((always_inline))
278#elif defined(NDEBUG) && ANGLE_HAS___FORCEINLINE
279#define ANGLE_INLINE __forceinline
280#else
281#define ANGLE_INLINE inline
282#endif
283
Jamie Madill4fef7732018-05-29 15:21:41 -0400284#if defined(__clang__) || (defined(__GNUC__) && defined(__has_attribute))
285#if __has_attribute(noinline)
286#define ANGLE_NOINLINE __attribute__((noinline))
287#else
288#define ANGLE_NOINLINE
289#endif
290#elif defined(_MSC_VER)
291#define ANGLE_NOINLINE __declspec(noinline)
292#else
293#define ANGLE_NOINLINE
294#endif
295
Jamie Madill92996b02017-08-17 10:39:02 -0400296#ifndef ANGLE_STRINGIFY
297#define ANGLE_STRINGIFY(x) #x
298#endif
299
300#ifndef ANGLE_MACRO_STRINGIFY
301#define ANGLE_MACRO_STRINGIFY(x) ANGLE_STRINGIFY(x)
302#endif
303
Jamie Madill71c88b32017-09-14 22:20:29 -0400304// Detect support for C++17 [[nodiscard]]
305#if !defined(__has_cpp_attribute)
306#define __has_cpp_attribute(name) 0
307#endif // !defined(__has_cpp_attribute)
308
309#if __has_cpp_attribute(nodiscard)
310#define ANGLE_NO_DISCARD [[nodiscard]]
311#else
312#define ANGLE_NO_DISCARD
313#endif // __has_cpp_attribute(nodiscard)
314
Frank Henigman95fb2a12018-05-27 20:17:05 -0400315#endif // COMMON_ANGLEUTILS_H_