Branch data Line data Source code
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 : : #ifndef LIBPLACEBO_OPENGL_H_ 19 : : #define LIBPLACEBO_OPENGL_H_ 20 : : 21 : : #include <string.h> 22 : : 23 : : #include <libplacebo/gpu.h> 24 : : #include <libplacebo/swapchain.h> 25 : : 26 : : PL_API_BEGIN 27 : : 28 : : // Note on thread safety: The thread safety of `pl_opengl` and any associated 29 : : // GPU objects follows the same thread safety rules as the underlying OpenGL 30 : : // context. In other words, they must only be called from the thread the OpenGL 31 : : // context is current on. 32 : : 33 : : typedef const struct pl_opengl_t { 34 : : pl_gpu gpu; 35 : : 36 : : // Detected GL version 37 : : int major, minor; 38 : : 39 : : // List of GL/EGL extensions, provided for convenience 40 : : const char * const *extensions; 41 : : int num_extensions; 42 : : } *pl_opengl; 43 : : 44 : 42 : static inline bool pl_opengl_has_ext(pl_opengl gl, const char *ext) 45 : : { 46 [ + + ]: 8849 : for (int i = 0; i < gl->num_extensions; i++) 47 [ + + ]: 8833 : if (!strcmp(ext, gl->extensions[i])) 48 : : return true; 49 : : return false; 50 : : } 51 : : 52 : : typedef void (*pl_voidfunc_t)(void); 53 : : 54 : : struct pl_opengl_params { 55 : : // Main gl*GetProcAddr function. This will be used to load all GL/EGL 56 : : // functions. Optional - if unspecified, libplacebo will default to an 57 : : // internal loading logic which should work on most platforms. 58 : : pl_voidfunc_t (*get_proc_addr_ex)(void *proc_ctx, const char *procname); 59 : : void *proc_ctx; 60 : : 61 : : // Simpler API for backwards compatibility / convenience. (This one 62 : : // directly matches the signature of most gl*GetProcAddr library functions) 63 : : pl_voidfunc_t (*get_proc_addr)(const char *procname); 64 : : 65 : : // Enable OpenGL debug report callbacks. May have little effect depending 66 : : // on whether or not the GL context was initialized with appropriate 67 : : // debugging enabled. 68 : : bool debug; 69 : : 70 : : // Allow the use of (suspected) software rasterizers and renderers. These 71 : : // can be useful for debugging purposes, but normally, their use is 72 : : // undesirable when GPU-accelerated processing is expected. 73 : : bool allow_software; 74 : : 75 : : // Disables the use of compute shaders. Some devices/drivers perform better 76 : : // without them. This may also help prevent image corruption in cases where 77 : : // the driver is misbehaving. Some features may be disabled if this is set. 78 : : bool no_compute; 79 : : 80 : : // Restrict the maximum allowed GLSL version. (Mainly for testing) 81 : : int max_glsl_version; 82 : : 83 : : // Optional. Required when importing/exporting dmabufs as textures. 84 : : void *egl_display; 85 : : void *egl_context; 86 : : 87 : : // Optional callbacks to bind/release the OpenGL context on the current 88 : : // thread. If these are specified, then the resulting `pl_gpu` will have 89 : : // `pl_gpu_limits.thread_safe` enabled, and may therefore be used from any 90 : : // thread without first needing to bind the OpenGL context. 91 : : // 92 : : // If the user is re-using the same OpenGL context in non-libplacebo code, 93 : : // then these callbacks should include whatever synchronization is 94 : : // necessary to prevent simultaneous use between libplacebo and the user. 95 : : bool (*make_current)(void *priv); 96 : : void (*release_current)(void *priv); 97 : : void *priv; 98 : : }; 99 : : 100 : : // Default/recommended parameters 101 : : #define pl_opengl_params(...) (&(struct pl_opengl_params) { __VA_ARGS__ }) 102 : : PL_API extern const struct pl_opengl_params pl_opengl_default_params; 103 : : 104 : : // Creates a new OpenGL renderer based on the given parameters. This will 105 : : // internally use whatever platform-defined mechanism (WGL, X11, EGL) is 106 : : // appropriate for loading the OpenGL function calls, so the user doesn't need 107 : : // to pass in a `getProcAddress` callback. If `params` is left as NULL, it 108 : : // defaults to `&pl_opengl_default_params`. The context must be active when 109 : : // calling this function, and must remain active whenever calling any 110 : : // libplacebo function on the resulting `pl_opengl` or `pl_gpu`. 111 : : // 112 : : // Note that creating multiple `pl_opengl` instances from the same OpenGL 113 : : // context is undefined behavior. 114 : : PL_API pl_opengl pl_opengl_create(pl_log log, const struct pl_opengl_params *params); 115 : : 116 : : // All resources allocated from the `pl_gpu` contained by this `pl_opengl` must 117 : : // be explicitly destroyed by the user before calling `pl_opengl_destroy`. 118 : : PL_API void pl_opengl_destroy(pl_opengl *gl); 119 : : 120 : : // For a `pl_gpu` backed by `pl_opengl`, this function can be used to retrieve 121 : : // the underlying `pl_opengl`. Returns NULL for any other type of `gpu`. 122 : : PL_API pl_opengl pl_opengl_get(pl_gpu gpu); 123 : : 124 : : struct pl_opengl_framebuffer { 125 : : // ID of the framebuffer, or 0 to use the context's default framebuffer. 126 : : int id; 127 : : 128 : : // If true, then the framebuffer is assumed to be "flipped" relative to 129 : : // normal GL semantics, i.e. set this to `true` if the first pixel is the 130 : : // top left corner. 131 : : bool flipped; 132 : : }; 133 : : 134 : : struct pl_opengl_swapchain_params { 135 : : // Set this to the platform-specific function to swap buffers, e.g. 136 : : // glXSwapBuffers, eglSwapBuffers etc. This will be called internally by 137 : : // `pl_swapchain_swap_buffers`. Required, unless you never call that 138 : : // function. 139 : : void (*swap_buffers)(void *priv); 140 : : 141 : : // Initial framebuffer description. This can be changed later on using 142 : : // `pl_opengl_swapchain_update_fb`. 143 : : struct pl_opengl_framebuffer framebuffer; 144 : : 145 : : // Attempt forcing a specific latency. If this is nonzero, then 146 : : // `pl_swapchain_swap_buffers` will wait until fewer than N frames are "in 147 : : // flight" before returning. Setting this to a high number generally 148 : : // accomplished nothing, because the OpenGL driver typically limits the 149 : : // number of buffers on its own. But setting it to a low number like 2 or 150 : : // even 1 can reduce latency (at the cost of throughput). 151 : : int max_swapchain_depth; 152 : : 153 : : // Arbitrary user pointer that gets passed to `swap_buffers` etc. 154 : : void *priv; 155 : : }; 156 : : 157 : : #define pl_opengl_swapchain_params(...) (&(struct pl_opengl_swapchain_params) { __VA_ARGS__ }) 158 : : 159 : : // Creates an instance of `pl_swapchain` tied to the active context. 160 : : // Note: Due to OpenGL semantics, users *must* call `pl_swapchain_resize` 161 : : // before attempting to use this swapchain, otherwise calls to 162 : : // `pl_swapchain_start_frame` will fail. 163 : : PL_API pl_swapchain pl_opengl_create_swapchain(pl_opengl gl, 164 : : const struct pl_opengl_swapchain_params *params); 165 : : 166 : : // Update the framebuffer description. After calling this function, users 167 : : // *must* call `pl_swapchain_resize` before attempting to use the swapchain 168 : : // again, otherwise calls to `pl_swapchain_start_frame` will fail. 169 : : PL_API void pl_opengl_swapchain_update_fb(pl_swapchain sw, 170 : : const struct pl_opengl_framebuffer *fb); 171 : : 172 : : struct pl_opengl_wrap_params { 173 : : // The GLuint texture object itself. Optional. If no texture is provided, 174 : : // then only the opaque framebuffer `fbo` will be wrapped, leaving the 175 : : // resulting `pl_tex` object with some operations (such as sampling) being 176 : : // unsupported. 177 : : unsigned int texture; 178 : : 179 : : // The GLuint associated framebuffer. Optional. If this is not specified, 180 : : // then libplacebo will attempt creating a framebuffer from the provided 181 : : // texture object (if possible). 182 : : // 183 : : // Note: As a special case, if neither a texture nor an FBO are provided, 184 : : // this is equivalent to wrapping the OpenGL default framebuffer (id 0). 185 : : unsigned int framebuffer; 186 : : 187 : : // The image's dimensions (unused dimensions must be 0) 188 : : int width; 189 : : int height; 190 : : int depth; 191 : : 192 : : // Texture-specific fields: 193 : : // 194 : : // Note: These are only relevant if `texture` is provided. 195 : : 196 : : // The GLenum for the texture target to use, e.g. GL_TEXTURE_2D. Optional. 197 : : // If this is left as 0, the target is inferred from the number of 198 : : // dimensions. Users may want to set this to something specific like 199 : : // GL_TEXTURE_EXTERNAL_OES depending on the nature of the texture. 200 : : unsigned int target; 201 : : 202 : : // The texture's GLint sized internal format (e.g. GL_RGBA16F). Required. 203 : : int iformat; 204 : : }; 205 : : 206 : : #define pl_opengl_wrap_params(...) (&(struct pl_opengl_wrap_params) { __VA_ARGS__ }) 207 : : 208 : : // Wraps an external OpenGL object into a `pl_tex` abstraction. Due to the 209 : : // internally synchronized nature of OpenGL, no explicit synchronization 210 : : // is needed between libplacebo `pl_tex_` operations, and host accesses to 211 : : // the texture. Wrapping the same OpenGL texture multiple times is permitted. 212 : : // Note that this function transfers no ownership. 213 : : // 214 : : // This wrapper can be destroyed by simply calling `pl_tex_destroy` on it, 215 : : // which will *not* destroy the user-provided OpenGL texture or framebuffer. 216 : : // 217 : : // This function may fail, in which case it returns NULL. 218 : : PL_API pl_tex pl_opengl_wrap(pl_gpu gpu, const struct pl_opengl_wrap_params *params); 219 : : 220 : : // Analogous to `pl_opengl_wrap`, this function takes any `pl_tex` (including 221 : : // ones created by `pl_tex_create`) and unwraps it to expose the underlying 222 : : // OpenGL texture to the user. Note that this function transfers no ownership, 223 : : // i.e. the texture object and framebuffer shall not be destroyed by the user. 224 : : // 225 : : // Returns the OpenGL texture. `out_target` and `out_iformat` will be updated 226 : : // to hold the target type and internal format, respectively. (Optional) 227 : : // 228 : : // For renderable/blittable textures, `out_fbo` will be updated to the ID of 229 : : // the framebuffer attached to this texture, or 0 if there is none. (Optional) 230 : : PL_API unsigned int pl_opengl_unwrap(pl_gpu gpu, pl_tex tex, unsigned int *out_target, 231 : : int *out_iformat, unsigned int *out_fbo); 232 : : 233 : : PL_API_END 234 : : 235 : : #endif // LIBPLACEBO_OPENGL_H_