1 /*
2  * This file is part of libplacebo.
3  *
4  * libplacebo is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * libplacebo is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with libplacebo. If not, see <http://www.gnu.org/licenses/>.
16  */
17 
18 #pragma once
19 
20 #define __STDC_FORMAT_MACROS
21 #include <stdatomic.h>
22 #include <stdbool.h>
23 #include <stddef.h>
24 #include <stdint.h>
25 #include <stdlib.h>
26 #include <inttypes.h>
27 
28 #if defined(__MINGW32__) && !defined(__clang__)
29 #define PL_PRINTF(fmt, va) __attribute__ ((format(gnu_printf, fmt, va)))
30 #elif defined(__GNUC__)
31 #define PL_PRINTF(fmt, va) __attribute__ ((format(printf, fmt, va)))
32 #else
33 #define PL_PRINTF(fmt, va)
34 #endif
35 
36 #ifdef __unix__
37 #define PL_HAVE_UNIX
38 #endif
39 
40 #ifdef _WIN32
41 #define PL_HAVE_WIN32
42 #endif
43 
44 #include "config_internal.h"
45 #include "pl_assert.h"
46 #include "pl_alloc.h"
47 #include "pl_string.h"
48 
49 // Include all of the symbols that should be public in a way that marks them
50 // as being externally visible. (Otherwise, all symbols are hidden by default)
51 #pragma GCC visibility push(default)
52 
53 #include "config.h"
54 #undef PL_DEPRECATED
55 #define PL_DEPRECATED
56 
57 #include "include/libplacebo/colorspace.h"
58 #include "include/libplacebo/common.h"
59 #include "include/libplacebo/log.h"
60 #include "include/libplacebo/dispatch.h"
61 #include "include/libplacebo/dither.h"
62 #include "include/libplacebo/dummy.h"
63 #include "include/libplacebo/filters.h"
64 #include "include/libplacebo/gpu.h"
65 #include "include/libplacebo/renderer.h"
66 #include "include/libplacebo/shaders.h"
67 #include "include/libplacebo/shaders/av1.h"
68 #include "include/libplacebo/shaders/colorspace.h"
69 #include "include/libplacebo/shaders/custom.h"
70 #include "include/libplacebo/shaders/lut.h"
71 #include "include/libplacebo/shaders/sampling.h"
72 #include "include/libplacebo/swapchain.h"
73 #include "include/libplacebo/utils/frame_queue.h"
74 #include "include/libplacebo/utils/upload.h"
75 
76 #ifdef PL_HAVE_LCMS
77 #include "include/libplacebo/shaders/icc.h"
78 #endif
79 
80 #ifdef PL_HAVE_VULKAN
81 #include "include/libplacebo/vulkan.h"
82 #endif
83 
84 #ifdef PL_HAVE_OPENGL
85 #include "include/libplacebo/opengl.h"
86 #endif
87 
88 #ifdef PL_HAVE_D3D11
89 #include "include/libplacebo/d3d11.h"
90 #endif
91 
92 #pragma GCC visibility pop
93 
94 // Align up to the nearest multiple of an arbitrary alignment, which may also
95 // be 0 to signal no alignment requirements.
96 #define PL_ALIGN(x, align) ((align) ? ((x) + (align) - 1) / (align) * (align) : (x))
97 
98 // This is faster but must only be called on positive powers of two.
99 #define PL_ALIGN2(x, align) (((x) + (align) - 1) & ~((align) - 1))
100 
101 // Returns the log base 2 of an unsigned long long
102 #define PL_LOG2(x) ((unsigned) (8*sizeof (unsigned long long) - __builtin_clzll((x)) - 1))
103 
104 // Returns whether or not a number is a power of two (or zero)
105 #define PL_ISPOT(x) (((x) & ((x) - 1)) == 0)
106 
107 // Returns the size of a static array with known size.
108 #define PL_ARRAY_SIZE(s) (sizeof(s) / sizeof((s)[0]))
109 
110 // Swaps two variables
111 #define PL_SWAP(a, b)             \
112     do {                          \
113         __typeof__ (a) tmp = (a); \
114         (a) = (b);                \
115         (b) = tmp;                \
116     } while (0)
117 
118 // Helper functions for transposing a matrix in-place.
119 #define PL_TRANSPOSE_DIM(d, m) \
120     pl_transpose((d), (float[(d)*(d)]){0}, (const float *)(m))
121 
122 #define PL_TRANSPOSE_2X2(m) PL_TRANSPOSE_DIM(2, m)
123 #define PL_TRANSPOSE_3X3(m) PL_TRANSPOSE_DIM(3, m)
124 #define PL_TRANSPOSE_4X4(m) PL_TRANSPOSE_DIM(4, m)
125 
pl_transpose(int dim,float * out,const float * in)126 static inline float *pl_transpose(int dim, float *out, const float *in)
127 {
128     for (int i = 0; i < dim; i++) {
129         for (int j = 0; j < dim; j++)
130             out[i * dim + j] = in[j * dim + i];
131     }
132 
133     return out;
134 }
135 
136 // Helper functions for some common numeric operations (careful: double-eval)
137 #define PL_MAX(x, y) ((x) > (y) ? (x) : (y))
138 #define PL_MIN(x, y) ((x) < (y) ? (x) : (y))
139 #define PL_CLAMP(x, l, h) ((x) < (l) ? (l) : (x) > (h) ? (h) : (x))
140 #define PL_CMP(a, b) ((a) < (b) ? -1 : (a) > (b) ? 1 : 0)
141 #define PL_DEF(x, d) ((x) ? (x) : (d))
142 #define PL_SQUARE(x) ((x) * (x))
143 #define PL_CUBE(x) ((x) * (x) * (x))
144 
145 // Helpers for doing alignment calculations
pl_gcd(size_t x,size_t y)146 static inline size_t pl_gcd(size_t x, size_t y)
147 {
148     assert(x && y);
149     while (y) {
150         size_t tmp = y;
151         y = x % y;
152         x = tmp;
153     }
154 
155     return x;
156 }
157 
pl_lcm(size_t x,size_t y)158 static inline size_t pl_lcm(size_t x, size_t y)
159 {
160     assert(x && y);
161     return x * (y / pl_gcd(x, y));
162 }
163 
164 // Error checking macro for stuff with integer errors, aborts on failure
165 #define PL_CHECK_ERR(expr)                                                      \
166     do {                                                                        \
167         int _ret = (expr);                                                      \
168         if (_ret) {                                                             \
169             fprintf(stderr, "libplacebo: internal error: %s (%s:%d)\n",         \
170                     strerror(_ret), __FILE__, __LINE__);                        \
171             abort();                                                            \
172         }                                                                       \
173     } while (0)
174 
175 // Refcounting helpers
176 typedef _Atomic uint64_t pl_rc_t;
177 #define pl_rc_init(rc)  atomic_init(rc, 1)
178 #define pl_rc_ref(rc)   ((void) atomic_fetch_add_explicit(rc, 1, memory_order_acquire))
179 #define pl_rc_deref(rc) (atomic_fetch_sub_explicit(rc, 1, memory_order_release) == 1)
180 #define pl_rc_count(rc)  atomic_load(rc)
181 
182 #define pl_unreachable() (assert(!"unreachable"), __builtin_unreachable())
183