[cairo] [PATCH] gl: fix the same surface bug and cairo_glx_surface_t source surface bug
Chuanbo Weng
strgnm at gmail.com
Wed Jan 11 01:03:46 PST 2012
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
More information about the cairo
mailing list