From 39f52871791f36d28c48750c0793358c9d1077e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20Denis-Courmont?= Date: Sun, 12 Oct 2014 22:44:00 +0300 Subject: [PATCH] vout: add helpers for OpenGL context without video output --- include/vlc_opengl.h | 7 +++ include/vlc_vout_window.h | 2 +- src/libvlccore.sym | 3 ++ src/video_output/opengl.c | 101 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 112 insertions(+), 1 deletion(-) diff --git a/include/vlc_opengl.h b/include/vlc_opengl.h index 1cc8ca241b..12d1b933d5 100644 --- a/include/vlc_opengl.h +++ b/include/vlc_opengl.h @@ -30,6 +30,7 @@ */ struct vout_window_t; +struct vout_window_cfg_t; /** * A VLC GL context (and its underlying surface) @@ -92,4 +93,10 @@ static inline void *vlc_gl_GetProcAddress(vlc_gl_t *gl, const char *name) return (gl->getProcAddress != NULL) ? gl->getProcAddress(gl, name) : NULL; } +VLC_API vlc_gl_t *vlc_gl_surface_Create(vlc_object_t *, + const struct vout_window_cfg_t *, + struct vout_window_t **) VLC_USED; +VLC_API bool vlc_gl_surface_CheckSize(vlc_gl_t *, unsigned *w, unsigned *h); +VLC_API void vlc_gl_surface_Destroy(vlc_gl_t *); + #endif /* VLC_GL_H */ diff --git a/include/vlc_vout_window.h b/include/vlc_vout_window.h index 6f38df4db6..1b766f5b7b 100644 --- a/include/vlc_vout_window.h +++ b/include/vlc_vout_window.h @@ -61,7 +61,7 @@ enum { VOUT_WINDOW_SET_FULLSCREEN, /* int b_fullscreen */ }; -typedef struct { +typedef struct vout_window_cfg_t { /* If true, a standalone window is requested */ bool is_standalone; diff --git a/src/libvlccore.sym b/src/libvlccore.sym index 1a35103cce..e3a90e6e7f 100644 --- a/src/libvlccore.sym +++ b/src/libvlccore.sym @@ -601,6 +601,9 @@ vlc_epg_SetCurrent vlc_epg_Merge vlc_gl_Create vlc_gl_Destroy +vlc_gl_surface_Create +vlc_gl_surface_CheckSize +vlc_gl_surface_Destroy vlm_Control vlm_Delete vlm_ExecuteCommand diff --git a/src/video_output/opengl.c b/src/video_output/opengl.c index 95b6121196..eedc04b6d2 100644 --- a/src/video_output/opengl.c +++ b/src/video_output/opengl.c @@ -22,6 +22,9 @@ # include #endif +#include +#include + #include #include #include "libvlc.h" @@ -80,3 +83,101 @@ void vlc_gl_Destroy(vlc_gl_t *gl) module_unneed(gl, gl->module); vlc_object_release(gl); } + +#include + +typedef struct vlc_gl_surface +{ + int width; + int height; + vlc_mutex_t lock; +} vlc_gl_surface_t; + +static void vlc_gl_surface_ResizeNotify(vout_window_t *surface, + unsigned width, unsigned height) +{ + vlc_gl_surface_t *sys = surface->owner.sys; + + msg_Dbg(surface, "resized to %ux%u", width, height); + + vlc_mutex_lock(&sys->lock); + sys->width = width; + sys->height = height; + vlc_mutex_unlock(&sys->lock); +} + +vlc_gl_t *vlc_gl_surface_Create(vlc_object_t *obj, + const vout_window_cfg_t *cfg, + struct vout_window_t **restrict wp) +{ + vlc_gl_surface_t *sys = malloc(sizeof (*sys)); + if (unlikely(sys == NULL)) + return NULL; + + sys->width = cfg->width; + sys->height = cfg->height; + vlc_mutex_init(&sys->lock); + + vout_window_owner_t owner = { + .sys = sys, + .resized = vlc_gl_surface_ResizeNotify, + }; + + vout_window_t *surface = vout_window_New(obj, "$window", cfg, &owner); + if (surface == NULL) + goto error; + if (wp != NULL) + *wp = surface; + + /* TODO: support ES? */ + vlc_gl_t *gl = vlc_gl_Create(surface, VLC_OPENGL, "glx"); + if (gl == NULL) { + vout_window_Delete(surface); + goto error; + } + return gl; + +error: + vlc_mutex_destroy(&sys->lock); + free(sys); + return NULL; +} + +/** + * Checks if the dimensions of the surface used by the OpenGL context have + * changed (since the previous call), and the OpenGL viewport should be + * updated. + * \return true if at least one dimension has changed, false otherwise + * \warning This function is intrinsically race-prone. + * The dimensions can change asynchronously. + */ +bool vlc_gl_surface_CheckSize(vlc_gl_t *gl, unsigned *restrict width, + unsigned *restrict height) +{ + vout_window_t *surface = gl->surface; + vlc_gl_surface_t *sys = surface->owner.sys; + bool ret = false; + + vlc_mutex_lock(&sys->lock); + if (sys->width >= 0 && sys->height >= 0) + { + *width = sys->width; + *height = sys->height; + sys->width = -1; + sys->height = -1; + ret = true; + } + vlc_mutex_unlock(&sys->lock); + return ret; +} + +void vlc_gl_surface_Destroy(vlc_gl_t *gl) +{ + vout_window_t *surface = gl->surface; + vlc_gl_surface_t *sys = surface->owner.sys; + + vlc_gl_Destroy(gl); + vout_window_Delete(surface); + vlc_mutex_destroy(&sys->lock); + free(sys); +} -- GitLab