gl: start returning the failure status aftern an invalid GL op.

This commit is contained in:
Chris Wilson 2010-06-12 16:49:46 +01:00
parent 5b2f90bf53
commit 8737bc8b17
5 changed files with 86 additions and 36 deletions

View file

@ -58,6 +58,7 @@ _cairo_gl_create_gradient_texture (cairo_gl_surface_t *dst,
status = _cairo_gl_gradient_create (ctx, pattern->n_stops, pattern->stops, gradient);
_cairo_gl_context_release (ctx);
return status;
}

View file

@ -92,9 +92,7 @@ _gl_flush (void *device)
glDisable (GL_SCISSOR_TEST);
glDisable (GL_BLEND);
_cairo_gl_context_release (ctx);
return CAIRO_STATUS_SUCCESS;
return _cairo_gl_context_release (ctx);
}
static void
@ -194,7 +192,7 @@ _cairo_gl_context_init (cairo_gl_context_t *ctx)
fprintf (stderr, " GL_ARB_texture_non_power_of_two, GL_ARB_texture_rectangle\n");
}
if (!GLEW_ARB_texture_non_power_of_two)
if (! GLEW_ARB_texture_non_power_of_two)
ctx->tex_target = GL_TEXTURE_RECTANGLE_EXT;
else
ctx->tex_target = GL_TEXTURE_2D;
@ -272,8 +270,23 @@ _cairo_gl_ensure_framebuffer (cairo_gl_context_t *ctx,
0);
status = glCheckFramebufferStatusEXT (GL_FRAMEBUFFER_EXT);
if (status != GL_FRAMEBUFFER_COMPLETE_EXT)
fprintf (stderr, "destination is framebuffer incomplete\n");
if (status != GL_FRAMEBUFFER_COMPLETE_EXT) {
const char *str;
switch (status) {
//case GL_FRAMEBUFFER_UNDEFINED_EXT: str= "undefined"; break;
case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT: str= "incomplete attachment"; break;
case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT: str= "incomplete/missing attachment"; break;
case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT: str= "incomplete draw buffer"; break;
case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT: str= "incomplete read buffer"; break;
case GL_FRAMEBUFFER_UNSUPPORTED_EXT: str= "unsupported"; break;
case GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_EXT: str= "incomplete multiple"; break;
default: str = "unknown error"; break;
}
fprintf (stderr,
"destination is framebuffer incomplete: %s [%#x]\n",
str, status);
}
}
void
@ -311,4 +324,3 @@ _cairo_gl_context_set_destination (cairo_gl_context_t *ctx,
glMatrixMode (GL_MODELVIEW);
glLoadIdentity ();
}

View file

@ -229,7 +229,7 @@ _render_glyphs (cairo_gl_surface_t *dst,
cairo_gl_glyph_cache_t *cache = NULL;
cairo_gl_context_t *ctx;
cairo_gl_composite_t setup;
cairo_status_t status;
cairo_status_t status, status_maybe_ignored;
int i = 0;
*has_component_alpha = FALSE;
@ -313,7 +313,9 @@ _render_glyphs (cairo_gl_surface_t *dst,
/* XXX: _cairo_gl_composite_begin() acquires the context a
* second time. Need to refactor this loop so this doesn't happen.
*/
_cairo_gl_context_release (ctx);
status = _cairo_gl_context_release (ctx);
if (unlikely (status))
goto FINISH;
}
if (scaled_glyph->surface_private == NULL) {
@ -349,7 +351,9 @@ _render_glyphs (cairo_gl_surface_t *dst,
FINISH:
_cairo_scaled_font_thaw_cache (scaled_font);
_cairo_gl_context_release (ctx);
status_maybe_ignored = _cairo_gl_context_release (ctx);
if (status == CAIRO_STATUS_SUCCESS)
status = status_maybe_ignored;
_cairo_gl_composite_fini (&setup);

View file

@ -43,10 +43,15 @@
#define CAIRO_GL_PRIVATE_H
#include "cairoint.h"
#include "cairo-gl-gradient-private.h"
#include "cairo-device-private.h"
#include "cairo-error-private.h"
#include "cairo-rtree-private.h"
#include <assert.h>
#include <GL/glew.h>
#include "cairo-gl.h"
@ -82,6 +87,7 @@ typedef struct _cairo_gl_surface {
GLuint tex; /* GL texture object containing our data. */
GLuint fb; /* GL framebuffer object wrapping our data. */
GLuint depth; /* GL framebuffer object holding depth */
} cairo_gl_surface_t;
typedef struct cairo_gl_glyph_cache {
@ -218,13 +224,22 @@ typedef struct _cairo_gl_composite {
cairo_private extern const cairo_surface_backend_t _cairo_gl_surface_backend;
cairo_private const char *_cairo_gl_error_to_string (GLenum err);
#define _cairo_gl_check_error() do { \
GLenum err; \
while ((err = glGetError ())) { \
fprintf (stderr, "%s:%d: GL error 0x%04x: %s\n", __FILE__,__LINE__, (int) err, _cairo_gl_error_to_string (err)); \
_cairo_error_throw (CAIRO_STATUS_DEVICE_ERROR); \
} \
} while (0)
static cairo_always_inline cairo_status_t
_do_cairo_gl_check_error (const char *file, int line)
{
cairo_status_t status = CAIRO_STATUS_SUCCESS;
GLenum err;
while (unlikely ((err = glGetError ()))) {
fprintf (stderr, "%s:%d: GL error 0x%04x: %s\n",
file, line, (int) err,
_cairo_gl_error_to_string (err));
status = _cairo_error (CAIRO_STATUS_DEVICE_ERROR);
}
return status;
}
#define _cairo_gl_check_error() _do_cairo_gl_check_error(__FILE__, __LINE__)
static inline cairo_device_t *
_cairo_gl_context_create_in_error (cairo_status_t status)
@ -276,14 +291,22 @@ _cairo_gl_context_acquire (cairo_device_t *device,
if (unlikely (status))
return status;
assert (_cairo_gl_check_error () == CAIRO_STATUS_SUCCESS);
*ctx = (cairo_gl_context_t *) device;
return CAIRO_STATUS_SUCCESS;
}
#define _cairo_gl_context_release(ctx) do {\
_cairo_gl_check_error (); \
cairo_device_release (&(ctx)->base); \
} while (0)
static cairo_always_inline cairo_status_t
_cairo_gl_context_release (cairo_gl_context_t *ctx)
{
cairo_status_t status;
status = _cairo_gl_check_error ();
cairo_device_release (&(ctx)->base);
return status;
}
cairo_private void
_cairo_gl_context_set_destination (cairo_gl_context_t *ctx, cairo_gl_surface_t *surface);

View file

@ -66,7 +66,8 @@ _cairo_gl_surface_composite (cairo_operator_t op,
unsigned int height,
cairo_region_t *clip_region);
#define BIAS .375
static cairo_status_t
_cairo_gl_surface_flush (void *abstract_surface);
static cairo_bool_t _cairo_surface_is_gl (cairo_surface_t *surface)
{
@ -86,6 +87,7 @@ const char *_cairo_gl_error_to_string (GLenum err)
case GL_STACK_OVERFLOW: return "stack overflow";
case GL_STACK_UNDERFLOW: return "stack underflow";
case GL_OUT_OF_MEMORY: return "out of memory";
case GL_INVALID_FRAMEBUFFER_OPERATION_EXT: return "invalid framebuffer operation";
default:
return "unknown error";
@ -321,9 +323,8 @@ _cairo_gl_surface_clear (cairo_gl_surface_t *surface,
glDisable (GL_SCISSOR_TEST);
glClearColor (r, g, b, a);
glClear (GL_COLOR_BUFFER_BIT);
_cairo_gl_context_release (ctx);
return CAIRO_STATUS_SUCCESS;
return _cairo_gl_context_release (ctx);
}
cairo_surface_t *
@ -369,7 +370,11 @@ cairo_gl_surface_create (cairo_device_t *abstract_device,
return _cairo_surface_create_in_error (status);
}
_cairo_gl_context_release (ctx);
status = _cairo_gl_context_release (ctx);
if (unlikely (status)) {
_cairo_gl_context_release (ctx);
return _cairo_surface_create_in_error (status);
}
return &surface->base;
}
@ -436,7 +441,7 @@ cairo_gl_surface_swapbuffers (cairo_surface_t *abstract_surface)
if (! _cairo_gl_surface_is_texture (surface)) {
cairo_gl_context_t *ctx;
if (_cairo_gl_context_acquire (surface->base.device, &ctx))
return;
@ -523,7 +528,9 @@ _cairo_gl_surface_draw_image (cairo_gl_surface_t *dst,
if (unlikely (status))
return status;
cairo_surface_flush (&dst->base);
status = _cairo_gl_surface_flush (&dst->base);
if (unlikely (status))
goto FAIL;
glPixelStorei (GL_UNPACK_ALIGNMENT, 1);
glPixelStorei (GL_UNPACK_ROW_LENGTH, src->stride / cpp);
@ -664,11 +671,16 @@ _cairo_gl_surface_get_image (cairo_gl_surface_t *surface,
if (! _cairo_gl_surface_is_texture (surface) && GLEW_MESA_pack_invert)
glPixelStorei (GL_PACK_INVERT_MESA, 0);
_cairo_gl_context_release (ctx);
status = _cairo_gl_context_release (ctx);
if (unlikely (status)) {
cairo_surface_destroy (&image->base);
return status;
}
*image_out = image;
if (rect_out != NULL)
*rect_out = *interest;
return CAIRO_STATUS_SUCCESS;
}
@ -692,13 +704,13 @@ _cairo_gl_surface_finish (void *abstract_surface)
if (ctx->current_target == surface)
ctx->current_target = NULL;
if (surface->depth)
glDeleteFramebuffersEXT (1, &surface->depth);
if (surface->fb)
glDeleteFramebuffersEXT (1, &surface->fb);
glDeleteTextures (1, &surface->tex);
_cairo_gl_context_release (ctx);
return CAIRO_STATUS_SUCCESS;
return _cairo_gl_context_release (ctx);
}
static cairo_status_t
@ -953,7 +965,7 @@ _cairo_gl_surface_composite (cairo_operator_t op,
0);
}
_cairo_gl_context_release (ctx);
status = _cairo_gl_context_release (ctx);
CLEANUP:
_cairo_gl_composite_fini (&setup);
@ -1050,7 +1062,7 @@ _cairo_gl_surface_fill_rectangles (void *abstract_dst,
0);
}
_cairo_gl_context_release (ctx);
status = _cairo_gl_context_release (ctx);
CLEANUP:
_cairo_gl_composite_fini (&setup);
@ -1295,9 +1307,7 @@ _cairo_gl_surface_flush (void *abstract_surface)
(ctx->current_target == surface))
_cairo_gl_composite_flush (ctx);
_cairo_gl_context_release (ctx);
return CAIRO_STATUS_SUCCESS;
return _cairo_gl_context_release (ctx);
}
static cairo_int_status_t