diff --git a/src/egl_context.c b/src/egl_context.c index 43615794..7b5bb0f3 100644 --- a/src/egl_context.c +++ b/src/egl_context.c @@ -372,6 +372,8 @@ GLFWbool _glfwInitEGL(void) _glfw_dlsym(_glfw.egl.handle, "eglQueryString"); _glfw.egl.GetProcAddress = (PFN_eglGetProcAddress) _glfw_dlsym(_glfw.egl.handle, "eglGetProcAddress"); + _glfw.egl.CreatePbufferSurface = (PFN_eglCreatePbufferSurface) + _glfw_dlsym(_glfw.egl.handle, "eglCreatePbufferSurface"); if (!_glfw.egl.GetConfigAttrib || !_glfw.egl.GetConfigs || @@ -833,10 +835,10 @@ static void _glfwMakeUserContextCurrentEGL(_GLFWusercontext* context) static void _glfwDestroyUserContextEGL(_GLFWusercontext* context) { - if (context->egl.handle) - { - eglDestroyContext(_glfw.egl.display, context->egl.handle); - } + if (context->egl.surface!=EGL_NO_SURFACE) + eglDestroySurface(_glfw.egl.display,context->egl.surface); + + eglDestroyContext(_glfw.egl.display, context->egl.handle); free(context); } @@ -844,6 +846,22 @@ _GLFWusercontext* _glfwCreateUserContextEGL(_GLFWwindow* window) { _GLFWusercontext* context; _GLFWctxconfig ctxconfig; + const EGLint auxConfigAttribs[] = + { + EGL_SURFACE_TYPE, EGL_PBUFFER_BIT, + EGL_BLUE_SIZE, 8, EGL_GREEN_SIZE, 8, EGL_RED_SIZE, 8, EGL_ALPHA_SIZE, 8, + EGL_DEPTH_SIZE, 0, EGL_STENCIL_SIZE, 0, + EGL_NONE + }; + EGLint dummySurfaceAttribs[] = + { + EGL_WIDTH, 1, EGL_HEIGHT, 1, + EGL_TEXTURE_TARGET, EGL_NO_TEXTURE, + EGL_TEXTURE_FORMAT, EGL_NO_TEXTURE, + EGL_NONE + }; + EGLint dummySurfaceNumConfigs; + EGLConfig dummySurfaceConfig; context = calloc(1, sizeof(_GLFWusercontext)); context->window = window; @@ -851,13 +869,29 @@ _GLFWusercontext* _glfwCreateUserContextEGL(_GLFWwindow* window) ctxconfig = _glfw.hints.context; ctxconfig.share = window; - if(!_glfwCreateContextForConfigEGL(window,&ctxconfig,&context->egl.handle)) + if (!_glfwCreateContextForConfigEGL(window,&ctxconfig,&context->egl.handle)) { _glfwInputError(GLFW_PLATFORM_ERROR, "EGL: Failed to create user OpenGL context"); free(context); return NULL; } + if (glfwExtensionSupported("EGL_KHR_surfaceless_context")) + context->egl.surface = EGL_NO_SURFACE; + else + { + // create dummy surface + eglChooseConfig(_glfw.egl.display, auxConfigAttribs, &dummySurfaceConfig, 1, &dummySurfaceNumConfigs); + context->egl.surface = eglCreatePbufferSurface(_glfw.egl.display, dummySurfaceConfig, dummySurfaceAttribs); + if (!context->egl.surface) + { + eglDestroyContext(_glfw.egl.display, context->egl.handle); + _glfwInputError(GLFW_PLATFORM_ERROR, + "EGL: Failed to create surface for user context and EGL_KHR_surfaceless_context not supported"); + free(context); + return NULL; + } + } context->makeCurrent = _glfwMakeUserContextCurrentEGL; context->destroy = _glfwDestroyUserContextEGL; diff --git a/src/egl_context.h b/src/egl_context.h index 1dcab099..62801740 100644 --- a/src/egl_context.h +++ b/src/egl_context.h @@ -71,6 +71,12 @@ #define EGL_NO_DISPLAY ((EGLDisplay) 0) #define EGL_NO_CONTEXT ((EGLContext) 0) #define EGL_DEFAULT_DISPLAY ((EGLNativeDisplayType) 0) +#define EGL_PBUFFER_BIT 0x0001 +#define EGL_HEIGHT 0x3056 +#define EGL_WIDTH 0x3057 +#define EGL_NO_TEXTURE 0x305C +#define EGL_TEXTURE_FORMAT 0x3080 +#define EGL_TEXTURE_TARGET 0x3081 #define EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR 0x00000002 #define EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR 0x00000001 @@ -130,6 +136,8 @@ typedef EGLBoolean (EGLAPIENTRY * PFN_eglSwapBuffers)(EGLDisplay,EGLSurface); typedef EGLBoolean (EGLAPIENTRY * PFN_eglSwapInterval)(EGLDisplay,EGLint); typedef const char* (EGLAPIENTRY * PFN_eglQueryString)(EGLDisplay,EGLint); typedef GLFWglproc (EGLAPIENTRY * PFN_eglGetProcAddress)(const char*); +typedef EGLSurface (EGLAPIENTRY * PFN_eglCreatePbufferSurface)(EGLDisplay,EGLConfig,const EGLint*); +typedef EGLBoolean (EGLAPIENTRY * PFN_eglChooseConfig)(EGLDisplay,EGLint const*,EGLConfig*,EGLint,EGLint*); #define eglGetConfigAttrib _glfw.egl.GetConfigAttrib #define eglGetConfigs _glfw.egl.GetConfigs #define eglGetDisplay _glfw.egl.GetDisplay @@ -146,6 +154,8 @@ typedef GLFWglproc (EGLAPIENTRY * PFN_eglGetProcAddress)(const char*); #define eglSwapInterval _glfw.egl.SwapInterval #define eglQueryString _glfw.egl.QueryString #define eglGetProcAddress _glfw.egl.GetProcAddress +#define eglCreatePbufferSurface _glfw.egl.CreatePbufferSurface +#define eglChooseConfig _glfw.egl.ChooseConfig typedef EGLDisplay (EGLAPIENTRY * PFNEGLGETPLATFORMDISPLAYEXTPROC)(EGLenum,void*,const EGLint*); typedef EGLSurface (EGLAPIENTRY * PFNEGLCREATEPLATFORMWINDOWSURFACEEXTPROC)(EGLDisplay,EGLConfig,void*,const EGLint*); @@ -169,6 +179,8 @@ typedef struct _GLFWcontextEGL typedef struct _GLFWusercontextEGL { EGLContext handle; + EGLSurface surface; + } _GLFWusercontextEGL; @@ -214,6 +226,8 @@ typedef struct _GLFWlibraryEGL PFN_eglSwapInterval SwapInterval; PFN_eglQueryString QueryString; PFN_eglGetProcAddress GetProcAddress; + PFN_eglCreatePbufferSurface CreatePbufferSurface; + PFN_eglChooseConfig ChooseConfig; PFNEGLGETPLATFORMDISPLAYEXTPROC GetPlatformDisplayEXT; PFNEGLCREATEPLATFORMWINDOWSURFACEEXTPROC CreatePlatformWindowSurfaceEXT;