diff options
-rw-r--r-- | src/cairo-gl-composite.c | 17 | ||||
-rw-r--r-- | src/cairo-gl-msaa-compositor.c | 131 | ||||
-rw-r--r-- | src/cairo-gl-private.h | 7 |
3 files changed, 151 insertions, 4 deletions
diff --git a/src/cairo-gl-composite.c b/src/cairo-gl-composite.c index f260c1d9..2f9697a7 100644 --- a/src/cairo-gl-composite.c +++ b/src/cairo-gl-composite.c @@ -789,7 +789,7 @@ _cairo_gl_composite_init (cairo_gl_composite_t *setup, static void _cairo_gl_composite_emit_tristrip_vertex (cairo_gl_context_t *ctx, - cairo_point_t *point) + const cairo_point_t *point) { GLfloat *vb = (GLfloat *) (void *) &ctx->vb[ctx->vb_offset]; @@ -841,7 +841,7 @@ _cairo_gl_composite_append_vertex_indices (cairo_gl_context_t *ctx, cairo_int_status_t _cairo_gl_composite_emit_quad_as_tristrip (cairo_gl_context_t *ctx, cairo_gl_composite_t *setup, - cairo_point_t quad[4]) + const cairo_point_t quad[4]) { _cairo_gl_composite_prepare_buffer (ctx, 4); @@ -857,6 +857,19 @@ _cairo_gl_composite_emit_quad_as_tristrip (cairo_gl_context_t *ctx, return _cairo_gl_composite_append_vertex_indices (ctx, 4); } +cairo_int_status_t +_cairo_gl_composite_emit_triangle_as_tristrip (cairo_gl_context_t *ctx, + cairo_gl_composite_t *setup, + const cairo_point_t triangle[3]) +{ + _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]); + return _cairo_gl_composite_append_vertex_indices (ctx, 3); +} + cairo_status_t _cairo_gl_composite_begin_tristrip (cairo_gl_composite_t *setup, cairo_gl_context_t **ctx_out) diff --git a/src/cairo-gl-msaa-compositor.c b/src/cairo-gl-msaa-compositor.c index 34754998..7a0e8288 100644 --- a/src/cairo-gl-msaa-compositor.c +++ b/src/cairo-gl-msaa-compositor.c @@ -47,6 +47,11 @@ #include "cairo-gl-private.h" #include "cairo-traps-private.h" +struct _tristrip_composite_info { + cairo_gl_composite_t setup; + cairo_gl_context_t *ctx; +}; + static cairo_int_status_t _draw_trap (cairo_gl_context_t *ctx, cairo_gl_composite_t *setup, @@ -94,6 +99,33 @@ _draw_traps (cairo_gl_context_t *ctx, } static cairo_int_status_t +_draw_triangle_fan (cairo_gl_context_t *ctx, + cairo_gl_composite_t *setup, + const cairo_point_t *midpt, + const cairo_point_t *points, + int npoints) +{ + int i; + + /* Our strategy here is to not even try to build a triangle fan, but to + draw each triangle as if it was an unconnected member of a triangle strip. */ + for (i = 1; i < npoints; i++) { + cairo_int_status_t status; + cairo_point_t triangle[3]; + + triangle[0] = *midpt; + triangle[1] = points[i - 1]; + triangle[2] = points[i]; + + status = _cairo_gl_composite_emit_triangle_as_tristrip (ctx, setup, triangle); + if (unlikely (status)) + return status; + } + + return CAIRO_STATUS_SUCCESS; +} + +static cairo_int_status_t _draw_clip (cairo_gl_context_t *ctx, cairo_gl_composite_t *setup, cairo_clip_t *clip) @@ -185,6 +217,36 @@ _cairo_gl_msaa_compositor_mask (const cairo_compositor_t *compositor, return CAIRO_INT_STATUS_UNSUPPORTED; } +static cairo_status_t +_stroke_shaper_add_triangle (void *closure, + const cairo_point_t triangle[3]) +{ + struct _tristrip_composite_info *info = closure; + return _cairo_gl_composite_emit_triangle_as_tristrip (info->ctx, + &info->setup, + triangle); +} + +static cairo_status_t +_stroke_shaper_add_triangle_fan (void *closure, + const cairo_point_t *midpoint, + const cairo_point_t *points, + int npoints) +{ + struct _tristrip_composite_info *info = closure; + return _draw_triangle_fan (info->ctx, &info->setup, + midpoint, points, npoints); +} + +static cairo_status_t +_stroke_shaper_add_quad (void *closure, + const cairo_point_t quad[4]) +{ + struct _tristrip_composite_info *info = closure; + return _cairo_gl_composite_emit_quad_as_tristrip (info->ctx, &info->setup, + quad); +} + static cairo_int_status_t _cairo_gl_msaa_compositor_stroke (const cairo_compositor_t *compositor, cairo_composite_rectangles_t *composite, @@ -195,7 +257,74 @@ _cairo_gl_msaa_compositor_stroke (const cairo_compositor_t *compositor, double tolerance, cairo_antialias_t antialias) { - return CAIRO_INT_STATUS_UNSUPPORTED; + cairo_int_status_t status; + cairo_gl_surface_t *dst = (cairo_gl_surface_t *) composite->surface; + struct _tristrip_composite_info info; + + if (antialias != CAIRO_ANTIALIAS_NONE) + return CAIRO_INT_STATUS_UNSUPPORTED; + + status = _cairo_gl_composite_init (&info.setup, + composite->op, + dst, + FALSE, /* assume_component_alpha */ + &composite->bounded); + if (unlikely (status)) + return status; + + info.ctx = NULL; + + status = _cairo_gl_composite_set_source (&info.setup, + &composite->source_pattern.base, + composite->bounded.x, + composite->bounded.y, + composite->bounded.x, + composite->bounded.y, + composite->bounded.width, + composite->bounded.height); + if (unlikely (status)) + goto finish; + + status = _cairo_gl_composite_begin_tristrip (&info.setup, &info.ctx); + if (unlikely (status)) + goto finish; + + glScissor (composite->unbounded.x, composite->unbounded.y, + composite->unbounded.width, composite->unbounded.height); + glEnable (GL_SCISSOR_TEST); + + if (! _cairo_composite_rectangles_can_reduce_clip (composite, + composite->clip)) + { + status = _draw_clip_to_stencil_buffer (info.ctx, &info.setup, composite->clip); + if (unlikely (status)) + goto finish; + } + + status = _cairo_path_fixed_stroke_to_shaper ((cairo_path_fixed_t *) path, + style, + ctm, + ctm_inverse, + tolerance, + _stroke_shaper_add_triangle, + _stroke_shaper_add_triangle_fan, + _stroke_shaper_add_quad, + &info); + if (unlikely (status)) + goto finish; + + _cairo_gl_composite_flush (info.ctx); + +finish: + _cairo_gl_composite_fini (&info.setup); + + if (info.ctx) { + glDisable (GL_SCISSOR_TEST); + _disable_stencil_buffer (); + status = _cairo_gl_context_release (info.ctx, status); + } + + return status; } static cairo_int_status_t diff --git a/src/cairo-gl-private.h b/src/cairo-gl-private.h index f8bf5712..ec7f8b2d 100644 --- a/src/cairo-gl-private.h +++ b/src/cairo-gl-private.h @@ -507,7 +507,12 @@ _cairo_gl_composite_begin_tristrip (cairo_gl_composite_t *setup, cairo_int_status_t _cairo_gl_composite_emit_quad_as_tristrip (cairo_gl_context_t *ctx, cairo_gl_composite_t *setup, - cairo_point_t quad[4]); + const cairo_point_t quad[4]); + +cairo_int_status_t +_cairo_gl_composite_emit_triangle_as_tristrip (cairo_gl_context_t *ctx, + cairo_gl_composite_t *setup, + const cairo_point_t triangle[3]); cairo_private void _cairo_gl_context_destroy_operand (cairo_gl_context_t *ctx, |