[cairo] [PATCH] gl: create a new texture when source surface type is cairo_glx_surface_t

Chuanbo Weng strgnm at gmail.com
Fri Jan 13 00:15:40 PST 2012


GL backend always uses texture as source operand in _cairo_gl_context_setup_operand().
So we should create a new texture surface when the source surface type is
cairo_glx_surface_t(created by cairo_gl_surface_create_for_window). This
fix issue in subsurface-modify-child test case in cairo/test/.
---
 src/cairo-gl-operand.c |   36 ++++++++++++++++++++++++++----------
 1 files changed, 26 insertions(+), 10 deletions(-)

diff --git a/src/cairo-gl-operand.c b/src/cairo-gl-operand.c
index bc5e541..4d60623 100644
--- a/src/cairo-gl-operand.c
+++ b/src/cairo-gl-operand.c
@@ -83,6 +83,7 @@ _cairo_gl_subsurface_clone_operand_init (cairo_gl_operand_t *operand,
     cairo_gl_context_t *ctx;
     cairo_surface_attributes_t *attributes;
     cairo_status_t status;
+    cairo_surface_t *image;
 
     sub = (cairo_surface_subsurface_t *) src->surface;
 
@@ -101,15 +102,24 @@ _cairo_gl_subsurface_clone_operand_init (cairo_gl_operand_t *operand,
 	if (surface->base.status)
 	    return _cairo_gl_context_release (ctx, surface->base.status);
 
-	_cairo_pattern_init_for_surface (&local_pattern, sub->target);
-	cairo_matrix_init_translate (&local_pattern.base.matrix,
-				     sub->extents.x, sub->extents.y);
-	local_pattern.base.filter = CAIRO_FILTER_NEAREST;
-	status = _cairo_surface_paint (&surface->base,
-				       CAIRO_OPERATOR_SOURCE,
-				       &local_pattern.base,
-				       NULL);
-	_cairo_pattern_fini (&local_pattern.base);
+        /* When the source surface type is cairo_glx_surface_t, we
+         * should create a new texture surface for it*/
+	if(! _cairo_gl_surface_is_texture (sub->target)){
+            image = cairo_surface_map_to_image (&surface->base, NULL);
+            status = _cairo_surface_offset_paint (image, extents->x, extents->y,
+						  CAIRO_OPERATOR_SOURCE, _src, NULL);
+            cairo_surface_unmap_image (&surface->base, image);
+	}else{
+            _cairo_pattern_init_for_surface (&local_pattern, sub->target);
+            cairo_matrix_init_translate (&local_pattern.base.matrix,
+					 sub->extents.x, sub->extents.y);
+            local_pattern.base.filter = CAIRO_FILTER_NEAREST;
+            status = _cairo_surface_paint (&surface->base,
+					   CAIRO_OPERATOR_SOURCE,
+					   &local_pattern.base,
+					   NULL);
+            _cairo_pattern_fini (&local_pattern.base);
+        }
 
 	status = _cairo_gl_context_release (ctx, status);
 	if (unlikely (status)) {
@@ -160,7 +170,8 @@ _cairo_gl_subsurface_operand_init (cairo_gl_operand_t *operand,
 
     if (sample->x < 0 || sample->y < 0 ||
 	sample->x + sample->width  > sub->extents.width ||
-	sample->y + sample->height > sub->extents.height)
+	sample->y + sample->height > sub->extents.height ||
+	! _cairo_gl_surface_is_texture (sub->target))
     {
 	return _cairo_gl_subsurface_clone_operand_init (operand, _src,
 							dst, sample, extents);
@@ -211,6 +222,11 @@ _cairo_gl_surface_operand_init (cairo_gl_operand_t *operand,
 	return CAIRO_INT_STATUS_UNSUPPORTED;
     }
 
+    /* When the source surface type is cairo_glx_surface_t, we
+     * should create a new texture surface for it*/
+    if(! _cairo_gl_surface_is_texture (surface))
+        return CAIRO_INT_STATUS_UNSUPPORTED;
+
     *operand = surface->operand;
 
     attributes = &operand->texture.attributes;
-- 
1.7.5.1



More information about the cairo mailing list