mirror of
https://gitlab.freedesktop.org/cairo/cairo.git
synced 2026-05-07 16:48:12 +02:00
Use the scanline rasterizer in the win32 backend.
Brings http://people.mozilla.com/~jmuizelaar/world-map.html from 8fps to 13fps in Vista on a Mac Mini
This commit is contained in:
parent
d066154e62
commit
7f238f5424
1 changed files with 144 additions and 2 deletions
|
|
@ -1969,6 +1969,148 @@ _cairo_win32_surface_reset (void *abstract_surface)
|
|||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
typedef struct _cairo_win32_surface_span_renderer {
|
||||
cairo_span_renderer_t base;
|
||||
|
||||
cairo_operator_t op;
|
||||
const cairo_pattern_t *pattern;
|
||||
cairo_antialias_t antialias;
|
||||
|
||||
cairo_image_surface_t *mask;
|
||||
cairo_win32_surface_t *dst;
|
||||
|
||||
cairo_composite_rectangles_t composite_rectangles;
|
||||
} cairo_win32_surface_span_renderer_t;
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_win32_surface_span_renderer_render_row (
|
||||
void *abstract_renderer,
|
||||
int y,
|
||||
const cairo_half_open_span_t *spans,
|
||||
unsigned num_spans)
|
||||
{
|
||||
cairo_win32_surface_span_renderer_t *renderer = abstract_renderer;
|
||||
_cairo_image_surface_span_render_row (y, spans, num_spans, renderer->mask, &renderer->composite_rectangles);
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static void
|
||||
_cairo_win32_surface_span_renderer_destroy (void *abstract_renderer)
|
||||
{
|
||||
cairo_win32_surface_span_renderer_t *renderer = abstract_renderer;
|
||||
if (!renderer) return;
|
||||
|
||||
if (renderer->mask != NULL)
|
||||
cairo_surface_destroy (&renderer->mask->base);
|
||||
|
||||
free (renderer);
|
||||
}
|
||||
|
||||
static cairo_status_t
|
||||
_cairo_win32_surface_span_renderer_finish (void *abstract_renderer)
|
||||
{
|
||||
cairo_win32_surface_span_renderer_t *renderer = abstract_renderer;
|
||||
cairo_status_t status = CAIRO_STATUS_SUCCESS;
|
||||
|
||||
if (renderer->pattern == NULL || renderer->mask == NULL)
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
|
||||
status = cairo_surface_status (&renderer->mask->base);
|
||||
if (status == CAIRO_STATUS_SUCCESS) {
|
||||
cairo_composite_rectangles_t *rects = &renderer->composite_rectangles;
|
||||
cairo_win32_surface_t *dst = renderer->dst;
|
||||
cairo_pattern_t *mask_pattern = cairo_pattern_create_for_surface (&renderer->mask->base);
|
||||
/* composite onto the image surface directly if we can */
|
||||
if (dst->image) {
|
||||
GdiFlush(); /* XXX: I'm not sure if this needed or not */
|
||||
|
||||
status = dst->image->backend->composite (renderer->op,
|
||||
renderer->pattern, mask_pattern, dst->image,
|
||||
rects->src.x,
|
||||
rects->src.y,
|
||||
0, 0, /* mask.x, mask.y */
|
||||
rects->dst.x, rects->dst.y,
|
||||
rects->width, rects->height);
|
||||
} else {
|
||||
/* otherwise go through the fallback_composite path which
|
||||
* will do the appropriate surface acquisition */
|
||||
status = _cairo_surface_fallback_composite (
|
||||
renderer->op,
|
||||
renderer->pattern, mask_pattern, dst,
|
||||
rects->src.x,
|
||||
rects->src.y,
|
||||
0, 0, /* mask.x, mask.y */
|
||||
rects->dst.x, rects->dst.y,
|
||||
rects->width, rects->height);
|
||||
}
|
||||
cairo_pattern_destroy (mask_pattern);
|
||||
|
||||
}
|
||||
if (status != CAIRO_STATUS_SUCCESS)
|
||||
return _cairo_span_renderer_set_error (abstract_renderer,
|
||||
status);
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static cairo_bool_t
|
||||
_cairo_win32_surface_check_span_renderer (cairo_operator_t op,
|
||||
const cairo_pattern_t *pattern,
|
||||
void *abstract_dst,
|
||||
cairo_antialias_t antialias,
|
||||
const cairo_composite_rectangles_t *rects)
|
||||
{
|
||||
(void) op;
|
||||
(void) pattern;
|
||||
(void) abstract_dst;
|
||||
(void) antialias;
|
||||
(void) rects;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static cairo_span_renderer_t *
|
||||
_cairo_win32_surface_create_span_renderer (cairo_operator_t op,
|
||||
const cairo_pattern_t *pattern,
|
||||
void *abstract_dst,
|
||||
cairo_antialias_t antialias,
|
||||
const cairo_composite_rectangles_t *rects)
|
||||
{
|
||||
cairo_win32_surface_t *dst = abstract_dst;
|
||||
cairo_win32_surface_span_renderer_t *renderer
|
||||
= calloc(1, sizeof(*renderer));
|
||||
cairo_status_t status;
|
||||
int width = rects->width;
|
||||
int height = rects->height;
|
||||
|
||||
if (renderer == NULL)
|
||||
return _cairo_span_renderer_create_in_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
renderer->base.destroy = _cairo_win32_surface_span_renderer_destroy;
|
||||
renderer->base.finish = _cairo_win32_surface_span_renderer_finish;
|
||||
renderer->base.render_row =
|
||||
_cairo_win32_surface_span_renderer_render_row;
|
||||
renderer->op = op;
|
||||
renderer->pattern = pattern;
|
||||
renderer->antialias = antialias;
|
||||
renderer->dst = dst;
|
||||
|
||||
renderer->composite_rectangles = *rects;
|
||||
|
||||
/* TODO: support rendering to A1 surfaces (or: go add span
|
||||
* compositing to pixman.) */
|
||||
renderer->mask = (cairo_image_surface_t *)
|
||||
cairo_image_surface_create (CAIRO_FORMAT_A8,
|
||||
width, height);
|
||||
|
||||
status = cairo_surface_status (&renderer->mask->base);
|
||||
|
||||
if (status != CAIRO_STATUS_SUCCESS) {
|
||||
_cairo_win32_surface_span_renderer_destroy (renderer);
|
||||
return _cairo_span_renderer_create_in_error (status);
|
||||
}
|
||||
return &renderer->base;
|
||||
}
|
||||
|
||||
|
||||
static const cairo_surface_backend_t cairo_win32_surface_backend = {
|
||||
CAIRO_SURFACE_TYPE_WIN32,
|
||||
_cairo_win32_surface_create_similar,
|
||||
|
|
@ -1981,8 +2123,8 @@ static const cairo_surface_backend_t cairo_win32_surface_backend = {
|
|||
_cairo_win32_surface_composite,
|
||||
_cairo_win32_surface_fill_rectangles,
|
||||
NULL, /* composite_trapezoids */
|
||||
NULL, /* create_span_renderer */
|
||||
NULL, /* check_span_renderer */
|
||||
_cairo_win32_surface_create_span_renderer,
|
||||
_cairo_win32_surface_check_span_renderer,
|
||||
NULL, /* copy_page */
|
||||
NULL, /* show_page */
|
||||
_cairo_win32_surface_set_clip_region,
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue