diff --git a/include/vlc_opengl.h b/include/vlc_opengl.h index 3ffac813c8..2b6430482d 100644 --- a/include/vlc_opengl.h +++ b/include/vlc_opengl.h @@ -49,7 +49,13 @@ enum vlc_gl_api_type { VLC_OPENGL_ES2, }; -typedef int (*vlc_gl_activate)(vlc_gl_t *, unsigned width, unsigned height); +struct vlc_gl_cfg +{ + bool need_alpha; /* False by default */ +}; + +typedef int (*vlc_gl_activate)(vlc_gl_t *, unsigned width, unsigned height, + const struct vlc_gl_cfg *cfg); #define set_callback_opengl_common(activate) \ { \ @@ -122,14 +128,17 @@ struct vlc_gl_t * @param cfg initial configuration (including window to use as OpenGL surface) * @param flags OpenGL context type * @param name module name (or NULL for auto) + * @param gl_cfg OpenGL configuration (or NULL for default) * @return a new context, or NULL on failure */ VLC_API vlc_gl_t *vlc_gl_Create(const struct vout_display_cfg *cfg, - unsigned flags, const char *name) VLC_USED; + unsigned flags, const char *name, + const struct vlc_gl_cfg *gl_cfg) VLC_USED; VLC_API vlc_gl_t *vlc_gl_CreateOffscreen(vlc_object_t *parent, struct vlc_decoder_device *device, unsigned width, unsigned height, - unsigned flags, const char *name); + unsigned flags, const char *name, + const struct vlc_gl_cfg *gl_cfg); VLC_API void vlc_gl_Delete(vlc_gl_t *); @@ -184,7 +193,9 @@ static inline void *vlc_gl_GetProcAddress(vlc_gl_t *gl, const char *name) VLC_API vlc_gl_t *vlc_gl_surface_Create(vlc_object_t *, const struct vlc_window_cfg *, - struct vlc_window **) VLC_USED; + struct vlc_window **, + const struct vlc_gl_cfg *) 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 *); diff --git a/modules/video_filter/egl_pbuffer.c b/modules/video_filter/egl_pbuffer.c index e1525e7f02..bf0dc8f845 100644 --- a/modules/video_filter/egl_pbuffer.c +++ b/modules/video_filter/egl_pbuffer.c @@ -385,8 +385,15 @@ static void Close( vlc_gl_t *gl ) vlc_egl_display_Delete(sys->vlc_display); } -static int Open(vlc_gl_t *gl, unsigned width, unsigned height) +static int Open(vlc_gl_t *gl, unsigned width, unsigned height, + const struct vlc_gl_cfg *gl_cfg) { + if (gl_cfg->need_alpha) + { + msg_Err(gl, "Cannot support alpha yet"); + return VLC_ENOTSUP; + } + struct vlc_gl_pbuffer *sys = vlc_obj_malloc(&gl->obj, sizeof *sys); if (sys == NULL) return VLC_ENOMEM; diff --git a/modules/video_filter/egl_surfacetexture.c b/modules/video_filter/egl_surfacetexture.c index f2a3049dfc..b57f3ba314 100644 --- a/modules/video_filter/egl_surfacetexture.c +++ b/modules/video_filter/egl_surfacetexture.c @@ -327,8 +327,15 @@ error: return VLC_EGENERIC; } -static int Open(vlc_gl_t *gl, unsigned width, unsigned height) +static int Open(vlc_gl_t *gl, unsigned width, unsigned height, + const struct vlc_gl_cfg *gl_cfg) { + if (gl_cfg->need_alpha) + { + msg_Err(gl, "Cannot support alpha yet"); + return VLC_ENOTSUP; + } + if (gl->device == NULL || gl->device->type != VLC_DECODER_DEVICE_AWINDOW) { msg_Err(gl, "Wrong decoder device"); diff --git a/modules/video_filter/opengl.c b/modules/video_filter/opengl.c index b390225dea..50cd635c4d 100644 --- a/modules/video_filter/opengl.c +++ b/modules/video_filter/opengl.c @@ -183,7 +183,7 @@ static int Open( vlc_object_t *obj ) struct vlc_decoder_device *device = filter_HoldDecoderDevice(filter); sys->gl = vlc_gl_CreateOffscreen(obj, device, width, height, VLCGLAPI, - NULL); + NULL, NULL); /* The vlc_gl_t instance must have hold the device if it needs it. */ if (device) diff --git a/modules/video_output/android/display.c b/modules/video_output/android/display.c index fd794c93cc..17f7d4109d 100644 --- a/modules/video_output/android/display.c +++ b/modules/video_output/android/display.c @@ -606,7 +606,7 @@ static void ClearSurface(vout_display_t *vd) { /* Clear the surface to black with OpenGL ES 2 */ char *modlist = var_InheritString(sys->embed, "gles2"); - vlc_gl_t *gl = vlc_gl_Create(vd->cfg, VLC_OPENGL_ES2, modlist); + vlc_gl_t *gl = vlc_gl_Create(vd->cfg, VLC_OPENGL_ES2, modlist, NULL); free(modlist); if (gl == NULL) return; diff --git a/modules/video_output/apple/VLCCVOpenGLProvider.m b/modules/video_output/apple/VLCCVOpenGLProvider.m index 15e6577e90..bf4e06601f 100644 --- a/modules/video_output/apple/VLCCVOpenGLProvider.m +++ b/modules/video_output/apple/VLCCVOpenGLProvider.m @@ -506,8 +506,15 @@ static void FreeCVBuffer(picture_t *picture) @end -static int Open(vlc_gl_t *gl, unsigned width, unsigned height) +static int Open(vlc_gl_t *gl, unsigned width, unsigned height, + const struct vlc_gl_cfg *gl_cfg) { + if (gl_cfg->need_alpha) + { + msg_Err(gl, "Cannot support alpha yet"); + return VLC_ENOTSUP; + } + VLCCVOpenGLProvider *sys = [[VLCCVOpenGLProvider alloc] initWithGL:gl width:width height:height]; if (sys == nil) return VLC_EGENERIC;; diff --git a/modules/video_output/apple/VLCOpenGLES2VideoView.m b/modules/video_output/apple/VLCOpenGLES2VideoView.m index 0f6e9ac6e9..a8f9baf2ab 100644 --- a/modules/video_output/apple/VLCOpenGLES2VideoView.m +++ b/modules/video_output/apple/VLCOpenGLES2VideoView.m @@ -490,10 +490,17 @@ static void Close(vlc_gl_t *gl) -static int Open(vlc_gl_t *gl, unsigned width, unsigned height) +static int Open(vlc_gl_t *gl, unsigned width, unsigned height, + const struct vlc_gl_cfg *gl_cfg) { vlc_window_t *wnd = gl->surface; + if (gl_cfg->need_alpha) + { + msg_Err(gl, "Cannot support alpha yet"); + return VLC_ENOTSUP; + } + /* We only support UIView container window. */ if (wnd->type != VLC_WINDOW_TYPE_NSOBJECT) return VLC_EGENERIC; diff --git a/modules/video_output/glx.c b/modules/video_output/glx.c index bdffdaf9e6..764b6ea2aa 100644 --- a/modules/video_output/glx.c +++ b/modules/video_output/glx.c @@ -152,10 +152,17 @@ static void Close(vlc_gl_t *gl) free(sys); } -static int Open(vlc_gl_t *gl, unsigned width, unsigned height) +static int Open(vlc_gl_t *gl, unsigned width, unsigned height, + const struct vlc_gl_cfg *gl_cfg) { vlc_object_t *obj = VLC_OBJECT(gl); + if (gl_cfg->need_alpha) + { + msg_Err(gl, "Cannot support alpha yet"); + return VLC_ENOTSUP; + } + if (gl->surface->type != VLC_WINDOW_TYPE_XID || !vlc_xlib_init (obj)) return VLC_EGENERIC; diff --git a/modules/video_output/libplacebo/instance_opengl.c b/modules/video_output/libplacebo/instance_opengl.c index 13afa29251..d5ca9ea6fb 100644 --- a/modules/video_output/libplacebo/instance_opengl.c +++ b/modules/video_output/libplacebo/instance_opengl.c @@ -105,7 +105,7 @@ static int InitInstance(vlc_placebo_t *pl, const vout_display_cfg_t *cfg) bool current = false; char *name = var_InheritString(pl, MODULE_VARNAME); - sys->gl = vlc_gl_Create(cfg, API, name); + sys->gl = vlc_gl_Create(cfg, API, name, NULL); free(name); if (!sys->gl || vlc_gl_MakeCurrent(sys->gl) != VLC_SUCCESS) goto error; diff --git a/modules/video_output/opengl/display.c b/modules/video_output/opengl/display.c index 7ff643c679..367c5fe7d9 100644 --- a/modules/video_output/opengl/display.c +++ b/modules/video_output/opengl/display.c @@ -186,7 +186,7 @@ static int Open(vout_display_t *vd, } #endif - sys->gl = vlc_gl_Create(vd->cfg, API, gl_name); + sys->gl = vlc_gl_Create(vd->cfg, API, gl_name, NULL); free(gl_name); if (sys->gl == NULL) goto error; diff --git a/modules/video_output/opengl/egl.c b/modules/video_output/opengl/egl.c index afeebfaabd..e7be37fe5a 100644 --- a/modules/video_output/opengl/egl.c +++ b/modules/video_output/opengl/egl.c @@ -597,8 +597,15 @@ static void InitEGL(void) * Probe EGL display availability */ static int Open(vlc_gl_t *gl, const struct gl_api *api, - unsigned width, unsigned height) + unsigned width, unsigned height, + const struct vlc_gl_cfg *gl_cfg) { + if (gl_cfg->need_alpha) + { + msg_Err(gl, "Cannot support alpha yet"); + return VLC_ENOTSUP; + } + InitEGL(); int ret = VLC_EGENERIC; @@ -699,22 +706,24 @@ error: return ret; } -static int OpenGLES2(vlc_gl_t *gl, unsigned width, unsigned height) +static int OpenGLES2(vlc_gl_t *gl, unsigned width, unsigned height, + const struct vlc_gl_cfg *gl_cfg) { static const struct gl_api api = { "OpenGL_ES", EGL_OPENGL_ES_API, 4, EGL_OPENGL_ES2_BIT, { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE }, }; - return Open(gl, &api, width, height); + return Open(gl, &api, width, height, gl_cfg); } -static int OpenGL(vlc_gl_t *gl, unsigned width, unsigned height) +static int OpenGL(vlc_gl_t *gl, unsigned width, unsigned height, + const struct vlc_gl_cfg *gl_cfg) { static const struct gl_api api = { "OpenGL", EGL_OPENGL_API, 4, EGL_OPENGL_BIT, { EGL_NONE }, }; - return Open(gl, &api, width, height); + return Open(gl, &api, width, height, gl_cfg); } #ifdef USE_PLATFORM_XCB diff --git a/modules/video_output/vgl.c b/modules/video_output/vgl.c index 88db16b74d..ea917a08a1 100644 --- a/modules/video_output/vgl.c +++ b/modules/video_output/vgl.c @@ -122,7 +122,8 @@ static void Close(vlc_gl_t *gl) } \ } while( 0 ) -static int Open(vlc_gl_t *gl, unsigned width, unsigned height) +static int Open(vlc_gl_t *gl, unsigned width, unsigned height, + const struct vlc_gl_cfg *gl_cfg) { vout_display_sys_t * sys; @@ -131,6 +132,12 @@ static int Open(vlc_gl_t *gl, unsigned width, unsigned height) engineType != libvlc_video_engine_gles2 ) return VLC_ENOTSUP; + if (gl_cfg->need_alpha) + { + msg_Err(gl, "Cannot support alpha yet"); + return VLC_ENOTSUP; + } + /* Allocate structure */ gl->sys = sys = vlc_obj_calloc(VLC_OBJECT(gl), 1, sizeof(*sys)); if( !sys ) diff --git a/modules/video_output/win32/glwin32.c b/modules/video_output/win32/glwin32.c index eaa271b4cb..f3a7d27c24 100644 --- a/modules/video_output/win32/glwin32.c +++ b/modules/video_output/win32/glwin32.c @@ -148,7 +148,7 @@ static int Open(vout_display_t *vd, goto error; char *modlist = var_InheritString(embed_cfg.window, "gl"); - sys->gl = vlc_gl_Create(&embed_cfg, VLC_OPENGL, modlist); + sys->gl = vlc_gl_Create(&embed_cfg, VLC_OPENGL, modlist, NULL); free(modlist); if (!sys->gl) { diff --git a/modules/video_output/win32/wgl.c b/modules/video_output/win32/wgl.c index afcea08edc..e179c24ac6 100644 --- a/modules/video_output/win32/wgl.c +++ b/modules/video_output/win32/wgl.c @@ -35,7 +35,8 @@ /***************************************************************************** * Module descriptor *****************************************************************************/ -static int Open(vlc_gl_t *, unsigned width, unsigned height); +static int Open(vlc_gl_t *, unsigned width, unsigned height, + const struct vlc_gl_cfg *gl_cfg); static void Close(vlc_gl_t *); #define HW_GPU_AFFINITY_TEXT N_("GPU affinity") @@ -148,10 +149,17 @@ static void DestroyGPUAffinityDC(vlc_gl_t *gl) { fncDeleteDCNV(sys->affinityHDC); } -static int Open(vlc_gl_t *gl, unsigned width, unsigned height) +static int Open(vlc_gl_t *gl, unsigned width, unsigned height, + const struct vlc_gl_cfg *gl_cfg) { vout_display_sys_t *sys; + if (gl_cfg->need_alpha) + { + msg_Err(gl, "Cannot support alpha yet"); + return VLC_ENOTSUP; + } + /* Allocate structure */ gl->sys = sys = calloc(1, sizeof(*sys)); if (!sys) diff --git a/modules/visualization/glspectrum.c b/modules/visualization/glspectrum.c index 2cd1b9fd6a..6db387dcac 100644 --- a/modules/visualization/glspectrum.c +++ b/modules/visualization/glspectrum.c @@ -199,7 +199,7 @@ static int Open(vlc_object_t * p_this) .height = var_InheritInteger(p_filter, "glspectrum-height"), }; - p_sys->gl = vlc_gl_surface_Create(p_this, &cfg, NULL); + p_sys->gl = vlc_gl_surface_Create(p_this, &cfg, NULL, NULL); if (p_sys->gl == NULL) return VLC_EGENERIC; diff --git a/modules/visualization/projectm.cpp b/modules/visualization/projectm.cpp index 2f3be210e4..c671ba51ec 100644 --- a/modules/visualization/projectm.cpp +++ b/modules/visualization/projectm.cpp @@ -190,7 +190,7 @@ static int Open( vlc_object_t * p_this ) cfg.width = var_CreateGetInteger( p_filter, "projectm-width" ); cfg.height = var_CreateGetInteger( p_filter, "projectm-height" ); - p_sys->gl = vlc_gl_surface_Create( VLC_OBJECT(p_filter), &cfg, NULL ); + p_sys->gl = vlc_gl_surface_Create( VLC_OBJECT(p_filter), &cfg, NULL, NULL ); if( p_sys->gl == NULL ) goto error; diff --git a/modules/visualization/vsxu.cpp b/modules/visualization/vsxu.cpp index 3bfe402af3..5b7f34ae7f 100644 --- a/modules/visualization/vsxu.cpp +++ b/modules/visualization/vsxu.cpp @@ -134,7 +134,7 @@ static int Open( vlc_object_t * p_this ) cfg.width = var_InheritInteger( p_filter, "vsxu-width" ); cfg.height = var_InheritInteger( p_filter, "vsxu-height" ); - p_sys->gl = vlc_gl_surface_Create( VLC_OBJECT(p_filter), &cfg, NULL ); + p_sys->gl = vlc_gl_surface_Create( VLC_OBJECT(p_filter), &cfg, NULL, NULL); if( p_sys->gl == NULL ) goto error; diff --git a/src/video_output/opengl.c b/src/video_output/opengl.c index 9b7d856cfe..963128a186 100644 --- a/src/video_output/opengl.c +++ b/src/video_output/opengl.c @@ -33,6 +33,10 @@ #include "libvlc.h" #include +static const struct vlc_gl_cfg gl_cfg_default = { + .need_alpha = false +}; + struct vlc_gl_priv_t { vlc_gl_t gl; @@ -44,8 +48,9 @@ static int vlc_gl_start(void *func, bool forced, va_list ap) vlc_gl_t *gl = va_arg(ap, vlc_gl_t *); unsigned width = va_arg(ap, unsigned); unsigned height = va_arg(ap, unsigned); + const struct vlc_gl_cfg *gl_cfg = va_arg(ap, const struct vlc_gl_cfg *); - int ret = activate(gl, width, height); + int ret = activate(gl, width, height, gl_cfg); if (ret) vlc_objres_clear(VLC_OBJECT(gl)); (void) forced; @@ -53,11 +58,14 @@ static int vlc_gl_start(void *func, bool forced, va_list ap) } vlc_gl_t *vlc_gl_Create(const struct vout_display_cfg *restrict cfg, - unsigned flags, const char *name) + unsigned flags, const char *name, + const struct vlc_gl_cfg * gl_cfg) { vlc_window_t *wnd = cfg->window; struct vlc_gl_priv_t *glpriv; const char *type; + if (gl_cfg == NULL) + gl_cfg = &gl_cfg_default; enum vlc_gl_api_type api_type; @@ -85,7 +93,8 @@ vlc_gl_t *vlc_gl_Create(const struct vout_display_cfg *restrict cfg, gl->device = NULL; gl->module = vlc_module_load(gl, type, name, true, vlc_gl_start, gl, - cfg->display.width, cfg->display.height); + cfg->display.width, cfg->display.height, + gl_cfg); if (gl->module == NULL) { vlc_object_delete(gl); @@ -104,12 +113,15 @@ vlc_gl_t *vlc_gl_Create(const struct vout_display_cfg *restrict cfg, vlc_gl_t *vlc_gl_CreateOffscreen(vlc_object_t *parent, struct vlc_decoder_device *device, unsigned width, unsigned height, - unsigned flags, const char *name) + unsigned flags, const char *name, + const struct vlc_gl_cfg *gl_cfg) { struct vlc_gl_priv_t *glpriv; const char *type; enum vlc_gl_api_type api_type; + if (gl_cfg == NULL) + gl_cfg = &gl_cfg_default; switch (flags /*& VLC_OPENGL_API_MASK*/) { @@ -140,7 +152,7 @@ vlc_gl_t *vlc_gl_CreateOffscreen(vlc_object_t *parent, gl->surface = NULL; gl->device = device ? vlc_decoder_device_Hold(device) : NULL; gl->module = vlc_module_load(gl, type, name, true, vlc_gl_start, gl, width, - height); + height, gl_cfg); if (gl->module == NULL) { vlc_object_delete(gl); @@ -199,7 +211,8 @@ static void vlc_gl_surface_ResizeNotify(vlc_window_t *surface, vlc_gl_t *vlc_gl_surface_Create(vlc_object_t *obj, const vlc_window_cfg_t *cfg, - struct vlc_window **restrict wp) + struct vlc_window **restrict wp, + const struct vlc_gl_cfg *gl_cfg) { vlc_gl_surface_t *sys = malloc(sizeof (*sys)); if (unlikely(sys == NULL)) @@ -244,7 +257,7 @@ vlc_gl_t *vlc_gl_surface_Create(vlc_object_t *obj, } vlc_mutex_unlock(&sys->lock); - vlc_gl_t *gl = vlc_gl_Create(&dcfg, VLC_OPENGL, NULL); + vlc_gl_t *gl = vlc_gl_Create(&dcfg, VLC_OPENGL, NULL, gl_cfg); if (gl == NULL) { vlc_window_Disable(surface); vlc_window_Delete(surface); diff --git a/test/src/video_output/opengl.c b/test/src/video_output/opengl.c index 385b4e7a78..b4087bee9b 100644 --- a/test/src/video_output/opengl.c +++ b/test/src/video_output/opengl.c @@ -122,9 +122,10 @@ static void OpenGLClose(vlc_gl_t *gl) static int OpenOpenGLCommon( vlc_gl_t *gl, unsigned width, unsigned height, - bool offscreen, enum vlc_gl_api_type api_type) + bool offscreen, enum vlc_gl_api_type api_type, + const struct vlc_gl_cfg *cfg) { - (void)width; (void)height; + (void)width; (void)height; (void) cfg; assert(gl->api_type == api_type); static const struct vlc_gl_operations onscreen_ops = @@ -152,20 +153,24 @@ OpenOpenGLCommon( } static int -OpenOpenGL(vlc_gl_t *gl, unsigned width, unsigned height) - { return OpenOpenGLCommon(gl, width, height, false, VLC_OPENGL); }; +OpenOpenGL(vlc_gl_t *gl, unsigned width, unsigned height, + const struct vlc_gl_cfg *cfg) + { return OpenOpenGLCommon(gl, width, height, false, VLC_OPENGL, cfg); }; static int -OpenOpenGLES(vlc_gl_t *gl, unsigned width, unsigned height) - { return OpenOpenGLCommon(gl, width, height, false, VLC_OPENGL_ES2); }; +OpenOpenGLES(vlc_gl_t *gl, unsigned width, unsigned height, + const struct vlc_gl_cfg *cfg) + { return OpenOpenGLCommon(gl, width, height, false, VLC_OPENGL_ES2, cfg); }; static int -OpenOpenGLOffscreen(vlc_gl_t *gl, unsigned width, unsigned height) - { return OpenOpenGLCommon(gl, width, height, true, VLC_OPENGL); }; +OpenOpenGLOffscreen(vlc_gl_t *gl, unsigned width, unsigned height, + const struct vlc_gl_cfg *cfg) + { return OpenOpenGLCommon(gl, width, height, true, VLC_OPENGL, cfg); }; static int -OpenOpenGLESOffscreen(vlc_gl_t *gl, unsigned width, unsigned height) - { return OpenOpenGLCommon(gl, width, height, true, VLC_OPENGL_ES2); }; +OpenOpenGLESOffscreen(vlc_gl_t *gl, unsigned width, unsigned height, + const struct vlc_gl_cfg *cfg) + { return OpenOpenGLCommon(gl, width, height, true, VLC_OPENGL_ES2, cfg); }; /** * Inject the mocked modules as a static plugin: @@ -206,7 +211,7 @@ static void test_opengl_offscreen(vlc_object_t *root, enum vlc_gl_api_type api_t assert(device != NULL); vlc_gl_t *gl = vlc_gl_CreateOffscreen( - root, device, 800, 600, api_type, MODULE_STRING); + root, device, 800, 600, api_type, MODULE_STRING, NULL); assert(gl != NULL); vlc_decoder_device_Release(device); @@ -233,7 +238,7 @@ static void test_opengl(vlc_object_t *root, enum vlc_gl_api_type api_type) .display.width = wnd_cfg.width, .display.height = wnd_cfg.height, }; - vlc_gl_t *gl = vlc_gl_Create(&cfg, api_type, MODULE_STRING); + vlc_gl_t *gl = vlc_gl_Create(&cfg, api_type, MODULE_STRING, NULL); assert(gl != NULL); assert(vlc_gl_MakeCurrent(gl) == VLC_SUCCESS);