From 986ba3aa79a9f2cffaf7c5061c25e92d431c64b3 Mon Sep 17 00:00:00 2001 From: Robert Bragg Date: Fri, 28 Sep 2012 11:08:16 +0100 Subject: [PATCH] egl: remove special re-try without stencil code The EGL winsys had a special case code path when trying to create a context where if it failed it would try again except without requesting a stencil buffer. Historically this code path was to allow Clutter to run on PowerVR MBX hardware which doesn't support a stencil buffer. It doesn't really make sense to keep this workaround in Cogl as it would leave Cogl in a state where the clip stack doesn't work without providing any feedback to the developer. If we need to support running on MBX like hardware - probably not very likely these days - then we should provide developer control over the stencil buffer so the equivalent workaround could be implemented on top of Cogl. Reviewed-by: Neil Roberts (cherry picked from commit a7c391a985e82707b17f2fb1105de5d37822a390) --- cogl/winsys/cogl-winsys-egl-private.h | 1 - cogl/winsys/cogl-winsys-egl.c | 161 +++++++++++--------------- 2 files changed, 68 insertions(+), 94 deletions(-) diff --git a/cogl/winsys/cogl-winsys-egl-private.h b/cogl/winsys/cogl-winsys-egl-private.h index 3f092aec8..f1e5361bf 100644 --- a/cogl/winsys/cogl-winsys-egl-private.h +++ b/cogl/winsys/cogl-winsys-egl-private.h @@ -108,7 +108,6 @@ typedef struct _CoglDisplayEGL EGLConfig egl_config; CoglBool found_egl_config; - CoglBool stencil_disabled; EGLSurface current_read_surface; EGLSurface current_draw_surface; diff --git a/cogl/winsys/cogl-winsys-egl.c b/cogl/winsys/cogl-winsys-egl.c index 26acab732..df07f8100 100644 --- a/cogl/winsys/cogl-winsys-egl.c +++ b/cogl/winsys/cogl-winsys-egl.c @@ -199,7 +199,6 @@ _cogl_winsys_renderer_connect (CoglRenderer *renderer, static void egl_attributes_from_framebuffer_config (CoglDisplay *display, CoglFramebufferConfig *config, - CoglBool needs_stencil_override, EGLint *attributes) { CoglRenderer *renderer = display->renderer; @@ -212,8 +211,11 @@ egl_attributes_from_framebuffer_config (CoglDisplay *display, config, attributes); - attributes[i++] = EGL_STENCIL_SIZE; - attributes[i++] = needs_stencil_override ? 2 : 0; + if (config->need_stencil) + { + attributes[i++] = EGL_STENCIL_SIZE; + attributes[i++] = 2; + } attributes[i++] = EGL_RED_SIZE; attributes[i++] = 1; @@ -254,78 +256,6 @@ egl_attributes_from_framebuffer_config (CoglDisplay *display, g_assert (i < MAX_EGL_CONFIG_ATTRIBS); } -static CoglBool -try_create_context (CoglDisplay *display, - CoglBool with_stencil_buffer, - CoglError **error) -{ - CoglRenderer *renderer = display->renderer; - CoglDisplayEGL *egl_display = display->winsys; - CoglRendererEGL *egl_renderer = renderer->winsys; - EGLDisplay edpy; - EGLConfig config; - EGLint config_count = 0; - EGLBoolean status; - EGLint attribs[3]; - EGLint cfg_attribs[MAX_EGL_CONFIG_ATTRIBS]; - const char *error_message; - - _COGL_RETURN_VAL_IF_FAIL (egl_display->egl_context == NULL, TRUE); - - if (renderer->driver == COGL_DRIVER_GL) - eglBindAPI (EGL_OPENGL_API); - - if (display->renderer->driver == COGL_DRIVER_GLES2) - { - attribs[0] = EGL_CONTEXT_CLIENT_VERSION; - attribs[1] = 2; - attribs[2] = EGL_NONE; - } - else - attribs[0] = EGL_NONE; - - egl_attributes_from_framebuffer_config (display, - &display->onscreen_template->config, - with_stencil_buffer, - cfg_attribs); - - edpy = egl_renderer->edpy; - - status = eglChooseConfig (edpy, - cfg_attribs, - &config, 1, - &config_count); - if (status != EGL_TRUE || config_count == 0) - { - error_message = "Unable to find a usable EGL configuration"; - goto fail; - } - - egl_display->egl_config = config; - - egl_display->egl_context = eglCreateContext (edpy, - config, - EGL_NO_CONTEXT, - attribs); - if (egl_display->egl_context == EGL_NO_CONTEXT) - { - error_message = "Unable to create a suitable EGL context"; - goto fail; - } - - if (egl_renderer->platform_vtable->context_created && - !egl_renderer->platform_vtable->context_created (display, error)) - return FALSE; - - return TRUE; - -fail: - _cogl_set_error (error, COGL_WINSYS_ERROR, - COGL_WINSYS_ERROR_CREATE_CONTEXT, - "%s", error_message); - return FALSE; -} - EGLBoolean _cogl_winsys_egl_make_current (CoglDisplay *display, EGLSurface draw, @@ -374,28 +304,76 @@ cleanup_context (CoglDisplay *display) } static CoglBool -create_context (CoglDisplay *display, CoglError **error) +try_create_context (CoglDisplay *display, + CoglError **error) { + CoglRenderer *renderer = display->renderer; CoglDisplayEGL *egl_display = display->winsys; + CoglRendererEGL *egl_renderer = renderer->winsys; + EGLDisplay edpy; + EGLConfig config; + EGLint config_count = 0; + EGLBoolean status; + EGLint attribs[3]; + EGLint cfg_attribs[MAX_EGL_CONFIG_ATTRIBS]; + const char *error_message; - /* Note: we don't just rely on eglChooseConfig to correctly - * report that the driver doesn't support a stencil buffer - * because we've seen PVR drivers that claim stencil buffer - * support according to the EGLConfig but then later fail - * when trying to create a context with such a config. - */ - if (try_create_context (display, TRUE, error)) + _COGL_RETURN_VAL_IF_FAIL (egl_display->egl_context == NULL, TRUE); + + if (renderer->driver == COGL_DRIVER_GL) + eglBindAPI (EGL_OPENGL_API); + + if (display->renderer->driver == COGL_DRIVER_GLES2) { - egl_display->stencil_disabled = FALSE; - return TRUE; + attribs[0] = EGL_CONTEXT_CLIENT_VERSION; + attribs[1] = 2; + attribs[2] = EGL_NONE; } else + attribs[0] = EGL_NONE; + + egl_attributes_from_framebuffer_config (display, + &display->onscreen_template->config, + cfg_attribs); + + edpy = egl_renderer->edpy; + + status = eglChooseConfig (edpy, + cfg_attribs, + &config, 1, + &config_count); + if (status != EGL_TRUE || config_count == 0) { - _cogl_clear_error (error); - cleanup_context (display); - egl_display->stencil_disabled = TRUE; - return try_create_context (display, FALSE, error); + error_message = "Unable to find a usable EGL configuration"; + goto fail; } + + egl_display->egl_config = config; + + egl_display->egl_context = eglCreateContext (edpy, + config, + EGL_NO_CONTEXT, + attribs); + if (egl_display->egl_context == EGL_NO_CONTEXT) + { + error_message = "Unable to create a suitable EGL context"; + goto fail; + } + + if (egl_renderer->platform_vtable->context_created && + !egl_renderer->platform_vtable->context_created (display, error)) + return FALSE; + + return TRUE; + +fail: + _cogl_set_error (error, COGL_WINSYS_ERROR, + COGL_WINSYS_ERROR_CREATE_CONTEXT, + "%s", error_message); + + cleanup_context (display); + + return FALSE; } static void @@ -443,7 +421,7 @@ _cogl_winsys_display_setup (CoglDisplay *display, !egl_renderer->platform_vtable->display_setup (display, error)) goto error; - if (!create_context (display, error)) + if (!try_create_context (display, error)) goto error; egl_display->found_egl_config = TRUE; @@ -570,14 +548,11 @@ _cogl_winsys_onscreen_init (CoglOnscreen *onscreen, EGLConfig egl_config; EGLint config_count = 0; EGLBoolean status; - CoglBool need_stencil = - egl_display->stencil_disabled ? FALSE : framebuffer->config.need_stencil; _COGL_RETURN_VAL_IF_FAIL (egl_display->egl_context, FALSE); egl_attributes_from_framebuffer_config (display, &framebuffer->config, - need_stencil, attributes); status = eglChooseConfig (egl_renderer->edpy,