mirror of
https://github.com/mpv-player/mpv
synced 2025-02-02 13:12:05 +00:00
vo_opengl: angle: dynamically load ANGLE
ANGLE is _really_ annoying to build. (Requires special toolchain and a recent MSVC version.) This results in various issues with people having trouble to build mpv against ANGLE (apparently linking it against a prebuilt binary doesn't count, or using binaries from potentially untrusted sources is not wanted). Dynamically loading ANGLE is going to be a huge convenience. This commit implements this, with special focus on keeping it source compatible to a normal build with ANGLE linked at build-time.
This commit is contained in:
parent
bea7675307
commit
fde20d10bc
33
video/out/opengl/angle_dynamic.c
Normal file
33
video/out/opengl/angle_dynamic.c
Normal file
@ -0,0 +1,33 @@
|
||||
#include <pthread.h>
|
||||
#include <windows.h>
|
||||
|
||||
#define ANGLE_NO_ALIASES
|
||||
#include "angle_dynamic.h"
|
||||
|
||||
#include "common/common.h"
|
||||
|
||||
#define ANGLE_DECL(NAME, VAR) \
|
||||
VAR;
|
||||
ANGLE_FNS(ANGLE_DECL)
|
||||
|
||||
static bool angle_loaded;
|
||||
static pthread_once_t angle_load_once = PTHREAD_ONCE_INIT;
|
||||
|
||||
static void angle_do_load(void)
|
||||
{
|
||||
// Note: we let this handle "leak", as the functions remain valid forever.
|
||||
HANDLE angle_dll = LoadLibraryW(L"LIBEGL.DLL");
|
||||
if (!angle_dll)
|
||||
return;
|
||||
#define ANGLE_LOAD_ENTRY(NAME, VAR) \
|
||||
MP_CONCAT(PFN_, NAME) = (void *)GetProcAddress(angle_dll, #NAME); \
|
||||
if (!MP_CONCAT(PFN_, NAME)) return;
|
||||
ANGLE_FNS(ANGLE_LOAD_ENTRY)
|
||||
angle_loaded = true;
|
||||
}
|
||||
|
||||
bool angle_load(void)
|
||||
{
|
||||
pthread_once(&angle_load_once, angle_do_load);
|
||||
return angle_loaded;
|
||||
}
|
82
video/out/opengl/angle_dynamic.h
Normal file
82
video/out/opengl/angle_dynamic.h
Normal file
@ -0,0 +1,82 @@
|
||||
// Based on Khronos headers, thus MIT licensed.
|
||||
|
||||
#ifndef MP_ANGLE_DYNAMIC_H
|
||||
#define MP_ANGLE_DYNAMIC_H
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
#include <EGL/egl.h>
|
||||
#include <EGL/eglext.h>
|
||||
|
||||
#define ANGLE_FNS(FN) \
|
||||
FN(eglBindAPI, EGLBoolean (*EGLAPIENTRY PFN_eglBindAPI)(EGLenum)) \
|
||||
FN(eglBindTexImage, EGLBoolean (*EGLAPIENTRY PFN_eglBindTexImage) \
|
||||
(EGLDisplay, EGLSurface, EGLint)) \
|
||||
FN(eglChooseConfig, EGLBoolean (*EGLAPIENTRY PFN_eglChooseConfig) \
|
||||
(EGLDisplay, const EGLint *, EGLConfig *, EGLint, EGLint *)) \
|
||||
FN(eglCreateContext, EGLContext (*EGLAPIENTRY PFN_eglCreateContext) \
|
||||
(EGLDisplay, EGLConfig, EGLContext, const EGLint *)) \
|
||||
FN(eglCreatePbufferFromClientBuffer, EGLSurface (*EGLAPIENTRY \
|
||||
PFN_eglCreatePbufferFromClientBuffer)(EGLDisplay, EGLenum, \
|
||||
EGLClientBuffer, EGLConfig, const EGLint *)) \
|
||||
FN(eglCreateWindowSurface, EGLSurface (*EGLAPIENTRY \
|
||||
PFN_eglCreateWindowSurface)(EGLDisplay, EGLConfig, \
|
||||
EGLNativeWindowType, const EGLint *)) \
|
||||
FN(eglDestroyContext, EGLBoolean (*EGLAPIENTRY PFN_eglDestroyContext) \
|
||||
(EGLDisplay, EGLContext)) \
|
||||
FN(eglDestroySurface, EGLBoolean (*EGLAPIENTRY PFN_eglDestroySurface) \
|
||||
(EGLDisplay, EGLSurface)) \
|
||||
FN(eglGetConfigAttrib, EGLBoolean (*EGLAPIENTRY PFN_eglGetConfigAttrib) \
|
||||
(EGLDisplay, EGLConfig, EGLint, EGLint *)) \
|
||||
FN(eglGetCurrentContext, EGLContext (*EGLAPIENTRY \
|
||||
PFN_eglGetCurrentContext)(void)) \
|
||||
FN(eglGetCurrentDisplay, EGLDisplay (*EGLAPIENTRY \
|
||||
PFN_eglGetCurrentDisplay)(void)) \
|
||||
FN(eglGetDisplay, EGLDisplay (*EGLAPIENTRY PFN_eglGetDisplay) \
|
||||
(EGLNativeDisplayType)) \
|
||||
FN(eglGetError, EGLint (*EGLAPIENTRY PFN_eglGetError)(void)) \
|
||||
FN(eglGetProcAddress, void *(*EGLAPIENTRY \
|
||||
PFN_eglGetProcAddress)(const char *)) \
|
||||
FN(eglInitialize, EGLBoolean (*EGLAPIENTRY PFN_eglInitialize) \
|
||||
(EGLDisplay, EGLint *, EGLint *)) \
|
||||
FN(eglMakeCurrent, EGLBoolean (*EGLAPIENTRY PFN_eglMakeCurrent) \
|
||||
(EGLDisplay, EGLSurface, EGLSurface, EGLContext)) \
|
||||
FN(eglQueryString, const char *(*EGLAPIENTRY PFN_eglQueryString) \
|
||||
(EGLDisplay, EGLint)) \
|
||||
FN(eglSwapBuffers, EGLBoolean (*EGLAPIENTRY PFN_eglSwapBuffers) \
|
||||
(EGLDisplay, EGLSurface)) \
|
||||
FN(eglReleaseTexImage, EGLBoolean (*EGLAPIENTRY PFN_eglReleaseTexImage) \
|
||||
(EGLDisplay, EGLSurface, EGLint)) \
|
||||
FN(eglTerminate, EGLBoolean (*EGLAPIENTRY PFN_eglTerminate)(EGLDisplay))
|
||||
|
||||
#define ANGLE_EXT_DECL(NAME, VAR) \
|
||||
extern VAR;
|
||||
ANGLE_FNS(ANGLE_EXT_DECL)
|
||||
|
||||
bool angle_load(void);
|
||||
|
||||
// Source compatibility to statically linked ANGLE.
|
||||
#ifndef ANGLE_NO_ALIASES
|
||||
#define eglBindAPI PFN_eglBindAPI
|
||||
#define eglBindTexImage PFN_eglBindTexImage
|
||||
#define eglChooseConfig PFN_eglChooseConfig
|
||||
#define eglCreateContext PFN_eglCreateContext
|
||||
#define eglCreatePbufferFromClientBuffer PFN_eglCreatePbufferFromClientBuffer
|
||||
#define eglCreateWindowSurface PFN_eglCreateWindowSurface
|
||||
#define eglDestroyContext PFN_eglDestroyContext
|
||||
#define eglDestroySurface PFN_eglDestroySurface
|
||||
#define eglGetConfigAttrib PFN_eglGetConfigAttrib
|
||||
#define eglGetCurrentContext PFN_eglGetCurrentContext
|
||||
#define eglGetCurrentDisplay PFN_eglGetCurrentDisplay
|
||||
#define eglGetDisplay PFN_eglGetDisplay
|
||||
#define eglGetError PFN_eglGetError
|
||||
#define eglGetProcAddress PFN_eglGetProcAddress
|
||||
#define eglInitialize PFN_eglInitialize
|
||||
#define eglMakeCurrent PFN_eglMakeCurrent
|
||||
#define eglQueryString PFN_eglQueryString
|
||||
#define eglReleaseTexImage PFN_eglReleaseTexImage
|
||||
#define eglSwapBuffers PFN_eglSwapBuffers
|
||||
#define eglTerminate PFN_eglTerminate
|
||||
#endif
|
||||
|
||||
#endif
|
@ -19,6 +19,8 @@
|
||||
#include <EGL/egl.h>
|
||||
#include <EGL/eglext.h>
|
||||
|
||||
#include "angle_dynamic.h"
|
||||
|
||||
#include "common/common.h"
|
||||
#include "video/out/w32_common.h"
|
||||
#include "context.h"
|
||||
@ -109,6 +111,11 @@ static int angle_init(struct MPGLContext *ctx, int flags)
|
||||
struct priv *p = ctx->priv;
|
||||
struct vo *vo = ctx->vo;
|
||||
|
||||
if (!angle_load()) {
|
||||
MP_VERBOSE(vo, "Failed to load LIBEGL.DLL\n");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (!vo_w32_init(vo))
|
||||
goto fail;
|
||||
|
||||
|
@ -23,6 +23,8 @@
|
||||
#include <EGL/egl.h>
|
||||
#include <EGL/eglext.h>
|
||||
|
||||
#include "angle_dynamic.h"
|
||||
|
||||
#include "common/common.h"
|
||||
#include "osdep/timer.h"
|
||||
#include "osdep/windows_utils.h"
|
||||
@ -147,6 +149,9 @@ static void destroy(struct gl_hwdec *hw)
|
||||
|
||||
static int create(struct gl_hwdec *hw)
|
||||
{
|
||||
if (!angle_load())
|
||||
return -1;
|
||||
|
||||
EGLDisplay egl_display = eglGetCurrentDisplay();
|
||||
if (!egl_display)
|
||||
return -1;
|
||||
|
@ -22,6 +22,8 @@
|
||||
#include <EGL/egl.h>
|
||||
#include <EGL/eglext.h>
|
||||
|
||||
#include "angle_dynamic.h"
|
||||
|
||||
#include "common/common.h"
|
||||
#include "osdep/timer.h"
|
||||
#include "osdep/windows_utils.h"
|
||||
@ -95,6 +97,9 @@ static void destroy(struct gl_hwdec *hw)
|
||||
|
||||
static int create(struct gl_hwdec *hw)
|
||||
{
|
||||
if (!angle_load())
|
||||
return -1;
|
||||
|
||||
EGLDisplay egl_display = eglGetCurrentDisplay();
|
||||
if (!egl_display)
|
||||
return -1;
|
||||
|
5
wscript
5
wscript
@ -699,9 +699,8 @@ video_output_features = [
|
||||
'desc': 'OpenGL Win32 ANGLE Backend',
|
||||
'deps_any': [ 'os-win32', 'os-cygwin' ],
|
||||
'groups': [ 'gl' ],
|
||||
'func': check_statement(['EGL/egl.h'],
|
||||
'eglCreateWindowSurface(0, 0, 0, 0)',
|
||||
lib='EGL')
|
||||
'func': check_statement(['EGL/egl.h', 'EGL/eglext.h'],
|
||||
'int x = EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE')
|
||||
} , {
|
||||
'name': '--vdpau',
|
||||
'desc': 'VDPAU acceleration',
|
||||
|
@ -329,6 +329,7 @@ def build(ctx):
|
||||
( "video/out/cocoa_common.m", "cocoa" ),
|
||||
( "video/out/dither.c" ),
|
||||
( "video/out/filter_kernels.c" ),
|
||||
( "video/out/opengl/angle_dynamic.c", "egl-angle" ),
|
||||
( "video/out/opengl/common.c", "gl" ),
|
||||
( "video/out/opengl/context.c", "gl" ),
|
||||
( "video/out/opengl/context_angle.c", "egl-angle" ),
|
||||
|
Loading…
Reference in New Issue
Block a user