TGX 1.0.3
A tiny 2D/3D graphics library optimized for 32 bits microcontrollers.
Loading...
Searching...
No Matches
Misc.h
Go to the documentation of this file.
1
5//
6// Copyright 2020 Arvind Singh
7//
8// This library is free software; you can redistribute it and/or
9// modify it under the terms of the GNU Lesser General Public
10// License as published by the Free Software Foundation; either
11//version 2.1 of the License, or (at your option) any later version.
12//
13// This library is distributed in the hope that it will be useful,
14// but WITHOUT ANY WARRANTY; without even the implied warranty of
15// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the GNU
16// Lesser General Public License for more details.
17//
18// You should have received a copy of the GNU Lesser General Public
19// License along with this library; If not, see <http://www.gnu.org/licenses/>.
20
21#ifndef _TGX_MISC_H_
22#define _TGX_MISC_H_
23
24
25#include <stdint.h>
26#include <math.h>
27#include <string.h>
28
29
30// disable mtools extensions by default
31#ifndef MTOOLS_TGX_EXTENSIONS
32#define MTOOLS_TGX_EXTENSIONS 0
33#endif
34
35
36
37#if defined(TEENSYDUINO) || defined(ESP32) || defined(ARDUINO_ARCH_STM32)
38 #include "Arduino.h" // include Arduino to get PROGMEM macro and others
39 #define TGX_ON_ARDUINO
40
41 #define TGX_USE_FAST_INV_SQRT_TRICK
42 #define TGX_USE_FAST_SQRT_TRICK
43 //#define TGX_USE_FAST_INV_TRICK // bug and slower then regular inv anyway...
44
45 #define TGX_INLINE __attribute__((always_inline))
46 #define TGX_NOINLINE __attribute__((noinline, noclone)) FLASHMEM
47#else
48 #define TGX_INLINE
49 #define TGX_NOINLINE
50#endif
51
52#ifndef PROGMEM
53 #define PROGMEM
54#endif
55
56#ifndef FLASHMEM
57 #define FLASHMEM
58#endif
59
60
61/* */
62#ifndef TGX_SINGLE_PRECISION_COMPUTATIONS
63 #define TGX_SINGLE_PRECISION_COMPUTATIONS 1
64#endif
65
66
67#define TGX_DEFAULT_NO_BLENDING -1.0f
68
69
70#if defined(TEENSYDUINO) || defined(ESP32)
71/* Size of the cache when reading in PROGMEM. This value is used to try to optimize cache read to
72improve rendering speed when reading large image in flash... On teensy, 8K give good results.*/
73#define TGX_PROGMEM_DEFAULT_CACHE_SIZE 8192
74#else
75/* Size of the cache when reading in PROGMEM. This value is used to try to optimize cache read to
76improve rendering speed when reading large image in flash... Can use large value on CPU.*/
77#define TGX_PROGMEM_DEFAULT_CACHE_SIZE 262144
78#endif
79
80
82#define TGX_CAST32(a) ((int32_t)(a))
83
84
85// c++, no plain c
86#ifdef __cplusplus
87
88#define DEPRECATED(X) [[deprecated(" " X " ")]]
89
90
91// check that int is at least 4 bytes.
92static_assert(sizeof(int) >= 4, "The TGX library only works on 32 bits or 64 bits architecture. Sorry!");
93
94
95
96#if defined(ARDUINO_TEENSY41)
97
98 // check existence of external ram (EXTMEM).
99 extern "C" uint8_t external_psram_size;
100
101 // check is an address is in flash
102 #define TGX_IS_PROGMEM(X) ((((uint32_t)(X)) >= 0x60000000)&&(((uint32_t)(X)) < 0x70000000))
103
104 // check if an address is in external ram
105 #define TGX_IS_EXTMEM(X) ((((uint32_t)(X)) >= 0x70000000)&&(((uint32_t)(X)) < 0x80000000))
106
107#endif
108
109#ifndef M_PI
110#define M_PI 3.14159265358979323846
111#endif
112
113
114namespace tgx
115{
116
117
123 template<int N> struct DummyType
124 {
125 // nothing here :-)
126 };
127
128
134 template<bool BB1, bool BB2> struct DummyTypeBB
135 {
136 // nothing here :-)
137 };
138
139
141 template<typename T = int> struct DefaultFPType
142 {
143#if TGX_SINGLE_PRECISION_COMPUTATIONS
144 typedef float fptype;
145#else
146 typedef double fptype;
147#endif
148 };
149
150#if TGX_SINGLE_PRECISION_COMPUTATIONS
152 template<> struct DefaultFPType<double>
153 {
154 typedef double fptype;
155 };
156#endif
157
158
160 template <typename, typename> struct is_same { static const bool value = false; };
161 template <typename T> struct is_same<T, T> { static const bool value = true; };
162
163
165 TGX_INLINE inline uint16_t BigEndian16(uint16_t v)
166 {
167#ifdef __GNUC__
168 return __builtin_bswap16(v);
169#else
170 return ((v >> 8) | (v << 8));
171#endif
172 }
173
174
176 template<typename T> TGX_INLINE inline void swap(T& a, T& b) { T c(a); a = b; b = c; }
177
178
180 template<typename T> TGX_INLINE inline T min(const T & a, const T & b) { return((a < b) ? a : b); }
181
182
184 template<typename T> TGX_INLINE inline T max(const T & a, const T & b) { return((a > b) ? a : b); }
185
186
188 template<typename T> TGX_INLINE inline T clamp(const T & v, const T & vmin, const T & vmax)
189 {
190 return max(vmin, min(vmax, v));
191 }
192
193
195 TGX_INLINE inline float roundfp(const float f) { return roundf(f); }
196
197
199 TGX_INLINE inline double roundfp(const double f) { return round(f); }
200
201
202
206 TGX_INLINE inline int32_t safeMultB(int32_t A, int32_t B)
207 {
208 if ((A == 0) || (B == 0)) return B;
209 const int32_t max32 = 2147483647;
210 const int32_t nB = max32 / ((A > 0) ? A : (-A));
211 return ((B <= nB) ? B : nB);
212 }
213
214
215
219 TGX_INLINE inline float fast_inv(float x)
220 {
221#if defined (TGX_USE_FAST_INV_TRICK)
222 union
223 {
224 float f;
225 uint32_t u;
226 } v;
227 v.f = x;
228 v.u = 0x5f375a86 - (v.u >> 1); // slightly more precise than the original 0x5f3759df
229 const float x2 = x * 0.5f;
230 const float threehalfs = 1.5f;
231 v.f = v.f * (threehalfs - (x2 * v.f * v.f)); // 1st iteration
232// v.f = v.f * (threehalfs - (x2 * v.f * v.f)); // 2nd iteration (not needed)
233 return v.f * v.f;
234#else
235 return ((x == 0) ? 1.0f : (1.0f / x));
236#endif
237 }
238
239
243 TGX_INLINE inline double fast_inv(double x)
244 {
245 // do not use fast approximation for double type.
246 return ((x == 0) ? 1.0 : (1.0 / x));
247 }
248
249
250
254 TGX_INLINE inline float precise_sqrt(float x)
255 {
256 return sqrtf(x);
257 }
258
259
263 TGX_INLINE inline double precise_sqrt(double x)
264 {
265 return sqrt(x);
266 }
267
268
272 TGX_INLINE inline float fast_sqrt(float x)
273 {
274#if defined (TGX_USE_FAST_SQRT_TRICK)
275 union
276 {
277 float f;
278 uint32_t u;
279 } v;
280 v.f = x;
281 v.u = 0x5f375a86 - (v.u >> 1); // slightly more precise than the original 0x5f3759df
282 const float x2 = x * 0.5f;
283 const float threehalfs = 1.5f;
284 v.f = v.f * (threehalfs - (x2 * v.f * v.f)); // 1st iteration
285// v.f = v.f * (threehalfs - (x2 * v.f * v.f)); // 2nd iteration (not needed)
286 return x * v.f;
287#else
288 return precise_sqrt(x);
289#endif
290 }
291
292
296 TGX_INLINE inline double fast_sqrt(double x)
297 {
298 // do not use fast approximation for double type.
299 return precise_sqrt(x);
300 }
301
302
306 TGX_INLINE inline float precise_invsqrt(float x)
307 {
308 const float s = sqrtf(x);
309 return (s == 0) ? 1.0f : (1.0f / s);
310 }
311
312
316 TGX_INLINE inline double precise_invsqrt(double x)
317 {
318 const double s = sqrt(x);
319 return (s == 0) ? 1.0 : (1.0 / sqrt(s));
320 }
321
322
326 TGX_INLINE inline float fast_invsqrt(float x)
327 {
328#if defined (TGX_USE_FAST_INV_SQRT_TRICK)
329 // fast reciprocal square root : https://en.wikipedia.org/wiki/Fast_inverse_square_root
330 //github.com/JarkkoPFC/meshlete/blob/master/src/core/math/fast_math.inl
331 union
332 {
333 float f;
334 uint32_t u;
335 } v;
336 v.f = x;
337 v.u = 0x5f375a86 - (v.u >> 1); // slightly more precise than the original 0x5f3759df
338 const float x2 = x * 0.5f;
339 const float threehalfs = 1.5f;
340 v.f = v.f * (threehalfs - (x2 * v.f * v.f)); // 1st iteration
341// v.f = v.f * (threehalfs - (x2 * v.f * v.f)); // 2nd iteration (not needed)
342 return v.f;
343#else
344 return precise_invsqrt(x);
345#endif
346 }
347
348
352 TGX_INLINE inline double fast_invsqrt(double x)
353 {
354 // do not use fast approximation for double type.
355 return precise_invsqrt(x);
356 }
357
358}
359
360#endif
361
362#endif
363
364
TGX_INLINE T min(const T &a, const T &b)
Don't know why but faster than fminf() for floats.
Definition: Misc.h:180
TGX_INLINE T max(const T &a, const T &b)
Don't know why but much faster than fmaxf() for floats.
Definition: Misc.h:184
TGX_INLINE T clamp(const T &v, const T &vmin, const T &vmax)
Template clamp version.
Definition: Misc.h:188
TGX_INLINE void swap(T &a, T &b)
Baby let me swap you one more time...
Definition: Misc.h:176
TGX_INLINE int32_t safeMultB(int32_t A, int32_t B)
Return a value smaller or equal to B such that the multiplication by A is safe (no overflow with int3...
Definition: Misc.h:206
TGX_INLINE float fast_invsqrt(float x)
Compute a fast approximation of the inverse square root of a float.
Definition: Misc.h:326
TGX_INLINE float precise_sqrt(float x)
Compute the square root of a float (exact computation).
Definition: Misc.h:254
TGX_INLINE float roundfp(const float f)
Rounding for floats.
Definition: Misc.h:195
TGX_INLINE float precise_invsqrt(float x)
Compute the inverse square root of a float (exact computation).
Definition: Misc.h:306
TGX_INLINE float fast_sqrt(float x)
Compute a fast approximation of the square root of a float.
Definition: Misc.h:272
TGX_INLINE float fast_inv(float x)
Fast (approximate) computation of 1/x.
Definition: Misc.h:219
TGX_INLINE uint16_t BigEndian16(uint16_t v)
little endian / big endian conversion
Definition: Misc.h:165