]> git.sesse.net Git - vlc/commitdiff
vout: add helpers for OpenGL context without video output
authorRémi Denis-Courmont <remi@remlab.net>
Sun, 12 Oct 2014 19:44:00 +0000 (22:44 +0300)
committerRémi Denis-Courmont <remi@remlab.net>
Thu, 16 Oct 2014 17:23:39 +0000 (20:23 +0300)
include/vlc_opengl.h
include/vlc_vout_window.h
src/libvlccore.sym
src/video_output/opengl.c

index 1cc8ca241beb974a17d3a4bf9486313cdaa1d17e..12d1b933d5bf414ee7ae9699a4744772f0294c2e 100644 (file)
@@ -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 */
index 6f38df4db61038fba482947028e7bb2e8a7877a0..1b766f5b7b07c32e90750ab2c7f3bdef63df32f1 100644 (file)
@@ -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;
 
index 1a35103cce92a92d1469e19284cef4f5ab8236e2..e3a90e6e7f3f1e8d845d34ae4cc88d6364f6a844 100644 (file)
@@ -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
index 95b61211967528b42ff5c73ffcb4a758a3e3712d..eedc04b6d2597f1702daacaa49b7d697c2f08b3f 100644 (file)
@@ -22,6 +22,9 @@
 # include <config.h>
 #endif
 
+#include <assert.h>
+#include <stdlib.h>
+
 #include <vlc_common.h>
 #include <vlc_opengl.h>
 #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 <vlc_vout_window.h>
+
+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);
+}