EGL: add context priority for the EGL context creation API

Allows to specify context priority low, medium, high or realtime if
the extension is available. This is currently only implemented for
the EGL context creation API.
This commit is contained in:
Gregor Burger 2022-04-01 12:52:12 +02:00
parent 955fbd9d26
commit 0a898628ff
7 changed files with 98 additions and 1 deletions

View File

@ -437,6 +437,18 @@ Context release behaviors are described in detail by the
[GL_KHR_context_flush_control](https://www.opengl.org/registry/specs/KHR/context_flush_control.txt)
extension.
@anchor GLFW_CONTEXT_PRIORITY_hint
__GLFW_CONTEXT_PRIORITY__ specifies the context priority to be used by the
context. Possible values are one of `GLFW_PRIORITY_LOW`, `GLFW_PRIORITY_MEDIUM`,
`GLFW_PRIORITY_HIGH` or `GLFW_PRIORITY_REALTIME`. This functionality is currently
only implemented for the EGL context creating API.
Context priorities are described in detail by the
[EGL_NV_context_priority_realtime](https://www.khronos.org/registry/EGL/extensions/NV/EGL_NV_context_priority_realtime.txt)
and
[EGL_IMG_context_priority](https://www.khronos.org/registry/EGL/extensions/IMG/EGL_IMG_context_priority.txt)
extensions.
@anchor GLFW_CONTEXT_NO_ERROR_hint
__GLFW_CONTEXT_NO_ERROR__ specifies whether errors should be generated by the
context. Possible values are `GLFW_TRUE` and `GLFW_FALSE`. If enabled,
@ -531,6 +543,7 @@ GLFW_CONTEXT_VERSION_MAJOR | 1 | Any valid major ve
GLFW_CONTEXT_VERSION_MINOR | 0 | Any valid minor version number of the chosen client API
GLFW_CONTEXT_ROBUSTNESS | `GLFW_NO_ROBUSTNESS` | `GLFW_NO_ROBUSTNESS`, `GLFW_NO_RESET_NOTIFICATION` or `GLFW_LOSE_CONTEXT_ON_RESET`
GLFW_CONTEXT_RELEASE_BEHAVIOR | `GLFW_ANY_RELEASE_BEHAVIOR` | `GLFW_ANY_RELEASE_BEHAVIOR`, `GLFW_RELEASE_BEHAVIOR_FLUSH` or `GLFW_RELEASE_BEHAVIOR_NONE`
GLFW_CONTEXT_PRIORITY | `GLFW_PRIORITY_MEDIUM` | `GLFW_PRIORITY_LOW`, `GLFW_PRIORITY_MEDIUM`, `GLFW_PRIORITY_HIGH`, `GLFW_PRIORITY_REALTIME`
GLFW_OPENGL_FORWARD_COMPAT | `GLFW_FALSE` | `GLFW_TRUE` or `GLFW_FALSE`
GLFW_CONTEXT_DEBUG | `GLFW_FALSE` | `GLFW_TRUE` or `GLFW_FALSE`
GLFW_OPENGL_PROFILE | `GLFW_OPENGL_ANY_PROFILE` | `GLFW_OPENGL_ANY_PROFILE`, `GLFW_OPENGL_COMPAT_PROFILE` or `GLFW_OPENGL_CORE_PROFILE`

View File

@ -1085,6 +1085,11 @@ extern "C" {
* [window hint](@ref GLFW_SCALE_TO_MONITOR).
*/
#define GLFW_SCALE_TO_MONITOR 0x0002200C
/*! @brief Context priority.
*
* Context priority hint [hint](@ref GLFW_CONTEXT_PRIORITY_hint).
*/
#define GLFW_CONTEXT_PRIORITY 0x0002200D
/*! @brief macOS specific
* [window hint](@ref GLFW_COCOA_RETINA_FRAMEBUFFER_hint).
*/
@ -1146,6 +1151,11 @@ extern "C" {
#define GLFW_ANGLE_PLATFORM_TYPE_VULKAN 0x00037007
#define GLFW_ANGLE_PLATFORM_TYPE_METAL 0x00037008
#define GLFW_PRIORITY_LOW 0x00038001
#define GLFW_PRIORITY_MEDIUM 0x00038002
#define GLFW_PRIORITY_HIGH 0x00038003
#define GLFW_PRIORITY_REALTIME 0x00038004
/*! @defgroup shapes Standard cursor shapes
* @brief Standard system cursor shapes.
*

View File

@ -170,6 +170,20 @@ GLFWbool _glfwIsValidContextConfig(const _GLFWctxconfig* ctxconfig)
}
}
if (ctxconfig->priority)
{
if (ctxconfig->priority != GLFW_PRIORITY_LOW &&
ctxconfig->priority != GLFW_PRIORITY_MEDIUM &&
ctxconfig->priority != GLFW_PRIORITY_HIGH &&
ctxconfig->priority != GLFW_PRIORITY_REALTIME)
{
_glfwInputError(GLFW_INVALID_ENUM,
"Invalid context priority 0x%08X",
ctxconfig->priority);
return GLFW_FALSE;
}
}
return GLFW_TRUE;
}

View File

@ -485,6 +485,8 @@ GLFWbool _glfwInitEGL(void)
extensionSupportedEGL("EGL_KHR_context_flush_control");
_glfw.egl.EXT_present_opaque =
extensionSupportedEGL("EGL_EXT_present_opaque");
_glfw.egl.IMG_context_priority =
extensionSupportedEGL("EGL_IMG_context_priority");
return GLFW_TRUE;
}
@ -634,6 +636,24 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window,
}
}
if (_glfw.egl.IMG_context_priority && ctxconfig->priority != GLFW_PRIORITY_MEDIUM)
{
if (ctxconfig->priority == GLFW_PRIORITY_LOW)
{
SET_ATTRIB(EGL_CONTEXT_PRIORITY_LEVEL_IMG,
EGL_CONTEXT_PRIORITY_LOW_IMG);
} else if (ctxconfig->priority == GLFW_PRIORITY_HIGH)
{
SET_ATTRIB(EGL_CONTEXT_PRIORITY_LEVEL_IMG,
EGL_CONTEXT_PRIORITY_HIGH_IMG);
}
else if (ctxconfig->priority == GLFW_PRIORITY_REALTIME)
{
SET_ATTRIB(EGL_CONTEXT_PRIORITY_LEVEL_IMG,
EGL_CONTEXT_PRIORITY_REALTIME_NV);
}
}
SET_ATTRIB(EGL_NONE, EGL_NONE);
window->context.egl.handle = eglCreateContext(_glfw.egl.display,

View File

@ -187,6 +187,11 @@ typedef const GLubyte* (APIENTRY * PFNGLGETSTRINGIPROC)(GLenum,GLuint);
#define EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE 0x3450
#define EGL_PLATFORM_ANGLE_TYPE_METAL_ANGLE 0x3489
#define EGL_PLATFORM_ANGLE_NATIVE_PLATFORM_TYPE_ANGLE 0x348f
#define EGL_CONTEXT_PRIORITY_LEVEL_IMG 0x3100
#define EGL_CONTEXT_PRIORITY_HIGH_IMG 0x3101
#define EGL_CONTEXT_PRIORITY_MEDIUM_IMG 0x3102
#define EGL_CONTEXT_PRIORITY_LOW_IMG 0x3103
#define EGL_CONTEXT_PRIORITY_REALTIME_NV 0x3357
typedef int EGLint;
typedef unsigned int EGLBoolean;
@ -441,6 +446,7 @@ struct _GLFWctxconfig
int profile;
int robustness;
int release;
int priority;
_GLFWwindow* share;
struct {
GLFWbool offline;
@ -810,6 +816,7 @@ struct _GLFWlibrary
GLFWbool ANGLE_platform_angle_d3d;
GLFWbool ANGLE_platform_angle_vulkan;
GLFWbool ANGLE_platform_angle_metal;
GLFWbool IMG_context_priority;
void* handle;

View File

@ -262,6 +262,7 @@ void glfwDefaultWindowHints(void)
_glfw.hints.context.source = GLFW_NATIVE_CONTEXT_API;
_glfw.hints.context.major = 1;
_glfw.hints.context.minor = 0;
_glfw.hints.context.priority = GLFW_PRIORITY_MEDIUM;
// The default is a focused, visible, resizable window with decorations
memset(&_glfw.hints.window, 0, sizeof(_glfw.hints.window));
@ -420,6 +421,9 @@ GLFWAPI void glfwWindowHint(int hint, int value)
case GLFW_REFRESH_RATE:
_glfw.hints.refreshRate = value;
return;
case GLFW_CONTEXT_PRIORITY:
_glfw.hints.context.priority = value;
return;
}
_glfwInputError(GLFW_INVALID_ENUM, "Invalid window hint 0x%08X", hint);

View File

@ -71,6 +71,11 @@
#define PLATFORM_NAME_X11 "x11"
#define PLATFORM_NAME_NULL "null"
#define PRIORITY_LOW "low"
#define PRIORITY_MEDIUM "medium"
#define PRIORITY_HIGH "high"
#define PRIORITY_REALTIME "realtime"
static void usage(void)
{
printf("Usage: glfwinfo [OPTION]...\n");
@ -133,6 +138,11 @@ static void usage(void)
ANGLE_TYPE_METAL ")\n");
printf(" --graphics-switching request macOS graphics switching\n");
printf(" --disable-xcb-surface disable VK_KHR_xcb_surface extension\n");
printf(" --priority=PRIORITY request context priority to use ("
PRIORITY_LOW ","
PRIORITY_MEDIUM ","
PRIORITY_HIGH ","
PRIORITY_REALTIME ")\n");
}
static void error_callback(int error, const char* description)
@ -391,6 +401,7 @@ int main(int argc, char** argv)
int context_robustness = GLFW_NO_ROBUSTNESS;
bool context_debug = false;
bool context_no_error = false;
int context_priority = GLFW_PRIORITY_MEDIUM;
bool opengl_forward = false;
int opengl_profile = GLFW_OPENGL_ANY_PROFILE;
int fb_red_bits = 8;
@ -418,7 +429,7 @@ int main(int argc, char** argv)
REDBITS, GREENBITS, BLUEBITS, ALPHABITS, DEPTHBITS, STENCILBITS,
ACCUMREDBITS, ACCUMGREENBITS, ACCUMBLUEBITS, ACCUMALPHABITS,
AUXBUFFERS, SAMPLES, STEREO, SRGB, SINGLEBUFFER, NOERROR_SRSLY,
ANGLE_TYPE, GRAPHICS_SWITCHING, XCB_SURFACE };
ANGLE_TYPE, GRAPHICS_SWITCHING, XCB_SURFACE, PRIORITY };
const struct option options[] =
{
{ "platform", 1, NULL, PLATFORM },
@ -454,6 +465,7 @@ int main(int argc, char** argv)
{ "angle-type", 1, NULL, ANGLE_TYPE },
{ "graphics-switching", 0, NULL, GRAPHICS_SWITCHING },
{ "vk-xcb-surface", 0, NULL, XCB_SURFACE },
{ "priority", 1, NULL, PRIORITY },
{ NULL, 0, NULL, 0 }
};
@ -682,6 +694,22 @@ int main(int argc, char** argv)
case XCB_SURFACE:
disable_xcb_surface = true;
break;
case PRIORITY:
if (strcasecmp(optarg, PRIORITY_LOW) == 0)
context_priority = GLFW_PRIORITY_LOW;
else if (strcasecmp(optarg, PRIORITY_MEDIUM) == 0)
context_priority = GLFW_PRIORITY_MEDIUM;
else if (strcasecmp(optarg, PRIORITY_HIGH) == 0)
context_priority = GLFW_PRIORITY_HIGH;
else if (strcasecmp(optarg, PRIORITY_REALTIME) == 0)
context_priority = GLFW_PRIORITY_REALTIME;
else
{
usage();
exit(EXIT_FAILURE);
}
break;
default:
usage();
exit(EXIT_FAILURE);
@ -720,6 +748,7 @@ int main(int argc, char** argv)
glfwWindowHint(GLFW_CONTEXT_NO_ERROR, context_no_error);
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, opengl_forward);
glfwWindowHint(GLFW_OPENGL_PROFILE, opengl_profile);
glfwWindowHint(GLFW_CONTEXT_PRIORITY, context_priority);
glfwWindowHint(GLFW_RED_BITS, fb_red_bits);
glfwWindowHint(GLFW_BLUE_BITS, fb_blue_bits);