From 51f11929f376a217d4307f0827e02f84d002f041 Mon Sep 17 00:00:00 2001 From: Doug Binks Date: Mon, 13 Jul 2020 18:48:10 +0100 Subject: [PATCH] User context Wayland and EGL implementations --- src/egl_context.c | 115 +++++++++++++++++++++++++++++++++++++--------- src/wgl_context.h | 14 +++--- src/wl_platform.h | 1 + src/wl_window.c | 13 ++++++ 4 files changed, 114 insertions(+), 29 deletions(-) diff --git a/src/egl_context.c b/src/egl_context.c index b059c4d9..2ea33da4 100644 --- a/src/egl_context.c +++ b/src/egl_context.c @@ -500,17 +500,15 @@ void _glfwTerminateEGL(void) attribs[index++] = v; \ } -// Create the OpenGL or OpenGL ES context +// Create the OpenGL or OpenGL ES context for the window eglConfig // -GLFWbool _glfwCreateContextEGL(_GLFWwindow* window, - const _GLFWctxconfig* ctxconfig, - const _GLFWfbconfig* fbconfig) +GLFWbool _glfwCreateContextForConfigEGL(_GLFWwindow* window, + const _GLFWctxconfig* ctxconfig, + EGLContext* context) { EGLint attribs[40]; - EGLConfig config; - EGLContext share = NULL; - EGLNativeWindowType native; int index = 0; + EGLContext share = NULL; if (!_glfw.egl.display) { @@ -521,13 +519,6 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window, if (ctxconfig->share) share = ctxconfig->share->context.egl.handle; - if (!chooseEGLConfig(ctxconfig, fbconfig, &config)) - { - _glfwInputError(GLFW_FORMAT_UNAVAILABLE, - "EGL: Failed to find a suitable EGLConfig"); - return GLFW_FALSE; - } - if (ctxconfig->client == GLFW_OPENGL_ES_API) { if (!eglBindAPI(EGL_OPENGL_ES_API)) @@ -624,7 +615,7 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window, setAttrib(EGL_NONE, EGL_NONE); window->context.egl.handle = eglCreateContext(_glfw.egl.display, - config, share, attribs); + window->context.egl.config, share, attribs); if (window->context.egl.handle == EGL_NO_CONTEXT) { @@ -634,9 +625,32 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window, return GLFW_FALSE; } - // Set up attributes for surface creation - index = 0; + return GLFW_TRUE; +} +// Create the OpenGL or OpenGL ES context +// +GLFWbool _glfwCreateContextEGL(_GLFWwindow* window, + const _GLFWctxconfig* ctxconfig, + const _GLFWfbconfig* fbconfig) +{ + EGLNativeWindowType native; + EGLint attribs[40]; + int index = 0; + + if (!chooseEGLConfig(ctxconfig, fbconfig, &window->context.egl.config)) + { + _glfwInputError(GLFW_FORMAT_UNAVAILABLE, + "EGL: Failed to find a suitable EGLConfig"); + return GLFW_FALSE; + } + + if (!_glfwCreateContextForConfigEGL(window,ctxconfig,&window->context.egl.handle)) + { + return GLFW_FALSE; + } + + // Set up attributes for surface creation if (fbconfig->sRGB) { if (_glfw.egl.KHR_gl_colorspace) @@ -651,12 +665,12 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window, if (_glfw.egl.platform && _glfw.egl.platform != EGL_PLATFORM_ANGLE_ANGLE) { window->context.egl.surface = - eglCreatePlatformWindowSurfaceEXT(_glfw.egl.display, config, native, attribs); + eglCreatePlatformWindowSurfaceEXT(_glfw.egl.display, window->context.egl.config, native, attribs); } else { window->context.egl.surface = - eglCreateWindowSurface(_glfw.egl.display, config, native, attribs); + eglCreateWindowSurface(_glfw.egl.display, window->context.egl.config, native, attribs); } if (window->context.egl.surface == EGL_NO_SURFACE) @@ -667,7 +681,6 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window, return GLFW_FALSE; } - window->context.egl.config = config; // Load the appropriate client library if (!_glfw.egl.KHR_get_all_proc_addresses) @@ -802,10 +815,68 @@ GLFWbool _glfwChooseVisualEGL(const _GLFWwndconfig* wndconfig, } #endif // _GLFW_X11 +static void _glfwMakeUserContextCurrentEGL(_GLFWusercontext* context) +{ + if(context) + { + if (!eglMakeCurrent(_glfw.egl.display, + context->window->context.egl.surface, + context->window->context.egl.surface, + context->egl.handle)) + { + _glfwInputError(GLFW_PLATFORM_ERROR, + "EGL: Failed to make context current: %s", + getEGLErrorString(eglGetError())); + return; + } + } + else + { + if (!eglMakeCurrent(_glfw.egl.display, + EGL_NO_SURFACE, + EGL_NO_SURFACE, + EGL_NO_CONTEXT)) + { + _glfwInputError(GLFW_PLATFORM_ERROR, + "EGL: Failed to clear current context: %s", + getEGLErrorString(eglGetError())); + return; + } + } +} + +static void _glfwDestroyUserContextEGL(_GLFWusercontext* context) +{ + if (context->egl.handle) + { + eglDestroyContext(_glfw.egl.display, context->egl.handle); + } + free(context); +} + _GLFWusercontext* _glfwCreateUserContextEGL(_GLFWwindow* window) { - // TODO - return NULL; + _GLFWusercontext* context; + _GLFWctxconfig ctxconfig; + + context = calloc(1, sizeof(_GLFWusercontext)); + context->window = window; + + ctxconfig = _glfw.hints.context; + ctxconfig.share = window; + + if(!_glfwCreateContextForConfigEGL(window,&ctxconfig,&context->egl.handle)) + { + _glfwInputError(GLFW_PLATFORM_ERROR, + "EGL: Failed to create user OpenGL context"); + free(context); + return NULL; + } + + context->makeCurrent = _glfwMakeUserContextCurrentEGL; + context->destroy = _glfwDestroyUserContextEGL; + + return context; } diff --git a/src/wgl_context.h b/src/wgl_context.h index d04cd661..1268065f 100644 --- a/src/wgl_context.h +++ b/src/wgl_context.h @@ -119,6 +119,13 @@ typedef struct _GLFWcontextWGL } _GLFWcontextWGL; +// WGL-specific user context data +// +typedef struct _GLFWusercontextWGL +{ + HGLRC handle; +} _GLFWusercontextWGL; + // WGL-specific global data // typedef struct _GLFWlibraryWGL @@ -152,13 +159,6 @@ typedef struct _GLFWlibraryWGL } _GLFWlibraryWGL; -// WGL-specific user context data -// -typedef struct _GLFWusercontextWGL -{ - HGLRC handle; -} _GLFWusercontextWGL; - GLFWbool _glfwInitWGL(void); void _glfwTerminateWGL(void); GLFWbool _glfwCreateContextWGL(_GLFWwindow* window, diff --git a/src/wl_platform.h b/src/wl_platform.h index 966155fd..a744588c 100644 --- a/src/wl_platform.h +++ b/src/wl_platform.h @@ -72,6 +72,7 @@ typedef VkBool32 (APIENTRY *PFN_vkGetPhysicalDeviceWaylandPresentationSupportKHR #define _GLFW_PLATFORM_CONTEXT_STATE struct { int dummyContext; } #define _GLFW_PLATFORM_LIBRARY_CONTEXT_STATE struct { int dummyLibraryContext; } +#define _GLFW_PLATFORM_USER_CONTEXT_STATE struct { int dummyUserContext; } struct wl_cursor_image { uint32_t width; diff --git a/src/wl_window.c b/src/wl_window.c index d1dad065..a9cefc97 100644 --- a/src/wl_window.c +++ b/src/wl_window.c @@ -1765,6 +1765,19 @@ VkResult _glfwPlatformCreateWindowSurface(VkInstance instance, return err; } +_GLFWusercontext* _glfwPlatformCreateUserContext(_GLFWwindow* window) +{ + if (window->context.egl.handle) + { + return _glfwCreateUserContextEGL(window); + } + else if (window->context.osmesa.handle) + { + return _glfwCreateUserContextOSMesa(window); + } + + return GLFW_FALSE; +} ////////////////////////////////////////////////////////////////////////// ////// GLFW native API //////