[cairo] [patch] gl: use a shared mask surface for text rendering via mask

Henry (Yu) Song - SISA hsong at sisa.samsung.com
Wed Apr 4 12:54:21 PDT 2012


commit b9a2f1f4e2fdd3351cea02e8334c2c1cea4f1253
Author: Henry (Yu) Song <hsong at sisa.samsung.com>
Date:   Wed Apr 4 11:20:44 2012 -0700

    gl:  use a shared mask surface for text rendering via mask case.  This
    reduces time to create mask surface on the fly

diff --git a/src/cairo-gl-device.c b/src/cairo-gl-device.c
index 47ee94e..ccbfd6f 100644
--- a/src/cairo-gl-device.c
+++ b/src/cairo-gl-device.c
@@ -106,6 +106,9 @@ _gl_finish (void *device)
 
     _cairo_gl_context_fini_shaders (ctx);
 
+    if (ctx->mask)
+	cairo_surface_destroy (ctx->mask);
+
     _gl_unlock (device);
 }
 
diff --git a/src/cairo-gl-glyphs.c b/src/cairo-gl-glyphs.c
index 9756ea4..18dab31 100644
--- a/src/cairo-gl-glyphs.c
+++ b/src/cairo-gl-glyphs.c
@@ -346,21 +346,50 @@ render_glyphs_via_mask (cairo_gl_surface_t *dst,
 			cairo_surface_t *source,
 			cairo_composite_glyphs_info_t *info)
 {
-    cairo_surface_t *mask;
     cairo_status_t status;
     cairo_bool_t has_component_alpha;
+    cairo_gl_context_t *ctx;
+    int width, height;
 
     TRACE ((stderr, "%s\n", __FUNCTION__));
 
+    status = _cairo_gl_context_acquire (dst->base.device, &ctx);
+    if (unlikely (status))
+	return status;
+
     /* XXX: For non-CA, this should be CAIRO_CONTENT_ALPHA to save memory */
-    mask = cairo_gl_surface_create (dst->base.device,
-                                    CAIRO_CONTENT_COLOR_ALPHA,
-                                    info->extents.width,
-                                    info->extents.height);
-    if (unlikely (mask->status))
-        return mask->status;
-
-    status = render_glyphs ((cairo_gl_surface_t *) mask,
+    width = info->extents.width;
+    height = info->extents.height;
+
+    if (ctx->mask && 
+        (((cairo_gl_surface_t *)ctx->mask)->width < info->extents.width ||
+	((cairo_gl_surface_t *)ctx->mask)->height < info->extents.height)){
+
+	if (((cairo_gl_surface_t *)ctx->mask)->width > width)
+	    width = ((cairo_gl_surface_t *)ctx->mask)->width;
+	else if (((cairo_gl_surface_t *)ctx->mask)->height > height)
+	    height = ((cairo_gl_surface_t *)ctx->mask)->height;
+
+	cairo_surface_destroy (ctx->mask);
+	ctx->mask = NULL;
+    }
+    
+    if (! ctx->mask) {
+	ctx->mask = cairo_gl_surface_create (dst->base.device,
+                        		     CAIRO_CONTENT_COLOR_ALPHA,
+					     width, height);
+	status = ctx->mask->status;
+    }
+    else 
+	status = _cairo_gl_surface_clear ((cairo_gl_surface_t *)ctx->mask,
+				CAIRO_COLOR_TRANSPARENT);
+    
+    if (unlikely (status)) {
+	status = _cairo_gl_context_release (ctx, status);
+ 	return status;
+    }
+
+    status = render_glyphs ((cairo_gl_surface_t *) ctx->mask,
 			    info->extents.x, info->extents.y,
 			    CAIRO_OPERATOR_ADD, NULL,
 			    info, &has_component_alpha);
@@ -368,8 +397,8 @@ render_glyphs_via_mask (cairo_gl_surface_t *dst,
 	cairo_surface_pattern_t mask_pattern;
 	cairo_surface_pattern_t source_pattern;
 
-	mask->is_clear = FALSE;
-	_cairo_pattern_init_for_surface (&mask_pattern, mask);
+	ctx->mask->is_clear = FALSE;
+	_cairo_pattern_init_for_surface (&mask_pattern, ctx->mask);
 	mask_pattern.base.has_component_alpha = has_component_alpha;
 	mask_pattern.base.filter = CAIRO_FILTER_NEAREST;
 	mask_pattern.base.extend = CAIRO_EXTEND_NONE;
@@ -390,7 +419,7 @@ render_glyphs_via_mask (cairo_gl_surface_t *dst,
 	_cairo_pattern_fini (&source_pattern.base);
     }
 
-    cairo_surface_destroy (mask);
+    status = _cairo_gl_context_release (ctx, status);
 
     return status;
 }
diff --git a/src/cairo-gl-private.h b/src/cairo-gl-private.h
index 3afdd70..9dcd473 100644
--- a/src/cairo-gl-private.h
+++ b/src/cairo-gl-private.h
@@ -320,6 +320,8 @@ struct _cairo_gl_context {
     cairo_bool_t has_map_buffer;
     cairo_bool_t has_packed_depth_stencil;
 
+    cairo_surface_t *mask; /* mask surface for text rendering */
+
     void (*acquire) (void *ctx);
     void (*release) (void *ctx);
 
@@ -706,6 +708,9 @@ _cairo_gl_surface_create_scratch (cairo_gl_context_t   *ctx,
 				  cairo_content_t	content,
 				  int			width,
 				  int			height);
+cairo_private cairo_status_t
+_cairo_gl_surface_clear (cairo_gl_surface_t  *surface,
+                         const cairo_color_t *color);
 
 cairo_private cairo_surface_t *
 _cairo_gl_pattern_to_source (cairo_surface_t *dst,
diff --git a/src/cairo-gl-surface.c b/src/cairo-gl-surface.c
index 32ecf63..afaa7a0 100644
--- a/src/cairo-gl-surface.c
+++ b/src/cairo-gl-surface.c
@@ -475,7 +475,7 @@ _cairo_gl_surface_create_scratch (cairo_gl_context_t   *ctx,
     return &surface->base;
 }
 
-static cairo_status_t
+cairo_status_t
 _cairo_gl_surface_clear (cairo_gl_surface_t  *surface,
                          const cairo_color_t *color)
 {


More information about the cairo mailing list