summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrea Canciani <ranma42@gmail.com>2011-01-15 12:39:09 +0100
committerAndrea Canciani <ranma42@gmail.com>2011-01-15 12:39:09 +0100
commitbfc9fa36b9767656d5686b18b49fa0d8c01af750 (patch)
tree383af3628e06c770fb60aa76101ce9029575baac
parent7d1d3cd2ec103261e23199a6a72a02f744a18f25 (diff)
Tentative support for zero-copy source fetchingwip/itersource
Just POC, the new flag is not used anywhere, so it's useless right now.
-rw-r--r--pixman/pixman-bits-image.c25
-rw-r--r--pixman/pixman-conical-gradient.c17
-rw-r--r--pixman/pixman-general.c24
-rw-r--r--pixman/pixman-image.c2
-rw-r--r--pixman/pixman-implementation.c20
-rw-r--r--pixman/pixman-linear-gradient.c20
-rw-r--r--pixman/pixman-private.h43
-rw-r--r--pixman/pixman-radial-gradient.c17
-rw-r--r--pixman/pixman-solid-fill.c3
-rw-r--r--pixman/pixman-utils.c5
10 files changed, 99 insertions, 77 deletions
diff --git a/pixman/pixman-bits-image.c b/pixman/pixman-bits-image.c
index 6c43b97..376753f 100644
--- a/pixman/pixman-bits-image.c
+++ b/pixman/pixman-bits-image.c
@@ -1347,24 +1347,24 @@ bits_image_property_changed (pixman_image_t *image)
}
static uint32_t *
-src_get_scanline_narrow (pixman_iter_t *iter, const uint32_t *mask)
+src_get_scanline_narrow (pixman_iter_t *iter, uint32_t *buffer, const uint32_t *mask)
{
iter->image->bits.get_scanline_32 (
- iter->image, iter->x, iter->y++, iter->width, iter->buffer, mask);
+ iter->image, iter->x, iter->y++, iter->width, buffer, mask);
- return iter->buffer;
+ return buffer;
}
static uint32_t *
-src_get_scanline_wide (pixman_iter_t *iter, const uint32_t *mask)
+src_get_scanline_wide (pixman_iter_t *iter, uint32_t *buffer, const uint32_t *mask)
{
iter->image->bits.get_scanline_64 (
- iter->image, iter->x, iter->y++, iter->width, iter->buffer, mask);
+ iter->image, iter->x, iter->y++, iter->width, buffer, mask);
- return iter->buffer;
+ return buffer;
}
-void
+iter_flags_t
_pixman_bits_image_src_iter_init (pixman_image_t *image,
pixman_iter_t *iter,
int x, int y, int width, int height,
@@ -1374,10 +1374,12 @@ _pixman_bits_image_src_iter_init (pixman_image_t *image,
iter->get_scanline = src_get_scanline_narrow;
else
iter->get_scanline = src_get_scanline_wide;
+
+ return flags;
}
static uint32_t *
-dest_get_scanline_narrow (pixman_iter_t *iter, const uint32_t *mask)
+dest_get_scanline_narrow (pixman_iter_t *iter, uint32_t *unused, const uint32_t *mask)
{
pixman_image_t *image = iter->image;
int x = iter->x;
@@ -1400,7 +1402,7 @@ dest_get_scanline_narrow (pixman_iter_t *iter, const uint32_t *mask)
}
static uint32_t *
-dest_get_scanline_wide (pixman_iter_t *iter, const uint32_t *mask)
+dest_get_scanline_wide (pixman_iter_t *iter, uint32_t *unused, const uint32_t *mask)
{
bits_image_t * image = &iter->image->bits;
int x = iter->x;
@@ -1474,7 +1476,7 @@ dest_write_back_direct (pixman_iter_t *iter)
iter->buffer += iter->image->bits.rowstride;
}
-void
+iter_flags_t
_pixman_bits_image_dest_iter_init (pixman_image_t *image,
pixman_iter_t *iter,
int x, int y, int width, int height,
@@ -1514,6 +1516,9 @@ _pixman_bits_image_dest_iter_init (pixman_image_t *image,
iter->get_scanline = dest_get_scanline_wide;
iter->write_back = dest_write_back_wide;
}
+
+ /* What would ITER_ON_DEST mean for dest iterators? */
+ return flags & ~ITER_ON_DEST;
}
static uint32_t *
diff --git a/pixman/pixman-conical-gradient.c b/pixman/pixman-conical-gradient.c
index 9d7d2e8..52d524c 100644
--- a/pixman/pixman-conical-gradient.c
+++ b/pixman/pixman-conical-gradient.c
@@ -51,13 +51,14 @@ coordinates_to_parameter (double x, double y, double angle)
}
static uint32_t *
-conical_get_scanline_narrow (pixman_iter_t *iter, const uint32_t *mask)
+conical_get_scanline_narrow (pixman_iter_t *iter,
+ uint32_t *buffer,
+ const uint32_t *mask)
{
pixman_image_t *image = iter->image;
int x = iter->x;
int y = iter->y;
int width = iter->width;
- uint32_t *buffer = iter->buffer;
gradient_t *gradient = (gradient_t *)image;
conical_gradient_t *conical = (conical_gradient_t *)image;
@@ -83,7 +84,7 @@ conical_get_scanline_narrow (pixman_iter_t *iter, const uint32_t *mask)
v.vector[2] = pixman_fixed_1;
if (!pixman_transform_point_3d (image->common.transform, &v))
- return iter->buffer;
+ return buffer;
cx = image->common.transform->matrix[0][0] / 65536.;
cy = image->common.transform->matrix[1][0] / 65536.;
@@ -157,20 +158,20 @@ conical_get_scanline_narrow (pixman_iter_t *iter, const uint32_t *mask)
}
iter->y++;
- return iter->buffer;
+ return buffer;
}
static uint32_t *
-conical_get_scanline_wide (pixman_iter_t *iter, const uint32_t *mask)
+conical_get_scanline_wide (pixman_iter_t *iter, uint32_t *buffer, const uint32_t *mask)
{
- uint32_t *buffer = conical_get_scanline_narrow (iter, NULL);
+ conical_get_scanline_narrow (iter, buffer, NULL);
pixman_expand ((uint64_t *)buffer, buffer, PIXMAN_a8r8g8b8, iter->width);
return buffer;
}
-void
+iter_flags_t
_pixman_conical_gradient_iter_init (pixman_image_t *image,
pixman_iter_t *iter,
int x, int y, int width, int height,
@@ -180,6 +181,8 @@ _pixman_conical_gradient_iter_init (pixman_image_t *image,
iter->get_scanline = conical_get_scanline_narrow;
else
iter->get_scanline = conical_get_scanline_wide;
+
+ return flags;
}
PIXMAN_EXPORT pixman_image_t *
diff --git a/pixman/pixman-general.c b/pixman/pixman-general.c
index 16ea3a4..5ef502d 100644
--- a/pixman/pixman-general.c
+++ b/pixman/pixman-general.c
@@ -39,7 +39,7 @@
#include "pixman-combine32.h"
#include "pixman-private.h"
-static void
+static iter_flags_t
general_src_iter_init (pixman_implementation_t *imp,
pixman_iter_t *iter,
pixman_image_t *image,
@@ -54,36 +54,37 @@ general_src_iter_init (pixman_implementation_t *imp,
if (image->type == SOLID)
{
- _pixman_solid_fill_iter_init (
+ return _pixman_solid_fill_iter_init (
image, iter, x, y, width, height, buffer, flags);
}
else if (image->type == LINEAR)
{
- _pixman_linear_gradient_iter_init (
+ return _pixman_linear_gradient_iter_init (
image, iter, x, y, width, height, buffer, flags);
}
else if (image->type == RADIAL)
{
- _pixman_radial_gradient_iter_init (
+ return _pixman_radial_gradient_iter_init (
image, iter, x, y, width, height, buffer, flags);
}
else if (image->type == CONICAL)
{
- _pixman_conical_gradient_iter_init (
+ return _pixman_conical_gradient_iter_init (
image, iter, x, y, width, height, buffer, flags);
}
else if (image->type == BITS)
{
- _pixman_bits_image_src_iter_init (
+ return _pixman_bits_image_src_iter_init (
image, iter, x, y, width, height, buffer, flags);
}
else
{
_pixman_log_error (FUNC, "Pixman bug: unknown image type\n");
+ return flags;
}
}
-static void
+static iter_flags_t
general_dest_iter_init (pixman_implementation_t *imp,
pixman_iter_t *iter,
pixman_image_t *image,
@@ -98,12 +99,13 @@ general_dest_iter_init (pixman_implementation_t *imp,
if (image->type == BITS)
{
- _pixman_bits_image_dest_iter_init (
+ return _pixman_bits_image_dest_iter_init (
image, iter, x, y, width, height, buffer, flags);
}
else
{
_pixman_log_error (FUNC, "Trying to write to a non-writable image");
+ return flags;
}
}
@@ -242,9 +244,9 @@ general_composite_rect (pixman_implementation_t *imp,
{
uint32_t *s, *m, *d;
- m = mask_iter.get_scanline (&mask_iter, NULL);
- s = src_iter.get_scanline (&src_iter, m);
- d = dest_iter.get_scanline (&dest_iter, NULL);
+ d = dest_iter.get_scanline (&dest_iter, dest_iter.buffer, NULL);
+ m = mask_iter.get_scanline (&mask_iter, mask_iter.buffer, NULL);
+ s = src_iter.get_scanline (&src_iter, src_iter.buffer, m);
compose (imp->toplevel, op, d, s, m, width);
diff --git a/pixman/pixman-image.c b/pixman/pixman-image.c
index f298e2d..51427b7 100644
--- a/pixman/pixman-image.c
+++ b/pixman/pixman-image.c
@@ -730,7 +730,7 @@ _pixman_image_get_solid (pixman_implementation_t *imp,
imp, &iter, image, 0, 0, 1, 1,
(uint8_t *)&result, ITER_NARROW);
- result = *iter.get_scanline (&iter, NULL);
+ result = *iter.get_scanline (&iter, &result, NULL);
/* If necessary, convert RGB <--> BGR. */
if (PIXMAN_FORMAT_TYPE (format) != PIXMAN_TYPE_ARGB)
diff --git a/pixman/pixman-implementation.c b/pixman/pixman-implementation.c
index adaf9c6..b1b7830 100644
--- a/pixman/pixman-implementation.c
+++ b/pixman/pixman-implementation.c
@@ -111,7 +111,7 @@ delegate_fill (pixman_implementation_t *imp,
imp->delegate, bits, stride, bpp, x, y, width, height, xor);
}
-static void
+static iter_flags_t
delegate_src_iter_init (pixman_implementation_t *imp,
pixman_iter_t * iter,
pixman_image_t * image,
@@ -122,11 +122,11 @@ delegate_src_iter_init (pixman_implementation_t *imp,
uint8_t * buffer,
iter_flags_t flags)
{
- _pixman_implementation_src_iter_init (
+ return _pixman_implementation_src_iter_init (
imp->delegate, iter, image, x, y, width, height, buffer, flags);
}
-static void
+static iter_flags_t
delegate_dest_iter_init (pixman_implementation_t *imp,
pixman_iter_t * iter,
pixman_image_t * image,
@@ -137,7 +137,7 @@ delegate_dest_iter_init (pixman_implementation_t *imp,
uint8_t * buffer,
iter_flags_t flags)
{
- _pixman_implementation_dest_iter_init (
+ return _pixman_implementation_dest_iter_init (
imp->delegate, iter, image, x, y, width, height, buffer, flags);
}
@@ -258,12 +258,12 @@ _pixman_implementation_fill (pixman_implementation_t *imp,
}
static uint32_t *
-get_scanline_null (pixman_iter_t *iter, const uint32_t *mask)
+get_scanline_null (pixman_iter_t *iter, uint32_t *buffer, const uint32_t *mask)
{
return NULL;
}
-void
+iter_flags_t
_pixman_implementation_src_iter_init (pixman_implementation_t *imp,
pixman_iter_t *iter,
pixman_image_t *image,
@@ -277,20 +277,22 @@ _pixman_implementation_src_iter_init (pixman_implementation_t *imp,
if (!image)
{
iter->get_scanline = get_scanline_null;
+ return flags & ~ITER_ON_DEST;
}
else if ((flags & (ITER_IGNORE_ALPHA | ITER_IGNORE_RGB)) ==
(ITER_IGNORE_ALPHA | ITER_IGNORE_RGB))
{
iter->get_scanline = _pixman_iter_get_scanline_noop;
+ return flags & ~ITER_ON_DEST;
}
else
{
- (*imp->src_iter_init) (
+ return (*imp->src_iter_init) (
imp, iter, image, x, y, width, height, buffer, flags);
}
}
-void
+iter_flags_t
_pixman_implementation_dest_iter_init (pixman_implementation_t *imp,
pixman_iter_t *iter,
pixman_image_t *image,
@@ -301,6 +303,6 @@ _pixman_implementation_dest_iter_init (pixman_implementation_t *imp,
uint8_t *buffer,
iter_flags_t flags)
{
- (*imp->dest_iter_init) (
+ return (*imp->dest_iter_init) (
imp, iter, image, x, y, width, height, buffer, flags);
}
diff --git a/pixman/pixman-linear-gradient.c b/pixman/pixman-linear-gradient.c
index 9208808..019c23e 100644
--- a/pixman/pixman-linear-gradient.c
+++ b/pixman/pixman-linear-gradient.c
@@ -90,13 +90,13 @@ linear_gradient_is_horizontal (pixman_image_t *image,
static uint32_t *
linear_gradient_get_scanline_narrow (pixman_iter_t *iter,
+ uint32_t *buffer,
const uint32_t *mask)
{
pixman_image_t *image = iter->image;
int x = iter->x;
int y = iter->y;
int width = iter->width;
- uint32_t * buffer = iter->buffer;
pixman_vector_t v, unit;
pixman_fixed_32_32_t l;
@@ -116,7 +116,7 @@ linear_gradient_get_scanline_narrow (pixman_iter_t *iter,
if (image->common.transform)
{
if (!pixman_transform_point_3d (image->common.transform, &v))
- return iter->buffer;
+ return buffer;
unit.vector[0] = image->common.transform->matrix[0][0];
unit.vector[1] = image->common.transform->matrix[1][0];
@@ -219,20 +219,20 @@ linear_gradient_get_scanline_narrow (pixman_iter_t *iter,
iter->y++;
- return iter->buffer;
+ return buffer;
}
static uint32_t *
-linear_gradient_get_scanline_wide (pixman_iter_t *iter, const uint32_t *mask)
+linear_gradient_get_scanline_wide (pixman_iter_t *iter, uint32_t *buffer, const uint32_t *mask)
{
- uint32_t *buffer = linear_gradient_get_scanline_narrow (iter, NULL);
+ linear_gradient_get_scanline_narrow (iter, buffer, NULL);
pixman_expand ((uint64_t *)buffer, buffer, PIXMAN_a8r8g8b8, iter->width);
return buffer;
}
-void
+iter_flags_t
_pixman_linear_gradient_iter_init (pixman_image_t *image,
pixman_iter_t *iter,
int x,
@@ -245,11 +245,13 @@ _pixman_linear_gradient_iter_init (pixman_image_t *image,
if (linear_gradient_is_horizontal (image, x, y, width, height))
{
if (flags & ITER_NARROW)
- linear_gradient_get_scanline_narrow (iter, NULL);
+ linear_gradient_get_scanline_narrow (iter, iter->buffer, NULL);
else
- linear_gradient_get_scanline_wide (iter, NULL);
+ linear_gradient_get_scanline_wide (iter, iter->buffer, NULL);
iter->get_scanline = _pixman_iter_get_scanline_noop;
+
+ return flags & ~ITER_ON_DEST;
}
else
{
@@ -257,6 +259,8 @@ _pixman_linear_gradient_iter_init (pixman_image_t *image,
iter->get_scanline = linear_gradient_get_scanline_narrow;
else
iter->get_scanline = linear_gradient_get_scanline_wide;
+
+ return flags;
}
}
diff --git a/pixman/pixman-private.h b/pixman/pixman-private.h
index 323bdf4..cae439f 100644
--- a/pixman/pixman-private.h
+++ b/pixman/pixman-private.h
@@ -205,12 +205,13 @@ typedef enum
*/
ITER_LOCALIZED_ALPHA = (1 << 1),
ITER_IGNORE_ALPHA = (1 << 2),
- ITER_IGNORE_RGB = (1 << 3)
+ ITER_IGNORE_RGB = (1 << 3),
+ ITER_ON_DEST = (1 << 4)
} iter_flags_t;
struct pixman_iter_t
{
- uint32_t *(* get_scanline) (pixman_iter_t *iter, const uint32_t *mask);
+ uint32_t *(* get_scanline) (pixman_iter_t *iter, uint32_t *buffer, const uint32_t *mask);
void (* write_back) (pixman_iter_t *iter);
pixman_image_t * image;
@@ -222,41 +223,41 @@ struct pixman_iter_t
void
_pixman_bits_image_setup_accessors (bits_image_t *image);
-void
+iter_flags_t
_pixman_bits_image_src_iter_init (pixman_image_t *image,
pixman_iter_t *iter,
int x, int y, int width, int height,
uint8_t *buffer, iter_flags_t flags);
-void
+iter_flags_t
_pixman_bits_image_dest_iter_init (pixman_image_t *image,
pixman_iter_t *iter,
int x, int y, int width, int height,
uint8_t *buffer, iter_flags_t flags);
-void
+iter_flags_t
_pixman_solid_fill_iter_init (pixman_image_t *image,
pixman_iter_t *iter,
int x, int y, int width, int height,
uint8_t *buffer, iter_flags_t flags);
-void
+iter_flags_t
_pixman_linear_gradient_iter_init (pixman_image_t *image,
pixman_iter_t *iter,
int x, int y, int width, int height,
uint8_t *buffer, iter_flags_t flags);
-void
+iter_flags_t
_pixman_solid_fill_iter_init (pixman_image_t *image,
pixman_iter_t *iter,
int x, int y, int width, int height,
uint8_t *buffer, iter_flags_t flags);
-void
+iter_flags_t
_pixman_radial_gradient_iter_init (pixman_image_t *image,
pixman_iter_t *iter,
int x, int y, int width, int height,
uint8_t *buffer, iter_flags_t flags);
-void
+iter_flags_t
_pixman_conical_gradient_iter_init (pixman_image_t *image,
pixman_iter_t *iter,
int x, int y, int width, int height,
@@ -407,15 +408,15 @@ typedef pixman_bool_t (*pixman_fill_func_t) (pixman_implementation_t *imp,
int width,
int height,
uint32_t xor);
-typedef void (*pixman_iter_init_func_t) (pixman_implementation_t *imp,
- pixman_iter_t *iter,
- pixman_image_t *image,
- int x,
- int y,
- int width,
- int height,
- uint8_t *buffer,
- iter_flags_t flags);
+typedef iter_flags_t (*pixman_iter_init_func_t) (pixman_implementation_t *imp,
+ pixman_iter_t *iter,
+ pixman_image_t *image,
+ int x,
+ int y,
+ int width,
+ int height,
+ uint8_t *buffer,
+ iter_flags_t flags);
void _pixman_setup_combiner_functions_32 (pixman_implementation_t *imp);
void _pixman_setup_combiner_functions_64 (pixman_implementation_t *imp);
@@ -513,7 +514,7 @@ _pixman_implementation_fill (pixman_implementation_t *imp,
int height,
uint32_t xor);
-void
+iter_flags_t
_pixman_implementation_src_iter_init (pixman_implementation_t *imp,
pixman_iter_t *iter,
pixman_image_t *image,
@@ -524,7 +525,7 @@ _pixman_implementation_src_iter_init (pixman_implementation_t *imp,
uint8_t *buffer,
iter_flags_t flags);
-void
+iter_flags_t
_pixman_implementation_dest_iter_init (pixman_implementation_t *imp,
pixman_iter_t *iter,
pixman_image_t *image,
@@ -576,7 +577,7 @@ _pixman_choose_implementation (void);
* Utilities
*/
uint32_t *
-_pixman_iter_get_scanline_noop (pixman_iter_t *iter, const uint32_t *mask);
+_pixman_iter_get_scanline_noop (pixman_iter_t *iter, uint32_t *buffer, const uint32_t *mask);
/* These "formats" all have depth 0, so they
* will never clash with any real ones
diff --git a/pixman/pixman-radial-gradient.c b/pixman/pixman-radial-gradient.c
index 6523b82..65ff47d 100644
--- a/pixman/pixman-radial-gradient.c
+++ b/pixman/pixman-radial-gradient.c
@@ -145,7 +145,9 @@ radial_compute_color (double a,
}
static uint32_t *
-radial_get_scanline_narrow (pixman_iter_t *iter, const uint32_t *mask)
+radial_get_scanline_narrow (pixman_iter_t *iter,
+ uint32_t *buffer,
+ const uint32_t *mask)
{
/*
* Implementation of radial gradients following the PDF specification.
@@ -232,7 +234,6 @@ radial_get_scanline_narrow (pixman_iter_t *iter, const uint32_t *mask)
int x = iter->x;
int y = iter->y;
int width = iter->width;
- uint32_t *buffer = iter->buffer;
gradient_t *gradient = (gradient_t *)image;
radial_gradient_t *radial = (radial_gradient_t *)image;
@@ -250,7 +251,7 @@ radial_get_scanline_narrow (pixman_iter_t *iter, const uint32_t *mask)
if (image->common.transform)
{
if (!pixman_transform_point_3d (image->common.transform, &v))
- return iter->buffer;
+ return buffer;
unit.vector[0] = image->common.transform->matrix[0][0];
unit.vector[1] = image->common.transform->matrix[1][0];
@@ -386,20 +387,20 @@ radial_get_scanline_narrow (pixman_iter_t *iter, const uint32_t *mask)
}
iter->y++;
- return iter->buffer;
+ return buffer;
}
static uint32_t *
-radial_get_scanline_wide (pixman_iter_t *iter, const uint32_t *mask)
+radial_get_scanline_wide (pixman_iter_t *iter, uint32_t *buffer, const uint32_t *mask)
{
- uint32_t *buffer = radial_get_scanline_narrow (iter, NULL);
+ radial_get_scanline_narrow (iter, buffer, NULL);
pixman_expand ((uint64_t *)buffer, buffer, PIXMAN_a8r8g8b8, iter->width);
return buffer;
}
-void
+iter_flags_t
_pixman_radial_gradient_iter_init (pixman_image_t *image,
pixman_iter_t *iter,
int x, int y, int width, int height,
@@ -409,6 +410,8 @@ _pixman_radial_gradient_iter_init (pixman_image_t *image,
iter->get_scanline = radial_get_scanline_narrow;
else
iter->get_scanline = radial_get_scanline_wide;
+
+ return flags;
}
PIXMAN_EXPORT pixman_image_t *
diff --git a/pixman/pixman-solid-fill.c b/pixman/pixman-solid-fill.c
index 67681f2..8646364 100644
--- a/pixman/pixman-solid-fill.c
+++ b/pixman/pixman-solid-fill.c
@@ -26,7 +26,7 @@
#endif
#include "pixman-private.h"
-void
+iter_flags_t
_pixman_solid_fill_iter_init (pixman_image_t *image,
pixman_iter_t *iter,
int x, int y, int width, int height,
@@ -52,6 +52,7 @@ _pixman_solid_fill_iter_init (pixman_image_t *image,
}
iter->get_scanline = _pixman_iter_get_scanline_noop;
+ return flags & ~ITER_ON_DEST;
}
static uint32_t
diff --git a/pixman/pixman-utils.c b/pixman/pixman-utils.c
index cb4e621..5c2aa2b 100644
--- a/pixman/pixman-utils.c
+++ b/pixman/pixman-utils.c
@@ -168,9 +168,10 @@ pixman_contract (uint32_t * dst,
}
uint32_t *
-_pixman_iter_get_scanline_noop (pixman_iter_t *iter, const uint32_t *mask)
+_pixman_iter_get_scanline_noop (pixman_iter_t *iter, uint32_t *buffer, const uint32_t *mask)
{
- return iter->buffer;
+ /* Assumption: iter->buffer == buffer */
+ return buffer;
}
#define N_TMP_BOXES (16)