From 1ae221afb2c03d2b3cd0a607dc6646f33c07341c Mon Sep 17 00:00:00 2001 From: Brendan King Date: Mon, 10 Feb 2020 09:23:03 +0000 Subject: [PATCH] egl: query the supported ES2 context version For OpenGL ES contexts, the EGL specification states that querying EGL_CONTEXT_CLIENT_VERSION with eglQueryContext may return a version that differs from that specified at context creation time. For example, if an OpenGL ES2 context is specified at context creation time, an OpenGL ES3 context may be created, and so "3" should be returned when EGL_CONTEXT_CLIENT_VERSION is queried. A new EGL driver API function has been added, QueryContextClientVersion, that is called when the context client version is queried, allowing EGL drivers to override the default value (i.e. the version specified at context creation time). If the function returns zero, the default is used. For DRI drivers, QueryContextClientVersion returns zero for all API contexts other than OpenGL ES2. For OpenGL ES2, the supported context client version is queried via the Query Renderer driver extension, using integer query __DRI2_RENDERER_OPENGL_ES2_CONTEXT_CLIENT_VERSION_IMG. If the query isn't supported, or the query returns zero, zero is returned to the caller. IMG NOTE: In order to avoid potential name and value clashes, "_IMG" has been added to the end of the new query name, this should be removed if an attempt is made to push this patch upstream. The value of the new query should be adjusted to be the next one in sequence, rather than the large value it currently has. --- include/GL/internal/dri_interface.h | 2 ++ src/egl/drivers/dri2/egl_dri2.c | 21 +++++++++++++++++++++ src/egl/drivers/haiku/egl_haiku.cpp | 9 +++++++++ src/egl/main/eglapi.c | 2 +- src/egl/main/eglcontext.c | 16 ++++++++++++++-- src/egl/main/eglcontext.h | 3 ++- src/egl/main/egldriver.h | 1 + 7 files changed, 50 insertions(+), 4 deletions(-) diff --git a/include/GL/internal/dri_interface.h b/include/GL/internal/dri_interface.h index 6490f6e..9c7bcac 100644 --- a/include/GL/internal/dri_interface.h +++ b/include/GL/internal/dri_interface.h @@ -2052,6 +2052,8 @@ typedef struct __DRIDriverVtableExtensionRec { #define __DRI2_RENDERER_HAS_PROTECTED_CONTENT 0x000e +#define __DRI2_RENDERER_OPENGL_ES2_CONTEXT_CLIENT_VERSION_IMG 0x7001 + typedef struct __DRI2rendererQueryExtensionRec __DRI2rendererQueryExtension; struct __DRI2rendererQueryExtensionRec { __DRIextension base; diff --git a/src/egl/drivers/dri2/egl_dri2.c b/src/egl/drivers/dri2/egl_dri2.c index 6b26ff9..c4a49ca 100644 --- a/src/egl/drivers/dri2/egl_dri2.c +++ b/src/egl/drivers/dri2/egl_dri2.c @@ -2055,6 +2055,26 @@ dri2_make_current(_EGLDisplay *disp, _EGLSurface *dsurf, return EGL_TRUE; } +static EGLint +dri2_query_context_client_version(_EGLDisplay *disp, _EGLContext *ctx) +{ + struct dri2_egl_context *dri2_ctx = dri2_egl_context(ctx); + struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); + + switch (dri2_ctx->base.ClientAPI) { + case EGL_OPENGL_ES_API: + switch (dri2_ctx->base.ClientMajorVersion) { + case 2: + return dri2_renderer_query_integer(dri2_dpy, + __DRI2_RENDERER_OPENGL_ES2_CONTEXT_CLIENT_VERSION_IMG); + default: + return 0; + } + default: + return 0; + } +} + __DRIdrawable * dri2_surface_get_dri_drawable(_EGLSurface *surf) { @@ -4336,6 +4356,7 @@ const _EGLDriver _eglDriver = { .CreateContext = dri2_create_context, .DestroyContext = dri2_destroy_context, .MakeCurrent = dri2_make_current, + .QueryContextClientVersion = dri2_query_context_client_version, .CreateWindowSurface = dri2_create_window_surface, .CreatePixmapSurface = dri2_create_pixmap_surface, .CreatePbufferSurface = dri2_create_pbuffer_surface, diff --git a/src/egl/drivers/haiku/egl_haiku.cpp b/src/egl/drivers/haiku/egl_haiku.cpp index 18c73c9..2690a82 100644 --- a/src/egl/drivers/haiku/egl_haiku.cpp +++ b/src/egl/drivers/haiku/egl_haiku.cpp @@ -297,6 +297,14 @@ haiku_make_current(_EGLDisplay *disp, _EGLSurface *dsurf, } +extern "C" +EGLint +haiku_dri2_query_context_client_version(_EGLDisplay *disp, _EGLContext *ctx) +{ + // Tell caller to use the default value. + return 0; +} + extern "C" EGLBoolean haiku_swap_buffers(_EGLDisplay *disp, _EGLSurface *surf) @@ -316,6 +324,7 @@ const _EGLDriver _eglDriver = { .CreateContext = haiku_create_context, .DestroyContext = haiku_destroy_context, .MakeCurrent = haiku_make_current, + .QueryContextClientVersion = haiku_dri2_query_context_client_version, .CreateWindowSurface = haiku_create_window_surface, .CreatePixmapSurface = haiku_create_pixmap_surface, .CreatePbufferSurface = haiku_create_pbuffer_surface, diff --git a/src/egl/main/eglapi.c b/src/egl/main/eglapi.c index 2d3931d..1cbff96 100644 --- a/src/egl/main/eglapi.c +++ b/src/egl/main/eglapi.c @@ -948,7 +948,7 @@ eglQueryContext(EGLDisplay dpy, EGLContext ctx, _EGL_CHECK_CONTEXT(disp, context, EGL_FALSE); - ret = _eglQueryContext(context, attribute, value); + ret = _eglQueryContext(disp, context, attribute, value); RETURN_EGL_EVAL(disp, ret); } diff --git a/src/egl/main/eglcontext.c b/src/egl/main/eglcontext.c index 15de7c9..7274d24 100644 --- a/src/egl/main/eglcontext.c +++ b/src/egl/main/eglcontext.c @@ -35,6 +35,7 @@ #include "eglcontext.h" #include "egldisplay.h" #include "eglcurrent.h" +#include "egldriver.h" #include "eglsurface.h" #include "egllog.h" #include "util/macros.h" @@ -670,8 +671,19 @@ _eglQueryContextRenderBuffer(_EGLContext *ctx) } +static EGLint +_eglQueryContextClientVersion(_EGLDisplay *disp, _EGLContext *ctx) +{ + EGLint version; + + version = disp->Driver->QueryContextClientVersion(disp, ctx); + + return (version) ? version : ctx->ClientMajorVersion; +} + EGLBoolean -_eglQueryContext(_EGLContext *c, EGLint attribute, EGLint *value) +_eglQueryContext(_EGLDisplay *disp, _EGLContext *c, + EGLint attribute, EGLint *value) { if (!value) return _eglError(EGL_BAD_PARAMETER, "eglQueryContext"); @@ -688,7 +700,7 @@ _eglQueryContext(_EGLContext *c, EGLint attribute, EGLint *value) *value = c->Config ? c->Config->ConfigID : 0; break; case EGL_CONTEXT_CLIENT_VERSION: - *value = c->ClientMajorVersion; + *value = _eglQueryContextClientVersion(disp, c); break; case EGL_CONTEXT_CLIENT_TYPE: *value = c->ClientAPI; diff --git a/src/egl/main/eglcontext.h b/src/egl/main/eglcontext.h index 06029e8..d890217 100644 --- a/src/egl/main/eglcontext.h +++ b/src/egl/main/eglcontext.h @@ -74,7 +74,8 @@ _eglInitContext(_EGLContext *ctx, _EGLDisplay *disp, extern EGLBoolean -_eglQueryContext(_EGLContext *ctx, EGLint attribute, EGLint *value); +_eglQueryContext(_EGLDisplay *disp, _EGLContext *ctx, + EGLint attribute, EGLint *value); extern EGLBoolean diff --git a/src/egl/main/egldriver.h b/src/egl/main/egldriver.h index 12f9a0a..92af8bd 100644 --- a/src/egl/main/egldriver.h +++ b/src/egl/main/egldriver.h @@ -97,6 +97,7 @@ struct _egl_driver EGLBoolean (*MakeCurrent)(_EGLDisplay *disp, _EGLSurface *draw, _EGLSurface *read, _EGLContext *ctx); + EGLint (*QueryContextClientVersion)(_EGLDisplay *disp, _EGLContext *ctx); /* surface funcs */ _EGLSurface *(*CreateWindowSurface)(_EGLDisplay *disp, _EGLConfig *config,