[Pixman] [PATCH 1/2] general: Ensure that iter buffers are aligned to 16 bytes
Søren Sandmann
sandmann at cs.au.dk
Wed Aug 28 13:01:26 PDT 2013
From: Søren Sandmann Pedersen <ssp at redhat.com>
At the moment iter buffers are only guaranteed to be aligned to an 8
byte bit boundary. It is useful for SIMD implementations to be able to
assume that these buffers are aligned to 16 bytes, so ensure this.
---
pixman/pixman-general.c | 22 +++++++++++++++-------
pixman/pixman-private.h | 3 +++
pixman/pixman-utils.c | 9 +++++++++
3 files changed, 27 insertions(+), 7 deletions(-)
diff --git a/pixman/pixman-general.c b/pixman/pixman-general.c
index 6310bff..60566c6 100644
--- a/pixman/pixman-general.c
+++ b/pixman/pixman-general.c
@@ -114,7 +114,7 @@ general_composite_rect (pixman_implementation_t *imp,
pixman_composite_info_t *info)
{
PIXMAN_COMPOSITE_ARGS (info);
- uint64_t stack_scanline_buffer[(SCANLINE_BUFFER_LENGTH * 3 + 7) / 8];
+ uint8_t stack_scanline_buffer[SCANLINE_BUFFER_LENGTH];
uint8_t *scanline_buffer = (uint8_t *) stack_scanline_buffer;
uint8_t *src_buffer, *mask_buffer, *dest_buffer;
pixman_iter_t src_iter, mask_iter, dest_iter;
@@ -137,17 +137,25 @@ general_composite_rect (pixman_implementation_t *imp,
Bpp = 16;
}
- if (width * Bpp > SCANLINE_BUFFER_LENGTH)
+#define ALIGN(addr) \
+ ((uint8_t *)((((unsigned long)(addr)) + 15) & (~15)))
+
+ src_buffer = ALIGN (scanline_buffer);
+ mask_buffer = ALIGN (src_buffer + width * Bpp);
+ dest_buffer = ALIGN (mask_buffer + width * Bpp);
+
+ if (ALIGN (dest_buffer + width * Bpp) >
+ scanline_buffer + SCANLINE_BUFFER_LENGTH)
{
- scanline_buffer = pixman_malloc_abc (width, 3, Bpp);
+ scanline_buffer = pixman_malloc_ab_plus_c (width, Bpp * 3, 32 * 3);
if (!scanline_buffer)
return;
- }
- src_buffer = scanline_buffer;
- mask_buffer = src_buffer + width * Bpp;
- dest_buffer = mask_buffer + width * Bpp;
+ src_buffer = ALIGN (scanline_buffer);
+ mask_buffer = ALIGN (src_buffer + width * Bpp);
+ dest_buffer = ALIGN (mask_buffer + width * Bpp);
+ }
if (width_flag == ITER_WIDE)
{
diff --git a/pixman/pixman-private.h b/pixman/pixman-private.h
index 9646605..0afabad 100644
--- a/pixman/pixman-private.h
+++ b/pixman/pixman-private.h
@@ -787,6 +787,9 @@ pixman_malloc_ab (unsigned int n, unsigned int b);
void *
pixman_malloc_abc (unsigned int a, unsigned int b, unsigned int c);
+void *
+pixman_malloc_ab_plus_c (unsigned int a, unsigned int b, unsigned int c);
+
pixman_bool_t
_pixman_multiply_overflows_size (size_t a, size_t b);
diff --git a/pixman/pixman-utils.c b/pixman/pixman-utils.c
index 98723a8..4a3a835 100644
--- a/pixman/pixman-utils.c
+++ b/pixman/pixman-utils.c
@@ -49,6 +49,15 @@ _pixman_addition_overflows_int (unsigned int a, unsigned int b)
}
void *
+pixman_malloc_ab_plus_c (unsigned int a, unsigned int b, unsigned int c)
+{
+ if (!b || a >= INT32_MAX / b || (a * b) > INT32_MAX - c)
+ return NULL;
+
+ return malloc (a * b + c);
+}
+
+void *
pixman_malloc_ab (unsigned int a,
unsigned int b)
{
--
1.7.1
More information about the Pixman
mailing list