From c0bc9bef7fb7bb416acff6160338664a17874773 Mon Sep 17 00:00:00 2001 From: Adel Gadllah Date: Sun, 26 Jul 2015 11:27:00 +0200 Subject: [PATCH 1/5] winsys-glx: Add error traps in create_context Both create_gl3_context and glXCreateNewContext can fail with an X error. https://bugzilla.gnome.org/show_bug.cgi?id=742678 --- cogl/winsys/cogl-winsys-glx.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/cogl/winsys/cogl-winsys-glx.c b/cogl/winsys/cogl-winsys-glx.c index 0487b79..4f7abfb 100644 --- a/cogl/winsys/cogl-winsys-glx.c +++ b/cogl/winsys/cogl-winsys-glx.c @@ -1075,6 +1075,8 @@ create_context (CoglDisplay *display, CoglError **error) COGL_NOTE (WINSYS, "Creating GLX Context (display: %p)", xlib_renderer->xdpy); + _cogl_xlib_renderer_trap_errors (display->renderer, &old_state); + if (display->renderer->driver == COGL_DRIVER_GL3) glx_display->glx_context = create_gl3_context (display, config); else @@ -1085,7 +1087,8 @@ create_context (CoglDisplay *display, CoglError **error) NULL, True); - if (glx_display->glx_context == NULL) + if (_cogl_xlib_renderer_untrap_errors (display->renderer, &old_state) || + glx_display->glx_context == NULL) { _cogl_set_error (error, COGL_WINSYS_ERROR, COGL_WINSYS_ERROR_CREATE_CONTEXT, -- 2.7.4 From 55af12d4ec146c610dd3c05d777f1ae33738c218 Mon Sep 17 00:00:00 2001 From: Emmanuele Bassi Date: Thu, 6 Aug 2015 12:19:52 +0100 Subject: [PATCH 2/5] gl: Do not use deprecated constants with the GL3 driver glGetIntegerv (GL_DEPTH_BITS, ...) and friends are deprecated in GL3; we have to use glGetFramebufferAttachmentParameteriv() instead, like we do for offscreen framebuffers. Based on a patch by: Adel Gadllah Signed-off-by: Emmanuele Bassi https://bugzilla.gnome.org/show_bug.cgi?id=753295 --- cogl/driver/gl/cogl-framebuffer-gl.c | 46 ++++++++++++++++++++---------------- 1 file changed, 26 insertions(+), 20 deletions(-) diff --git a/cogl/driver/gl/cogl-framebuffer-gl.c b/cogl/driver/gl/cogl-framebuffer-gl.c index 793b10b..26bcc5f 100644 --- a/cogl/driver/gl/cogl-framebuffer-gl.c +++ b/cogl/driver/gl/cogl-framebuffer-gl.c @@ -1028,29 +1028,35 @@ _cogl_framebuffer_init_bits (CoglFramebuffer *framebuffer) COGL_FRAMEBUFFER_STATE_BIND); #ifdef HAVE_COGL_GL - if (_cogl_has_private_feature - (ctx, COGL_PRIVATE_FEATURE_QUERY_FRAMEBUFFER_BITS) && - framebuffer->type == COGL_FRAMEBUFFER_TYPE_OFFSCREEN) + if ((ctx->driver == COGL_DRIVER_GL3 && + framebuffer->type == COGL_FRAMEBUFFER_TYPE_ONSCREEN) || + (_cogl_has_private_feature (ctx, COGL_PRIVATE_FEATURE_QUERY_FRAMEBUFFER_BITS) && + framebuffer->type == COGL_FRAMEBUFFER_TYPE_OFFSCREEN)) { - static const struct - { + gboolean is_offscreen = framebuffer->type == COGL_FRAMEBUFFER_TYPE_OFFSCREEN; + const struct { GLenum attachment, pname; size_t offset; - } params[] = - { - { GL_COLOR_ATTACHMENT0, GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE, - offsetof (CoglFramebufferBits, red) }, - { GL_COLOR_ATTACHMENT0, GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE, - offsetof (CoglFramebufferBits, green) }, - { GL_COLOR_ATTACHMENT0, GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE, - offsetof (CoglFramebufferBits, blue) }, - { GL_COLOR_ATTACHMENT0, GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE, - offsetof (CoglFramebufferBits, alpha) }, - { GL_DEPTH_ATTACHMENT, GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE, - offsetof (CoglFramebufferBits, depth) }, - { GL_STENCIL_ATTACHMENT, GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE, - offsetof (CoglFramebufferBits, stencil) }, - }; + } params[] = { + { is_offscreen ? GL_COLOR_ATTACHMENT0 : GL_BACK_LEFT, + GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE, + offsetof (CoglFramebufferBits, red) }, + { is_offscreen ? GL_COLOR_ATTACHMENT0 : GL_BACK_LEFT, + GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE, + offsetof (CoglFramebufferBits, green) }, + { is_offscreen ? GL_COLOR_ATTACHMENT0 : GL_BACK_LEFT, + GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE, + offsetof (CoglFramebufferBits, blue) }, + { is_offscreen ? GL_COLOR_ATTACHMENT0 : GL_BACK_LEFT, + GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE, + offsetof (CoglFramebufferBits, alpha) }, + { is_offscreen ? GL_DEPTH_ATTACHMENT : GL_DEPTH, + GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE, + offsetof (CoglFramebufferBits, depth) }, + { is_offscreen ? GL_STENCIL_ATTACHMENT : GL_STENCIL, + GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE, + offsetof (CoglFramebufferBits, stencil) }, + }; int i; for (i = 0; i < G_N_ELEMENTS (params); i++) -- 2.7.4 From 067d3cb0f8a67a1c5ba144505c124ec42f409aaf Mon Sep 17 00:00:00 2001 From: Rui Matos Date: Wed, 29 Jun 2016 15:37:14 +0200 Subject: [PATCH 3/5] cogl-winsys-glx: Add support for NV_robustness_video_memory_purge This adds API to allow callers to specify that they're interested in video memory purge errors. https://bugzilla.gnome.org/show_bug.cgi?id=739178 --- cogl/cogl-renderer-private.h | 1 + cogl/cogl-renderer.c | 10 ++++++++ cogl/cogl-xlib-renderer.h | 41 +++++++++++++++++++++++++++++++ cogl/cogl.symbols | 1 + cogl/gl-prototypes/cogl-all-functions.h | 8 ++++++ cogl/winsys/cogl-winsys-glx.c | 43 +++++++++++++++++++++++++++++++++ 6 files changed, 104 insertions(+) diff --git a/cogl/cogl-renderer-private.h b/cogl/cogl-renderer-private.h index 3871d91..4a2fa6e 100644 --- a/cogl/cogl-renderer-private.h +++ b/cogl/cogl-renderer-private.h @@ -70,6 +70,7 @@ struct _CoglRenderer #ifdef COGL_HAS_XLIB_SUPPORT Display *foreign_xdpy; CoglBool xlib_enable_event_retrieval; + CoglBool xlib_want_reset_on_video_memory_purge; #endif #ifdef COGL_HAS_WIN32_SUPPORT diff --git a/cogl/cogl-renderer.c b/cogl/cogl-renderer.c index ef6e900..52a4732 100644 --- a/cogl/cogl-renderer.c +++ b/cogl/cogl-renderer.c @@ -347,6 +347,16 @@ cogl_xlib_renderer_set_event_retrieval_enabled (CoglRenderer *renderer, renderer->xlib_enable_event_retrieval = enable; } + +void +cogl_xlib_renderer_request_reset_on_video_memory_purge (CoglRenderer *renderer, + CoglBool enable) +{ + _COGL_RETURN_IF_FAIL (cogl_is_renderer (renderer)); + _COGL_RETURN_IF_FAIL (!renderer->connected); + + renderer->xlib_want_reset_on_video_memory_purge = enable; +} #endif /* COGL_HAS_XLIB_SUPPORT */ CoglBool diff --git a/cogl/cogl-xlib-renderer.h b/cogl/cogl-xlib-renderer.h index 6318957..a81f275 100644 --- a/cogl/cogl-xlib-renderer.h +++ b/cogl/cogl-xlib-renderer.h @@ -169,6 +169,47 @@ cogl_xlib_renderer_set_event_retrieval_enabled (CoglRenderer *renderer, Display * cogl_xlib_renderer_get_display (CoglRenderer *renderer); +/** + * cogl_xlib_renderer_request_reset_on_video_memory_purge: + * @renderer: a #CoglRenderer + * @enable: The new value + * + * Sets whether Cogl should make use of the + * NV_robustness_video_memory_purge extension, if exposed by the + * driver, by initializing the GLX context appropriately. + * + * The extension is only useful when running on certain versions of + * the NVIDIA driver. Quoting from the spec: + * + * "The NVIDIA OpenGL driver architecture on Linux has a limitation: + * resources located in video memory are not persistent across certain + * events. VT switches, suspend/resume events, and mode switching + * events may erase the contents of video memory. Any resource that + * is located exclusively in video memory, such as framebuffer objects + * (FBOs), will be lost." + * + * "This extension provides a way for applications to discover when video + * memory content has been lost, so that the application can re-populate + * the video memory content as necessary." + * + * "Any driver that exposes this extension is a driver that considers + * video memory to be volatile. Once the driver stack has been + * improved, the extension will no longer be exposed." + * + * cogl_get_graphics_reset_status() needs to be called at least once + * every frame to find out if video memory was purged. + * + * Note that this doesn't cause Cogl to enable robust buffer access + * but other context reset errors may still happen and be reported via + * cogl_get_graphics_reset_status() if external factors cause the + * driver to trigger them. + * + * This defaults to %FALSE and is effective only if called before + * cogl_display_setup() . + */ +void +cogl_xlib_renderer_request_reset_on_video_memory_purge (CoglRenderer *renderer, + CoglBool enable); COGL_END_DECLS /* The gobject introspection scanner seems to parse public headers in diff --git a/cogl/cogl.symbols b/cogl/cogl.symbols index c48314a..feb9e65 100644 --- a/cogl/cogl.symbols +++ b/cogl/cogl.symbols @@ -1065,6 +1065,7 @@ cogl_xlib_renderer_get_display cogl_xlib_renderer_get_foreign_display cogl_xlib_renderer_handle_event cogl_xlib_renderer_remove_filter +cogl_xlib_renderer_request_reset_on_video_memory_purge cogl_xlib_renderer_set_event_retrieval_enabled cogl_xlib_renderer_set_foreign_display cogl_xlib_set_display diff --git a/cogl/gl-prototypes/cogl-all-functions.h b/cogl/gl-prototypes/cogl-all-functions.h index dda08f7..c1c5462 100644 --- a/cogl/gl-prototypes/cogl-all-functions.h +++ b/cogl/gl-prototypes/cogl-all-functions.h @@ -326,3 +326,11 @@ COGL_EXT_BEGIN (draw_buffers, 2, 0, COGL_EXT_FUNCTION (void, glDrawBuffers, (GLsizei n, const GLenum *bufs)) COGL_EXT_END () + +COGL_EXT_BEGIN (robustness, 255, 255, + 0, + "ARB\0", + "robustness\0") +COGL_EXT_FUNCTION (GLenum, glGetGraphicsResetStatus, + (void)) +COGL_EXT_END () diff --git a/cogl/winsys/cogl-winsys-glx.c b/cogl/winsys/cogl-winsys-glx.c index 4f7abfb..097589f 100644 --- a/cogl/winsys/cogl-winsys-glx.c +++ b/cogl/winsys/cogl-winsys-glx.c @@ -71,6 +71,11 @@ #include #include +/* This is a relatively new extension */ +#ifndef GLX_GENERATE_RESET_ON_VIDEO_MEMORY_PURGE_NV +#define GLX_GENERATE_RESET_ON_VIDEO_MEMORY_PURGE_NV 0x20F7 +#endif + #define COGL_ONSCREEN_X11_EVENT_MASK (StructureNotifyMask | ExposureMask) #define MAX_GLX_CONFIG_ATTRIBS 30 @@ -1025,12 +1030,50 @@ create_gl3_context (CoglDisplay *display, GLX_CONTEXT_FLAGS_ARB, GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB, None }; + /* NV_robustness_video_memory_purge relies on GLX_ARB_create_context + and in part on ARB_robustness. Namely, it needs the notification + strategy to be set to GLX_LOSE_CONTEXT_ON_RESET_ARB and that the + driver exposes the GetGraphicsResetStatusARB function. This means + we don't actually enable robust buffer access. */ + static const int attrib_list_reset_on_purge[] = + { + GLX_CONTEXT_MAJOR_VERSION_ARB, 3, + GLX_CONTEXT_MINOR_VERSION_ARB, 1, + GLX_CONTEXT_PROFILE_MASK_ARB, GLX_CONTEXT_CORE_PROFILE_BIT_ARB, + GLX_CONTEXT_FLAGS_ARB, GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB, + GLX_GENERATE_RESET_ON_VIDEO_MEMORY_PURGE_NV, + GL_TRUE, + GLX_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB, + GLX_LOSE_CONTEXT_ON_RESET_ARB, + None + }; /* Make sure that the display supports the GLX_ARB_create_context extension */ if (glx_renderer->glXCreateContextAttribs == NULL) return NULL; + /* We can't check the presence of this extension with the usual + COGL_WINSYS_FEATURE machinery because that only gets initialized + later when the CoglContext is created. */ + if (display->renderer->xlib_want_reset_on_video_memory_purge && + strstr (glx_renderer->glXQueryExtensionsString (xlib_renderer->xdpy, + DefaultScreen (xlib_renderer->xdpy)), + "GLX_NV_robustness_video_memory_purge")) + { + CoglXlibTrapState old_state; + GLXContext ctx; + + _cogl_xlib_renderer_trap_errors (display->renderer, &old_state); + ctx = glx_renderer->glXCreateContextAttribs (xlib_renderer->xdpy, + fb_config, + NULL /* share_context */, + True, /* direct */ + attrib_list_reset_on_purge); + if (!_cogl_xlib_renderer_untrap_errors (display->renderer, &old_state) && ctx) + return ctx; + } + return glx_renderer->glXCreateContextAttribs (xlib_renderer->xdpy, fb_config, NULL /* share_context */, -- 2.7.4 From e91a1f5217d28e8e181e4fd98b78ec180d601228 Mon Sep 17 00:00:00 2001 From: Rui Matos Date: Sun, 29 May 2016 20:30:36 +0200 Subject: [PATCH 4/5] cogl-context: Add a cogl_get_graphics_reset_status API If the driver supports the GL_ARB_robustness extension we can expose the graphics reset status this way. https://bugzilla.gnome.org/show_bug.cgi?id=739178 --- cogl/cogl-context.c | 30 ++++++++++++++++++++++++++++++ cogl/cogl-context.h | 42 ++++++++++++++++++++++++++++++++++++++++++ cogl/cogl.symbols | 1 + 3 files changed, 73 insertions(+) diff --git a/cogl/cogl-context.c b/cogl/cogl-context.c index a7eed29..4b1af61 100644 --- a/cogl/cogl-context.c +++ b/cogl/cogl-context.c @@ -76,6 +76,11 @@ #define GL_NUM_EXTENSIONS 0x821D #endif +/* This is a relatively new extension */ +#ifndef GL_PURGED_CONTEXT_RESET_NV +#define GL_PURGED_CONTEXT_RESET_NV 0x92BB +#endif + static void _cogl_context_free (CoglContext *context); COGL_OBJECT_DEFINE (Context, context); @@ -784,3 +789,28 @@ cogl_get_clock_time (CoglContext *context) else return 0; } + +CoglGraphicsResetStatus +cogl_get_graphics_reset_status (CoglContext *context) +{ + if (!context->glGetGraphicsResetStatus) + return COGL_GRAPHICS_RESET_STATUS_NO_ERROR; + + switch (context->glGetGraphicsResetStatus ()) + { + case GL_GUILTY_CONTEXT_RESET_ARB: + return COGL_GRAPHICS_RESET_STATUS_GUILTY_CONTEXT_RESET; + + case GL_INNOCENT_CONTEXT_RESET_ARB: + return COGL_GRAPHICS_RESET_STATUS_INNOCENT_CONTEXT_RESET; + + case GL_UNKNOWN_CONTEXT_RESET_ARB: + return COGL_GRAPHICS_RESET_STATUS_UNKNOWN_CONTEXT_RESET; + + case GL_PURGED_CONTEXT_RESET_NV: + return COGL_GRAPHICS_RESET_STATUS_PURGED_CONTEXT_RESET; + + default: + return COGL_GRAPHICS_RESET_STATUS_NO_ERROR; + } +} diff --git a/cogl/cogl-context.h b/cogl/cogl-context.h index 07badeb..cab586b 100644 --- a/cogl/cogl-context.h +++ b/cogl/cogl-context.h @@ -393,6 +393,48 @@ cogl_foreach_feature (CoglContext *context, int64_t cogl_get_clock_time (CoglContext *context); +/** + * CoglGraphicsResetStatus: + * @COGL_GRAPHICS_RESET_STATUS_NO_ERROR: + * @COGL_GRAPHICS_RESET_STATUS_GUILTY_CONTEXT_RESET: + * @COGL_GRAPHICS_RESET_STATUS_INNOCENT_CONTEXT_RESET: + * @COGL_GRAPHICS_RESET_STATUS_UNKNOWN_CONTEXT_RESET: + * @COGL_GRAPHICS_RESET_STATUS_PURGED_CONTEXT_RESET: + * + * All the error values that might be returned by + * cogl_get_graphics_reset_status(). Each value's meaning corresponds + * to the similarly named value defined in the ARB_robustness and + * NV_robustness_video_memory_purge extensions. + */ +typedef enum _CoglGraphicsResetStatus +{ + COGL_GRAPHICS_RESET_STATUS_NO_ERROR, + COGL_GRAPHICS_RESET_STATUS_GUILTY_CONTEXT_RESET, + COGL_GRAPHICS_RESET_STATUS_INNOCENT_CONTEXT_RESET, + COGL_GRAPHICS_RESET_STATUS_UNKNOWN_CONTEXT_RESET, + COGL_GRAPHICS_RESET_STATUS_PURGED_CONTEXT_RESET, +} CoglGraphicsResetStatus; + +/** + * cogl_get_graphics_reset_status: + * @context: a #CoglContext pointer + * + * Returns the graphics reset status as reported by + * GetGraphicsResetStatusARB defined in the ARB_robustness extension. + * + * Note that Cogl doesn't normally enable the ARB_robustness + * extension in which case this will only ever return + * #COGL_GRAPHICS_RESET_STATUS_NO_ERROR. + * + * Applications must explicitly use a backend specific method to + * request that errors get reported such as X11's + * cogl_xlib_renderer_request_reset_on_video_memory_purge(). + * + * Return value: a #CoglGraphicsResetStatus + */ +CoglGraphicsResetStatus +cogl_get_graphics_reset_status (CoglContext *context); + #endif /* COGL_ENABLE_EXPERIMENTAL_API */ COGL_END_DECLS diff --git a/cogl/cogl.symbols b/cogl/cogl.symbols index feb9e65..eb72407 100644 --- a/cogl/cogl.symbols +++ b/cogl/cogl.symbols @@ -334,6 +334,7 @@ cogl_get_clock_time cogl_get_depth_test_enabled cogl_get_draw_framebuffer cogl_get_features +cogl_get_graphics_reset_status cogl_get_modelview_matrix cogl_get_option_group cogl_get_proc_address -- 2.7.4 From 6361d971c0775b4d7c20e3c2deb8c87ce546a94d Mon Sep 17 00:00:00 2001 From: Rui Matos Date: Tue, 24 May 2016 19:37:02 +0200 Subject: [PATCH 5/5] cogl: Ignore GL_CONTEXT_LOST when checking for GL errors When using a context with robustness, glGetError() may return GL_CONTEXT_LOST at any time and this error doesn't get cleared until the application calls glGetGraphicsResetStatus() . This means that our error checking can't call glGetError() in a loop without checking for that return value and returning in that case. https://bugzilla.gnome.org/show_bug.cgi?id=739178 --- cogl/cogl-texture-3d.c | 4 +--- cogl/cogl-texture-rectangle.c | 10 +++------- cogl/deprecated/cogl-shader.c | 5 ++--- cogl/driver/gl/cogl-buffer-gl.c | 15 ++++----------- cogl/driver/gl/cogl-pipeline-opengl.c | 7 ++----- cogl/driver/gl/cogl-texture-2d-gl.c | 16 +++++----------- cogl/driver/gl/cogl-util-gl-private.h | 10 ++++++++-- cogl/driver/gl/cogl-util-gl.c | 22 +++++++++++++++++++++- cogl/driver/gl/gl/cogl-pipeline-fragend-arbfp.c | 6 ++---- cogl/driver/gl/gl/cogl-texture-driver-gl.c | 12 +++--------- cogl/driver/gl/gles/cogl-texture-driver-gles.c | 18 +++++------------- 11 files changed, 56 insertions(+), 69 deletions(-) diff --git a/cogl/cogl-texture-3d.c b/cogl/cogl-texture-3d.c index 8e2ff08..31d2941 100644 --- a/cogl/cogl-texture-3d.c +++ b/cogl/cogl-texture-3d.c @@ -361,7 +361,6 @@ allocate_with_size (CoglTexture3D *tex_3d, GLenum gl_intformat; GLenum gl_format; GLenum gl_type; - GLenum gl_error; GLenum gl_texture; internal_format = @@ -387,8 +386,7 @@ allocate_with_size (CoglTexture3D *tex_3d, gl_texture, FALSE); /* Clear any GL errors */ - while ((gl_error = ctx->glGetError ()) != GL_NO_ERROR) - ; + _cogl_gl_util_clear_gl_errors (ctx); ctx->glTexImage3D (GL_TEXTURE_3D, 0, gl_intformat, width, height, depth, diff --git a/cogl/cogl-texture-rectangle.c b/cogl/cogl-texture-rectangle.c index 65d2f06..da5f1f0 100644 --- a/cogl/cogl-texture-rectangle.c +++ b/cogl/cogl-texture-rectangle.c @@ -228,7 +228,6 @@ allocate_with_size (CoglTextureRectangle *tex_rect, GLenum gl_intformat; GLenum gl_format; GLenum gl_type; - GLenum gl_error; GLenum gl_texture; internal_format = @@ -256,8 +255,7 @@ allocate_with_size (CoglTextureRectangle *tex_rect, tex_rect->is_foreign); /* Clear any GL errors */ - while ((gl_error = ctx->glGetError ()) != GL_NO_ERROR) - ; + _cogl_gl_util_clear_gl_errors (ctx); ctx->glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0, gl_intformat, width, height, 0, gl_format, gl_type, NULL); @@ -361,7 +359,6 @@ allocate_from_gl_foreign (CoglTextureRectangle *tex_rect, CoglTexture *tex = COGL_TEXTURE (tex_rect); CoglContext *ctx = tex->context; CoglPixelFormat format = loader->src.gl_foreign.format; - GLenum gl_error = 0; GLint gl_compressed = GL_FALSE; GLenum gl_int_format = 0; @@ -377,12 +374,11 @@ allocate_from_gl_foreign (CoglTextureRectangle *tex_rect, } /* Make sure binding succeeds */ - while ((gl_error = ctx->glGetError ()) != GL_NO_ERROR) - ; + _cogl_gl_util_clear_gl_errors (ctx); _cogl_bind_gl_texture_transient (GL_TEXTURE_RECTANGLE_ARB, loader->src.gl_foreign.gl_handle, TRUE); - if (ctx->glGetError () != GL_NO_ERROR) + if (_cogl_gl_util_get_error (ctx) != GL_NO_ERROR) { _cogl_set_error (error, COGL_SYSTEM_ERROR, diff --git a/cogl/deprecated/cogl-shader.c b/cogl/deprecated/cogl-shader.c index 08dcb82..d4b687c 100644 --- a/cogl/deprecated/cogl-shader.c +++ b/cogl/deprecated/cogl-shader.c @@ -213,15 +213,14 @@ _cogl_shader_compile_real (CoglHandle handle, g_message ("user ARBfp program:\n%s", shader->source); #ifdef COGL_GL_DEBUG - while ((gl_error = ctx->glGetError ()) != GL_NO_ERROR) - ; + _cogl_gl_util_clear_gl_errors (ctx); #endif ctx->glProgramString (GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB, strlen (shader->source), shader->source); #ifdef COGL_GL_DEBUG - gl_error = ctx->glGetError (); + gl_error = _cogl_gl_util_get_error (ctx); if (gl_error != GL_NO_ERROR) { g_warning ("%s: GL error (%d): Failed to compile ARBfp:\n%s\n%s", diff --git a/cogl/driver/gl/cogl-buffer-gl.c b/cogl/driver/gl/cogl-buffer-gl.c index 0f98406..b8cd03f 100644 --- a/cogl/driver/gl/cogl-buffer-gl.c +++ b/cogl/driver/gl/cogl-buffer-gl.c @@ -142,7 +142,6 @@ recreate_store (CoglBuffer *buffer, CoglContext *ctx = buffer->context; GLenum gl_target; GLenum gl_enum; - GLenum gl_error; /* This assumes the buffer is already bound */ @@ -150,8 +149,7 @@ recreate_store (CoglBuffer *buffer, gl_enum = update_hints_to_gl_enum (buffer); /* Clear any GL errors */ - while ((gl_error = ctx->glGetError ()) != GL_NO_ERROR) - ; + _cogl_gl_util_clear_gl_errors (ctx); ctx->glBufferData (gl_target, buffer->size, @@ -216,7 +214,6 @@ _cogl_buffer_gl_map_range (CoglBuffer *buffer, CoglBufferBindTarget target; GLenum gl_target; CoglContext *ctx = buffer->context; - GLenum gl_error; if (((access & COGL_BUFFER_ACCESS_READ) && !cogl_has_feature (ctx, COGL_FEATURE_ID_MAP_BUFFER_FOR_READ)) || @@ -282,8 +279,7 @@ _cogl_buffer_gl_map_range (CoglBuffer *buffer, } /* Clear any GL errors */ - while ((gl_error = ctx->glGetError ()) != GL_NO_ERROR) - ; + _cogl_gl_util_clear_gl_errors (ctx); data = ctx->glMapBufferRange (gl_target, offset, @@ -314,8 +310,7 @@ _cogl_buffer_gl_map_range (CoglBuffer *buffer, } /* Clear any GL errors */ - while ((gl_error = ctx->glGetError ()) != GL_NO_ERROR) - ; + _cogl_gl_util_clear_gl_errors (ctx); data = ctx->glMapBuffer (gl_target, _cogl_buffer_access_to_gl_enum (access)); @@ -363,7 +358,6 @@ _cogl_buffer_gl_set_data (CoglBuffer *buffer, CoglBufferBindTarget target; GLenum gl_target; CoglContext *ctx = buffer->context; - GLenum gl_error; CoglBool status = TRUE; CoglError *internal_error = NULL; @@ -384,8 +378,7 @@ _cogl_buffer_gl_set_data (CoglBuffer *buffer, gl_target = convert_bind_target_to_gl_target (target); /* Clear any GL errors */ - while ((gl_error = ctx->glGetError ()) != GL_NO_ERROR) - ; + _cogl_gl_util_clear_gl_errors (ctx); ctx->glBufferSubData (gl_target, offset, size, data); diff --git a/cogl/driver/gl/cogl-pipeline-opengl.c b/cogl/driver/gl/cogl-pipeline-opengl.c index c7b44ee..52c2392 100644 --- a/cogl/driver/gl/cogl-pipeline-opengl.c +++ b/cogl/driver/gl/cogl-pipeline-opengl.c @@ -253,12 +253,9 @@ set_glsl_program (GLuint gl_program) if (ctx->current_gl_program != gl_program) { - GLenum gl_error; - - while ((gl_error = ctx->glGetError ()) != GL_NO_ERROR) - ; + _cogl_gl_util_clear_gl_errors (ctx); ctx->glUseProgram (gl_program); - if (ctx->glGetError () == GL_NO_ERROR) + if (_cogl_gl_util_get_error (ctx) == GL_NO_ERROR) ctx->current_gl_program = gl_program; else { diff --git a/cogl/driver/gl/cogl-texture-2d-gl.c b/cogl/driver/gl/cogl-texture-2d-gl.c index 8675f52..1cae680 100644 --- a/cogl/driver/gl/cogl-texture-2d-gl.c +++ b/cogl/driver/gl/cogl-texture-2d-gl.c @@ -116,7 +116,6 @@ allocate_with_size (CoglTexture2D *tex_2d, GLenum gl_intformat; GLenum gl_format; GLenum gl_type; - GLenum gl_error; GLenum gl_texture; internal_format = @@ -149,8 +148,7 @@ allocate_with_size (CoglTexture2D *tex_2d, tex_2d->is_foreign); /* Clear any GL errors */ - while ((gl_error = ctx->glGetError ()) != GL_NO_ERROR) - ; + _cogl_gl_util_clear_gl_errors (ctx); ctx->glTexImage2D (GL_TEXTURE_2D, 0, gl_intformat, width, height, 0, gl_format, gl_type, NULL); @@ -286,18 +284,16 @@ allocate_from_egl_image (CoglTexture2D *tex_2d, CoglTexture *tex = COGL_TEXTURE (tex_2d); CoglContext *ctx = tex->context; CoglPixelFormat internal_format = loader->src.egl_image.format; - GLenum gl_error; tex_2d->gl_texture = ctx->texture_driver->gen (ctx, GL_TEXTURE_2D, internal_format); _cogl_bind_gl_texture_transient (GL_TEXTURE_2D, tex_2d->gl_texture, FALSE); + _cogl_gl_util_clear_gl_errors (ctx); - while ((gl_error = ctx->glGetError ()) != GL_NO_ERROR) - ; ctx->glEGLImageTargetTexture2D (GL_TEXTURE_2D, loader->src.egl_image.image); - if (ctx->glGetError () != GL_NO_ERROR) + if (_cogl_gl_util_get_error (ctx) != GL_NO_ERROR) { _cogl_set_error (error, COGL_TEXTURE_ERROR, @@ -327,7 +323,6 @@ allocate_from_gl_foreign (CoglTexture2D *tex_2d, CoglTexture *tex = COGL_TEXTURE (tex_2d); CoglContext *ctx = tex->context; CoglPixelFormat format = loader->src.gl_foreign.format; - GLenum gl_error = 0; GLint gl_compressed = GL_FALSE; GLenum gl_int_format = 0; @@ -342,12 +337,11 @@ allocate_from_gl_foreign (CoglTexture2D *tex_2d, } /* Make sure binding succeeds */ - while ((gl_error = ctx->glGetError ()) != GL_NO_ERROR) - ; + _cogl_gl_util_clear_gl_errors (ctx); _cogl_bind_gl_texture_transient (GL_TEXTURE_2D, loader->src.gl_foreign.gl_handle, TRUE); - if (ctx->glGetError () != GL_NO_ERROR) + if (_cogl_gl_util_get_error (ctx) != GL_NO_ERROR) { _cogl_set_error (error, COGL_SYSTEM_ERROR, diff --git a/cogl/driver/gl/cogl-util-gl-private.h b/cogl/driver/gl/cogl-util-gl-private.h index dcc61c0..1407e0f 100644 --- a/cogl/driver/gl/cogl-util-gl-private.h +++ b/cogl/driver/gl/cogl-util-gl-private.h @@ -45,7 +45,7 @@ _cogl_gl_error_to_string (GLenum error_code); #define GE(ctx, x) G_STMT_START { \ GLenum __err; \ (ctx)->x; \ - while ((__err = (ctx)->glGetError ()) != GL_NO_ERROR) \ + while ((__err = (ctx)->glGetError ()) != GL_NO_ERROR && __err != GL_CONTEXT_LOST) \ { \ g_warning ("%s: GL error (%d): %s\n", \ G_STRLOC, \ @@ -56,7 +56,7 @@ _cogl_gl_error_to_string (GLenum error_code); #define GE_RET(ret, ctx, x) G_STMT_START { \ GLenum __err; \ ret = (ctx)->x; \ - while ((__err = (ctx)->glGetError ()) != GL_NO_ERROR) \ + while ((__err = (ctx)->glGetError ()) != GL_NO_ERROR && __err != GL_CONTEXT_LOST) \ { \ g_warning ("%s: GL error (%d): %s\n", \ G_STRLOC, \ @@ -71,6 +71,12 @@ _cogl_gl_error_to_string (GLenum error_code); #endif /* COGL_GL_DEBUG */ +GLenum +_cogl_gl_util_get_error (CoglContext *ctx); + +void +_cogl_gl_util_clear_gl_errors (CoglContext *ctx); + CoglBool _cogl_gl_util_catch_out_of_memory (CoglContext *ctx, CoglError **error); diff --git a/cogl/driver/gl/cogl-util-gl.c b/cogl/driver/gl/cogl-util-gl.c index 814621a..f136673 100644 --- a/cogl/driver/gl/cogl-util-gl.c +++ b/cogl/driver/gl/cogl-util-gl.c @@ -77,13 +77,33 @@ _cogl_gl_error_to_string (GLenum error_code) } #endif /* COGL_GL_DEBUG */ +GLenum +_cogl_gl_util_get_error (CoglContext *ctx) +{ + GLenum gl_error = ctx->glGetError (); + + if (gl_error != GL_NO_ERROR && gl_error != GL_CONTEXT_LOST) + return gl_error; + else + return GL_NO_ERROR; +} + +void +_cogl_gl_util_clear_gl_errors (CoglContext *ctx) +{ + GLenum gl_error; + + while ((gl_error = ctx->glGetError ()) != GL_NO_ERROR && gl_error != GL_CONTEXT_LOST) + ; +} + CoglBool _cogl_gl_util_catch_out_of_memory (CoglContext *ctx, CoglError **error) { GLenum gl_error; CoglBool out_of_memory = FALSE; - while ((gl_error = ctx->glGetError ()) != GL_NO_ERROR) + while ((gl_error = ctx->glGetError ()) != GL_NO_ERROR && gl_error != GL_CONTEXT_LOST) { if (gl_error == GL_OUT_OF_MEMORY) out_of_memory = TRUE; diff --git a/cogl/driver/gl/gl/cogl-pipeline-fragend-arbfp.c b/cogl/driver/gl/gl/cogl-pipeline-fragend-arbfp.c index 16b13be..7be4a3f 100644 --- a/cogl/driver/gl/gl/cogl-pipeline-fragend-arbfp.c +++ b/cogl/driver/gl/gl/cogl-pipeline-fragend-arbfp.c @@ -837,7 +837,6 @@ _cogl_pipeline_fragend_arbfp_end (CoglPipeline *pipeline, if (shader_state->source) { - GLenum gl_error; COGL_STATIC_COUNTER (fragend_arbfp_compile_counter, "arbfp compile counter", "Increments each time a new ARBfp " @@ -857,14 +856,13 @@ _cogl_pipeline_fragend_arbfp_end (CoglPipeline *pipeline, GE (ctx, glBindProgram (GL_FRAGMENT_PROGRAM_ARB, shader_state->gl_program)); + _cogl_gl_util_clear_gl_errors (ctx); - while ((gl_error = ctx->glGetError ()) != GL_NO_ERROR) - ; ctx->glProgramString (GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB, shader_state->source->len, shader_state->source->str); - if (ctx->glGetError () != GL_NO_ERROR) + if (_cogl_gl_util_get_error (ctx) != GL_NO_ERROR) { g_warning ("\n%s\n%s", shader_state->source->str, diff --git a/cogl/driver/gl/gl/cogl-texture-driver-gl.c b/cogl/driver/gl/gl/cogl-texture-driver-gl.c index 109af81..1113966 100644 --- a/cogl/driver/gl/gl/cogl-texture-driver-gl.c +++ b/cogl/driver/gl/gl/cogl-texture-driver-gl.c @@ -207,7 +207,6 @@ _cogl_texture_driver_upload_subregion_to_gl (CoglContext *ctx, uint8_t *data; CoglPixelFormat source_format = cogl_bitmap_get_format (source_bmp); int bpp = _cogl_pixel_format_get_bytes_per_pixel (source_format); - GLenum gl_error; CoglBool status = TRUE; CoglError *internal_error = NULL; int level_width; @@ -237,8 +236,7 @@ _cogl_texture_driver_upload_subregion_to_gl (CoglContext *ctx, _cogl_bind_gl_texture_transient (gl_target, gl_handle, is_foreign); /* Clear any GL errors */ - while ((gl_error = ctx->glGetError ()) != GL_NO_ERROR) - ; + _cogl_gl_util_clear_gl_errors (ctx); _cogl_texture_get_level_size (texture, level, @@ -315,7 +313,6 @@ _cogl_texture_driver_upload_to_gl (CoglContext *ctx, uint8_t *data; CoglPixelFormat source_format = cogl_bitmap_get_format (source_bmp); int bpp = _cogl_pixel_format_get_bytes_per_pixel (source_format); - GLenum gl_error; CoglBool status = TRUE; CoglError *internal_error = NULL; @@ -341,8 +338,7 @@ _cogl_texture_driver_upload_to_gl (CoglContext *ctx, _cogl_bind_gl_texture_transient (gl_target, gl_handle, is_foreign); /* Clear any GL errors */ - while ((gl_error = ctx->glGetError ()) != GL_NO_ERROR) - ; + _cogl_gl_util_clear_gl_errors (ctx); ctx->glTexImage2D (gl_target, 0, internal_gl_format, @@ -377,7 +373,6 @@ _cogl_texture_driver_upload_to_gl_3d (CoglContext *ctx, uint8_t *data; CoglPixelFormat source_format = cogl_bitmap_get_format (source_bmp); int bpp = _cogl_pixel_format_get_bytes_per_pixel (source_format); - GLenum gl_error; CoglBool status = TRUE; data = _cogl_bitmap_gl_bind (source_bmp, COGL_BUFFER_ACCESS_READ, 0, error); @@ -394,8 +389,7 @@ _cogl_texture_driver_upload_to_gl_3d (CoglContext *ctx, _cogl_bind_gl_texture_transient (gl_target, gl_handle, is_foreign); /* Clear any GL errors */ - while ((gl_error = ctx->glGetError ()) != GL_NO_ERROR) - ; + _cogl_gl_util_clear_gl_errors (ctx); ctx->glTexImage3D (gl_target, 0, /* level */ diff --git a/cogl/driver/gl/gles/cogl-texture-driver-gles.c b/cogl/driver/gl/gles/cogl-texture-driver-gles.c index f87f1e9..85412a8 100644 --- a/cogl/driver/gl/gles/cogl-texture-driver-gles.c +++ b/cogl/driver/gl/gles/cogl-texture-driver-gles.c @@ -201,7 +201,6 @@ _cogl_texture_driver_upload_subregion_to_gl (CoglContext *ctx, int bpp = _cogl_pixel_format_get_bytes_per_pixel (source_format); CoglBitmap *slice_bmp; int rowstride; - GLenum gl_error; CoglBool status = TRUE; CoglError *internal_error = NULL; int level_width; @@ -265,8 +264,7 @@ _cogl_texture_driver_upload_subregion_to_gl (CoglContext *ctx, _cogl_bind_gl_texture_transient (gl_target, gl_handle, is_foreign); /* Clear any GL errors */ - while ((gl_error = ctx->glGetError ()) != GL_NO_ERROR) - ; + _cogl_gl_util_clear_gl_errors (ctx); _cogl_texture_get_level_size (texture, level, @@ -348,7 +346,6 @@ _cogl_texture_driver_upload_to_gl (CoglContext *ctx, int bmp_height = cogl_bitmap_get_height (source_bmp); CoglBitmap *bmp; uint8_t *data; - GLenum gl_error; CoglError *internal_error = NULL; CoglBool status = TRUE; @@ -379,8 +376,7 @@ _cogl_texture_driver_upload_to_gl (CoglContext *ctx, } /* Clear any GL errors */ - while ((gl_error = ctx->glGetError ()) != GL_NO_ERROR) - ; + _cogl_gl_util_clear_gl_errors (ctx); ctx->glTexImage2D (gl_target, 0, internal_gl_format, @@ -419,7 +415,6 @@ _cogl_texture_driver_upload_to_gl_3d (CoglContext *ctx, int bmp_width = cogl_bitmap_get_width (source_bmp); int bmp_height = cogl_bitmap_get_height (source_bmp); uint8_t *data; - GLenum gl_error; _cogl_bind_gl_texture_transient (gl_target, gl_handle, is_foreign); @@ -440,8 +435,7 @@ _cogl_texture_driver_upload_to_gl_3d (CoglContext *ctx, image with a sub-region update */ /* Clear any GL errors */ - while ((gl_error = ctx->glGetError ()) != GL_NO_ERROR) - ; + _cogl_gl_util_clear_gl_errors (ctx); ctx->glTexImage3D (gl_target, 0, /* level */ @@ -488,8 +482,7 @@ _cogl_texture_driver_upload_to_gl_3d (CoglContext *ctx, } /* Clear any GL errors */ - while ((gl_error = ctx->glGetError ()) != GL_NO_ERROR) - ; + _cogl_gl_util_clear_gl_errors (ctx); ctx->glTexSubImage3D (gl_target, 0, /* level */ @@ -524,8 +517,7 @@ _cogl_texture_driver_upload_to_gl_3d (CoglContext *ctx, _cogl_texture_driver_prep_gl_for_pixels_upload (ctx, rowstride, bpp); /* Clear any GL errors */ - while ((gl_error = ctx->glGetError ()) != GL_NO_ERROR) - ; + _cogl_gl_util_clear_gl_errors (ctx); ctx->glTexImage3D (gl_target, 0, /* level */ -- 2.7.4