[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