Skip to content

Commit b2e14d4

Browse files
author
sparks
committed
vo_libmpv: introduce 'gpu-next' render backend
1 parent ee0f701 commit b2e14d4

File tree

11 files changed

+1820
-48
lines changed

11 files changed

+1820
-48
lines changed

include/mpv/render.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -422,6 +422,16 @@ typedef enum mpv_render_param_type {
422422
* See MPV_RENDER_PARAM_SW_STRIDE for alignment requirements.
423423
*/
424424
MPV_RENDER_PARAM_SW_POINTER = 20,
425+
/**
426+
* The name of the render backend to use. Valid for mpv_render_context_create().
427+
*
428+
* Type: char*
429+
*
430+
* Defined backends:
431+
* "gpu" (default)
432+
* "gpu-next"
433+
*/
434+
MPV_RENDER_PARAM_BACKEND = 21,
425435
} mpv_render_param_type;
426436

427437
/**

meson.build

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,9 @@ sources = files(
237237
'video/out/gpu/utils.c',
238238
'video/out/gpu/video.c',
239239
'video/out/gpu/video_shaders.c',
240+
'video/out/gpu_next/libmpv_gpu_next.c',
241+
'video/out/gpu_next/ra.c',
242+
'video/out/gpu_next/video.c',
240243
'video/out/libmpv_sw.c',
241244
'video/out/vo.c',
242245
'video/out/vo_gpu.c',

video/out/gpu_next/context.c

Lines changed: 208 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -15,22 +15,32 @@
1515
* License along with mpv. If not, see <https://www.gnu.org/licenses/>.
1616
*/
1717

18-
#include <libplacebo/config.h>
18+
#include <libplacebo/config.h> // for PL_HAVE_OPENGL, PL_API_VER
1919

2020
#ifdef PL_HAVE_D3D11
2121
#include <libplacebo/d3d11.h>
2222
#endif
2323

2424
#ifdef PL_HAVE_OPENGL
25-
#include <libplacebo/opengl.h>
25+
#include "mpv/render_gl.h" // for mpv_opengl_init_params
26+
#include <libplacebo/opengl.h> // for pl_opengl_destroy
27+
#include "video/out/gpu_next/libmpv_gpu_next.h" // for libmpv_gpu_next_context
28+
#include "video/out/gpu_next/ra.h" // for ra_pl_create, ra_pl_...
2629
#endif
2730

28-
#include "context.h"
29-
#include "config.h"
30-
#include "common/common.h"
31-
#include "options/m_config.h"
32-
#include "video/out/placebo/utils.h"
33-
#include "video/out/gpu/video.h"
31+
#include <stddef.h> // for NULL
32+
#include "config.h" // for HAVE_GL, HAVE_D3D11
33+
#include "context.h" // for gpu_ctx
34+
#include "common/msg.h" // for MP_ERR, mp_msg, mp_msg_err
35+
#include "mpv/client.h" // for mpv_error
36+
#include "mpv/render.h" // for mpv_render_param
37+
#include "options/options.h" // for mp_vo_opts
38+
#include "ta/ta_talloc.h" // for talloc_zero, talloc_...
39+
#include "video/out/gpu/context.h" // for ra_ctx_opts, ra_ctx
40+
#include "video/out/libmpv.h" // for get_mpv_render_param
41+
#include "video/out/opengl/common.h" // for GL
42+
#include "video/out/placebo/utils.h" // for mppl_log_set_probing
43+
#include "video/out/vo.h" // for vo
3444

3545
#if HAVE_D3D11
3646
#include "osdep/windows_utils.h"
@@ -39,15 +49,27 @@
3949
#endif
4050

4151
#if HAVE_GL
42-
#include "video/out/opengl/context.h"
43-
#include "video/out/opengl/ra_gl.h"
52+
#include "video/out/opengl/ra_gl.h" // for ra_is_gl, ra_gl_get
4453
# if HAVE_EGL
45-
#include <EGL/egl.h>
54+
#include <EGL/egl.h> // for eglGetCurrentContext
4655
# endif
4756
#endif
4857

4958
#if HAVE_VULKAN
50-
#include "video/out/vulkan/context.h"
59+
#include "video/out/vulkan/context.h" // for ra_vk_ctx_get
60+
#endif
61+
62+
#if HAVE_GL
63+
// Store Libplacebo OpenGL context information.
64+
struct priv {
65+
pl_log pl_log;
66+
pl_opengl gl;
67+
pl_gpu gpu;
68+
struct ra_next *ra;
69+
70+
// Store a persistent copy of the init params to avoid a dangling pointer.
71+
mpv_opengl_init_params gl_params;
72+
};
5173
#endif
5274

5375
#if HAVE_D3D11
@@ -235,3 +257,177 @@ void gpu_ctx_destroy(struct gpu_ctx **ctxp)
235257
talloc_free(ctx);
236258
*ctxp = NULL;
237259
}
260+
261+
#if HAVE_GL && defined(PL_HAVE_OPENGL)
262+
/**
263+
* @brief Callback to make the OpenGL context current.
264+
* @param priv Pointer to the private data (mpv_opengl_init_params).
265+
* @return True on success, false on failure.
266+
*/
267+
static bool pl_callback_makecurrent_gl(void *priv)
268+
{
269+
mpv_opengl_init_params *gl_params = priv;
270+
// The mpv render API contract specifies that the client must make the
271+
// context current inside its get_proc_address callback. We can trigger
272+
// this by calling it with a harmless, common function name.
273+
if (gl_params && gl_params->get_proc_address) {
274+
gl_params->get_proc_address(gl_params->get_proc_address_ctx, "glGetString");
275+
return true;
276+
}
277+
278+
return false;
279+
}
280+
281+
/**
282+
* @brief Callback to release the OpenGL context.
283+
* @param priv Pointer to the private data (mpv_opengl_init_params).
284+
*/
285+
static void pl_callback_releasecurrent_gl(void *priv)
286+
{
287+
}
288+
289+
/**
290+
* @brief Callback to log messages from libplacebo.
291+
* @param log_priv Pointer to the private data (mp_log).
292+
* @param level The log level.
293+
* @param msg The log message.
294+
*/
295+
static void pl_log_cb(void *log_priv, enum pl_log_level level, const char *msg)
296+
{
297+
struct mp_log *log = log_priv;
298+
mp_msg(log, MSGL_WARN, "[gpu-next:pl] %s\n", msg);
299+
}
300+
301+
/**
302+
* @brief Initializes the OpenGL context for the GPU next renderer.
303+
* @param ctx The libmpv_gpu_next_context to initialize.
304+
* @param params The render parameters.
305+
* @return 0 on success, negative error code on failure.
306+
*/
307+
static int libmpv_gpu_next_init_gl(struct libmpv_gpu_next_context *ctx, mpv_render_param *params)
308+
{
309+
ctx->priv = talloc_zero(NULL, struct priv);
310+
struct priv *p = ctx->priv;
311+
312+
mpv_opengl_init_params *gl_params =
313+
get_mpv_render_param(params, MPV_RENDER_PARAM_OPENGL_INIT_PARAMS, NULL);
314+
if (!gl_params || !gl_params->get_proc_address)
315+
return MPV_ERROR_INVALID_PARAMETER;
316+
317+
// Make a persistent copy of the params struct's contents.
318+
p->gl_params = *gl_params;
319+
320+
// Setup libplacebo logging
321+
struct pl_log_params log_params = {
322+
.log_level = PL_LOG_DEBUG
323+
};
324+
325+
// Enable verbose logging if trace is enabled
326+
if (mp_msg_test(ctx->log, MSGL_TRACE)) {
327+
log_params.log_cb = pl_log_cb;
328+
log_params.log_priv = ctx->log;
329+
}
330+
331+
p->pl_log = pl_log_create(PL_API_VER, &log_params);
332+
p->gl = pl_opengl_create(p->pl_log, pl_opengl_params(
333+
.get_proc_addr_ex = (pl_voidfunc_t (*)(void*, const char*))gl_params->get_proc_address,
334+
.proc_ctx = gl_params->get_proc_address_ctx,
335+
.make_current = pl_callback_makecurrent_gl,
336+
.release_current = pl_callback_releasecurrent_gl,
337+
.priv = &p->gl_params // Pass the ADDRESS of our persistent copy
338+
));
339+
340+
if (!p->gl) {
341+
MP_ERR(ctx, "Failed to create libplacebo OpenGL context.\n");
342+
pl_log_destroy(&p->pl_log);
343+
return MPV_ERROR_UNSUPPORTED;
344+
}
345+
p->gpu = p->gl->gpu;
346+
347+
// Pass the libplacebo log to the RA as well.
348+
p->ra = ra_pl_create(p->gpu, ctx->log, p->pl_log);
349+
if (!p->ra) {
350+
pl_opengl_destroy(&p->gl);
351+
pl_log_destroy(&p->pl_log);
352+
return MPV_ERROR_VO_INIT_FAILED;
353+
}
354+
355+
ctx->ra = p->ra;
356+
ctx->gpu = p->gpu;
357+
return 0;
358+
}
359+
360+
/**
361+
* @brief Wraps an OpenGL framebuffer object (FBO) as a libplacebo texture.
362+
* @param ctx The libmpv_gpu_next_context.
363+
* @param params The render parameters.
364+
* @param out_tex Pointer to the output texture.
365+
* @return 0 on success, negative error code on failure.
366+
*/
367+
static int libmpv_gpu_next_wrap_fbo_gl(struct libmpv_gpu_next_context *ctx,
368+
mpv_render_param *params, pl_tex *out_tex)
369+
{
370+
struct priv *p = ctx->priv;
371+
*out_tex = NULL;
372+
373+
// Get the FBO from the render parameters
374+
mpv_opengl_fbo *fbo =
375+
get_mpv_render_param(params, MPV_RENDER_PARAM_OPENGL_FBO, NULL);
376+
if (!fbo)
377+
return MPV_ERROR_INVALID_PARAMETER;
378+
379+
// Wrap the FBO as a libplacebo texture
380+
pl_tex tex = pl_opengl_wrap(p->gpu, pl_opengl_wrap_params(
381+
.framebuffer = fbo->fbo,
382+
.width = fbo->w,
383+
.height = fbo->h,
384+
.iformat = fbo->internal_format
385+
));
386+
387+
if (!tex) {
388+
MP_ERR(ctx, "Failed to wrap provided FBO as a libplacebo texture.\n");
389+
return MPV_ERROR_GENERIC;
390+
}
391+
392+
*out_tex = tex;
393+
return 0;
394+
}
395+
396+
/**
397+
* @brief Callback to mark the end of a frame rendering.
398+
* @param ctx The libmpv_gpu_next_context.
399+
*/
400+
static void libmpv_gpu_next_done_frame_gl(struct libmpv_gpu_next_context *ctx)
401+
{
402+
// Nothing to do (yet), leaving the function empty.
403+
}
404+
405+
/**
406+
* @brief Destroys the OpenGL context for the GPU next renderer.
407+
* @param ctx The libmpv_gpu_next_context to destroy.
408+
*/
409+
static void libmpv_gpu_next_destroy_gl(struct libmpv_gpu_next_context *ctx)
410+
{
411+
struct priv *p = ctx->priv;
412+
if (!p)
413+
return;
414+
415+
if (p->ra) {
416+
ra_pl_destroy(&p->ra);
417+
}
418+
419+
pl_opengl_destroy(&p->gl);
420+
pl_log_destroy(&p->pl_log);
421+
}
422+
423+
/**
424+
* @brief Context functions for the OpenGL GPU next renderer.
425+
*/
426+
const struct libmpv_gpu_next_context_fns libmpv_gpu_next_context_gl = {
427+
.api_name = MPV_RENDER_API_TYPE_OPENGL,
428+
.init = libmpv_gpu_next_init_gl,
429+
.wrap_fbo = libmpv_gpu_next_wrap_fbo_gl,
430+
.done_frame = libmpv_gpu_next_done_frame_gl,
431+
.destroy = libmpv_gpu_next_destroy_gl,
432+
};
433+
#endif

video/out/gpu_next/context.h

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,20 @@
1717

1818
#pragma once
1919

20-
#include <libplacebo/renderer.h>
20+
#include "libplacebo/gpu.h" // for pl_gpu
21+
#include "libplacebo/log.h" // for pl_log
22+
#include "libplacebo/swapchain.h" // for pl_swapchain
23+
#include "stdbool.h" // for bool
2124

22-
struct mp_log;
23-
struct ra_ctx;
25+
/**
26+
* The rendering abstraction context.
27+
*/
2428
struct ra_ctx_opts;
2529
struct vo;
2630

31+
/**
32+
* The main GPU context structure.
33+
*/
2734
struct gpu_ctx {
2835
struct mp_log *log;
2936
struct ra_ctx *ra_ctx;

0 commit comments

Comments
 (0)