[cairo-commit] src/cairo-gl-composite.c src/cairo-gl-msaa-compositor.c

Martin Robinson mrobinson at kemper.freedesktop.org
Tue May 8 12:35:01 PDT 2012


 src/cairo-gl-composite.c       |   53 +++++++++++++----------
 src/cairo-gl-msaa-compositor.c |   92 ++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 122 insertions(+), 23 deletions(-)

New commits:
commit b099f8b0c70dc0208135cdeda76be9ab33e61d9b
Author: Henry (Yu) Song <hsong at sisa.samsung.com>
Date:   Fri Oct 14 14:32:28 2011 -0700

    gl/msaa: Support for masking
    
    Add support for masking in the OpenGL MSAA compositor. This is
    accomplished simply by properly setting up the masking source,
    emitting the entire bounded composite region, and unforking
    vertex emission.

diff --git a/src/cairo-gl-composite.c b/src/cairo-gl-composite.c
index 2595db0..4a70af7 100644
--- a/src/cairo-gl-composite.c
+++ b/src/cairo-gl-composite.c
@@ -576,6 +576,19 @@ _cairo_gl_composite_draw_tristrip (cairo_gl_context_t *ctx)
 {
     cairo_array_t* indices = &ctx->tristrip_indices;
     const int *indices_array = _cairo_array_index_const (indices, 0);
+
+
+    if (ctx->pre_shader) {
+	cairo_gl_shader_t *prev_shader = ctx->current_shader;
+
+	_cairo_gl_set_shader (ctx, ctx->pre_shader);
+	_cairo_gl_set_operator (ctx, CAIRO_OPERATOR_DEST_OUT, TRUE);
+	glDrawElements (GL_TRIANGLE_STRIP, _cairo_array_num_elements (indices), GL_UNSIGNED_INT, indices_array);
+
+	_cairo_gl_set_shader (ctx, prev_shader);
+	_cairo_gl_set_operator (ctx, CAIRO_OPERATOR_ADD, TRUE);
+    }
+
     glDrawElements (GL_TRIANGLE_STRIP, _cairo_array_num_elements (indices), GL_UNSIGNED_INT, indices_array);
     _cairo_array_truncate (indices, 0);
 }
@@ -696,6 +709,17 @@ _cairo_gl_composite_emit_vertex (cairo_gl_context_t *ctx,
     ctx->vb_offset += ctx->vertex_size;
 }
 
+static void
+_cairo_gl_composite_emit_point (cairo_gl_context_t	*ctx,
+				const cairo_point_t	*point,
+				uint8_t alpha)
+{
+    _cairo_gl_composite_emit_vertex (ctx,
+				     _cairo_fixed_to_double (point->x),
+				     _cairo_fixed_to_double (point->y),
+				     alpha);
+}
+
 void
 _cairo_gl_composite_emit_rect (cairo_gl_context_t *ctx,
                                GLfloat x1,
@@ -789,21 +813,6 @@ _cairo_gl_composite_init (cairo_gl_composite_t *setup,
     return CAIRO_STATUS_SUCCESS;
 }
 
-static void
-_cairo_gl_composite_emit_tristrip_vertex (cairo_gl_context_t	*ctx,
-					  const cairo_point_t	*point)
-{
-    GLfloat *vb = (GLfloat *) (void *) &ctx->vb[ctx->vb_offset];
-    GLfloat x = _cairo_fixed_to_double (point->x);
-    GLfloat y = _cairo_fixed_to_double (point->y);
-
-    *vb++ = x;
-    *vb++ = y;
-    _cairo_gl_operand_emit (&ctx->operands[CAIRO_GL_TEX_SOURCE], &vb, x, y);
-
-    ctx->vb_offset += ctx->vertex_size;
-}
-
 static cairo_int_status_t
 _cairo_gl_composite_append_vertex_indices (cairo_gl_context_t	*ctx,
 					   int			 number_of_new_indices)
@@ -854,14 +863,14 @@ _cairo_gl_composite_emit_quad_as_tristrip (cairo_gl_context_t	*ctx,
 
     _cairo_gl_composite_prepare_buffer (ctx, 4);
 
-    _cairo_gl_composite_emit_tristrip_vertex (ctx, &quad[0]);
-    _cairo_gl_composite_emit_tristrip_vertex (ctx, &quad[1]);
+    _cairo_gl_composite_emit_point (ctx, &quad[0], 0);
+    _cairo_gl_composite_emit_point (ctx, &quad[1], 0);
 
     /* Cairo stores quad vertices in counter-clockwise order, but we need to
        emit them from top to bottom in the triangle strip, so we need to reverse
        the order of the last two vertices. */
-    _cairo_gl_composite_emit_tristrip_vertex (ctx, &quad[3]);
-    _cairo_gl_composite_emit_tristrip_vertex (ctx, &quad[2]);
+    _cairo_gl_composite_emit_point (ctx, &quad[3], 0);
+    _cairo_gl_composite_emit_point (ctx, &quad[2], 0);
 
     return _cairo_gl_composite_append_vertex_indices (ctx, 4);
 }
@@ -877,8 +886,8 @@ _cairo_gl_composite_emit_triangle_as_tristrip (cairo_gl_context_t	*ctx,
 
     _cairo_gl_composite_prepare_buffer (ctx, 3);
 
-    _cairo_gl_composite_emit_tristrip_vertex (ctx, &triangle[0]);
-    _cairo_gl_composite_emit_tristrip_vertex (ctx, &triangle[1]);
-    _cairo_gl_composite_emit_tristrip_vertex (ctx, &triangle[2]);
+    _cairo_gl_composite_emit_point (ctx, &triangle[0], 0);
+    _cairo_gl_composite_emit_point (ctx, &triangle[1], 0);
+    _cairo_gl_composite_emit_point (ctx, &triangle[2], 0);
     return _cairo_gl_composite_append_vertex_indices (ctx, 3);
 }
diff --git a/src/cairo-gl-msaa-compositor.c b/src/cairo-gl-msaa-compositor.c
index a773ef3..a53c1a9 100644
--- a/src/cairo-gl-msaa-compositor.c
+++ b/src/cairo-gl-msaa-compositor.c
@@ -47,6 +47,10 @@
 #include "cairo-gl-private.h"
 #include "cairo-traps-private.h"
 
+static void
+_scissor_to_rectangle (cairo_gl_surface_t	*surface,
+		       const cairo_rectangle_int_t	*rect);
+
 struct _tristrip_composite_info {
     cairo_gl_composite_t	setup;
     cairo_gl_context_t		*ctx;
@@ -99,6 +103,27 @@ _draw_traps (cairo_gl_context_t		*ctx,
 }
 
 static cairo_int_status_t
+_draw_int_rect (cairo_gl_context_t	*ctx,
+		cairo_gl_composite_t	*setup,
+		cairo_rectangle_int_t	*rect)
+{
+    cairo_box_t box;
+    cairo_point_t quad[4];
+
+    _cairo_box_from_rectangle (&box, rect);
+    quad[0].x = box.p1.x;
+    quad[0].y = box.p1.y;
+    quad[1].x = box.p1.x;
+    quad[1].y = box.p2.y;
+    quad[2].x = box.p2.x;
+    quad[2].y = box.p2.y;
+    quad[3].x = box.p2.x;
+    quad[3].y = box.p1.y;
+
+    return _cairo_gl_composite_emit_quad_as_tristrip (ctx, setup, quad);
+}
+
+static cairo_int_status_t
 _draw_triangle_fan (cairo_gl_context_t		*ctx,
 		    cairo_gl_composite_t	*setup,
 		    const cairo_point_t		*midpt,
@@ -264,7 +289,72 @@ static cairo_int_status_t
 _cairo_gl_msaa_compositor_mask (const cairo_compositor_t	*compositor,
 				cairo_composite_rectangles_t	*composite)
 {
-    return CAIRO_INT_STATUS_UNSUPPORTED;
+    cairo_gl_composite_t setup;
+    cairo_gl_surface_t *dst = (cairo_gl_surface_t *) composite->surface;
+    cairo_gl_context_t *ctx = NULL;
+    cairo_bool_t used_stencil_buffer;
+    cairo_int_status_t status;
+    cairo_operator_t op = composite->op;
+
+    /* GL compositing operators cannot properly represent a mask operation
+       using the SOURCE compositing operator in one pass. This only matters if
+       there actually is a mask (there isn't in a paint operation) and if the
+       mask isn't totally opaque. */
+    if (op == CAIRO_OPERATOR_SOURCE &&
+	 composite->original_mask_pattern != NULL &&
+	! _cairo_pattern_is_opaque (&composite->mask_pattern.base,
+				    &composite->mask_sample_area)) {
+
+       /* If the source is opaque the operation reduces to OVER. */
+	if (_cairo_pattern_is_opaque (&composite->source_pattern.base,
+				      &composite->source_sample_area))
+	    op = CAIRO_OPERATOR_OVER;
+	else
+	    return CAIRO_INT_STATUS_UNSUPPORTED;
+    }
+
+    status = _cairo_gl_composite_init (&setup,
+				       op,
+				       dst,
+				       FALSE /* assume_component_alpha */);
+    if (unlikely (status))
+	return status;
+
+    status = _cairo_gl_composite_set_source (&setup,
+					     &composite->source_pattern.base,
+					     &composite->source_sample_area,
+					     &composite->bounded);
+    if (unlikely (status))
+	goto finish;
+
+    status = _cairo_gl_composite_set_mask (&setup,
+					   &composite->mask_pattern.base,
+					   &composite->source_sample_area,
+					   &composite->bounded);
+    if (unlikely (status))
+	goto finish;
+
+    status = _cairo_gl_composite_begin (&setup, &ctx);
+    if (unlikely (status))
+	goto finish;
+
+    status = _scissor_and_clip (ctx, &setup, composite, &used_stencil_buffer);
+    if (unlikely (status))
+	goto finish;
+
+    _draw_int_rect (ctx, &setup, &composite->bounded);
+    _cairo_gl_composite_flush (ctx);
+
+finish:
+    _cairo_gl_composite_fini (&setup);
+
+    if (ctx) {
+	glDisable (GL_SCISSOR_TEST);
+	_disable_stencil_buffer ();
+	status = _cairo_gl_context_release (ctx, status);
+    }
+
+    return status;
 }
 
 static cairo_status_t


More information about the cairo-commit mailing list