1 /* Copyright (C) 2017 the mpv developers 2 * Copyright (C) 2020 fence 3 * 4 * Permission to use, copy, modify, and/or distribute this software for any 5 * purpose with or without fee is hereby granted, provided that the above 6 * copyright notice and this permission notice appear in all copies. 7 * 8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 */ 16 17 module mpv.opengl_cb; 18 19 import mpv.client; 20 21 extern (C): 22 23 /** 24 * 25 * Overview 26 * -------- 27 * 28 * Warning: this API is deprecated. A very similar API is provided by render.h 29 * and render_gl.h. The deprecated API is emulated with the new API. 30 * 31 * This API can be used to make mpv render into a foreign OpenGL context. It 32 * can be used to handle video display. 33 * 34 * The renderer needs to be explicitly initialized with mpv_opengl_cb_init_gl(), 35 * and then video can be drawn with mpv_opengl_cb_draw(). The user thread can 36 * be notified by new frames with mpv_opengl_cb_set_update_callback(). 37 * 38 * You can output and embed video without this API by setting the mpv "wid" 39 * option to a native window handle (see "Embedding the video window" section 40 * in the client.h header). In general, using the opengl-cb API is recommended, 41 * because window embedding can cause various issues, especially with GUI 42 * toolkits and certain platforms. 43 * 44 * OpenGL interop 45 * -------------- 46 * 47 * This assumes the OpenGL context lives on a certain thread controlled by the 48 * API user. The following functions require access to the OpenGL context: 49 * mpv_opengl_cb_init_gl 50 * mpv_opengl_cb_draw 51 * mpv_opengl_cb_uninit_gl 52 * 53 * The OpenGL context is indirectly accessed through the OpenGL function 54 * pointers returned by the get_proc_address callback in mpv_opengl_cb_init_gl. 55 * Generally, mpv will not load the system OpenGL library when using this API. 56 * 57 * Only "desktop" OpenGL version 2.1 and later and OpenGL ES version 2.0 and 58 * later are supported. With OpenGL 2.1, the GL_ARB_texture_rg is required. The 59 * renderer was written for the OpenGL 3.x core profile, with additional support 60 * for OpenGL 2.1 and OpenGL ES 2.0. 61 * 62 * Note that some hardware decoding interop API (as set with the "hwdec" option) 63 * may actually access some sort of host API, such as EGL. 64 * 65 * OpenGL state 66 * ------------ 67 * 68 * OpenGL has a large amount of implicit state. All the mpv functions mentioned 69 * above expect that the OpenGL state is reasonably set to OpenGL standard 70 * defaults. Likewise, mpv will attempt to leave the OpenGL context with 71 * standard defaults. The following state is excluded from this: 72 * 73 * - the glViewport state 74 * - the glScissor state (but GL_SCISSOR_TEST is in its default value) 75 * - glBlendFuncSeparate() state (but GL_BLEND is in its default value) 76 * - glClearColor() state 77 * - mpv may overwrite the callback set with glDebugMessageCallback() 78 * - mpv always disables GL_DITHER at init 79 * 80 * Messing with the state could be avoided by creating shared OpenGL contexts, 81 * but this is avoided for the sake of compatibility and interoperability. 82 * 83 * On OpenGL 2.1, mpv will strictly call functions like glGenTextures() to 84 * create OpenGL objects. You will have to do the same. This ensures that 85 * objects created by mpv and the API users don't clash. Also, legacy state 86 * must be either in its defaults, or not interfere with core state. 87 * 88 * Threading 89 * --------- 90 * 91 * The mpv_opengl_cb_* functions can be called from any thread, under the 92 * following conditions: 93 * - only one of the mpv_opengl_cb_* functions can be called at the same time 94 * (unless they belong to different mpv cores created by mpv_create()) 95 * - for functions which need an OpenGL context (see above) the OpenGL context 96 * must be "current" in the current thread, and it must be the same context 97 * as used with mpv_opengl_cb_init_gl() 98 * - never can be called from within the callbacks set with 99 * mpv_set_wakeup_callback() or mpv_opengl_cb_set_update_callback() 100 * 101 * Context and handle lifecycle 102 * ---------------------------- 103 * 104 * Video initialization will fail if the OpenGL context was not initialized yet 105 * (with mpv_opengl_cb_init_gl()). Likewise, mpv_opengl_cb_uninit_gl() will 106 * disable video. 107 * 108 * When the mpv core is destroyed (e.g. via mpv_terminate_destroy()), the OpenGL 109 * context must have been uninitialized. If this doesn't happen, undefined 110 * behavior will result. 111 * 112 * Hardware decoding 113 * ----------------- 114 * 115 * Hardware decoding via opengl_cb is fully supported, but requires some 116 * additional setup. (At least if direct hardware decoding modes are wanted, 117 * instead of copying back surface data from GPU to CPU RAM.) 118 * 119 * While "normal" mpv loads the OpenGL hardware decoding interop on demand, 120 * this can't be done with opengl_cb for internal technical reasons. Instead, 121 * it loads them by default, even if hardware decoding is not going to be used. 122 * In older mpv releases, this had to be done by setting the 123 * "opengl-hwdec-interop" or "hwdec-preload" options before calling 124 * mpv_opengl_cb_init_gl(). You can still use the newer "gpu-hwdec-interop" 125 * option to prevent loading of interop, or to load only a specific interop. 126 * 127 * There may be certain requirements on the OpenGL implementation: 128 * - Windows: ANGLE is required (although in theory GL/DX interop could be used) 129 * - Intel/Linux: EGL is required, and also a glMPGetNativeDisplay() callback 130 * must be provided (see sections below) 131 * - nVidia/Linux: Both GLX and EGL should work (GLX is required if vdpau is 132 * used, e.g. due to old drivers.) 133 * - OSX: CGL is required (CGLGetCurrentContext() returning non-NULL) 134 * - iOS: EAGL is required (EAGLContext.currentContext returning non-nil) 135 * 136 * Once these things are setup, hardware decoding can be enabled/disabled at 137 * any time by setting the "hwdec" property. 138 * 139 * Special windowing system interop considerations 140 * ------------------------------------------------ 141 * 142 * In some cases, libmpv needs to have access to the windowing system's handles. 143 * This can be a pointer to a X11 "Display" for example. Usually this is needed 144 * only for hardware decoding. 145 * 146 * You can communicate these handles to libmpv by adding a pseudo-OpenGL 147 * extension "GL_MP_MPGetNativeDisplay" to the additional extension string when 148 * calling mpv_opengl_cb_init_gl(). The get_proc_address callback should resolve 149 * a function named "glMPGetNativeDisplay", which has the signature: 150 * 151 * void* GLAPIENTRY glMPGetNativeDisplay(const char* name) 152 * 153 * See below what names are defined. Usually, libmpv will use the native handle 154 * up until mpv_opengl_cb_uninit_gl() is called. If the name is not anything 155 * you know/expected, return NULL from the function. 156 */ 157 158 // Legacy - not supported anymore. 159 struct mpv_opengl_cb_window_pos 160 { 161 int x; // left coordinates of window (usually 0) 162 int y; // top coordinates of window (usually 0) 163 int width; // width of GL window 164 int height; // height of GL window 165 } 166 167 // Legacy - not supported anymore. 168 struct mpv_opengl_cb_drm_params 169 { 170 // DRM fd (int). set this to -1 if invalid. 171 int fd; 172 173 // currently used crtc id 174 int crtc_id; 175 176 // currently used connector id 177 int connector_id; 178 179 // pointer to the drmModeAtomicReq that is being used for the renderloop. 180 // This atomic request pointer should be usually created at every renderloop. 181 struct _drmModeAtomicReq; 182 _drmModeAtomicReq* atomic_request; 183 } 184 185 /** 186 * nVidia/Linux via VDPAU requires GLX, which does not have this problem (the 187 * GLX API can return the current X11 Display). 188 * 189 * Windowing system interop on MS win32 190 * ------------------------------------ 191 * 192 * You should use ANGLE, and make sure your application and libmpv are linked 193 * to the same ANGLE DLLs. libmpv will pick the device context (needed for 194 * hardware decoding) from the current ANGLE EGL context. 195 */ 196 197 /** 198 * Opaque context, returned by mpv_get_sub_api(MPV_SUB_API_OPENGL_CB). 199 * 200 * A context is bound to the mpv_handle it was retrieved from. The context 201 * will always be the same (for the same mpv_handle), and is valid until the 202 * mpv_handle it belongs to is released. 203 */ 204 struct mpv_opengl_cb_context; 205 206 alias mpv_opengl_cb_update_fn = void function (void* cb_ctx); 207 alias mpv_opengl_cb_get_proc_address_fn = void* function (void* fn_ctx, const(char)* name); 208 209 /** 210 * Set the callback that notifies you when a new video frame is available, or 211 * if the video display configuration somehow changed and requires a redraw. 212 * Similar to mpv_set_wakeup_callback(), you must not call any mpv API from 213 * the callback, and all the other listed restrictions apply (such as not 214 * exiting the callback by throwing exceptions). 215 * 216 * @param callback callback(callback_ctx) is called if the frame should be 217 * redrawn 218 * @param callback_ctx opaque argument to the callback 219 */ 220 void mpv_opengl_cb_set_update_callback ( 221 mpv_opengl_cb_context* ctx, 222 mpv_opengl_cb_update_fn callback, 223 void* callback_ctx); 224 225 /** 226 * Initialize the mpv OpenGL state. This retrieves OpenGL function pointers via 227 * get_proc_address, and creates OpenGL objects needed by mpv internally. It 228 * will also call APIs needed for rendering hardware decoded video in OpenGL, 229 * according to the mpv "hwdec" option. 230 * 231 * You must free the associated state at some point by calling the 232 * mpv_opengl_cb_uninit_gl() function. Not doing so may result in memory leaks 233 * or worse. 234 * 235 * @param exts optional _additional_ extension string, can be NULL 236 * @param get_proc_address callback used to retrieve function pointers to OpenGL 237 * functions. This is used for both standard functions 238 * and extension functions. (The extension string is 239 * checked whether extensions are really available.) 240 * The callback will be called from this function only 241 * (it is not stored and never used later). 242 * Usually, GL context APIs do this for you (e.g. with 243 * glXGetProcAddressARB or wglGetProcAddress), but 244 * some APIs do not always return pointers for all 245 * standard functions (even if present); in this case 246 * you have to compensate by looking up these functions 247 * yourself. 248 * @param get_proc_address_ctx arbitrary opaque user context passed to the 249 * get_proc_address callback 250 * @return error code (same as normal mpv_* API), including but not limited to: 251 * MPV_ERROR_UNSUPPORTED: the OpenGL version is not supported 252 * (or required extensions are missing) 253 * MPV_ERROR_INVALID_PARAMETER: the OpenGL state was already initialized 254 */ 255 int mpv_opengl_cb_init_gl ( 256 mpv_opengl_cb_context* ctx, 257 const(char)* exts, 258 mpv_opengl_cb_get_proc_address_fn get_proc_address, 259 void* get_proc_address_ctx); 260 261 /** 262 * Render video. Requires that the OpenGL state is initialized. 263 * 264 * The video will use the full provided framebuffer. Options like "panscan" are 265 * applied to determine which part of the video should be visible and how the 266 * video should be scaled. You can change these options at runtime by using the 267 * mpv property API. 268 * 269 * The renderer will reconfigure itself every time the output rectangle/size 270 * is changed. (If you want to do animations, it might be better to do the 271 * animation on a FBO instead.) 272 * 273 * This function implicitly pulls a video frame from the internal queue and 274 * renders it. If no new frame is available, the previous frame is redrawn. 275 * The update callback set with mpv_opengl_cb_set_update_callback() notifies 276 * you when a new frame was added. 277 * 278 * @param fbo The framebuffer object to render on. Because the renderer might 279 * manage multiple FBOs internally for the purpose of video 280 * postprocessing, it will always bind and unbind FBOs itself. If 281 * you want mpv to render on the main framebuffer, pass 0. 282 * @param w Width of the framebuffer. This is either the video size if the fbo 283 * parameter is 0, or the allocated size of the texture backing the 284 * fbo. The renderer will always use the full size of the fbo. 285 * @param h Height of the framebuffer. Same as with the w parameter, except 286 * that this parameter can be negative. In this case, the video 287 * frame will be rendered flipped. 288 * @return 0 289 */ 290 int mpv_opengl_cb_draw (mpv_opengl_cb_context* ctx, int fbo, int w, int h); 291 292 /** 293 * Deprecated. Use mpv_opengl_cb_draw(). This function is equivalent to: 294 * 295 * int mpv_opengl_cb_render(mpv_opengl_cb_context *ctx, int fbo, int vp[4]) 296 * { return mpv_opengl_cb_draw(ctx, fbo, vp[2], vp[3]); } 297 * 298 * vp[0] and vp[1] used to have a meaning, but are ignored in newer versions. 299 * 300 * This function will be removed in the future without version bump (this API 301 * was never marked as stable). 302 */ 303 int mpv_opengl_cb_render (mpv_opengl_cb_context* ctx, int fbo, ref int[4] vp); 304 305 /** 306 * Tell the renderer that a frame was flipped at the given time. This is 307 * optional, but can help the player to achieve better timing. 308 * 309 * Note that calling this at least once informs libmpv that you will use this 310 * function. If you use it inconsistently, expect bad video playback. 311 * 312 * If this is called while no video or no OpenGL is initialized, it is ignored. 313 * 314 * @param time The mpv time (using mpv_get_time_us()) at which the flip call 315 * returned. If 0 is passed, mpv_get_time_us() is used instead. 316 * Currently, this parameter is ignored. 317 * @return error code 318 */ 319 int mpv_opengl_cb_report_flip (mpv_opengl_cb_context* ctx, long time); 320 321 /** 322 * Destroy the mpv OpenGL state. 323 * 324 * If video is still active (e.g. a file playing), video will be disabled 325 * forcefully. 326 * 327 * Calling this multiple times is ok. 328 * 329 * @return error code 330 */ 331 int mpv_opengl_cb_uninit_gl (mpv_opengl_cb_context* ctx); 332 333 /* else #if MPV_ENABLE_DEPRECATED */ 334