[PATCH] gl: fix the same surface bug and cairo_glx_surface_t source surface bug

Chuanbo Weng <[email protected]>
Newsgroups gmane.comp.lib.cairo
Message-ID <[email protected]>
We have to create a new surface to avoid drawing error when the source
and destination is the same surface. Also, we should create a new texture
surface when the source surface type is cairo_glx_surface_t. This fix
issue in self-copy, subsurface and subsurface-modify-child test case.
---
 src/cairo-gl-operand.c |   82 +++++++++++++++++++++++++++---------------------
 1 files changed, 46 insertions(+), 36 deletions(-)

diff --git a/src/cairo-gl-operand.c b/src/cairo-gl-operand.c
index bc5e541..f9d4410 100644
--- a/src/cairo-gl-operand.c
+++ b/src/cairo-gl-operand.c
@@ -151,41 +151,10 @@ _cairo_gl_subsurface_operand_init (cairo_gl_operand_t *operand,
 				   const cairo_rectangle_int_t *sample,
 				   const cairo_rectangle_int_t *extents)
 {
-    const cairo_surface_pattern_t *src = (cairo_surface_pattern_t *)_src;
-    cairo_surface_subsurface_t *sub;
-    cairo_gl_surface_t *surface;
-    cairo_surface_attributes_t *attributes;
-
-    sub = (cairo_surface_subsurface_t *) src->surface;
-
-    if (sample->x < 0 || sample->y < 0 ||
-	sample->x + sample->width  > sub->extents.width ||
-	sample->y + sample->height > sub->extents.height)
-    {
-	return _cairo_gl_subsurface_clone_operand_init (operand, _src,
+    /* To avoid the drawing error when the source and destination
+     * is the same surface, we have to create a new surface*/
+    return _cairo_gl_subsurface_clone_operand_init (operand, _src,
 							dst, sample, extents);
-    }
-
-    surface = (cairo_gl_surface_t *) sub->target;
-
-    /* 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;
-    cairo_matrix_multiply (&attributes->matrix,
-			   &attributes->matrix,
-			   &surface->operand.texture.attributes.matrix);
-
-    attributes->extend = src->base.extend;
-    attributes->filter = src->base.filter;
-    attributes->has_component_alpha = src->base.has_component_alpha;
-    return CAIRO_STATUS_SUCCESS;
 }
 
 static cairo_status_t
@@ -196,9 +165,13 @@ _cairo_gl_surface_operand_init (cairo_gl_operand_t *operand,
 				const cairo_rectangle_int_t *extents)
 {
     const cairo_surface_pattern_t *src = (cairo_surface_pattern_t *)_src;
-    cairo_gl_surface_t *surface;
+    cairo_gl_surface_t *surface, *temp_surface;
     cairo_surface_attributes_t *attributes;
 
+    cairo_gl_context_t *ctx;
+    cairo_status_t status;
+    cairo_surface_pattern_t local_pattern;
+
     surface = (cairo_gl_surface_t *) src->surface;
     if (surface->base.type != CAIRO_SURFACE_TYPE_GL)
 	return CAIRO_INT_STATUS_UNSUPPORTED;
@@ -211,7 +184,44 @@ _cairo_gl_surface_operand_init (cairo_gl_operand_t *operand,
 	return CAIRO_INT_STATUS_UNSUPPORTED;
     }
 
-    *operand = surface->operand;
+     /* 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;
+
+    /* To avoid the drawing error when the source and destination
+     * is the same surface, we have to create a new surface*/
+    if(surface == dst){
+	status = _cairo_gl_context_acquire (dst->base.device, &ctx);
+	if (unlikely (status))
+	    return status;
+
+	temp_surface = (cairo_gl_surface_t *)
+	    _cairo_gl_surface_create_scratch (ctx,
+					      surface->base.content,
+					      surface->width, surface->height);
+	if (temp_surface->base.status)
+	    return _cairo_gl_context_release (ctx, temp_surface->base.status);
+
+	_cairo_pattern_init_for_surface (&local_pattern, &surface->base);
+	local_pattern.base.filter = CAIRO_FILTER_NEAREST;
+	status = _cairo_surface_paint (&temp_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)) {
+	    cairo_surface_destroy (&temp_surface->base);
+	    return status;
+	}
+        temp_surface->operand.texture.owns_surface = temp_surface;
+        temp_surface->operand.texture.attributes = surface->operand.texture.attributes;
+	*operand = temp_surface->operand;
+    }
+    else
+	*operand = surface->operand;
 
     attributes = &operand->texture.attributes;
     cairo_matrix_multiply (&attributes->matrix,
-- 
1.7.5.1

--
cairo mailing list
[email protected]
http://lists.cairographics.org/mailman/listinfo/cairo
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.