summaryrefslogtreecommitdiffstats
path: root/video/out/opengl
diff options
context:
space:
mode:
Diffstat (limited to 'video/out/opengl')
-rw-r--r--video/out/opengl/angle_dynamic.c15
-rw-r--r--video/out/opengl/angle_dynamic.h4
-rw-r--r--video/out/opengl/common.c62
-rw-r--r--video/out/opengl/common.h14
-rw-r--r--video/out/opengl/context.c74
-rw-r--r--video/out/opengl/context.h23
-rw-r--r--video/out/opengl/context_android.c1
-rw-r--r--video/out/opengl/context_angle.c12
-rw-r--r--video/out/opengl/context_cocoa.c223
-rw-r--r--video/out/opengl/context_drm_egl.c674
-rw-r--r--video/out/opengl/context_dxinterop.c5
-rw-r--r--video/out/opengl/context_glx.c161
-rw-r--r--video/out/opengl/context_rpi.c327
-rw-r--r--video/out/opengl/context_wayland.c157
-rw-r--r--video/out/opengl/context_win.c56
-rw-r--r--video/out/opengl/context_x11egl.c49
-rw-r--r--video/out/opengl/egl_helpers.c173
-rw-r--r--video/out/opengl/egl_helpers.h3
-rw-r--r--video/out/opengl/formats.c2
-rw-r--r--video/out/opengl/gl_headers.h1
-rw-r--r--video/out/opengl/hwdec_d3d11egl.c16
-rw-r--r--video/out/opengl/hwdec_drmprime_drm.c321
-rw-r--r--video/out/opengl/hwdec_dxva2egl.c18
-rw-r--r--video/out/opengl/hwdec_dxva2gldx.c16
-rw-r--r--video/out/opengl/hwdec_ios.m275
-rw-r--r--video/out/opengl/hwdec_osx.c221
-rw-r--r--video/out/opengl/hwdec_rpi.c384
-rw-r--r--video/out/opengl/hwdec_vdpau.c8
-rw-r--r--video/out/opengl/libmpv_gl.c31
-rw-r--r--video/out/opengl/oml_sync.c112
-rw-r--r--video/out/opengl/oml_sync.h28
-rw-r--r--video/out/opengl/ra_gl.c34
32 files changed, 704 insertions, 2796 deletions
diff --git a/video/out/opengl/angle_dynamic.c b/video/out/opengl/angle_dynamic.c
index 1ff3cc8c6e..2483828884 100644
--- a/video/out/opengl/angle_dynamic.c
+++ b/video/out/opengl/angle_dynamic.c
@@ -1,14 +1,9 @@
-#include <pthread.h>
#include <windows.h>
-#ifndef ANGLE_NO_ALIASES
-#define ANGLE_NO_ALIASES
-#endif
-
#include "angle_dynamic.h"
-#include "config.h"
#include "common/common.h"
+#include "osdep/threads.h"
#if HAVE_EGL_ANGLE_LIB
bool angle_load(void)
@@ -21,7 +16,7 @@ bool angle_load(void)
ANGLE_FNS(ANGLE_DECL)
static bool angle_loaded;
-static pthread_once_t angle_load_once = PTHREAD_ONCE_INIT;
+static mp_once angle_load_once = MP_STATIC_ONCE_INITIALIZER;
static void angle_do_load(void)
{
@@ -30,15 +25,15 @@ static void angle_do_load(void)
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;
+ NAME = (void *)GetProcAddress(angle_dll, #NAME); \
+ if (!NAME) return;
ANGLE_FNS(ANGLE_LOAD_ENTRY)
angle_loaded = true;
}
bool angle_load(void)
{
- pthread_once(&angle_load_once, angle_do_load);
+ mp_exec_once(&angle_load_once, angle_do_load);
return angle_loaded;
}
#endif
diff --git a/video/out/opengl/angle_dynamic.h b/video/out/opengl/angle_dynamic.h
index 12a0c692eb..d419c3fc91 100644
--- a/video/out/opengl/angle_dynamic.h
+++ b/video/out/opengl/angle_dynamic.h
@@ -8,6 +8,8 @@
#include <EGL/egl.h>
#include <EGL/eglext.h>
+#include "config.h"
+
#define ANGLE_FNS(FN) \
FN(eglBindAPI, EGLBoolean (*EGLAPIENTRY PFN_eglBindAPI)(EGLenum)) \
FN(eglBindTexImage, EGLBoolean (*EGLAPIENTRY PFN_eglBindTexImage) \
@@ -59,7 +61,7 @@ ANGLE_FNS(ANGLE_EXT_DECL)
bool angle_load(void);
// Source compatibility to statically linked ANGLE.
-#ifndef ANGLE_NO_ALIASES
+#if !HAVE_EGL_ANGLE_LIB
#define eglBindAPI PFN_eglBindAPI
#define eglBindTexImage PFN_eglBindTexImage
#define eglChooseConfig PFN_eglChooseConfig
diff --git a/video/out/opengl/common.c b/video/out/opengl/common.c
index 8fcc94df70..e3fc1ba032 100644
--- a/video/out/opengl/common.c
+++ b/video/out/opengl/common.c
@@ -25,6 +25,7 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
+#include <strings.h>
#include <stdbool.h>
#include <math.h>
#include <assert.h>
@@ -37,16 +38,28 @@
static bool is_software_gl(GL *gl)
{
const char *renderer = gl->GetString(GL_RENDERER);
- const char *vendor = gl->GetString(GL_VENDOR);
- return !(renderer && vendor) ||
+ // Note we don't attempt to blacklist Microsoft's fallback implementation.
+ // It only provides OpenGL 1.1 and will be skipped anyway.
+ return !renderer ||
strcmp(renderer, "Software Rasterizer") == 0 ||
strstr(renderer, "llvmpipe") ||
strstr(renderer, "softpipe") ||
- strcmp(vendor, "Microsoft Corporation") == 0 ||
strcmp(renderer, "Mesa X11") == 0 ||
strcmp(renderer, "Apple Software Renderer") == 0;
}
+// This guesses whether our DR path is fast or slow
+static bool is_fast_dr(GL *gl)
+{
+ const char *vendor = gl->GetString(GL_VENDOR);
+ if (!vendor)
+ return false;
+
+ return strcasecmp(vendor, "AMD") == 0 ||
+ strcasecmp(vendor, "NVIDIA Corporation") == 0 ||
+ strcasecmp(vendor, "ATI Technologies Inc.") == 0; // AMD on Windows
+}
+
static void GLAPIENTRY dummy_glBindFramebuffer(GLenum target, GLuint framebuffer)
{
assert(framebuffer == 0);
@@ -143,6 +156,7 @@ 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(ReadBuffer),
DEF_FN(TexImage1D),
@@ -307,6 +321,7 @@ static const struct gl_functions gl_functions[] = {
},
{
.ver_core = 430,
+ .extension = "GL_ARB_invalidate_subdata",
.functions = (const struct gl_function[]) {
DEF_FN(InvalidateTexImage),
{0}
@@ -338,8 +353,17 @@ static const struct gl_functions gl_functions[] = {
{0}
},
},
+ // Equivalent extension for ES
+ {
+ .extension = "GL_EXT_buffer_storage",
+ .functions = (const struct gl_function[]) {
+ DEF_FN_NAME(BufferStorage, "glBufferStorageEXT"),
+ {0}
+ },
+ },
{
.ver_core = 420,
+ .ver_es_core = 310,
.extension = "GL_ARB_shader_image_load_store",
.functions = (const struct gl_function[]) {
DEF_FN(BindImageTexture),
@@ -349,16 +373,19 @@ static const struct gl_functions gl_functions[] = {
},
{
.ver_core = 310,
+ .ver_es_core = 300,
.extension = "GL_ARB_uniform_buffer_object",
.provides = MPGL_CAP_UBO,
},
{
.ver_core = 430,
+ .ver_es_core = 310,
.extension = "GL_ARB_shader_storage_buffer_object",
.provides = MPGL_CAP_SSBO,
},
{
.ver_core = 430,
+ .ver_es_core = 310,
.extension = "GL_ARB_compute_shader",
.functions = (const struct gl_function[]) {
DEF_FN(DispatchCompute),
@@ -371,7 +398,7 @@ static const struct gl_functions gl_functions[] = {
.provides = MPGL_CAP_NESTED_ARRAY,
},
// Swap control, always an OS specific extension
- // The OSX code loads this manually.
+ // The macOS code loads this manually.
{
.extension = "GLX_SGI_swap_control",
.functions = (const struct gl_function[]) {
@@ -454,21 +481,14 @@ static const struct gl_functions gl_functions[] = {
{0}
},
},
- // These don't exist - they are for the sake of mpv internals, and libmpv
- // interaction (see libmpv/opengl_cb.h).
- // This is not used by the render API, only the deprecated opengl-cb API.
- {
- .extension = "GL_MP_MPGetNativeDisplay",
- .functions = (const struct gl_function[]) {
- DEF_FN(MPGetNativeDisplay),
- {0}
- },
- },
- // Same, but using the old name.
+ // ES version uses a different extension.
{
- .extension = "GL_MP_D3D_interfaces",
+ .ver_es_core = 320,
+ .extension = "GL_KHR_debug",
+ .provides = MPGL_CAP_DEBUG,
.functions = (const struct gl_function[]) {
- DEF_FN_NAME(MPGetNativeDisplay, "glMPGetD3DInterface"),
+ // (only functions needed by us)
+ DEF_FN(DebugMessageCallback),
{0}
},
},
@@ -486,7 +506,6 @@ static const struct gl_functions gl_functions[] = {
#undef DEF_FN
#undef DEF_FN_NAME
-
// Fill the GL struct with function pointers and extensions from the current
// GL context. Called by the backend.
// get_fn: function to resolve function names
@@ -498,6 +517,8 @@ void mpgl_load_functions2(GL *gl, void *(*get_fn)(void *ctx, const char *n),
talloc_free(gl->extensions);
*gl = (GL) {
.extensions = talloc_strdup(gl, ext2 ? ext2 : ""),
+ .get_fn = get_fn,
+ .fn_ctx = fn_ctx,
};
gl->GetString = get_fn(fn_ctx, "glGetString");
@@ -627,7 +648,7 @@ void mpgl_load_functions2(GL *gl, void *(*get_fn)(void *ctx, const char *n),
if (gl->es >= 200)
gl->glsl_version = 100;
if (gl->es >= 300)
- gl->glsl_version = 300;
+ gl->glsl_version = gl->es;
} else {
gl->glsl_version = 120;
int glsl_major = 0, glsl_minor = 0;
@@ -642,6 +663,9 @@ void mpgl_load_functions2(GL *gl, void *(*get_fn)(void *ctx, const char *n),
mp_verbose(log, "Detected suspected software renderer.\n");
}
+ if (!is_fast_dr(gl))
+ gl->mpgl_caps |= MPGL_CAP_SLOW_DR;
+
// GL_ARB_compute_shader & GL_ARB_shader_image_load_store
if (gl->DispatchCompute && gl->BindImageTexture)
gl->mpgl_caps |= MPGL_CAP_COMPUTE_SHADER;
diff --git a/video/out/opengl/common.h b/video/out/opengl/common.h
index 38414fe18b..a6b02c9366 100644
--- a/video/out/opengl/common.h
+++ b/video/out/opengl/common.h
@@ -59,6 +59,7 @@ enum {
MPGL_CAP_COMPUTE_SHADER = (1 << 23), // GL_ARB_compute_shader & GL_ARB_shader_image_load_store
MPGL_CAP_NESTED_ARRAY = (1 << 24), // GL_ARB_arrays_of_arrays
+ MPGL_CAP_SLOW_DR = (1 << 29), // direct rendering is assumed to be slow
MPGL_CAP_SW = (1 << 30), // indirect or sw renderer
};
@@ -87,6 +88,16 @@ struct GL {
int mpgl_caps; // Bitfield of MPGL_CAP_* constants
bool debug_context; // use of e.g. GLX_CONTEXT_DEBUG_BIT_ARB
+ // Set to false if the implementation follows normal GL semantics, which is
+ // upside down. Set to true if it does *not*, i.e. if rendering is right
+ // side up
+ bool flipped;
+
+ // Copy of function pointer used to load GL.
+ // Caution: Not necessarily valid to use after VO init has completed!
+ void *(*get_fn)(void *ctx, const char *n);
+ void *fn_ctx;
+
void (GLAPIENTRY *Viewport)(GLint, GLint, GLsizei, GLsizei);
void (GLAPIENTRY *Clear)(GLbitfield);
void (GLAPIENTRY *GenTextures)(GLsizei, GLuint *);
@@ -111,6 +122,7 @@ struct GL {
void (GLAPIENTRY *ReadPixels)(GLint, GLint, GLsizei, GLsizei, GLenum,
GLenum, GLvoid *);
void (GLAPIENTRY *ReadBuffer)(GLenum);
+ void (GLAPIENTRY *DrawBuffer)(GLenum);
void (GLAPIENTRY *DrawArrays)(GLenum, GLint, GLsizei);
GLenum (GLAPIENTRY *GetError)(void);
void (GLAPIENTRY *GetTexLevelParameteriv)(GLenum, GLint, GLenum, GLint *);
@@ -241,8 +253,6 @@ struct GL {
void (GLAPIENTRY *DebugMessageCallback)(MP_GLDEBUGPROC callback,
const void *userParam);
-
- void *(GLAPIENTRY *MPGetNativeDisplay)(const char *name);
};
#endif /* MPLAYER_GL_COMMON_H */
diff --git a/video/out/opengl/context.c b/video/out/opengl/context.c
index c491039b66..05e279b473 100644
--- a/video/out/opengl/context.c
+++ b/video/out/opengl/context.c
@@ -21,15 +21,18 @@
#include "utils.h"
// 0-terminated list of desktop GL versions a backend should try to
-// initialize. The first entry is the most preferred version.
-const int mpgl_preferred_gl_versions[] = {
+// initialize. Each entry is the minimum required version.
+const int mpgl_min_required_gl_versions[] = {
+ /*
+ * Nvidia drivers will not provide the highest supported version
+ * when 320 core is requested. Instead, it just returns 3.2. This
+ * would be bad, as we actually want compute shaders that require
+ * 4.2, so we have to request a sufficiently high version. We use
+ * 440 to maximise driver compatibility as we don't need anything
+ * from newer versions.
+ */
440,
- 430,
- 400,
- 330,
320,
- 310,
- 300,
210,
0
};
@@ -40,39 +43,27 @@ enum {
FLUSH_AUTO,
};
-enum {
- GLES_AUTO = 0,
- GLES_YES,
- GLES_NO,
-};
-
struct opengl_opts {
- int use_glfinish;
- int waitvsync;
+ bool use_glfinish;
+ bool waitvsync;
int vsync_pattern[2];
int swapinterval;
int early_flush;
- int restrict_version;
int gles_mode;
};
#define OPT_BASE_STRUCT struct opengl_opts
const struct m_sub_options opengl_conf = {
.opts = (const struct m_option[]) {
- {"opengl-glfinish", OPT_FLAG(use_glfinish)},
- {"opengl-waitvsync", OPT_FLAG(waitvsync)},
+ {"opengl-glfinish", OPT_BOOL(use_glfinish)},
+ {"opengl-waitvsync", OPT_BOOL(waitvsync)},
{"opengl-swapinterval", OPT_INT(swapinterval)},
{"opengl-check-pattern-a", OPT_INT(vsync_pattern[0])},
{"opengl-check-pattern-b", OPT_INT(vsync_pattern[1])},
- {"opengl-restrict", OPT_INT(restrict_version)},
{"opengl-es", OPT_CHOICE(gles_mode,
{"auto", GLES_AUTO}, {"yes", GLES_YES}, {"no", GLES_NO})},
{"opengl-early-flush", OPT_CHOICE(early_flush,
{"no", FLUSH_NO}, {"yes", FLUSH_YES}, {"auto", FLUSH_AUTO})},
- {"opengl-debug", OPT_REPLACED("gpu-debug")},
- {"opengl-sw", OPT_REPLACED("gpu-sw")},
- {"opengl-vsync-fences", OPT_REPLACED("swapchain-depth")},
- {"opengl-backend", OPT_REPLACED("gpu-context")},
{0},
},
.defaults = &(const struct opengl_opts) {
@@ -100,29 +91,17 @@ struct priv {
int num_vsync_fences;
};
-bool ra_gl_ctx_test_version(struct ra_ctx *ctx, int version, bool es)
+enum gles_mode ra_gl_ctx_get_glesmode(struct ra_ctx *ctx)
{
- bool ret;
- struct opengl_opts *opts;
void *tmp = talloc_new(NULL);
- opts = mp_get_config_group(tmp, ctx->global, &opengl_conf);
-
- // Version too high
- if (opts->restrict_version && version >= opts->restrict_version) {
- ret = false;
- goto done;
- }
+ struct opengl_opts *opts;
+ enum gles_mode mode;
- switch (opts->gles_mode) {
- case GLES_YES: ret = es; goto done;
- case GLES_NO: ret = !es; goto done;
- case GLES_AUTO: ret = true; goto done;
- default: abort();
- }
+ opts = mp_get_config_group(tmp, ctx->global, &opengl_conf);
+ mode = opts->gles_mode;
-done:
talloc_free(tmp);
- return ret;
+ return mode;
}
void ra_gl_ctx_uninit(struct ra_ctx *ctx)
@@ -239,9 +218,18 @@ int ra_gl_ctx_color_depth(struct ra_swapchain *sw)
bool ra_gl_ctx_start_frame(struct ra_swapchain *sw, struct ra_fbo *out_fbo)
{
struct priv *p = sw->priv;
+
+ bool visible = true;
+ if (p->params.check_visible)
+ visible = p->params.check_visible(sw->ctx);
+
+ // If out_fbo is NULL, this was called from vo_gpu_next. Bail out.
+ if (!out_fbo || !visible)
+ return visible;
+
*out_fbo = (struct ra_fbo) {
.tex = p->wrapped_fb,
- .flip = !p->params.flipped, // OpenGL FBs are normally flipped
+ .flip = !p->gl->flipped, // OpenGL FBs are normally flipped
};
return true;
}
@@ -264,7 +252,7 @@ bool ra_gl_ctx_submit_frame(struct ra_swapchain *sw, const struct vo_frame *fram
case FLUSH_AUTO:
if (frame->display_synced)
break;
- // fall through
+ MP_FALLTHROUGH;
case FLUSH_YES:
gl->Flush();
}
diff --git a/video/out/opengl/context.h b/video/out/opengl/context.h
index 2dd2517ef5..c96450ebd5 100644
--- a/video/out/opengl/context.h
+++ b/video/out/opengl/context.h
@@ -4,12 +4,16 @@
#include "video/out/gpu/context.h"
#include "common.h"
-extern const int mpgl_preferred_gl_versions[];
+extern const int mpgl_min_required_gl_versions[];
-// Returns whether or not a candidate GL version should be accepted or not
-// (based on the --opengl opts). Implementations may call this before
-// ra_gl_ctx_init if they wish to probe for multiple possible GL versions.
-bool ra_gl_ctx_test_version(struct ra_ctx *ctx, int version, bool es);
+enum gles_mode {
+ GLES_AUTO = 0,
+ GLES_YES,
+ GLES_NO,
+};
+
+// Returns the gles mode based on the --opengl opts.
+enum gles_mode ra_gl_ctx_get_glesmode(struct ra_ctx *ctx);
// These are a set of helpers for ra_ctx providers based on ra_gl.
// The init function also initializes ctx->ra and ctx->swapchain, so the user
@@ -17,6 +21,10 @@ bool ra_gl_ctx_test_version(struct ra_ctx *ctx, int version, bool es);
// clean them up)
struct ra_gl_ctx_params {
+ // For special contexts (i.e. wayland) that want to check visibility
+ // before drawing a frame.
+ bool (*check_visible)(struct ra_ctx *ctx);
+
// Set to the platform-specific function to swap buffers, like
// glXSwapBuffers, eglSwapBuffers etc. This will be called by
// ra_gl_ctx_swap_buffers. Required unless you either never call that
@@ -26,11 +34,6 @@ struct ra_gl_ctx_params {
// See ra_swapchain_fns.get_vsync.
void (*get_vsync)(struct ra_ctx *ctx, struct vo_vsync_info *info);
- // Set to false if the implementation follows normal GL semantics, which is
- // upside down. Set to true if it does *not*, i.e. if rendering is right
- // side up
- bool flipped;
-
// If this is set to non-NULL, then the ra_gl_ctx will consider the GL
// implementation to be using an external swapchain, which disables the
// software simulation of --swapchain-depth. Any functions defined by this
diff --git a/video/out/opengl/context_android.c b/video/out/opengl/context_android.c
index bc1717c1be..269f36dbc3 100644
--- a/video/out/opengl/context_android.c
+++ b/video/out/opengl/context_android.c
@@ -123,6 +123,7 @@ static int android_control(struct ra_ctx *ctx, int *events, int request, void *a
const struct ra_ctx_fns ra_ctx_android = {
.type = "opengl",
.name = "android",
+ .description = "Android/EGL",
.reconfig = android_reconfig,
.control = android_control,
.init = android_init,
diff --git a/video/out/opengl/context_angle.c b/video/out/opengl/context_angle.c
index 2784026d1d..3a70c09c7e 100644
--- a/video/out/opengl/context_angle.c
+++ b/video/out/opengl/context_angle.c
@@ -18,6 +18,7 @@
#include <windows.h>
#include <EGL/egl.h>
#include <EGL/eglext.h>
+#include <EGL/eglext_angle.h>
#include <d3d11.h>
#include <dxgi1_2.h>
#include <dwmapi.h>
@@ -53,7 +54,7 @@ struct angle_opts {
int d3d11_warp;
int d3d11_feature_level;
int egl_windowing;
- int flip;
+ bool flip;
};
#define OPT_BASE_STRUCT struct angle_opts
@@ -76,9 +77,7 @@ const struct m_sub_options angle_conf = {
{"auto", -1},
{"no", 0},
{"yes", 1})},
- {"angle-flip", OPT_FLAG(flip)},
- {"angle-max-frame-latency", OPT_REPLACED("swapchain-depth")},
- {"angle-swapchain-length", OPT_REMOVED("controlled by --swapchain-depth")},
+ {"angle-flip", OPT_BOOL(flip)},
{0}
},
.defaults = &(const struct angle_opts) {
@@ -86,7 +85,7 @@ const struct m_sub_options angle_conf = {
.d3d11_warp = -1,
.d3d11_feature_level = D3D_FEATURE_LEVEL_11_0,
.egl_windowing = -1,
- .flip = 1,
+ .flip = true,
},
.size = sizeof(struct angle_opts),
};
@@ -604,10 +603,10 @@ static bool angle_init(struct ra_ctx *ctx)
};
struct ra_gl_ctx_params params = {
.swap_buffers = angle_swap_buffers,
- .flipped = p->flipped,
.external_swapchain = p->dxgi_swapchain ? &dxgi_swapchain_fns : NULL,
};
+ gl->flipped = p->flipped;
if (!ra_gl_ctx_init(ctx, gl, params))
goto fail;
@@ -647,6 +646,7 @@ static int angle_control(struct ra_ctx *ctx, int *events, int request, void *arg
const struct ra_ctx_fns ra_ctx_angle = {
.type = "opengl",
.name = "angle",
+ .description = "Win32/ANGLE (via Direct3D)",
.init = angle_init,
.reconfig = angle_reconfig,
.control = angle_control,
diff --git a/video/out/opengl/context_cocoa.c b/video/out/opengl/context_cocoa.c
deleted file mode 100644
index b7cab8e718..0000000000
--- a/video/out/opengl/context_cocoa.c
+++ /dev/null
@@ -1,223 +0,0 @@
-/*
- * This file is part of mpv.
- *
- * mpv is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * mpv is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with mpv. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <OpenGL/OpenGL.h>
-#include <dlfcn.h>
-#include "options/m_config.h"
-#include "video/out/cocoa_common.h"
-#include "context.h"
-#include "osdep/macosx_application.h"
-
-struct cocoa_opts {
-};
-
-#define OPT_BASE_STRUCT struct cocoa_opts
-const struct m_sub_options cocoa_conf = {
- .opts = (const struct m_option[]) {
- {"cocoa-force-dedicated-gpu", OPT_REPLACED("macos-force-dedicated-gpu")},
- {0}
- },
- .size = sizeof(struct cocoa_opts),
-};
-
-struct priv {
- GL gl;
- void (GLAPIENTRY *Flush)(void);
- CGLPixelFormatObj pix;
- CGLContextObj ctx;
-
- struct cocoa_opts *opts;
- struct macos_opts *macos_opts;
-};
-
-static int set_swap_interval(int enabled)
-{
- CGLContextObj ctx = CGLGetCurrentContext();
- CGLError err = CGLSetParameter(ctx, kCGLCPSwapInterval, &enabled);
- return (err == kCGLNoError) ? 0 : -1;
-}
-
-static void glFlushDummy(void) { }
-
-static void *cocoa_glgetaddr(const char *s)
-{
- void *ret = NULL;
- void *handle = dlopen(
- "/System/Library/Frameworks/OpenGL.framework/OpenGL",
- RTLD_LAZY | RTLD_LOCAL);
- if (!handle)
- return NULL;
- ret = dlsym(handle, s);
- dlclose(handle);
- return ret;
-}
-
-static CGLError test_gl_version(struct ra_ctx *ctx, CGLOpenGLProfile ver)
-{
- struct priv *p = ctx->priv;
-
- CGLPixelFormatAttribute attrs[] = {
- // let this array ordered by the inverse order of the most probably
- // rejected attribute to preserve the fallback code
- kCGLPFAOpenGLProfile,
- (CGLPixelFormatAttribute) ver,
- kCGLPFAAccelerated,
- kCGLPFAAllowOfflineRenderers,
- // keep this one last to apply the cocoa-force-dedicated-gpu option
- kCGLPFASupportsAutomaticGraphicsSwitching,
- 0
- };
-
- GLint npix;
- CGLError err;
- int supported_attribute = MP_ARRAY_SIZE(attrs)-1;
-
- if (p->macos_opts->macos_force_dedicated_gpu)
- attrs[--supported_attribute] = 0;
-
- err = CGLChoosePixelFormat(attrs, &p->pix, &npix);
- while (err == kCGLBadAttribute && supported_attribute > 3) {
- // kCGLPFASupportsAutomaticGraphicsSwitching is probably not
- // supported by the current hardware. Falling back to not using
- // it and disallowing Offline Renderers if further restrictions
- // apply
- attrs[--supported_attribute] = 0;
- err = CGLChoosePixelFormat(attrs, &p->pix, &npix);
- }
-
- if (err != kCGLNoError) {
- MP_ERR(ctx->vo, "error creating CGL pixel format: %s (%d)\n",
- CGLErrorString(err), err);
- goto error_out;
- }
-
- err = CGLCreateContext(p->pix, 0, &p->ctx);
-
-error_out:
- return err;
-}
-
-static bool create_gl_context(struct ra_ctx *ctx)
-{
- struct priv *p = ctx->priv;
- GL *gl = &p->gl;
- CGLError err;
-
- CGLOpenGLProfile gl_versions[] = {
- kCGLOGLPVersion_3_2_Core,
- kCGLOGLPVersion_Legacy,
- };
-
- for (int n = 0; n < MP_ARRAY_SIZE(gl_versions); n++) {
- err = test_gl_version(ctx, gl_versions[n]);
- if (err == kCGLNoError)
- break;
- }
-
- if (err != kCGLNoError) {
- MP_FATAL(ctx->vo, "error creating CGL context: %s (%d)\n",
- CGLErrorString(err), err);
- return false;
- }
-
- vo_cocoa_set_opengl_ctx(ctx->vo, p->ctx);
- CGLSetCurrentContext(p->ctx);
-
- if (ctx->opts.want_alpha)
- CGLSetParameter(p->ctx, kCGLCPSurfaceOpacity, &(GLint){0});
-
- mpgl_load_functions(gl, (void *)cocoa_glgetaddr, NULL, ctx->vo->log);
- gl->SwapInterval = set_swap_interval;
- p->Flush = gl->Flush;
- gl->Flush = glFlushDummy;
-
- CGLReleasePixelFormat(p->pix);
-
- return true;
-}
-
-static void cocoa_uninit(struct ra_ctx *ctx)
-{
- struct priv *p = ctx->priv;
- ra_gl_ctx_uninit(ctx);
- CGLReleaseContext(p->ctx);
- vo_cocoa_uninit(ctx->vo);
-}
-
-static void cocoa_swap_buffers(struct ra_ctx *ctx)
-{
- struct priv *p = ctx->priv;
- vo_cocoa_swap_buffers(ctx->vo);
- p->Flush();
-}
-
-static bool cocoa_init(struct ra_ctx *ctx)
-{
- struct priv *p = ctx->priv = talloc_zero(ctx, struct priv);
- GL *gl = &p->gl;
- p->opts = mp_get_config_group(ctx, ctx->global, &cocoa_conf);
- p->macos_opts = mp_get_config_group(ctx, ctx->global, &macos_conf);
- vo_cocoa_init(ctx->vo);
-
- MP_WARN(ctx->vo, "opengl cocoa backend is deprecated, use vo=libmpv instead\n");
-
- if (!create_gl_context(ctx))
- goto fail;
-
- struct ra_gl_ctx_params params = {
- .swap_buffers = cocoa_swap_buffers,
- };
-
- if (!ra_gl_ctx_init(ctx, gl, params))
- goto fail;
-
- return true;
-
-fail:
- cocoa_uninit(ctx);
- return false;
-}
-
-static void resize(struct ra_ctx *ctx)
-{
- ra_gl_ctx_resize(ctx->swapchain, ctx->vo->dwidth, ctx->vo->dheight, 0);
-}
-
-static bool cocoa_reconfig(struct ra_ctx *ctx)
-{
- vo_cocoa_config_window(ctx->vo);
- resize(ctx);
- return true;
-}
-
-static int cocoa_control(struct ra_ctx *ctx, int *events, int request,
- void *arg)
-{
- int ret = vo_cocoa_control(ctx->vo, events, request, arg);
- if (*events & VO_EVENT_RESIZE)
- resize(ctx);
- return ret;
-}
-
-const struct ra_ctx_fns ra_ctx_cocoa = {
- .type = "opengl",
- .name = "cocoa",
- .init = cocoa_init,
- .reconfig = cocoa_reconfig,
- .control = cocoa_control,
- .uninit = cocoa_uninit,
-};
diff --git a/video/out/opengl/context_drm_egl.c b/video/out/opengl/context_drm_egl.c
index 86ce57122c..da28093562 100644
--- a/video/out/opengl/context_drm_egl.c
+++ b/video/out/opengl/context_drm_egl.c
@@ -26,11 +26,14 @@
#include <gbm.h>
#include <EGL/egl.h>
#include <EGL/eglext.h>
+#include <drm_fourcc.h>
#include "libmpv/render_gl.h"
-#include "video/out/drm_common.h"
#include "common/common.h"
#include "osdep/timer.h"
+#include "video/out/drm_atomic.h"
+#include "video/out/drm_common.h"
+#include "video/out/present_sync.h"
#include "egl_helpers.h"
#include "common.h"
@@ -44,35 +47,18 @@
#define EGL_PLATFORM_GBM_KHR 0x31D7
#endif
<