mirror of
https://gitlab.freedesktop.org/cairo/cairo.git
synced 2026-05-05 06:28:01 +02:00
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.
This commit is contained in:
parent
e3f5b14fba
commit
4b3ad4e8da
3 changed files with 128 additions and 22 deletions
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 *
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue