[cairo-commit] 10 commits - src/cairo-egl-context.c src/cairo-fallback-compositor.c src/cairo-gl-composite.c src/cairo-gl-glyphs.c src/cairo-gl-operand.c src/cairo-gl-private.h src/cairo-gl-source.c src/cairo-gl-spans-compositor.c src/cairo-gl-surface.c src/cairo-gl-traps-compositor.c src/cairo-glx-context.c src/cairo-rtree.c src/cairo-rtree-private.h src/cairo-wgl-context.c src/Makefile.sources

Chris Wilson ickle at kemper.freedesktop.org
Mon Dec 5 09:19:49 PST 2011


 src/Makefile.sources            |    1 
 src/cairo-egl-context.c         |    3 +
 src/cairo-fallback-compositor.c |    4 -
 src/cairo-gl-composite.c        |    1 
 src/cairo-gl-glyphs.c           |   79 +++++++++++-----------------
 src/cairo-gl-operand.c          |   79 ++++------------------------
 src/cairo-gl-private.h          |   22 ++++++--
 src/cairo-gl-source.c           |  109 ++++++++++++++++++++++++++++++++++++++++
 src/cairo-gl-spans-compositor.c |   75 ---------------------------
 src/cairo-gl-surface.c          |   13 +++-
 src/cairo-gl-traps-compositor.c |   61 ----------------------
 src/cairo-glx-context.c         |    3 +
 src/cairo-rtree-private.h       |    5 +
 src/cairo-rtree.c               |   28 ++++++++++
 src/cairo-wgl-context.c         |    3 +
 15 files changed, 228 insertions(+), 258 deletions(-)

New commits:
commit e68eb874e9cdeb087834a65cc356e94d9bbbeeb8
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Mon Dec 5 16:38:05 2011 +0000

    fallback: fix the offset for painting
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/cairo-fallback-compositor.c b/src/cairo-fallback-compositor.c
index 105859d..767fc6b 100644
--- a/src/cairo-fallback-compositor.c
+++ b/src/cairo-fallback-compositor.c
@@ -55,8 +55,8 @@ _cairo_fallback_compositor_paint (const cairo_compositor_t	*_compositor,
 
     image = cairo_surface_map_to_image (extents->surface, &extents->unbounded);
     status = _cairo_surface_offset_paint (image,
-					  -extents->unbounded.x,
-					  -extents->unbounded.y,
+					  extents->unbounded.x,
+					  extents->unbounded.y,
 					  extents->op,
 					  &extents->source_pattern.base,
 					  extents->clip);
commit dd73add00c7886467d60e27cca8311e3cf5ee2e2
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Mon Dec 5 16:20:53 2011 +0000

    gl: Set the device offset on map-to-image
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/cairo-gl-surface.c b/src/cairo-gl-surface.c
index b6dbedc..c201c51 100644
--- a/src/cairo-gl-surface.c
+++ b/src/cairo-gl-surface.c
@@ -1042,6 +1042,8 @@ _cairo_gl_surface_map_to_image (void      *abstract_surface,
 	return _cairo_surface_create_in_error (status);
     }
 
+    cairo_surface_set_device_offset (&image->base, -extents->x, -extents->y);
+
     /* This is inefficient, as we'd rather just read the thing without making
      * it the destination.  But then, this is the fallback path, so let's not
      * fall back instead.
commit f7daaa8fce8dd399500551d84cf6207824e5c28e
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Mon Dec 5 16:07:45 2011 +0000

    gl: Propagate clip region
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/cairo-gl-composite.c b/src/cairo-gl-composite.c
index 90c189a..777a714 100644
--- a/src/cairo-gl-composite.c
+++ b/src/cairo-gl-composite.c
@@ -779,6 +779,7 @@ _cairo_gl_composite_init (cairo_gl_composite_t *setup,
 
     setup->dst = dst;
     setup->op = op;
+    setup->clip_region = dst->clip_region;
 
     return CAIRO_STATUS_SUCCESS;
 }
diff --git a/src/cairo-gl-private.h b/src/cairo-gl-private.h
index be109fa..d108e03 100644
--- a/src/cairo-gl-private.h
+++ b/src/cairo-gl-private.h
@@ -164,6 +164,8 @@ struct _cairo_gl_surface {
     GLuint depth_stencil; /* GL renderbuffer object for holding stencil buffer clip. */
     int owns_tex;
     cairo_bool_t needs_update;
+
+    cairo_region_t *clip_region;
 };
 
 typedef struct cairo_gl_glyph_cache {
diff --git a/src/cairo-gl-traps-compositor.c b/src/cairo-gl-traps-compositor.c
index 6c55ab6..60a7331 100644
--- a/src/cairo-gl-traps-compositor.c
+++ b/src/cairo-gl-traps-compositor.c
@@ -69,7 +69,7 @@ set_clip_region (void *_surface,
 {
     cairo_gl_surface_t *surface = _surface;
 
-    //surface->clip_region = region;
+    surface->clip_region = region;
     return CAIRO_STATUS_SUCCESS;
 }
 
commit 3b1151f60d28d4e0de7160043cf24579751425cc
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Mon Dec 5 15:41:23 2011 +0000

    gl: Substitute the white source for the default pattern
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/cairo-gl-source.c b/src/cairo-gl-source.c
index 0106468..00c68db 100644
--- a/src/cairo-gl-source.c
+++ b/src/cairo-gl-source.c
@@ -65,6 +65,9 @@ _cairo_gl_pattern_to_source (cairo_surface_t *dst,
     cairo_gl_source_t *source;
     cairo_int_status_t status;
 
+    if (pattern == NULL)
+	return _cairo_gl_white_source ();
+
     source = malloc (sizeof (*source));
     if (unlikely (source == NULL))
 	return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
commit 0ce8dad9a2330575276b28a37098fe6cc4bf877f
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Mon Dec 5 15:39:03 2011 +0000

    gl: Decouple glyphs on shutdown from the scaled font caches
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/cairo-gl-glyphs.c b/src/cairo-gl-glyphs.c
index 90ff8a6..3285fc5 100644
--- a/src/cairo-gl-glyphs.c
+++ b/src/cairo-gl-glyphs.c
@@ -124,6 +124,7 @@ _cairo_gl_glyph_cache_add_glyph (cairo_gl_context_t *ctx,
 					&glyph_private->base,
 					cache,
 					_cairo_gl_glyph_fini);
+    glyph_private->node.owner = (void*)scaled_glyph;
 
     scaled_glyph->dev_private = glyph_private;
     scaled_glyph->dev_private_key = cache;
@@ -205,16 +206,6 @@ _cairo_gl_glyph_cache_unlock (cairo_gl_glyph_cache_t *cache)
     _cairo_rtree_unpin (&cache->rtree);
 }
 
-static void
-_cairo_gl_font_fini (cairo_scaled_font_private_t *_priv,
-		     cairo_scaled_font_t  *scaled_font)
-{
-    cairo_gl_font_t *priv = (cairo_gl_font_t *)_priv;
-
-    cairo_list_del (&priv->link);
-    free (priv);
-}
-
 static cairo_status_t
 render_glyphs (cairo_gl_surface_t	*dst,
 	       int dst_x, int dst_y,
@@ -456,10 +447,23 @@ _cairo_gl_glyph_cache_init (cairo_gl_glyph_cache_t *cache)
 		       sizeof (cairo_gl_glyph_t));
 }
 
+static void
+_cairo_gl_glyph_cache_fini_glyph (cairo_rtree_node_t *node,
+				  void *cache)
+{
+    cairo_gl_glyph_t *glyph_private = (cairo_gl_glyph_t *) node;
+    if (glyph_private->node.owner) {
+	cairo_list_del (&glyph_private->base.link);
+	glyph_private->node.owner = NULL;
+    }
+}
+
 void
 _cairo_gl_glyph_cache_fini (cairo_gl_context_t *ctx,
 			    cairo_gl_glyph_cache_t *cache)
 {
+    _cairo_rtree_foreach (&cache->rtree,
+			  _cairo_gl_glyph_cache_fini_glyph, NULL);
     _cairo_rtree_fini (&cache->rtree);
     cairo_surface_destroy (&cache->operand.texture.surface->base);
 }
diff --git a/src/cairo-rtree-private.h b/src/cairo-rtree-private.h
index 11079e7..3289f79 100644
--- a/src/cairo-rtree-private.h
+++ b/src/cairo-rtree-private.h
@@ -112,6 +112,11 @@ _cairo_rtree_evict_random (cairo_rtree_t	 *rtree,
 		           int			  height,
 		           cairo_rtree_node_t	**out);
 
+cairo_private void
+_cairo_rtree_foreach (cairo_rtree_t *rtree,
+		      void (*func)(cairo_rtree_node_t *, void *data),
+		      void *data);
+
 static inline void *
 _cairo_rtree_pin (cairo_rtree_t *rtree, cairo_rtree_node_t *node)
 {
diff --git a/src/cairo-rtree.c b/src/cairo-rtree.c
index d6e5791..94af45b 100644
--- a/src/cairo-rtree.c
+++ b/src/cairo-rtree.c
@@ -368,6 +368,34 @@ _cairo_rtree_reset (cairo_rtree_t *rtree)
     cairo_list_add (&rtree->root.link, &rtree->available);
 }
 
+static void
+_cairo_rtree_node_foreach (cairo_rtree_node_t *node,
+			   void (*func)(cairo_rtree_node_t *, void *data),
+			   void *data)
+{
+    int i;
+
+    for (i = 0; i < 4 && node->children[i] != NULL; i++)
+	_cairo_rtree_node_foreach(node->children[i], func, data);
+
+    func(node, data);
+}
+
+void
+_cairo_rtree_foreach (cairo_rtree_t *rtree,
+		      void (*func)(cairo_rtree_node_t *, void *data),
+		      void *data)
+{
+    int i;
+
+    if (rtree->root.state == CAIRO_RTREE_NODE_OCCUPIED) {
+	func(&rtree->root, data);
+    } else {
+	for (i = 0; i < 4 && rtree->root.children[i] != NULL; i++)
+	    _cairo_rtree_node_foreach (rtree->root.children[i], func, data);
+    }
+}
+
 void
 _cairo_rtree_fini (cairo_rtree_t *rtree)
 {
commit 31c0726f682159e6465719c389975ec8885fa38b
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Mon Dec 5 15:28:10 2011 +0000

    gl: Embed the operand rather than a pattern into the glyph cache
    
    Use the native encoding for patterns.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/cairo-gl-glyphs.c b/src/cairo-gl-glyphs.c
index ae2d181..90ff8a6 100644
--- a/src/cairo-gl-glyphs.c
+++ b/src/cairo-gl-glyphs.c
@@ -82,7 +82,6 @@ _cairo_gl_glyph_cache_add_glyph (cairo_gl_context_t *ctx,
 				 cairo_scaled_glyph_t  *scaled_glyph)
 {
     cairo_image_surface_t *glyph_surface = scaled_glyph->surface;
-    cairo_gl_surface_t *cache_surface;
     cairo_gl_glyph_t *glyph_private;
     cairo_rtree_node_t *node = NULL;
     cairo_int_status_t status;
@@ -109,11 +108,9 @@ _cairo_gl_glyph_cache_add_glyph (cairo_gl_context_t *ctx,
     if (status)
 	return status;
 
-    cache_surface = (cairo_gl_surface_t *) cache->pattern.surface;
-
     /* XXX: Make sure we use the mask texture. This should work automagically somehow */
     glActiveTexture (GL_TEXTURE1);
-    status = _cairo_gl_surface_draw_image (cache_surface,
+    status = _cairo_gl_surface_draw_image (cache->operand.texture.surface,
                                            glyph_surface,
                                            0, 0,
                                            glyph_surface->width, glyph_surface->height,
@@ -137,10 +134,10 @@ _cairo_gl_glyph_cache_add_glyph (cairo_gl_context_t *ctx,
     glyph_private->p2.x = node->x + glyph_surface->width;
     glyph_private->p2.y = node->y + glyph_surface->height;
     if (! _cairo_gl_device_requires_power_of_two_textures (&ctx->base)) {
-	glyph_private->p1.x /= cache_surface->width;
-	glyph_private->p1.y /= cache_surface->height;
-	glyph_private->p2.x /= cache_surface->width;
-	glyph_private->p2.y /= cache_surface->height;
+	glyph_private->p1.x /= cache->operand.texture.surface->width;
+	glyph_private->p2.x /= cache->operand.texture.surface->width;
+	glyph_private->p1.y /= cache->operand.texture.surface->height;
+	glyph_private->p1.y /= cache->operand.texture.surface->height;
     }
 
     return CAIRO_STATUS_SUCCESS;
@@ -180,21 +177,22 @@ cairo_gl_context_get_glyph_cache (cairo_gl_context_t *ctx,
 	return _cairo_error (CAIRO_STATUS_INVALID_FORMAT);
     }
 
-    if (unlikely (cache->pattern.surface == NULL)) {
+    if (unlikely (cache->operand.texture.surface == NULL)) {
         cairo_surface_t *surface;
+
         surface = cairo_gl_surface_create (&ctx->base,
                                            content,
                                            GLYPH_CACHE_WIDTH,
                                            GLYPH_CACHE_HEIGHT);
-        if (unlikely (surface->status)) {
-            cairo_status_t status = surface->status;
-            cairo_surface_destroy (surface);
-            return status;
-        }
+        if (unlikely (surface->status))
+            return surface->status;
+
         _cairo_surface_release_device_reference (surface);
-        _cairo_pattern_init_for_surface (&cache->pattern, surface);
-        cairo_surface_destroy (surface);
-        cache->pattern.base.has_component_alpha = (content == CAIRO_CONTENT_COLOR_ALPHA);
+
+	cache->operand = ((cairo_gl_surface_t *)surface)->operand;
+	cache->operand.texture.surface = (cairo_gl_surface_t *)surface;
+	cache->operand.texture.attributes.has_component_alpha =
+	    content == CAIRO_CONTENT_COLOR_ALPHA;
     }
 
     *cache_out = cache;
@@ -272,14 +270,8 @@ render_glyphs (cairo_gl_surface_t	*dst,
 
 	    last_format = scaled_glyph->surface->format;
 
-            status = _cairo_gl_composite_set_mask (&setup,
-                                                   &cache->pattern.base,
-						   &_cairo_unbounded_rectangle,
-						   &_cairo_unbounded_rectangle);
-            if (unlikely (status))
-                goto FINISH;
-
-	    *has_component_alpha |= cache->pattern.base.has_component_alpha;
+	    _cairo_gl_composite_set_mask_operand (&setup, &cache->operand);
+	    *has_component_alpha |= cache->operand.texture.attributes.has_component_alpha;
 
             /* XXX: _cairo_gl_composite_begin() acquires the context a
              * second time. Need to refactor this loop so this doesn't happen.
@@ -469,9 +461,5 @@ _cairo_gl_glyph_cache_fini (cairo_gl_context_t *ctx,
 			    cairo_gl_glyph_cache_t *cache)
 {
     _cairo_rtree_fini (&cache->rtree);
-
-    if (cache->pattern.surface) {
-        _cairo_pattern_fini (&cache->pattern.base);
-        cache->pattern.surface = NULL;
-    }
+    cairo_surface_destroy (&cache->operand.texture.surface->base);
 }
diff --git a/src/cairo-gl-private.h b/src/cairo-gl-private.h
index d844676..be109fa 100644
--- a/src/cairo-gl-private.h
+++ b/src/cairo-gl-private.h
@@ -168,7 +168,7 @@ struct _cairo_gl_surface {
 
 typedef struct cairo_gl_glyph_cache {
     cairo_rtree_t rtree;
-    cairo_surface_pattern_t pattern;
+    cairo_gl_operand_t operand;
 } cairo_gl_glyph_cache_t;
 
 typedef enum cairo_gl_tex {
commit 16038150b3691d4d4a320a727afc107cd0937ac6
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Mon Dec 5 15:03:43 2011 +0000

    gl: Use the embedded operand to allow passing sources around
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/Makefile.sources b/src/Makefile.sources
index 1182631..67e3537 100644
--- a/src/Makefile.sources
+++ b/src/Makefile.sources
@@ -369,6 +369,7 @@ cairo_gl_sources = cairo-gl-composite.c \
 		   cairo-gl-msaa-compositor.c \
 		   cairo-gl-spans-compositor.c \
 		   cairo-gl-traps-compositor.c \
+		   cairo-gl-source.c \
 		   cairo-gl-surface.c
 
 cairo_glesv2_headers = $(cairo_gl_headers)
diff --git a/src/cairo-gl-glyphs.c b/src/cairo-gl-glyphs.c
index 395222c..ae2d181 100644
--- a/src/cairo-gl-glyphs.c
+++ b/src/cairo-gl-glyphs.c
@@ -217,13 +217,6 @@ _cairo_gl_font_fini (cairo_scaled_font_private_t *_priv,
     free (priv);
 }
 
-static inline cairo_gl_operand_t *
-source_to_operand (cairo_surface_t *surface)
-{
-    cairo_gl_source_t *source = (cairo_gl_source_t *) surface;
-    return &source->operand;
-}
-
 static cairo_status_t
 render_glyphs (cairo_gl_surface_t	*dst,
 	       int dst_x, int dst_y,
diff --git a/src/cairo-gl-operand.c b/src/cairo-gl-operand.c
index d494eb9..9b53b2f 100644
--- a/src/cairo-gl-operand.c
+++ b/src/cairo-gl-operand.c
@@ -154,7 +154,6 @@ _cairo_gl_subsurface_operand_init (cairo_gl_operand_t *operand,
     cairo_surface_subsurface_t *sub;
     cairo_gl_surface_t *surface;
     cairo_surface_attributes_t *attributes;
-    cairo_matrix_t m;
 
     sub = (cairo_surface_subsurface_t *) src->surface;
 
@@ -168,37 +167,19 @@ _cairo_gl_subsurface_operand_init (cairo_gl_operand_t *operand,
 
     surface = (cairo_gl_surface_t *) sub->target;
 
-    attributes = &operand->texture.attributes;
-
-    operand->type = CAIRO_GL_OPERAND_TEXTURE;
-    operand->texture.surface =
-	(cairo_gl_surface_t *) cairo_surface_reference (&surface->base);
-    operand->texture.tex = surface->tex;
-
     /* Translate the matrix from
      * (unnormalized src -> unnormalized src) to
      * (unnormalized dst -> unnormalized src)
      */
+    *operand = surface->operand;
+
+    attributes = &operand->texture.attributes;
     attributes->matrix = src->base.matrix;
     attributes->matrix.x0 += sub->extents.x;
     attributes->matrix.y0 += sub->extents.y;
-
-    /* Translate the matrix from
-     * (unnormalized dst -> unnormalized src) to
-     * (unnormalized dst -> normalized src)
-     */
-    if (_cairo_gl_device_requires_power_of_two_textures (dst->base.device)) {
-	cairo_matrix_init_scale (&m,
-				 1.0,
-				 1.0);
-    } else {
-	cairo_matrix_init_scale (&m,
-				 1.0 / surface->width,
-				 1.0 / surface->height);
-    }
     cairo_matrix_multiply (&attributes->matrix,
 			   &attributes->matrix,
-			   &m);
+			   &surface->operand.texture.attributes.matrix);
 
     attributes->extend = src->base.extend;
     attributes->filter = src->base.filter;
@@ -216,7 +197,6 @@ _cairo_gl_surface_operand_init (cairo_gl_operand_t *operand,
     const cairo_surface_pattern_t *src = (cairo_surface_pattern_t *)_src;
     cairo_gl_surface_t *surface;
     cairo_surface_attributes_t *attributes;
-    cairo_matrix_t m;
 
     surface = (cairo_gl_surface_t *) src->surface;
     if (surface->base.type != CAIRO_SURFACE_TYPE_GL)
@@ -230,35 +210,12 @@ _cairo_gl_surface_operand_init (cairo_gl_operand_t *operand,
 	return CAIRO_INT_STATUS_UNSUPPORTED;
     }
 
-    attributes = &operand->texture.attributes;
-
-    operand->type = CAIRO_GL_OPERAND_TEXTURE;
-    operand->texture.surface =
-	(cairo_gl_surface_t *) cairo_surface_reference (&surface->base);
-    operand->texture.tex = surface->tex;
-
-    /* Translate the matrix from
-     * (unnormalized src -> unnormalized src) to
-     * (unnormalized dst -> unnormalized src)
-     */
-    attributes->matrix = src->base.matrix;
+    *operand = surface->operand;
 
-    /* Translate the matrix from
-     * (unnormalized dst -> unnormalized src) to
-     * (unnormalized dst -> normalized src)
-     */
-    if (_cairo_gl_device_requires_power_of_two_textures (dst->base.device)) {
-	cairo_matrix_init_scale (&m,
-				 1.0,
-				 1.0);
-    } else {
-	cairo_matrix_init_scale (&m,
-				 1.0 / surface->width,
-				 1.0 / surface->height);
-    }
+    attributes = &operand->texture.attributes;
     cairo_matrix_multiply (&attributes->matrix,
-			   &attributes->matrix,
-			   &m);
+			   &src->base.matrix,
+			   &attributes->matrix);
 
     attributes->extend = src->base.extend;
     attributes->filter = src->base.filter;
@@ -275,11 +232,8 @@ _cairo_gl_pattern_texture_setup (cairo_gl_operand_t *operand,
     cairo_status_t status;
     cairo_gl_surface_t *surface;
     cairo_gl_context_t *ctx;
-    cairo_surface_attributes_t *attributes;
     cairo_surface_t *image;
 
-    attributes = &operand->texture.attributes;
-
     status = _cairo_gl_context_acquire (dst->base.device, &ctx);
     if (unlikely (status))
 	return status;
@@ -299,21 +253,10 @@ _cairo_gl_pattern_texture_setup (cairo_gl_operand_t *operand,
 	return status;
     }
 
-    attributes->extend = CAIRO_EXTEND_NONE;
-    attributes->filter = CAIRO_FILTER_NEAREST;
-    attributes->has_component_alpha = FALSE;
-
-    operand->type = CAIRO_GL_OPERAND_TEXTURE;
+    *operand = surface->operand;
     operand->texture.surface = surface;
-    operand->texture.tex = surface->tex;
-
-    if (_cairo_gl_device_requires_power_of_two_textures (dst->base.device)) {
-	cairo_matrix_init_identity (&attributes->matrix);
-    } else {
-	cairo_matrix_init_scale (&attributes->matrix,
-				 1.0 / surface->width,
-				 1.0 / surface->height);
-    }
+    operand->texture.attributes.matrix.x0 -= extents->x * operand->texture.attributes.matrix.xx;
+    operand->texture.attributes.matrix.y0 -= extents->y * operand->texture.attributes.matrix.yy;
     return CAIRO_STATUS_SUCCESS;
 }
 
diff --git a/src/cairo-gl-private.h b/src/cairo-gl-private.h
index e508714..d844676 100644
--- a/src/cairo-gl-private.h
+++ b/src/cairo-gl-private.h
@@ -150,7 +150,6 @@ typedef struct cairo_gl_operand {
 
 typedef struct cairo_gl_source {
     cairo_surface_t base;
-
     cairo_gl_operand_t operand;
 } cairo_gl_source_t;
 
@@ -699,8 +698,23 @@ _cairo_gl_surface_create_scratch (cairo_gl_context_t   *ctx,
 				  int			height);
 
 cairo_private cairo_surface_t *
+_cairo_gl_pattern_to_source (cairo_surface_t *dst,
+			     const cairo_pattern_t *pattern,
+			     cairo_bool_t is_mask,
+			     const cairo_rectangle_int_t *extents,
+			     const cairo_rectangle_int_t *sample,
+			     int *src_x, int *src_y);
+
+cairo_private cairo_surface_t *
 _cairo_gl_white_source (void);
 
+static inline cairo_gl_operand_t *
+source_to_operand (cairo_surface_t *surface)
+{
+    cairo_gl_source_t *source = (cairo_gl_source_t *)surface;
+    return source ? &source->operand : NULL;
+}
+
 slim_hidden_proto (cairo_gl_surface_create);
 slim_hidden_proto (cairo_gl_surface_create_for_texture);
 
diff --git a/src/cairo-gl-source.c b/src/cairo-gl-source.c
new file mode 100644
index 0000000..0106468
--- /dev/null
+++ b/src/cairo-gl-source.c
@@ -0,0 +1,106 @@
+/* cairo - a vector graphics library with display and print output
+ *
+ * Copyright © 2011 Intel Corporation
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it either under the terms of the GNU Lesser General Public
+ * License version 2.1 as published by the Free Software Foundation
+ * (the "LGPL") or, at your option, under the terms of the Mozilla
+ * Public License Version 1.1 (the "MPL"). If you do not alter this
+ * notice, a recipient may use your version of this file under either
+ * the MPL or the LGPL.
+ *
+ * You should have received a copy of the LGPL along with this library
+ * in the file COPYING-LGPL-2.1; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
+ * You should have received a copy of the MPL along with this library
+ * in the file COPYING-MPL-1.1
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
+ * OF ANY KIND, either express or implied. See the LGPL or the MPL for
+ * the specific language governing rights and limitations.
+ *
+ * The Original Code is the cairo graphics library.
+ *
+ * The Initial Developer of the Original Code is Red Hat, Inc.
+ *
+ * Contributor(s):
+ *	Chris Wilson <chris at chris-wilson.co.uk>
+ */
+
+#include "cairoint.h"
+
+#include "cairo-gl-private.h"
+
+#include "cairo-surface-backend-private.h"
+
+static cairo_status_t
+_cairo_gl_source_finish (void *abstract_surface)
+{
+    cairo_gl_source_t *source = abstract_surface;
+
+    _cairo_gl_operand_destroy (&source->operand);
+    return CAIRO_STATUS_SUCCESS;
+}
+
+static const cairo_surface_backend_t cairo_gl_source_backend = {
+    CAIRO_SURFACE_TYPE_GL,
+    _cairo_gl_source_finish,
+    NULL, /* read-only wrapper */
+};
+
+cairo_surface_t *
+_cairo_gl_pattern_to_source (cairo_surface_t *dst,
+			     const cairo_pattern_t *pattern,
+			     cairo_bool_t is_mask,
+			     const cairo_rectangle_int_t *extents,
+			     const cairo_rectangle_int_t *sample,
+			     int *src_x, int *src_y)
+{
+    cairo_gl_source_t *source;
+    cairo_int_status_t status;
+
+    source = malloc (sizeof (*source));
+    if (unlikely (source == NULL))
+	return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
+
+    _cairo_surface_init (&source->base,
+			 &cairo_gl_source_backend,
+			 NULL, /* device */
+			 CAIRO_CONTENT_COLOR_ALPHA);
+
+    *src_x = *src_y = 0;
+    status = _cairo_gl_operand_init (&source->operand, pattern,
+				     (cairo_gl_surface_t *)dst,
+				     sample, extents);
+    if (unlikely (status)) {
+	cairo_surface_destroy (&source->base);
+	return _cairo_surface_create_in_error (status);
+    }
+
+    return &source->base;
+}
+
+cairo_surface_t *
+_cairo_gl_white_source (void)
+{
+    cairo_gl_source_t *source;
+
+    source = malloc (sizeof (*source));
+    if (unlikely (source == NULL))
+	return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
+
+    _cairo_surface_init (&source->base,
+			 &cairo_gl_source_backend,
+			 NULL, /* device */
+			 CAIRO_CONTENT_COLOR_ALPHA);
+
+    _cairo_gl_solid_operand_init (&source->operand, CAIRO_COLOR_WHITE);
+
+    return &source->base;
+}
diff --git a/src/cairo-gl-spans-compositor.c b/src/cairo-gl-spans-compositor.c
index 710cbe2..c86b638 100644
--- a/src/cairo-gl-spans-compositor.c
+++ b/src/cairo-gl-spans-compositor.c
@@ -279,79 +279,6 @@ FAIL:
     return status;
 }
 
-static cairo_status_t
-_cairo_gl_source_finish (void *abstract_surface)
-{
-    cairo_gl_source_t *source = abstract_surface;
-
-    _cairo_gl_operand_destroy (&source->operand);
-    return CAIRO_STATUS_SUCCESS;
-}
-
-static const cairo_surface_backend_t cairo_gl_source_backend = {
-    CAIRO_SURFACE_TYPE_GL,
-    _cairo_gl_source_finish,
-    NULL, /* read-only wrapper */
-};
-
-static cairo_surface_t *
-pattern_to_surface (cairo_surface_t *dst,
-		    const cairo_pattern_t *pattern,
-		    cairo_bool_t is_mask,
-		    const cairo_rectangle_int_t *extents,
-		    const cairo_rectangle_int_t *sample,
-		    int *src_x, int *src_y)
-{
-    cairo_gl_source_t *source;
-    cairo_int_status_t status;
-
-    source = malloc (sizeof (*source));
-    if (unlikely (source == NULL))
-	return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
-
-    _cairo_surface_init (&source->base,
-			 &cairo_gl_source_backend,
-			 NULL, /* device */
-			 CAIRO_CONTENT_COLOR_ALPHA);
-
-    *src_x = *src_y = 0;
-    status = _cairo_gl_operand_init (&source->operand, pattern,
-				     (cairo_gl_surface_t *)dst,
-				     sample, extents);
-    if (unlikely (status)) {
-	cairo_surface_destroy (&source->base);
-	return _cairo_surface_create_in_error (status);
-    }
-
-    return &source->base;
-}
-
-cairo_surface_t *
-_cairo_gl_white_source (void)
-{
-    cairo_gl_source_t *source;
-
-    source = malloc (sizeof (*source));
-    if (unlikely (source == NULL))
-	return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
-
-    _cairo_surface_init (&source->base,
-			 &cairo_gl_source_backend,
-			 NULL, /* device */
-			 CAIRO_CONTENT_COLOR_ALPHA);
-
-    _cairo_gl_solid_operand_init (&source->operand, CAIRO_COLOR_WHITE);
-
-    return &source->base;
-}
-
-static inline cairo_gl_operand_t *
-source_to_operand (cairo_surface_t *surface)
-{
-    cairo_gl_source_t *source = (cairo_gl_source_t *)surface;
-    return source ? &source->operand : NULL;
-}
-
 static cairo_int_status_t
 composite_boxes (void			*_dst,
 		 cairo_operator_t	op,
@@ -498,7 +425,7 @@ _cairo_gl_span_compositor_get (void)
 
 	compositor.fill_boxes = fill_boxes;
 	//compositor.check_composite_boxes = check_composite_boxes;
-	compositor.pattern_to_surface = pattern_to_surface;
+	compositor.pattern_to_surface = _cairo_gl_pattern_to_source;
 	compositor.composite_boxes = composite_boxes;
 	//compositor.check_span_renderer = check_span_renderer;
 	compositor.renderer_init = _cairo_gl_span_renderer_init;
diff --git a/src/cairo-gl-surface.c b/src/cairo-gl-surface.c
index ba6857e..b6dbedc 100644
--- a/src/cairo-gl-surface.c
+++ b/src/cairo-gl-surface.c
@@ -360,7 +360,7 @@ _cairo_gl_surface_embedded_operand_init (cairo_gl_surface_t *surface)
     memset (operand, 0, sizeof (cairo_gl_operand_t));
 
     operand->type = CAIRO_GL_OPERAND_TEXTURE;
-    operand->texture.surface = surface;
+    operand->texture.surface = NULL;
     operand->texture.tex = surface->tex;
 
     if (_cairo_gl_device_requires_power_of_two_textures (surface->base.device)) {
diff --git a/src/cairo-gl-traps-compositor.c b/src/cairo-gl-traps-compositor.c
index eb8f7ff..6c55ab6 100644
--- a/src/cairo-gl-traps-compositor.c
+++ b/src/cairo-gl-traps-compositor.c
@@ -150,63 +150,6 @@ FAIL:
     return status;
 }
 
-static cairo_status_t
-_cairo_gl_source_finish (void *abstract_surface)
-{
-    cairo_gl_source_t *source = abstract_surface;
-
-    _cairo_gl_operand_destroy (&source->operand);
-    return CAIRO_STATUS_SUCCESS;
-}
-
-static const cairo_surface_backend_t cairo_gl_source_backend = {
-    CAIRO_SURFACE_TYPE_GL,
-    _cairo_gl_source_finish,
-    NULL, /* read-only wrapper */
-};
-
-static cairo_surface_t *
-pattern_to_surface (cairo_surface_t *dst,
-		    const cairo_pattern_t *pattern,
-		    cairo_bool_t is_mask,
-		    const cairo_rectangle_int_t *extents,
-		    const cairo_rectangle_int_t *sample,
-		    int *src_x, int *src_y)
-{
-    cairo_gl_source_t *source;
-    cairo_int_status_t status;
-
-    if (pattern == NULL)
-	return _cairo_gl_white_source ();
-
-    source = malloc (sizeof (*source));
-    if (unlikely (source == NULL))
-	return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
-
-    _cairo_surface_init (&source->base,
-			 &cairo_gl_source_backend,
-			 NULL, /* device */
-			 CAIRO_CONTENT_COLOR_ALPHA);
-
-    *src_x = *src_y = 0;
-    status = _cairo_gl_operand_init (&source->operand, pattern,
-				     (cairo_gl_surface_t *)dst,
-				     sample, extents);
-    if (unlikely (status)) {
-	cairo_surface_destroy (&source->base);
-	return _cairo_surface_create_in_error (status);
-    }
-
-    return &source->base;
-}
-
-static inline cairo_gl_operand_t *
-source_to_operand (cairo_surface_t *surface)
-{
-    cairo_gl_source_t *source = (cairo_gl_source_t *)surface;
-    return surface ? &source->operand : NULL;
-}
-
 static cairo_int_status_t
 composite_boxes (void			*_dst,
 		 cairo_operator_t	op,
@@ -544,7 +487,7 @@ _cairo_gl_traps_compositor_get (void)
 	compositor.acquire = acquire;
 	compositor.release = release;
 	compositor.set_clip_region = set_clip_region;
-	compositor.pattern_to_surface = pattern_to_surface;
+	compositor.pattern_to_surface = _cairo_gl_pattern_to_source;
 	compositor.draw_image_boxes = draw_image_boxes;
 	//compositor.copy_boxes = copy_boxes;
 	compositor.fill_boxes = fill_boxes;
commit 65cd7d3bebe12e0db61b2739a7950d1ed49c20f3
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Mon Dec 5 16:02:51 2011 +0000

    gl: Propagate surface texture to embedded operand
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/cairo-gl-surface.c b/src/cairo-gl-surface.c
index 82bb2f0..ba6857e 100644
--- a/src/cairo-gl-surface.c
+++ b/src/cairo-gl-surface.c
@@ -409,8 +409,8 @@ _cairo_gl_surface_create_scratch_for_texture (cairo_gl_context_t   *ctx,
     if (unlikely (surface == NULL))
 	return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
 
-    _cairo_gl_surface_init (&ctx->base, surface, content, width, height);
     surface->tex = tex;
+    _cairo_gl_surface_init (&ctx->base, surface, content, width, height);
 
     /* Create the texture used to store the surface's data. */
     _cairo_gl_context_activate (ctx, CAIRO_GL_TEX_TEMP);
commit d7dcf9d28fdf05c8acabd8ed3dc25e0cf279e61e
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Mon Dec 5 14:42:15 2011 +0000

    gl: Check against user-provided invalid sizes
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/cairo-egl-context.c b/src/cairo-egl-context.c
index ec23852..00bfcbf 100644
--- a/src/cairo-egl-context.c
+++ b/src/cairo-egl-context.c
@@ -218,6 +218,9 @@ cairo_gl_surface_create_for_egl (cairo_device_t	*device,
     if (device->backend->type != CAIRO_DEVICE_TYPE_GL)
 	return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH));
 
+    if (width <= 0 || height <= 0)
+        return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_SIZE));
+
     surface = calloc (1, sizeof (cairo_egl_surface_t));
     if (unlikely (surface == NULL))
 	return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
diff --git a/src/cairo-glx-context.c b/src/cairo-glx-context.c
index f89fa32..512bee8 100644
--- a/src/cairo-glx-context.c
+++ b/src/cairo-glx-context.c
@@ -265,6 +265,9 @@ cairo_gl_surface_create_for_window (cairo_device_t	*device,
     if (device->backend->type != CAIRO_DEVICE_TYPE_GL)
 	return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH));
 
+    if (width <= 0 || height <= 0)
+        return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_SIZE));
+
     surface = calloc (1, sizeof (cairo_glx_surface_t));
     if (unlikely (surface == NULL))
 	return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
diff --git a/src/cairo-wgl-context.c b/src/cairo-wgl-context.c
index 82f1211..4872374 100644
--- a/src/cairo-wgl-context.c
+++ b/src/cairo-wgl-context.c
@@ -246,6 +246,9 @@ cairo_gl_surface_create_for_dc (cairo_device_t	*device,
     if (device->backend->type != CAIRO_DEVICE_TYPE_GL)
         return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_SURFACE_TYPE_MISMATCH));
 
+    if (width <= 0 || height <= 0)
+        return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_SIZE));
+
     surface = calloc (1, sizeof (cairo_wgl_surface_t));
     if (unlikely (surface == NULL))
         return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
commit 3edf369eade8b587aeaa162bd3bbeb3546c35b84
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Mon Dec 5 14:40:19 2011 +0000

    gl: Make the backend struct static
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/cairo-gl-private.h b/src/cairo-gl-private.h
index 77b58ad..e508714 100644
--- a/src/cairo-gl-private.h
+++ b/src/cairo-gl-private.h
@@ -342,8 +342,6 @@ typedef struct _cairo_gl_font {
     cairo_list_t			link;
 } cairo_gl_font_t;
 
-cairo_private extern const cairo_surface_backend_t _cairo_gl_surface_backend;
-
 static cairo_always_inline GLenum
 _cairo_gl_get_error (void)
 {
diff --git a/src/cairo-gl-surface.c b/src/cairo-gl-surface.c
index 3a3a09d..82bb2f0 100644
--- a/src/cairo-gl-surface.c
+++ b/src/cairo-gl-surface.c
@@ -49,6 +49,8 @@
 #include "cairo-image-surface-private.h"
 #include "cairo-surface-backend-private.h"
 
+static const cairo_surface_backend_t _cairo_gl_surface_backend;
+
 static cairo_status_t
 _cairo_gl_surface_flush (void *abstract_surface);
 
@@ -379,6 +381,8 @@ _cairo_gl_surface_init (cairo_device_t *device,
 			cairo_content_t content,
 			int width, int height)
 {
+    assert (width > 0 && height > 0);
+
     _cairo_surface_init (&surface->base,
 			 &_cairo_gl_surface_backend,
 			 device,
@@ -401,7 +405,6 @@ _cairo_gl_surface_create_scratch_for_texture (cairo_gl_context_t   *ctx,
     cairo_gl_surface_t *surface;
 
     assert (width <= ctx->max_framebuffer_size && height <= ctx->max_framebuffer_size);
-
     surface = calloc (1, sizeof (cairo_gl_surface_t));
     if (unlikely (surface == NULL))
 	return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
@@ -1233,7 +1236,7 @@ _cairo_gl_surface_glyphs (void			*surface,
 				     clip);
 }
 
-const cairo_surface_backend_t _cairo_gl_surface_backend = {
+static const cairo_surface_backend_t _cairo_gl_surface_backend = {
     CAIRO_SURFACE_TYPE_GL,
     _cairo_gl_surface_finish,
     _cairo_default_context_create,


More information about the cairo-commit mailing list