mirror of https://github.com/mpv-player/mpv
opengl: add --egl-output-format
This commit is contained in:
parent
cd74f8f7c5
commit
c55ff4176c
|
@ -1 +1,2 @@
|
||||||
add `--egl-config-id` option
|
add `--egl-config-id` option
|
||||||
|
add `--egl-output-format` option
|
||||||
|
|
|
@ -5722,6 +5722,27 @@ them.
|
||||||
Rendering surfaces and contexts will be created using this EGLConfig.
|
Rendering surfaces and contexts will be created using this EGLConfig.
|
||||||
You can use ``--msg-level=vo=trace`` to obtain a list of available configs.
|
You can use ``--msg-level=vo=trace`` to obtain a list of available configs.
|
||||||
|
|
||||||
|
``--egl-output-format=<auto|rgb8|rgba8|rgb10|rgb10_a2|rgb16|rgba16|rgb16f|rgba16f|rgb32f|rgba32f>``
|
||||||
|
(EGL only)
|
||||||
|
Select a specific EGL output format to utilize for OpenGL rendering.
|
||||||
|
This option is mutually exclusive with ``--egl-config-id``.
|
||||||
|
"auto" is the default, which will pick the first usable config
|
||||||
|
based on the order given by the driver.
|
||||||
|
|
||||||
|
All formats are not available.
|
||||||
|
A fatal error is caused if an unavailable format is selected.
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
|
||||||
|
There is no reliable API to query desktop bit depth in EGL.
|
||||||
|
You can manually set this option
|
||||||
|
according to the bit depth of your display.
|
||||||
|
This option also affects the auto-detection of ``--dither-depth``.
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
|
||||||
|
Unlike ``--d3d11-output-format``, this option also takes effect with ``--vo=gpu-next``.
|
||||||
|
|
||||||
``--vulkan-device=<device name|UUID>``
|
``--vulkan-device=<device name|UUID>``
|
||||||
The name or UUID of the Vulkan device to use for rendering and presentation. Use
|
The name or UUID of the Vulkan device to use for rendering and presentation. Use
|
||||||
``--vulkan-device=help`` to see the list of available devices and their
|
``--vulkan-device=help`` to see the list of available devices and their
|
||||||
|
|
|
@ -905,7 +905,7 @@ static const m_option_t mp_opts[] = {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if HAVE_EGL || HAVE_EGL_ANDROID || HAVE_EGL_ANGLE_WIN32
|
#if HAVE_EGL || HAVE_EGL_ANDROID || HAVE_EGL_ANGLE_WIN32
|
||||||
{"", OPT_SUBSTRUCT(egl_opts, egl_conf)},
|
{"egl", OPT_SUBSTRUCT(egl_opts, egl_conf)},
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if HAVE_VULKAN
|
#if HAVE_VULKAN
|
||||||
|
|
|
@ -54,6 +54,12 @@ typedef intptr_t EGLAttrib;
|
||||||
#define EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR 0
|
#define EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef EGL_COLOR_COMPONENT_TYPE_EXT
|
||||||
|
#define EGL_COLOR_COMPONENT_TYPE_EXT EGL_NONE
|
||||||
|
#define EGL_COLOR_COMPONENT_TYPE_FLOAT_EXT EGL_NONE
|
||||||
|
#define EGL_COLOR_COMPONENT_TYPE_FIXED_EXT EGL_NONE
|
||||||
|
#endif
|
||||||
|
|
||||||
struct mp_egl_config_attr {
|
struct mp_egl_config_attr {
|
||||||
int attrib;
|
int attrib;
|
||||||
const char *name;
|
const char *name;
|
||||||
|
@ -103,12 +109,35 @@ static void *mpegl_get_proc_address(void *ctx, const char *name)
|
||||||
|
|
||||||
struct egl_opts {
|
struct egl_opts {
|
||||||
int config_id;
|
int config_id;
|
||||||
|
int output_format;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define RGBA_FORMAT(r, g, b, a) ((r) << 18 | (g) << 12 | (b) << 6 | (a))
|
||||||
|
#define FLOAT_FORMAT (1 << 24)
|
||||||
|
static void unpack_format(int format, EGLint *r_size, EGLint *g_size, EGLint *b_size, EGLint *a_size, bool *is_float) {
|
||||||
|
*is_float = format & FLOAT_FORMAT;
|
||||||
|
*r_size = format >> 18 & 0x3f;
|
||||||
|
*g_size = (format >> 12) & 0x3f;
|
||||||
|
*b_size = (format >> 6) & 0x3f;
|
||||||
|
*a_size = format & 0x3f;
|
||||||
|
}
|
||||||
|
|
||||||
#define OPT_BASE_STRUCT struct egl_opts
|
#define OPT_BASE_STRUCT struct egl_opts
|
||||||
const struct m_sub_options egl_conf = {
|
const struct m_sub_options egl_conf = {
|
||||||
.opts = (const struct m_option[]) {
|
.opts = (const struct m_option[]) {
|
||||||
{"egl-config-id", OPT_INT(config_id)},
|
{"config-id", OPT_INT(config_id)},
|
||||||
|
{"output-format", OPT_CHOICE(output_format,
|
||||||
|
{"auto", 0},
|
||||||
|
{"rgb8", RGBA_FORMAT(8, 8, 8, 0)},
|
||||||
|
{"rgba8", RGBA_FORMAT(8, 8, 8, 8)},
|
||||||
|
{"rgb10", RGBA_FORMAT(10, 10, 10, 0)},
|
||||||
|
{"rgb10_a2", RGBA_FORMAT(10, 10, 10, 2)},
|
||||||
|
{"rgb16", RGBA_FORMAT(16, 16, 16, 0)},
|
||||||
|
{"rgba16", RGBA_FORMAT(16, 16, 16, 16)},
|
||||||
|
{"rgb16f", RGBA_FORMAT(16, 16, 16, 0) | FLOAT_FORMAT},
|
||||||
|
{"rgba16f", RGBA_FORMAT(16, 16, 16, 16) | FLOAT_FORMAT},
|
||||||
|
{"rgb32f", RGBA_FORMAT(32, 32, 32, 0) | FLOAT_FORMAT},
|
||||||
|
{"rgba32f", RGBA_FORMAT(32, 32, 32, 32) | FLOAT_FORMAT})},
|
||||||
{0},
|
{0},
|
||||||
},
|
},
|
||||||
.size = sizeof(struct egl_opts),
|
.size = sizeof(struct egl_opts),
|
||||||
|
@ -134,6 +163,8 @@ static bool create_context(struct ra_ctx *ctx, EGLDisplay display,
|
||||||
name = "GLES 2.x +";
|
name = "GLES 2.x +";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const char *egl_exts = eglQueryString(display, EGL_EXTENSIONS);
|
||||||
|
|
||||||
MP_VERBOSE(ctx, "Trying to create %s context.\n", name);
|
MP_VERBOSE(ctx, "Trying to create %s context.\n", name);
|
||||||
|
|
||||||
if (!eglBindAPI(api)) {
|
if (!eglBindAPI(api)) {
|
||||||
|
@ -141,19 +172,31 @@ static bool create_context(struct ra_ctx *ctx, EGLDisplay display,
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool request_float_fmt;
|
||||||
|
EGLint r_size, g_size, b_size, a_size;
|
||||||
|
unpack_format(opts->output_format, &r_size, &g_size, &b_size, &a_size, &request_float_fmt);
|
||||||
|
bool has_float_format_ext = gl_check_extension(egl_exts, "EGL_EXT_pixel_format_float");
|
||||||
|
if (request_float_fmt && !has_float_format_ext) {
|
||||||
|
MP_MSG(ctx, msgl, "Could not request floating point pixel format for %s!\n", name);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
EGLint attributes[] = {
|
EGLint attributes[] = {
|
||||||
EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
|
EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
|
||||||
EGL_RED_SIZE, 8,
|
|
||||||
EGL_GREEN_SIZE, 8,
|
|
||||||
EGL_BLUE_SIZE, 8,
|
|
||||||
EGL_ALPHA_SIZE, ctx->opts.want_alpha ? 8 : 0,
|
|
||||||
EGL_RENDERABLE_TYPE, rend,
|
EGL_RENDERABLE_TYPE, rend,
|
||||||
|
EGL_RED_SIZE, MPMAX(r_size, 8),
|
||||||
|
EGL_GREEN_SIZE, MPMAX(g_size, 8),
|
||||||
|
EGL_BLUE_SIZE, MPMAX(b_size, 8),
|
||||||
|
EGL_ALPHA_SIZE, opts->output_format ? a_size : (ctx->opts.want_alpha ? 8 : 0),
|
||||||
|
opts->output_format && has_float_format_ext ? EGL_COLOR_COMPONENT_TYPE_EXT : EGL_NONE,
|
||||||
|
request_float_fmt ? EGL_COLOR_COMPONENT_TYPE_FLOAT_EXT : EGL_COLOR_COMPONENT_TYPE_FIXED_EXT,
|
||||||
EGL_NONE
|
EGL_NONE
|
||||||
};
|
};
|
||||||
if (opts->config_id) {
|
if (opts->config_id) {
|
||||||
attributes[0] = EGL_CONFIG_ID;
|
// Keep EGL_SURFACE_TYPE & EGL_RENDERABLE_TYPE
|
||||||
attributes[1] = opts->config_id;
|
attributes[4] = EGL_CONFIG_ID;
|
||||||
attributes[2] = EGL_NONE;
|
attributes[5] = opts->config_id;
|
||||||
|
attributes[6] = EGL_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
EGLint num_configs;
|
EGLint num_configs;
|
||||||
|
@ -174,9 +217,20 @@ static bool create_context(struct ra_ctx *ctx, EGLDisplay display,
|
||||||
dump_egl_config(ctx->log, MSGL_TRACE, display, configs[n]);
|
dump_egl_config(ctx->log, MSGL_TRACE, display, configs[n]);
|
||||||
|
|
||||||
int chosen = 0;
|
int chosen = 0;
|
||||||
if (cb.refine_config)
|
if (opts->output_format) {
|
||||||
|
for (; chosen < num_configs; chosen++) {
|
||||||
|
EGLint real_r_size, real_g_size, real_b_size, real_a_size;
|
||||||
|
eglGetConfigAttrib(display, configs[chosen], EGL_RED_SIZE, &real_r_size);
|
||||||
|
eglGetConfigAttrib(display, configs[chosen], EGL_GREEN_SIZE, &real_g_size);
|
||||||
|
eglGetConfigAttrib(display, configs[chosen], EGL_BLUE_SIZE, &real_b_size);
|
||||||
|
eglGetConfigAttrib(display, configs[chosen], EGL_ALPHA_SIZE, &real_a_size);
|
||||||
|
if (r_size == real_r_size && g_size == real_g_size && b_size == real_b_size && a_size == real_a_size)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else if (cb.refine_config) {
|
||||||
chosen = cb.refine_config(cb.user_data, configs, num_configs);
|
chosen = cb.refine_config(cb.user_data, configs, num_configs);
|
||||||
if (chosen < 0) {
|
}
|
||||||
|
if (chosen < 0 || chosen == num_configs) {
|
||||||
talloc_free(configs);
|
talloc_free(configs);
|
||||||
MP_MSG(ctx, msgl, "Could not refine EGLConfig for %s!\n", name);
|
MP_MSG(ctx, msgl, "Could not refine EGLConfig for %s!\n", name);
|
||||||
return false;
|
return false;
|
||||||
|
|
Loading…
Reference in New Issue