Bug 498689. Use scanline rasterizer on win32. r=joedrew, r=zweinberg

This commit is contained in:
Jeff Muizelaar 2009-06-22 15:01:50 -04:00
parent 6fe7954588
commit 7a11cbc4a7
31 changed files with 436 additions and 14 deletions

View File

@ -52,6 +52,8 @@ text-path-filling-threshold.patch: use path filling instead of platform glyph ra
zombie-face.patch: bug 486974; leak and possible crash with @font-face{src:url()}. Upstream commit: 0238fe2cafea2e1ed19bb222117bd73ee6898d4d
win32-raster.patch: bug 498689; use scanline rasterizer on win32
==== pixman patches ====
pixman-neon.patch: add ARM NEON optimized compositing functions

View File

@ -1232,27 +1232,27 @@ typedef struct _cairo_image_surface_span_renderer {
cairo_composite_rectangles_t composite_rectangles;
} cairo_image_surface_span_renderer_t;
static cairo_status_t
_cairo_image_surface_span_renderer_render_row (
void *abstract_renderer,
void
_cairo_image_surface_span_render_row (
int y,
const cairo_half_open_span_t *spans,
unsigned num_spans)
unsigned num_spans,
cairo_image_surface_t *mask,
const cairo_composite_rectangles_t *rects)
{
cairo_image_surface_span_renderer_t *renderer = abstract_renderer;
int xmin = renderer->composite_rectangles.mask.x;
int xmax = xmin + renderer->composite_rectangles.width;
int xmin = rects->mask.x;
int xmax = xmin + rects->width;
uint8_t *row;
int prev_x = xmin;
int prev_alpha = 0;
unsigned i;
/* Make sure we're within y-range. */
y -= renderer->composite_rectangles.mask.y;
if (y < 0 || y >= renderer->composite_rectangles.height)
y -= rects->mask.y;
if (y < 0 || y >= rects->height)
return CAIRO_STATUS_SUCCESS;
row = (uint8_t*)(renderer->mask->data) + y*(size_t)renderer->mask->stride - xmin;
row = (uint8_t*)(mask->data) + y*(size_t)mask->stride - xmin;
/* Find the first span within x-range. */
for (i=0; i < num_spans && spans[i].x < xmin; i++) {}
@ -1286,7 +1286,17 @@ _cairo_image_surface_span_renderer_render_row (
if (prev_alpha != 0 && prev_x < xmax) {
memset(row + prev_x, prev_alpha, xmax - prev_x);
}
}
static cairo_status_t
_cairo_image_surface_span_renderer_render_row (
void *abstract_renderer,
int y,
const cairo_half_open_span_t *spans,
unsigned num_spans)
{
cairo_image_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;
}

View File

@ -295,9 +295,9 @@ typedef int grid_area_t;
#elif GRID_XY == 15
# define GRID_AREA_TO_ALPHA(c) (((c) << 4) + (c))
#elif GRID_XY == 2*256*15
# define GRID_AREA_TO_ALPHA(c) (((c) + ((c)<<4)) >> 9)
# define GRID_AREA_TO_ALPHA(c) (((c) + ((c)<<4) + 256) >> 9)
#else
# define GRID_AREA_TO_ALPHA(c) ((c)*255 / GRID_XY) /* tweak me for rounding */
# define GRID_AREA_TO_ALPHA(c) (((c)*255 + GRID_XY/2) / GRID_XY)
#endif
#define UNROLL3(x) x x x

View File

@ -2048,6 +2048,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();
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,
@ -2060,8 +2202,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,

View File

@ -2193,6 +2193,12 @@ _cairo_image_surface_set_clip_region (void *abstract_surface,
cairo_private cairo_image_surface_t *
_cairo_image_surface_coerce (cairo_image_surface_t *surface,
cairo_format_t format);
cairo_private void
_cairo_image_surface_span_render_row (int y,
const cairo_half_open_span_t *spans,
unsigned num_spans,
cairo_image_surface_t *mask,
const cairo_composite_rectangles_t *rects);
cairo_private cairo_image_transparency_t
_cairo_image_analyze_transparency (cairo_image_surface_t *image);

View File

@ -0,0 +1,262 @@
changeset: 29338:f2a10f325734
tag: qtip
tag: tip
tag: win32-raster-mask2.patch
tag: qbase
user: Jeff Muizelaar <jmuizelaar@mozilla.com>
date: Mon Jun 22 14:26:07 2009 -0400
summary: imported patch win32-raster-mask2.patch
diff --git a/gfx/cairo/cairo/src/cairo-image-surface.c b/gfx/cairo/cairo/src/cairo-image-surface.c
--- a/gfx/cairo/cairo/src/cairo-image-surface.c
+++ b/gfx/cairo/cairo/src/cairo-image-surface.c
@@ -1232,27 +1232,27 @@ typedef struct _cairo_image_surface_span
cairo_composite_rectangles_t composite_rectangles;
} cairo_image_surface_span_renderer_t;
-static cairo_status_t
-_cairo_image_surface_span_renderer_render_row (
- void *abstract_renderer,
+void
+_cairo_image_surface_span_render_row (
int y,
const cairo_half_open_span_t *spans,
- unsigned num_spans)
+ unsigned num_spans,
+ cairo_image_surface_t *mask,
+ const cairo_composite_rectangles_t *rects)
{
- cairo_image_surface_span_renderer_t *renderer = abstract_renderer;
- int xmin = renderer->composite_rectangles.mask.x;
- int xmax = xmin + renderer->composite_rectangles.width;
+ int xmin = rects->mask.x;
+ int xmax = xmin + rects->width;
uint8_t *row;
int prev_x = xmin;
int prev_alpha = 0;
unsigned i;
/* Make sure we're within y-range. */
- y -= renderer->composite_rectangles.mask.y;
- if (y < 0 || y >= renderer->composite_rectangles.height)
+ y -= rects->mask.y;
+ if (y < 0 || y >= rects->height)
return CAIRO_STATUS_SUCCESS;
- row = (uint8_t*)(renderer->mask->data) + y*(size_t)renderer->mask->stride - xmin;
+ row = (uint8_t*)(mask->data) + y*(size_t)mask->stride - xmin;
/* Find the first span within x-range. */
for (i=0; i < num_spans && spans[i].x < xmin; i++) {}
@@ -1286,7 +1286,17 @@ _cairo_image_surface_span_renderer_rende
if (prev_alpha != 0 && prev_x < xmax) {
memset(row + prev_x, prev_alpha, xmax - prev_x);
}
+}
+static cairo_status_t
+_cairo_image_surface_span_renderer_render_row (
+ void *abstract_renderer,
+ int y,
+ const cairo_half_open_span_t *spans,
+ unsigned num_spans)
+{
+ cairo_image_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;
}
diff --git a/gfx/cairo/cairo/src/cairo-tor-scan-converter.c b/gfx/cairo/cairo/src/cairo-tor-scan-converter.c
--- a/gfx/cairo/cairo/src/cairo-tor-scan-converter.c
+++ b/gfx/cairo/cairo/src/cairo-tor-scan-converter.c
@@ -295,9 +295,9 @@ typedef int grid_area_t;
#elif GRID_XY == 15
# define GRID_AREA_TO_ALPHA(c) (((c) << 4) + (c))
#elif GRID_XY == 2*256*15
-# define GRID_AREA_TO_ALPHA(c) (((c) + ((c)<<4)) >> 9)
+# define GRID_AREA_TO_ALPHA(c) (((c) + ((c)<<4) + 256) >> 9)
#else
-# define GRID_AREA_TO_ALPHA(c) ((c)*255 / GRID_XY) /* tweak me for rounding */
+# define GRID_AREA_TO_ALPHA(c) (((c)*255 + GRID_XY/2) / GRID_XY)
#endif
#define UNROLL3(x) x x x
diff --git a/gfx/cairo/cairo/src/cairo-win32-surface.c b/gfx/cairo/cairo/src/cairo-win32-surface.c
--- a/gfx/cairo/cairo/src/cairo-win32-surface.c
+++ b/gfx/cairo/cairo/src/cairo-win32-surface.c
@@ -2048,6 +2048,148 @@ _cairo_win32_surface_reset (void *abstra
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();
+
+ 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,
@@ -2060,8 +2202,8 @@ static const cairo_surface_backend_t cai
_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,
diff --git a/gfx/cairo/cairo/src/cairoint.h b/gfx/cairo/cairo/src/cairoint.h
--- a/gfx/cairo/cairo/src/cairoint.h
+++ b/gfx/cairo/cairo/src/cairoint.h
@@ -2193,6 +2193,12 @@ _cairo_image_surface_set_clip_region (vo
cairo_private cairo_image_surface_t *
_cairo_image_surface_coerce (cairo_image_surface_t *surface,
cairo_format_t format);
+cairo_private void
+_cairo_image_surface_span_render_row (int y,
+ const cairo_half_open_span_t *spans,
+ unsigned num_spans,
+ cairo_image_surface_t *mask,
+ const cairo_composite_rectangles_t *rects);
cairo_private cairo_image_transparency_t
_cairo_image_analyze_transparency (cairo_image_surface_t *image);

Binary file not shown.

Before

Width:  |  Height:  |  Size: 195 B

After

Width:  |  Height:  |  Size: 163 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 282 B

After

Width:  |  Height:  |  Size: 244 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 376 B

After

Width:  |  Height:  |  Size: 318 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 444 B

After

Width:  |  Height:  |  Size: 387 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 450 B

After

Width:  |  Height:  |  Size: 414 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 203 B

After

Width:  |  Height:  |  Size: 165 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 257 B

After

Width:  |  Height:  |  Size: 222 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 378 B

After

Width:  |  Height:  |  Size: 301 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 477 B

After

Width:  |  Height:  |  Size: 376 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 492 B

After

Width:  |  Height:  |  Size: 435 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 199 B

After

Width:  |  Height:  |  Size: 162 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 254 B

After

Width:  |  Height:  |  Size: 215 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 358 B

After

Width:  |  Height:  |  Size: 314 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 350 B

After

Width:  |  Height:  |  Size: 385 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 350 B

After

Width:  |  Height:  |  Size: 385 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 210 B

After

Width:  |  Height:  |  Size: 168 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 281 B

After

Width:  |  Height:  |  Size: 240 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 421 B

After

Width:  |  Height:  |  Size: 363 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 421 B

After

Width:  |  Height:  |  Size: 445 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 476 B

After

Width:  |  Height:  |  Size: 507 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 201 B

After

Width:  |  Height:  |  Size: 163 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 286 B

After

Width:  |  Height:  |  Size: 260 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 417 B

After

Width:  |  Height:  |  Size: 357 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 421 B

After

Width:  |  Height:  |  Size: 443 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 532 B

After

Width:  |  Height:  |  Size: 492 B