[cairo-commit] 2 commits - src/cairo-gl-composite.c src/cairo-gl-device.c src/cairo-gl-glyphs.c src/cairo-gl-private.h src/cairo-gl-surface.c test/clipped-group.xlib-fallback.ref.png

Chris Wilson ickle at kemper.freedesktop.org
Sat Jun 12 08:50:14 PDT 2010


 src/cairo-gl-composite.c                 |    1 
 src/cairo-gl-device.c                    |   26 +++++++++++++----
 src/cairo-gl-glyphs.c                    |   10 ++++--
 src/cairo-gl-private.h                   |   45 +++++++++++++++++++++++--------
 src/cairo-gl-surface.c                   |   40 +++++++++++++++++----------
 test/clipped-group.xlib-fallback.ref.png |binary
 6 files changed, 86 insertions(+), 36 deletions(-)

New commits:
commit 8737bc8b17ff0c437bb57df018bb7c540a394a7c
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Sat Jun 12 16:49:46 2010 +0100

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

diff --git a/src/cairo-gl-composite.c b/src/cairo-gl-composite.c
index ddb06d6..0614fa3 100644
--- a/src/cairo-gl-composite.c
+++ b/src/cairo-gl-composite.c
@@ -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;
 }
 
diff --git a/src/cairo-gl-device.c b/src/cairo-gl-device.c
index 51b72e0..380d393 100644
--- a/src/cairo-gl-device.c
+++ b/src/cairo-gl-device.c
@@ -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 ();
 }
-
diff --git a/src/cairo-gl-glyphs.c b/src/cairo-gl-glyphs.c
index a19174d..b390f82 100644
--- a/src/cairo-gl-glyphs.c
+++ b/src/cairo-gl-glyphs.c
@@ -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);
 
diff --git a/src/cairo-gl-private.h b/src/cairo-gl-private.h
index a02e279..132fcb8 100644
--- a/src/cairo-gl-private.h
+++ b/src/cairo-gl-private.h
@@ -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);
diff --git a/src/cairo-gl-surface.c b/src/cairo-gl-surface.c
index e79f46c..e6aa655 100644
--- a/src/cairo-gl-surface.c
+++ b/src/cairo-gl-surface.c
@@ -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
commit 5b2f90bf532184e46829de4b2e2f9d0b10c1ff81
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Sat Jun 12 16:49:11 2010 +0100

    test: Forgotten ref image.

diff --git a/test/clipped-group.xlib-fallback.ref.png b/test/clipped-group.xlib-fallback.ref.png
new file mode 100644
index 0000000..e0a5dc0
Binary files /dev/null and b/test/clipped-group.xlib-fallback.ref.png differ


More information about the cairo-commit mailing list