feat(linux/glad): implement EGL_IMG_context_priority (#4857)

This commit is contained in:
Conn O'Griofa
2026-03-22 00:27:21 +00:00
committed by GitHub
parent 0d3be0bb1e
commit ae8adfd8ed
9 changed files with 72 additions and 23 deletions

View File

@@ -11,6 +11,11 @@
#include "src/logging.h"
#include "src/video.h"
// platform includes
#if !defined(__FreeBSD__)
#include <sys/capability.h>
#endif
extern "C" {
#include <libavutil/pixdesc.h>
}
@@ -387,6 +392,18 @@ namespace egl {
}
std::optional<ctx_t> make_ctx(display_t::pointer display) {
bool nice_warning = false;
#if !defined(__FreeBSD__)
cap_t caps = cap_get_proc();
cap_value_t sys_nice = CAP_SYS_NICE;
if (cap_set_flag(caps, CAP_EFFECTIVE, 1, &sys_nice, CAP_SET) || cap_set_proc(caps)) {
BOOST_LOG(debug) << "Failed to gain CAP_SYS_NICE"sv;
nice_warning = true;
}
cap_free(caps);
#endif
constexpr int conf_attr[] {
EGL_RENDERABLE_TYPE,
EGL_OPENGL_BIT,
@@ -405,20 +422,42 @@ namespace egl {
return std::nullopt;
}
constexpr int attr[] {
EGL_CONTEXT_CLIENT_VERSION,
3,
EGL_NONE
};
const char *extension_st = eglQueryString(display, EGL_EXTENSIONS);
ctx_t ctx {display, eglCreateContext(display, conf, EGL_NO_CONTEXT, attr)};
if (fail()) {
std::vector<EGLint> attr;
attr.push_back(EGL_CONTEXT_CLIENT_VERSION);
attr.push_back(3);
// Only add the high priority attribute if the driver explicitly supports it
if (extension_st && std::string_view(extension_st).contains("EGL_IMG_context_priority"sv)) {
BOOST_LOG(debug) << "EGL: High priority context supported"sv;
attr.push_back(EGL_CONTEXT_PRIORITY_LEVEL_IMG);
attr.push_back(EGL_CONTEXT_PRIORITY_HIGH_IMG);
}
attr.push_back(EGL_NONE);
EGLContext raw_ctx = eglCreateContext(display, conf, EGL_NO_CONTEXT, attr.data());
if (raw_ctx == EGL_NO_CONTEXT) {
BOOST_LOG(error) << "Couldn't create EGL context: ["sv << util::hex(eglGetError()).to_string_view() << ']';
return std::nullopt;
}
TUPLE_EL_REF(ctx_p, 1, ctx.el);
if (!eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, ctx_p)) {
ctx_t ctx {display, raw_ctx};
EGLint actual_priority = EGL_CONTEXT_PRIORITY_MEDIUM_IMG;
std::string actual_priority_str = "MEDIUM";
if (eglQueryContext(display, raw_ctx, EGL_CONTEXT_PRIORITY_LEVEL_IMG, &actual_priority)) {
if (actual_priority == EGL_CONTEXT_PRIORITY_HIGH_IMG) {
actual_priority_str = "HIGH";
}
if (nice_warning) {
BOOST_LOG(warning) << "EGL: context priority set to "sv << actual_priority_str << " but CAP_SYS_NICE capability is missing"sv;
} else {
BOOST_LOG(info) << "EGL: context priority set to "sv << actual_priority_str;
}
}
if (!eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, raw_ctx)) {
BOOST_LOG(error) << "Couldn't make current display"sv;
return std::nullopt;
}
@@ -453,6 +492,14 @@ namespace egl {
gl::ctx.PixelStorei(GL_UNPACK_ALIGNMENT, 1);
#if !defined(__FreeBSD__)
caps = cap_get_proc();
if (cap_set_flag(caps, CAP_EFFECTIVE, 1, &sys_nice, CAP_CLEAR) || cap_set_proc(caps)) {
BOOST_LOG(debug) << "Failed to drop CAP_SYS_NICE"sv;
}
cap_free(caps);
#endif
return ctx;
}