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