summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMartin Robinson <mrobinson@igalia.com>2012-03-12 15:28:23 -0700
committerMartin Robinson <mrobinson@igalia.com>2012-05-17 14:02:18 -0700
commit4b3ad4e8dacdfb84636f188b2dc7afe3ad6966c5 (patch)
tree9fd3e71adc3d3affad2d2ad71714743d5dd08ebe /src
parente3f5b14fbabba2128de4ee2d8513800aa145fb2f (diff)
gl/msaa: Implement glyph rendering
Instead of falling back to the traps compositor to do glyph rendering, handle it in the MSAA compositor. This allows using the stencil buffer or scissor to clip and simplifies the MSAA code path.
Diffstat (limited to 'src')
-rw-r--r--src/cairo-gl-glyphs.c56
-rw-r--r--src/cairo-gl-msaa-compositor.c83
-rw-r--r--src/cairo-gl-private.h11
3 files changed, 128 insertions, 22 deletions
diff --git a/src/cairo-gl-glyphs.c b/src/cairo-gl-glyphs.c
index 9756ea44..c2660ac5 100644
--- a/src/cairo-gl-glyphs.c
+++ b/src/cairo-gl-glyphs.c
@@ -220,12 +220,13 @@ cairo_gl_context_get_glyph_cache (cairo_gl_context_t *ctx,
}
static cairo_status_t
-render_glyphs (cairo_gl_surface_t *dst,
+render_glyphs (cairo_gl_surface_t *dst,
int dst_x, int dst_y,
- cairo_operator_t op,
- cairo_surface_t *source,
+ cairo_operator_t op,
+ cairo_surface_t *source,
cairo_composite_glyphs_info_t *info,
- cairo_bool_t *has_component_alpha)
+ cairo_bool_t *has_component_alpha,
+ cairo_clip_t *clip)
{
cairo_format_t last_format = CAIRO_FORMAT_INVALID;
cairo_gl_glyph_cache_t *cache = NULL;
@@ -255,6 +256,9 @@ render_glyphs (cairo_gl_surface_t *dst,
source_to_operand (source));
}
+
+ _cairo_gl_composite_set_clip (&setup, clip);
+
for (i = 0; i < info->num_glyphs; i++) {
cairo_scaled_glyph_t *scaled_glyph;
cairo_gl_glyph_t *glyph;
@@ -344,7 +348,8 @@ render_glyphs_via_mask (cairo_gl_surface_t *dst,
int dst_x, int dst_y,
cairo_operator_t op,
cairo_surface_t *source,
- cairo_composite_glyphs_info_t *info)
+ cairo_composite_glyphs_info_t *info,
+ cairo_clip_t *clip)
{
cairo_surface_t *mask;
cairo_status_t status;
@@ -363,7 +368,7 @@ render_glyphs_via_mask (cairo_gl_surface_t *dst,
status = render_glyphs ((cairo_gl_surface_t *) mask,
info->extents.x, info->extents.y,
CAIRO_OPERATOR_ADD, NULL,
- info, &has_component_alpha);
+ info, &has_component_alpha, NULL);
if (likely (status == CAIRO_STATUS_SUCCESS)) {
cairo_surface_pattern_t mask_pattern;
cairo_surface_pattern_t source_pattern;
@@ -384,7 +389,7 @@ render_glyphs_via_mask (cairo_gl_surface_t *dst,
status = _cairo_surface_mask (&dst->base, op,
&source_pattern.base,
&mask_pattern.base,
- NULL);
+ clip);
_cairo_pattern_fini (&mask_pattern.base);
_cairo_pattern_fini (&source_pattern.base);
@@ -412,14 +417,15 @@ _cairo_gl_check_composite_glyphs (const cairo_composite_rectangles_t *extents,
}
cairo_int_status_t
-_cairo_gl_composite_glyphs (void *_dst,
- cairo_operator_t op,
- cairo_surface_t *_src,
- int src_x,
- int src_y,
- int dst_x,
- int dst_y,
- cairo_composite_glyphs_info_t *info)
+_cairo_gl_composite_glyphs_with_clip (void *_dst,
+ cairo_operator_t op,
+ cairo_surface_t *_src,
+ int src_x,
+ int src_y,
+ int dst_x,
+ int dst_y,
+ cairo_composite_glyphs_info_t *info,
+ cairo_clip_t *clip)
{
cairo_gl_surface_t *dst = _dst;
cairo_bool_t has_component_alpha;
@@ -440,12 +446,28 @@ _cairo_gl_composite_glyphs (void *_dst,
if (info->use_mask) {
return render_glyphs_via_mask (dst, dst_x, dst_y,
- op, _src, info);
+ op, _src, info, clip);
} else {
return render_glyphs (dst, dst_x, dst_y,
op, _src, info,
- &has_component_alpha);
+ &has_component_alpha,
+ clip);
}
+
+}
+
+cairo_int_status_t
+_cairo_gl_composite_glyphs (void *_dst,
+ cairo_operator_t op,
+ cairo_surface_t *_src,
+ int src_x,
+ int src_y,
+ int dst_x,
+ int dst_y,
+ cairo_composite_glyphs_info_t *info)
+{
+ return _cairo_gl_composite_glyphs_with_clip (_dst, op, _src, src_x, src_y,
+ dst_x, dst_y, info, NULL);
}
void
diff --git a/src/cairo-gl-msaa-compositor.c b/src/cairo-gl-msaa-compositor.c
index f5bb6f46..f0a8c96f 100644
--- a/src/cairo-gl-msaa-compositor.c
+++ b/src/cairo-gl-msaa-compositor.c
@@ -47,10 +47,6 @@
#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);
-
static cairo_bool_t
should_fall_back (cairo_gl_surface_t *surface,
cairo_antialias_t antialias);
@@ -655,6 +651,83 @@ cleanup_traps:
return status;
}
+static cairo_int_status_t
+_cairo_gl_msaa_compositor_glyphs (const cairo_compositor_t *compositor,
+ cairo_composite_rectangles_t *composite,
+ cairo_scaled_font_t *scaled_font,
+ cairo_glyph_t *glyphs,
+ int num_glyphs,
+ cairo_bool_t overlap)
+{
+ cairo_int_status_t status;
+ cairo_surface_t *src = NULL;
+ int src_x, src_y;
+ cairo_composite_glyphs_info_t info;
+
+ cairo_gl_surface_t *dst = (cairo_gl_surface_t *) composite->surface;
+
+ query_surface_capabilities (dst);
+ if (! dst->supports_stencil)
+ return CAIRO_INT_STATUS_UNSUPPORTED;
+
+ if (composite->is_bounded == FALSE) {
+ cairo_surface_t* surface = _prepare_unbounded_surface (dst);
+
+ if (unlikely (surface == NULL))
+ return CAIRO_INT_STATUS_UNSUPPORTED;
+
+ status = _cairo_compositor_glyphs (compositor, surface,
+ CAIRO_OPERATOR_SOURCE,
+ &composite->source_pattern.base,
+ glyphs, num_glyphs,
+ scaled_font, composite->clip);
+
+ if (unlikely (status)) {
+ cairo_surface_destroy (surface);
+ return status;
+ }
+
+ return _paint_back_unbounded_surface (compositor, composite, surface);
+ }
+
+ src = _cairo_gl_pattern_to_source (&dst->base,
+ &composite->source_pattern.base,
+ FALSE,
+ &composite->bounded,
+ &composite->source_sample_area,
+ &src_x, &src_y);
+ if (unlikely (src->status)) {
+ status = src->status;
+ goto finish;
+ }
+
+ status = _cairo_gl_check_composite_glyphs (composite,
+ scaled_font, glyphs,
+ &num_glyphs);
+ if (unlikely (status != CAIRO_INT_STATUS_SUCCESS))
+ goto finish;
+
+ info.font = scaled_font;
+ info.glyphs = glyphs;
+ info.num_glyphs = num_glyphs;
+ info.use_mask = overlap || ! composite->is_bounded;
+ info.extents = composite->bounded;
+
+ _cairo_scaled_font_freeze_cache (scaled_font);
+ status = _cairo_gl_composite_glyphs_with_clip (dst, composite->op,
+ src, src_x, src_y,
+ 0, 0, &info,
+ composite->clip);
+
+ _cairo_scaled_font_thaw_cache (scaled_font);
+
+finish:
+ if (src)
+ cairo_surface_destroy (src);
+
+ return status;
+}
+
static void
_cairo_gl_msaa_compositor_init (cairo_compositor_t *compositor,
const cairo_compositor_t *delegate)
@@ -665,7 +738,7 @@ _cairo_gl_msaa_compositor_init (cairo_compositor_t *compositor,
compositor->mask = _cairo_gl_msaa_compositor_mask;
compositor->fill = _cairo_gl_msaa_compositor_fill;
compositor->stroke = _cairo_gl_msaa_compositor_stroke;
- /* always fallback to common glyph cache implmentation */
+ compositor->glyphs = _cairo_gl_msaa_compositor_glyphs;
}
const cairo_compositor_t *
diff --git a/src/cairo-gl-private.h b/src/cairo-gl-private.h
index 0664320e..87fe2131 100644
--- a/src/cairo-gl-private.h
+++ b/src/cairo-gl-private.h
@@ -740,6 +740,17 @@ _cairo_gl_composite_glyphs (void *_dst,
int dst_y,
cairo_composite_glyphs_info_t *info);
+cairo_int_status_t
+_cairo_gl_composite_glyphs_with_clip (void *_dst,
+ cairo_operator_t op,
+ cairo_surface_t *_src,
+ int src_x,
+ int src_y,
+ int dst_x,
+ int dst_y,
+ cairo_composite_glyphs_info_t *info,
+ cairo_clip_t *clip);
+
cairo_private cairo_surface_t *
_cairo_gl_surface_create_scratch (cairo_gl_context_t *ctx,
cairo_content_t content,