diff options
Diffstat (limited to 'video/out/opengl')
47 files changed, 3966 insertions, 2183 deletions
diff --git a/video/out/opengl/angle_common.c b/video/out/opengl/angle_common.c new file mode 100644 index 0000000000..21cc924714 --- /dev/null +++ b/video/out/opengl/angle_common.c @@ -0,0 +1,13 @@ +#include "angle_common.h" + +// Test if Direct3D11 can be used by us. Basically, this prevents trying to use +// D3D11 on Win7, and then failing somewhere in the process. +bool d3d11_check_decoding(ID3D11Device *dev) +{ + HRESULT hr; + // We assume that NV12 is always supported, if hw decoding is supported at + // all. + UINT supported = 0; + hr = ID3D11Device_CheckFormatSupport(dev, DXGI_FORMAT_NV12, &supported); + return !FAILED(hr) && (supported & D3D11_BIND_DECODER); +} diff --git a/video/out/opengl/angle_common.h b/video/out/opengl/angle_common.h new file mode 100644 index 0000000000..14ecd6ab3c --- /dev/null +++ b/video/out/opengl/angle_common.h @@ -0,0 +1,13 @@ +#ifndef MP_ANGLE_COMMON_H +#define MP_ANGLE_COMMON_H + +#include <initguid.h> +#include <assert.h> +#include <windows.h> +#include <d3d11.h> + +#include <stdbool.h> + +bool d3d11_check_decoding(ID3D11Device *dev); + +#endif
\ No newline at end of file diff --git a/video/out/opengl/angle_dynamic.c b/video/out/opengl/angle_dynamic.c new file mode 100644 index 0000000000..f4540c473a --- /dev/null +++ b/video/out/opengl/angle_dynamic.c @@ -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; +} diff --git a/video/out/opengl/angle_dynamic.h b/video/out/opengl/angle_dynamic.h new file mode 100644 index 0000000000..87ad85c268 --- /dev/null +++ b/video/out/opengl/angle_dynamic.h @@ -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 diff --git a/video/out/opengl/common.c b/video/out/opengl/common.c index 46cbc2fc8c..dd44165b81 100644 --- a/video/out/opengl/common.c +++ b/video/out/opengl/common.c @@ -72,6 +72,8 @@ struct gl_functions { int provides; // bitfield of MPGL_CAP_* constants int ver_core; // introduced as required function int ver_es_core; // introduced as required GL ES function + int ver_exclude; // not applicable to versions >= ver_exclude + int ver_es_exclude; // same for GLES const struct gl_function *functions; }; @@ -144,15 +146,23 @@ static const struct gl_functions gl_functions[] = { .ver_core = 210, .provides = MPGL_CAP_ROW_LENGTH | MPGL_CAP_1D_TEX, .functions = (const struct gl_function[]) { - DEF_FN(DrawBuffer), DEF_FN(GetTexLevelParameteriv), - DEF_FN(MapBuffer), DEF_FN(ReadBuffer), DEF_FN(TexImage1D), DEF_FN(UnmapBuffer), {0} }, }, + // GL 2.1 has this as extension only. + { + .ver_exclude = 300, + .ver_es_exclude = 300, + .extension = "GL_ARB_map_buffer_range", + .functions = (const struct gl_function[]) { + DEF_FN(MapBufferRange), + {0} + }, + }, // GL 3.0+ and ES 3.x core only functions. { .ver_core = 300, @@ -161,6 +171,7 @@ static const struct gl_functions gl_functions[] = { DEF_FN(BindBufferBase), DEF_FN(BlitFramebuffer), DEF_FN(GetStringi), + DEF_FN(MapBufferRange), // for ES 3.0 DEF_FN(ReadBuffer), DEF_FN(UnmapBuffer), @@ -203,6 +214,7 @@ static const struct gl_functions gl_functions[] = { DEF_FN(DeleteFramebuffers), DEF_FN(CheckFramebufferStatus), DEF_FN(FramebufferTexture2D), + DEF_FN(GetFramebufferAttachmentParameteriv), {0} }, }, @@ -227,6 +239,32 @@ static const struct gl_functions gl_functions[] = { .provides = MPGL_CAP_TEX_RG, }, { + .ver_core = 300, + .ver_es_core = 300, + .extension = "GL_EXT_texture_rg", + .provides = MPGL_CAP_TEX_RG, + }, + // GL_R16 etc. + { + .extension = "GL_EXT_texture_norm16", + .provides = MPGL_CAP_EXT16, + .ver_exclude = 1, // never in desktop GL + }, + // Float texture support for GL 2.x + { + .extension = "GL_ARB_texture_float", + .provides = MPGL_CAP_ARB_FLOAT, + .ver_exclude = 300, + .ver_es_exclude = 1, + }, + // 16 bit float textures that can be rendered to in GLES + { + .extension = "GL_EXT_color_buffer_half_float", + .provides = MPGL_CAP_EXT_CR_HFLOAT, + .ver_exclude = 1, + .ver_es_exclude = 320, + }, + { .ver_core = 320, .extension = "GL_ARB_sync", .functions = (const struct gl_function[]) { @@ -236,6 +274,47 @@ static const struct gl_functions gl_functions[] = { {0} }, }, + { + .ver_core = 330, + .extension = "GL_ARB_timer_query", + .functions = (const struct gl_function[]) { + DEF_FN(GenQueries), + DEF_FN(DeleteQueries), + DEF_FN(BeginQuery), + DEF_FN(EndQuery), + DEF_FN(QueryCounter), + DEF_FN(IsQuery), + DEF_FN(GetQueryObjectiv), + DEF_FN(GetQueryObjecti64v), + DEF_FN(GetQueryObjectuiv), + DEF_FN(GetQueryObjectui64v), + {0} + }, + }, + { + .extension = "GL_EXT_disjoint_timer_query", + .functions = (const struct gl_function[]) { + DEF_FN_NAME(GenQueries, "glGenQueriesEXT"), + DEF_FN_NAME(DeleteQueries, "glDeleteQueriesEXT"), + DEF_FN_NAME(BeginQuery, "glBeginQueryEXT"), + DEF_FN_NAME(EndQuery, "glEndQueryEXT"), + DEF_FN_NAME(QueryCounter, "glQueryCounterEXT"), + DEF_FN_NAME(IsQuery, "glIsQueryEXT"), + DEF_FN_NAME(GetQueryObjectiv, "glGetQueryObjectivEXT"), + DEF_FN_NAME(GetQueryObjecti64v, "glGetQueryObjecti64vEXT"), + DEF_FN_NAME(GetQueryObjectuiv, "glGetQueryObjectuivEXT"), + DEF_FN_NAME(GetQueryObjectui64v, "glGetQueryObjectui64vEXT"), + {0} + }, + }, + { + .ver_core = 430, + .ver_es_core = 300, + .functions = (const struct gl_function[]) { + DEF_FN(InvalidateFramebuffer), + {0} + }, + }, // Swap control, always an OS specific extension // The OSX code loads this manually. { @@ -270,6 +349,7 @@ static const struct gl_functions gl_functions[] = { DEF_FN(VDPAUInitNV), DEF_FN(VDPAUFiniNV), DEF_FN(VDPAURegisterOutputSurfaceNV), + DEF_FN(VDPAURegisterVideoSurfaceNV), DEF_FN(VDPAUUnregisterSurfaceNV), DEF_FN(VDPAUSurfaceAccessNV), DEF_FN(VDPAUMapSurfacesNV), @@ -327,14 +407,10 @@ static const struct gl_functions gl_functions[] = { {0} }, }, - // uniform buffer object extensions, requires OpenGL 3.1. { - .ver_core = 310, - .ver_es_core = 300, - .extension = "GL_ARB_uniform_buffer_object", + .extension = "GL_ANGLE_translated_shader_source", .functions = (const struct gl_function[]) { - DEF_FN(GetUniformBlockIndex), - DEF_FN(UniformBlockBinding), + DEF_FN(GetTranslatedShaderSourceANGLE), {0} }, }, @@ -348,11 +424,9 @@ static const struct gl_functions gl_functions[] = { // Fill the GL struct with function pointers and extensions from the current // GL context. Called by the backend. -// getProcAddress: function to resolve function names, may be NULL +// get_fn: function to resolve function names // ext2: an extra extension string // log: used to output messages -// Note: if you create a CONTEXT_FORWARD_COMPATIBLE_BIT_ARB with OpenGL 3.0, -// you must append "GL_ARB_compatibility" to ext2. void mpgl_load_functions2(GL *gl, void *(*get_fn)(void *ctx, const char *n), void *fn_ctx, const char *ext2, struct mp_log *log) { @@ -428,6 +502,13 @@ void mpgl_load_functions2(GL *gl, void *(*get_fn)(void *ctx, const char *n), // NOTE: Function entrypoints can exist, even if they do not work. // We must always check extension strings and versions. + if (gl->version && section->ver_exclude && + gl->version >= section->ver_exclude) + continue; + if (gl->es && section->ver_es_exclude && + gl->es >= section->ver_es_exclude) + continue; + bool exists = false, must_exist = false; if (ver_core) must_exist = version >= ver_core; @@ -448,13 +529,15 @@ void mpgl_load_functions2(GL *gl, void *(*get_fn)(void *ctx, const char *n), void *ptr = get_fn(fn_ctx, fn->name); if (!ptr) { all_loaded = false; - mp_warn(log, "Required function '%s' not " - "found for %s OpenGL %d.%d.\n", fn->name, - section->extension ? section->extension : "builtin", - MPGL_VER_GET_MAJOR(ver_core), - MPGL_VER_GET_MINOR(ver_core)); - if (must_exist) + if (must_exist) { + mp_err(log, "GL %d.%d function %s not found.\n", + MPGL_VER_GET_MAJOR(ver_core), + MPGL_VER_GET_MINOR(ver_core), fn->name); goto error; + } else { + mp_warn(log, "Function %s from extension %s not found.\n", + fn->name, section->extension); + } break; } assert(i < MAX_FN_COUNT); @@ -469,8 +552,8 @@ void mpgl_load_functions2(GL *gl, void *(*get_fn)(void *ctx, const char *n), if (loaded[i]) *funcptr = loaded[i]; } - mp_verbose(log, "Loaded functions for %d/%s.\n", ver_core, - section->extension ? section->extension : "builtin"); + if (!must_exist && section->extension) + mp_verbose(log, "Loaded extension %s.\n", section->extension); } } @@ -494,14 +577,6 @@ void mpgl_load_functions2(GL *gl, void *(*get_fn)(void *ctx, const char *n), mp_verbose(log, "Detected suspected software renderer.\n"); } - // Detect 16F textures that work with GL_LINEAR filtering. - if ((!gl->es && (gl->version >= 300 || check_ext(gl, "GL_ARB_texture_float"))) || - (gl->es && (gl->version >= 310 || check_ext(gl, "GL_OES_texture_half_float_linear")))) - { - mp_verbose(log, "Filterable half-float textures supported.\n"); - gl->mpgl_caps |= MPGL_CAP_FLOAT_TEX; - } - // Provided for simpler handling if no framebuffer support is available. if (!gl->BindFramebuffer) gl->BindFramebuffer = &dummy_glBindFramebuffer; diff --git a/video/out/opengl/common.h b/video/out/opengl/common.h index f790dcb166..e3ebd66c41 100644 --- a/video/out/opengl/common.h +++ b/video/out/opengl/common.h @@ -53,7 +53,6 @@ enum { MPGL_CAP_ROW_LENGTH = (1 << 4), // GL_[UN]PACK_ROW_LENGTH MPGL_CAP_FB = (1 << 5), MPGL_CAP_VAO = (1 << 6), - MPGL_CAP_FLOAT_TEX = (1 << 9), MPGL_CAP_TEX_RG = (1 << 10), // GL_ARB_texture_rg / GL 3.x MPGL_CAP_VDPAU = (1 << 11), // GL_NV_vdpau_interop MPGL_CAP_APPLE_RGB_422 = (1 << 12), // GL_APPLE_rgb_422 @@ -61,6 +60,10 @@ enum { MPGL_CAP_3D_TEX = (1 << 15), MPGL_CAP_DEBUG = (1 << 16), MPGL_CAP_DXINTEROP = (1 << 17), // WGL_NV_DX_interop + MPGL_CAP_EXT16 = (1 << 18), // GL_EXT_texture_norm16 + MPGL_CAP_ARB_FLOAT = (1 << 19), // GL_ARB_texture_float + MPGL_CAP_EXT_CR_HFLOAT = (1 << 20), // GL_EXT_color_buffer_half_float + MPGL_CAP_SW = (1 << 30), // indirect or sw renderer }; @@ -88,7 +91,7 @@ struct GL { char *extensions; // Equivalent to GL_EXTENSIONS int mpgl_caps; // Bitfield of MPGL_CAP_* constants bool debug_context; // use of e.g. GLX_CONTEXT_DEBUG_BIT_ARB - int fb_r, fb_g, fb_b; // frame buffer bit depth (0 if unknown) + GLuint main_fb; // framebuffer to render to (normally 0) void (GLAPIENTRY *Viewport)(GLint, GLint, GLsizei, GLsizei); void (GLAPIENTRY *Clear)(GLbitfield); @@ -98,7 +101,6 @@ struct GL { void (GLAPIENTRY *Enable)(GLenum); void (GLAPIENTRY *Disable)(GLenum); const GLubyte *(GLAPIENTRY * GetString)(GLenum); - void (GLAPIENTRY *DrawBuffer)(GLenum); void (GLAPIENTRY *BlendFuncSeparate)(GLenum, GLenum, GLenum, GLenum); void (GLAPIENTRY *Flush)(void); void (GLAPIENTRY *Finish)(void); @@ -123,7 +125,8 @@ struct GL { void (GLAPIENTRY *DeleteBuffers)(GLsizei, const GLuint *); void (GLAPIENTRY *BindBuffer)(GLenum, GLuint); void (GLAPIENTRY *BindBufferBase)(GLenum, GLuint, GLuint); - GLvoid * (GLAPIENTRY * MapBuffer)(GLenum, GLenum); + GLvoid * (GLAPIENTRY *MapBufferRange)(GLenum, GLintptr, GLsizeiptr, + GLbitfield); GLboolean (GLAPIENTRY *UnmapBuffer)(GLenum); void (GLAPIENTRY *BufferData)(GLenum, intptr_t, const GLvoid *, GLenum); void (GLAPIENTRY *ActiveTexture)(GLenum); @@ -166,6 +169,8 @@ struct GL { GLint); void (GLAPIENTRY *BlitFramebuffer)(GLint, GLint, GLint, GLint, GLint, GLint, GLint, GLint, GLbitfield, GLenum); + void (GLAPIENTRY *GetFramebufferAttachmentParameteriv)(GLenum, GLenum, + GLenum, GLint *); void (GLAPIENTRY *Uniform1f)(GLint, GLfloat); void (GLAPIENTRY *Uniform2f)(GLint, GLfloat, GLfloat); @@ -177,14 +182,29 @@ struct GL { void (GLAPIENTRY *UniformMatrix3fv)(GLint, GLsizei, GLboolean, const GLfloat *); + void (GLAPIENTRY *InvalidateFramebuffer)(GLenum, GLsizei, const GLenum *); + GLsync (GLAPIENTRY *FenceSync)(GLenum, GLbitfield); GLenum (GLAPIENTRY *ClientWaitSync)(GLsync, GLbitfield, GLuint64); void (GLAPIENTRY *DeleteSync)(GLsync sync); + void (GLAPIENTRY *GenQueries)(GLsizei, GLuint *); + void (GLAPIENTRY *DeleteQueries)(GLsizei, const GLuint *); + void (GLAPIENTRY *BeginQuery)(GLenum, GLuint); + void (GLAPIENTRY *EndQuery)(GLenum); + void (GLAPIENTRY *QueryCounter)(GLuint, GLenum); + GLboolean (GLAPIENTRY *IsQuery)(GLuint); + void (GLAPIENTRY *GetQueryObjectiv)(GLuint, GLenum, GLint *); + void (GLAPIENTRY *GetQueryObjecti64v)(GLuint, GLenum, GLint64 *); + void (GLAPIENTRY *GetQueryObjectuiv)(GLuint, GLenum, GLuint *); + void (GLAPIENTRY *GetQueryObjectui64v)(GLuint, GLenum, GLuint64 *); + void (GLAPIENTRY *VDPAUInitNV)(const GLvoid *, const GLvoid *); void (GLAPIENTRY *VDPAUFiniNV)(void); GLvdpauSurfaceNV (GLAPIENTRY *VDPAURegisterOutputSurfaceNV) (GLvoid *, GLenum, GLsizei, const GLuint *); + GLvdpauSurfaceNV (GLAPIENTRY *VDPAURegisterVideoSurfaceNV) + (GLvoid *, GLenum, GLsizei, const GLuint *); void (GLAPIENTRY *VDPAUUnregisterSurfaceNV)(GLvdpauSurfaceNV); void (GLAPIENTRY *VDPAUSurfaceAccessNV)(GLvdpauSurfaceNV, GLenum); void (GLAPIENTRY *VDPAUMapSurfacesNV)(GLsizei, const GLvdpauSurfaceNV *); @@ -208,8 +228,8 @@ struct GL { GLint (GLAPIENTRY *GetVideoSync)(GLuint *); GLint (GLAPIENTRY *WaitVideoSync)(GLint, GLint, unsigned int *); - GLuint (GLAPIENTRY *GetUniformBlockIndex)(GLuint, const GLchar *); - void (GLAPIENTRY *UniformBlockBinding)(GLuint, GLuint, GLuint); + void (GLAPIENTRY *GetTranslatedShaderSourceANGLE)(GLuint, GLsizei, + GLsizei*, GLchar* source); void (GLAPIENTRY *DebugMessageCallback)(MP_GLDEBUGPROC callback, const void *userParam); diff --git a/video/out/opengl/context.c b/video/out/opengl/context.c index 77e9709426..186211da2f 100644 --- a/video/out/opengl/context.c +++ b/video/out/opengl/context.c @@ -42,6 +42,7 @@ extern const struct mpgl_driver mpgl_driver_cocoa; extern const struct mpgl_driver mpgl_driver_wayland; extern const struct mpgl_driver mpgl_driver_w32; extern const struct mpgl_driver mpgl_driver_angle; +extern const struct mpgl_driver mpgl_driver_angle_es2; extern const struct mpgl_driver mpgl_driver_dxinterop; extern const struct mpgl_driver mpgl_driver_rpi; @@ -54,6 +55,7 @@ static const struct mpgl_driver *const backends[] = { #endif #if HAVE_EGL_ANGLE &mpgl_driver_angle, + &mpgl_driver_angle_es2, #endif #if HAVE_GL_WIN32 &mpgl_driver_w32, diff --git a/video/out/opengl/context_angle.c b/video/out/opengl/context_angle.c index b922ce8f24..cc14fc32c6 100644 --- a/video/out/opengl/context_angle.c +++ b/video/out/opengl/context_angle.c @@ -18,15 +18,26 @@ #include <windows.h> #include <EGL/egl.h> #include <EGL/eglext.h> +#include <d3d11.h> +#include <dxgi.h> + +#include "angle_dynamic.h" #include "common/common.h" #include "video/out/w32_common.h" #include "context.h" +#ifndef EGL_OPTIMAL_SURFACE_ORIENTATION_ANGLE +#define EGL_OPTIMAL_SURFACE_ORIENTATION_ANGLE 0x33A7 +#define EGL_SURFACE_ORIENTATION_ANGLE 0x33A8 +#define EGL_SURFACE_ORIENTATION_INVERT_Y_ANGLE 0x0002 +#endif + struct priv { EGLDisplay egl_display; EGLContext egl_context; EGLSurface egl_surface; + bool use_es2; }; static void angle_uninit(MPGLContext *ctx) @@ -39,6 +50,8 @@ static void angle_uninit(MPGLContext *ctx) eglDestroyContext(p->egl_display, p->egl_context); } p->egl_context = EGL_NO_CONTEXT; + if (p->egl_display) + eglTerminate(p->egl_display); vo_w32_uninit(ctx->vo); } @@ -90,6 +103,74 @@ static bool create_context_egl(MPGLContext *ctx, EGLConfig config, int version) return true; } +static void d3d_init(struct MPGLContext *ctx) +{ + HRESULT hr; + struct priv *p = ctx->priv; + struct vo *vo = ctx->vo; + IDXGIDevice *dxgi_dev = NULL; + IDXGIAdapter *dxgi_adapter = NULL; + IDXGIFactory *dxgi_factory = NULL; + + PFNEGLQUERYDISPLAYATTRIBEXTPROC eglQueryDisplayAttribEXT = + (PFNEGLQUERYDISPLAYATTRIBEXTPROC)eglGetProcAddress("eglQueryDisplayAttribEXT"); + PFNEGLQUERYDEVICEATTRIBEXTPROC eglQueryDeviceAttribEXT = + (PFNEGLQUERYDEVICEATTRIBEXTPROC)eglGetProcAddress("eglQueryDeviceAttribEXT"); + if (!eglQueryDisplayAttribEXT || !eglQueryDeviceAttribEXT) { + MP_VERBOSE(vo, "Missing EGL_EXT_device_query\n"); + goto done; + } + + EGLAttrib dev_attr; + if (!eglQueryDisplayAttribEXT(p->egl_display, EGL_DEVICE_EXT, &dev_attr)) { + MP_VERBOSE(vo, "Missing EGL_EXT_device_query\n"); + goto done; + } + + // If ANGLE is in D3D11 mode, get the underlying ID3D11Device + EGLDeviceEXT dev = (EGLDeviceEXT)dev_attr; + EGLAttrib d3d11_dev_attr; + if (eglQueryDeviceAttribEXT(dev, EGL_D3D11_DEVICE_ANGLE, &d3d11_dev_attr)) { + ID3D11Device *d3d11_dev = (ID3D11Device*)d3d11_dev_attr; + + hr = ID3D11Device_QueryInterface(d3d11_dev, &IID_IDXGIDevice, + (void**)&dxgi_dev); + if (FAILED(hr)) { + MP_ERR(vo, "Device is not a IDXGIDevice\n"); + goto done; + } + |