summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMartin Robinson <mrobinson@webkit.org>2011-10-07 15:34:13 -0700
committerChris Wilson <chris@chris-wilson.co.uk>2011-10-13 14:42:23 +0100
commitc25027f2a1570b78c314896a127e518db370645c (patch)
tree42cd2b04b30de5641cf66bddb214dcaadccdd1dd /src
parent32aa361c5ea0c761e26bc6fd94acfddd8df3b759 (diff)
gl/msaa: Support for solid color strokes.
Add support for basic solid color strokes using the fixed path stroke shaper. Currently components of the stroke overlap, but that will be handled in the following patch.
Diffstat (limited to 'src')
-rw-r--r--src/cairo-gl-composite.c17
-rw-r--r--src/cairo-gl-msaa-compositor.c131
-rw-r--r--src/cairo-gl-private.h7
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,