summaryrefslogtreecommitdiffstats
path: root/video/out/opengl
diff options
context:
space:
mode:
Diffstat (limited to 'video/out/opengl')
-rw-r--r--video/out/opengl/angle_common.c13
-rw-r--r--video/out/opengl/angle_common.h13
-rw-r--r--video/out/opengl/angle_dynamic.c33
-rw-r--r--video/out/opengl/angle_dynamic.h82
-rw-r--r--video/out/opengl/common.c129
-rw-r--r--video/out/opengl/common.h32
-rw-r--r--video/out/opengl/context.c2
-rw-r--r--video/out/opengl/context_angle.c148
-rw-r--r--video/out/opengl/context_cocoa.c9
-rw-r--r--video/out/opengl/context_dxinterop.c85
-rw-r--r--video/out/opengl/context_rpi.c1
-rw-r--r--video/out/opengl/context_w32.c8
-rw-r--r--video/out/opengl/context_wayland.c11
-rw-r--r--video/out/opengl/context_x11.c4
-rw-r--r--video/out/opengl/context_x11egl.c12
-rw-r--r--video/out/opengl/egl_helpers.c10
-rw-r--r--video/out/opengl/egl_helpers.h3
-rw-r--r--video/out/opengl/formats.c272
-rw-r--r--video/out/opengl/formats.h59
-rw-r--r--video/out/opengl/header_fixes.h26
-rw-r--r--video/out/opengl/hwdec.c34
-rw-r--r--video/out/opengl/hwdec.h47
-rw-r--r--video/out/opengl/hwdec_d3d11egl.c335
-rw-r--r--video/out/opengl/hwdec_d3d11eglrgb.c268
-rw-r--r--video/out/opengl/hwdec_dxva2.c35
-rw-r--r--video/out/opengl/hwdec_dxva2egl.c49
-rw-r--r--video/out/opengl/hwdec_dxva2gldx.c46
-rw-r--r--video/out/opengl/hwdec_osx.c63
-rw-r--r--video/out/opengl/hwdec_vaegl.c103
-rw-r--r--video/out/opengl/hwdec_vaglx.c29
-rw-r--r--video/out/opengl/hwdec_vdpau.c155
-rw-r--r--video/out/opengl/lcms.c153
-rw-r--r--video/out/opengl/lcms.h10
-rw-r--r--video/out/opengl/nnedi3.c253
-rw-r--r--video/out/opengl/nnedi3.h45
-rw-r--r--video/out/opengl/nnedi3_weights.binbin161280 -> 0 bytes
-rw-r--r--video/out/opengl/osd.c211
-rw-r--r--video/out/opengl/superxbr.c244
-rw-r--r--video/out/opengl/superxbr.h31
-rw-r--r--video/out/opengl/user_shaders.c195
-rw-r--r--video/out/opengl/user_shaders.h74
-rw-r--r--video/out/opengl/utils.c442
-rw-r--r--video/out/opengl/utils.h39
-rw-r--r--video/out/opengl/video.c2113
-rw-r--r--video/out/opengl/video.h49
-rw-r--r--video/out/opengl/video_shaders.c167
-rw-r--r--video/out/opengl/video_shaders.h7
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;
+ }
+