From 99dc4bf4cedda6f8c71ce978a945b8f445d31105 Mon Sep 17 00:00:00 2001 From: Heiko Lewin Date: Tue, 19 Jan 2021 11:26:33 +0000 Subject: [PATCH] Fix device errors for GLESv2 contexts Ignore GLerrors when re-selecting a (possibly deleted) GLprogram --- src/cairo-gl-info.c | 42 +++++++++++++++++++++++++++++++++++++----- src/cairo-gl-shaders.c | 18 +++++++++++++++--- 2 files changed, 52 insertions(+), 8 deletions(-) diff --git a/src/cairo-gl-info.c b/src/cairo-gl-info.c index 26b7b4551..53f5b1720 100644 --- a/src/cairo-gl-info.c +++ b/src/cairo-gl-info.c @@ -27,6 +27,7 @@ * * Contributor(s): * Alexandros Frantzis + * Heiko Lewin */ #include "cairoint.h" @@ -57,22 +58,53 @@ _cairo_gl_get_version (void) return CAIRO_GL_VERSION_ENCODE (major, minor); } + +cairo_gl_flavor_t +_cairo_gl_degrade_flavor_by_build_features (cairo_gl_flavor_t flavor) { + switch(flavor) { + case CAIRO_GL_FLAVOR_DESKTOP: +#if CAIRO_HAS_GL_SURFACE + return CAIRO_GL_FLAVOR_DESKTOP; +#else + return CAIRO_GL_FLAVOR_NONE; +#endif + + case CAIRO_GL_FLAVOR_ES3: +#if CAIRO_HAS_GLESV3_SURFACE + return CAIRO_GL_FLAVOR_ES3; +#else + /* intentional fall through: degrade to GLESv2 if GLESv3-surfaces are not available */ +#endif + + case CAIRO_GL_FLAVOR_ES2: +#if CAIRO_HAS_GLESV2_SURFACE + return CAIRO_GL_FLAVOR_ES2; +#else + /* intentional fall through: no OpenGL in first place or no surfaces for it's version */ +#endif + + default: + return CAIRO_GL_FLAVOR_NONE; + } +} + cairo_gl_flavor_t _cairo_gl_get_flavor (void) { const char *version = (const char *) glGetString (GL_VERSION); cairo_gl_flavor_t flavor; - if (version == NULL) + if (version == NULL) { flavor = CAIRO_GL_FLAVOR_NONE; - else if (strstr (version, "OpenGL ES 3") != NULL) + } else if (strstr (version, "OpenGL ES 3") != NULL) { flavor = CAIRO_GL_FLAVOR_ES3; - else if (strstr (version, "OpenGL ES 2") != NULL) + } else if (strstr (version, "OpenGL ES 2") != NULL) { flavor = CAIRO_GL_FLAVOR_ES2; - else + } else { flavor = CAIRO_GL_FLAVOR_DESKTOP; + } - return flavor; + return _cairo_gl_degrade_flavor_by_build_features(flavor); } unsigned long diff --git a/src/cairo-gl-shaders.c b/src/cairo-gl-shaders.c index f789ae1d9..745302f87 100644 --- a/src/cairo-gl-shaders.c +++ b/src/cairo-gl-shaders.c @@ -37,6 +37,7 @@ * Eric Anholt * T. Zachary Laine * Alexandros Frantzis + * H. Lewin */ #include "cairoint.h" @@ -900,7 +901,7 @@ _cairo_gl_shader_compile_and_link (cairo_gl_context_t *ctx, * texture unit 1 if present, so we can just initialize these once at * compile time. */ -static void +static cairo_status_t _cairo_gl_shader_set_samplers (cairo_gl_context_t *ctx, cairo_gl_shader_t *shader) { @@ -924,8 +925,14 @@ _cairo_gl_shader_set_samplers (cairo_gl_context_t *ctx, if (location != -1) { dispatch->Uniform1i (location, CAIRO_GL_TEX_MASK); } - + if(_cairo_gl_get_error()) return CAIRO_STATUS_DEVICE_ERROR; dispatch->UseProgram (saved_program); + /* Pop and ignore a possible gl-error when restoring the previous program. + * It may be that being selected in the gl-context was the last reference + * to the shader. + */ + _cairo_gl_get_error(); + return CAIRO_STATUS_SUCCESS; } void @@ -1084,7 +1091,12 @@ _cairo_gl_get_shader_by_type (cairo_gl_context_t *ctx, return status; } - _cairo_gl_shader_set_samplers (ctx, &entry->shader); + status = _cairo_gl_shader_set_samplers (ctx, &entry->shader); + if (unlikely (status)) { + _cairo_gl_shader_fini (ctx, &entry->shader); + free (entry); + return status; + } status = _cairo_cache_insert (&ctx->shaders, &entry->base); if (unlikely (status)) {