From 31d105abd8f5f5c145c82ac4cc92252acad2312c Mon Sep 17 00:00:00 2001 From: Robert Bragg Date: Thu, 25 Oct 2012 16:56:14 +0100 Subject: [PATCH] Check for out-of-memory when allocating 2d textures This makes Cogl explicitly check for out-of-memory errors reported by the opengl driver in cogl_texture_2d_new_with_size() calls. This allows us to throw a COGL_SYSTEM_ERROR_NO_MEMORY error and return NULL so applications may gracefully handle this condition. This patch only affects the cogl_texture_2d_new_with_size() api not _new_from_data() or _new_from_bitmap(). Reviewed-by: Neil Roberts (cherry picked from commit 0283423dad59ba3d3e4cde400c29ac8e7803f888) --- cogl/Makefile.am | 2 + cogl/driver/gl/cogl-texture-2d-gl.c | 17 ++++++- cogl/driver/gl/cogl-util-gl-private.h | 33 ++++++++++++++ cogl/driver/gl/cogl-util-gl.c | 66 +++++++++++++++++++++++++++ 4 files changed, 116 insertions(+), 2 deletions(-) create mode 100644 cogl/driver/gl/cogl-util-gl-private.h create mode 100644 cogl/driver/gl/cogl-util-gl.c diff --git a/cogl/Makefile.am b/cogl/Makefile.am index 8f3480825..1d610a1bb 100644 --- a/cogl/Makefile.am +++ b/cogl/Makefile.am @@ -159,6 +159,8 @@ cogl_gl_prototypes_h = \ $(NULL) cogl_driver_sources += \ + $(srcdir)/driver/gl/cogl-util-gl-private.h \ + $(srcdir)/driver/gl/cogl-util-gl.c \ $(srcdir)/driver/gl/cogl-framebuffer-gl-private.h \ $(srcdir)/driver/gl/cogl-framebuffer-gl.c \ $(srcdir)/driver/gl/cogl-texture-2d-gl-private.h \ diff --git a/cogl/driver/gl/cogl-texture-2d-gl.c b/cogl/driver/gl/cogl-texture-2d-gl.c index 7c344acd2..224436f44 100644 --- a/cogl/driver/gl/cogl-texture-2d-gl.c +++ b/cogl/driver/gl/cogl-texture-2d-gl.c @@ -37,6 +37,7 @@ #include "cogl-texture-2d-private.h" #include "cogl-pipeline-opengl-private.h" #include "cogl-error-private.h" +#include "cogl-util-gl-private.h" void _cogl_texture_2d_gl_free (CoglTexture2D *tex_2d) @@ -97,6 +98,7 @@ _cogl_texture_2d_gl_new_with_size (CoglContext *ctx, GLenum gl_intformat; GLenum gl_format; GLenum gl_type; + GLenum gl_error; internal_format = ctx->driver_vtable->pixel_format_to_gl (ctx, internal_format, @@ -113,8 +115,19 @@ _cogl_texture_2d_gl_new_with_size (CoglContext *ctx, _cogl_bind_gl_texture_transient (GL_TEXTURE_2D, tex_2d->gl_texture, tex_2d->is_foreign); - GE( ctx, glTexImage2D (GL_TEXTURE_2D, 0, gl_intformat, - width, height, 0, gl_format, gl_type, NULL) ); + + /* Clear any GL errors */ + while ((gl_error = ctx->glGetError ()) != GL_NO_ERROR) + ; + + ctx->glTexImage2D (GL_TEXTURE_2D, 0, gl_intformat, + width, height, 0, gl_format, gl_type, NULL); + + if (_cogl_gl_util_catch_out_of_memory (ctx, error)) + { + cogl_object_unref (tex_2d); + return NULL; + } return tex_2d; } diff --git a/cogl/driver/gl/cogl-util-gl-private.h b/cogl/driver/gl/cogl-util-gl-private.h new file mode 100644 index 000000000..332df4fab --- /dev/null +++ b/cogl/driver/gl/cogl-util-gl-private.h @@ -0,0 +1,33 @@ +/* + * Cogl + * + * An object oriented GL/GLES Abstraction/Utility Layer + * + * Copyright (C) 2012 Intel Corporation. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see . + * + * + * Authors: + * Robert Bragg + */ + +#ifndef _COGL_UTIL_GL_PRIVATE_H_ + +#include "cogl-types.h" + +CoglBool +_cogl_gl_util_catch_out_of_memory (CoglContext *ctx, CoglError **error); + +#endif /* _COGL_UTIL_GL_PRIVATE_H_ */ diff --git a/cogl/driver/gl/cogl-util-gl.c b/cogl/driver/gl/cogl-util-gl.c new file mode 100644 index 000000000..b0033c156 --- /dev/null +++ b/cogl/driver/gl/cogl-util-gl.c @@ -0,0 +1,66 @@ +/* + * Cogl + * + * An object oriented GL/GLES Abstraction/Utility Layer + * + * Copyright (C) 2012 Intel Corporation. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see . + * + * + * Authors: + * Robert Bragg + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "cogl-types.h" +#include "cogl-context-private.h" +#include "cogl-error-private.h" +#include "cogl-internal.h" +#include "cogl-util-gl-private.h" + +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) + { + if (gl_error == GL_OUT_OF_MEMORY) + out_of_memory = TRUE; +#ifdef COGL_GL_DEBUG + else + { + g_warning ("%s: GL error (%d): %s\n", + G_STRLOC, + gl_error, + _cogl_gl_error_to_string (gl_error)); + } +#endif + } + + if (out_of_memory) + { + _cogl_set_error (error, COGL_SYSTEM_ERROR, + COGL_SYSTEM_ERROR_NO_MEMORY, + "Out of memory"); + return TRUE; + } + + return FALSE; +}