aboutsummaryrefslogtreecommitdiff
path: root/pixman
diff options
context:
space:
mode:
Diffstat (limited to 'pixman')
-rw-r--r--pixman/configure.ac27
-rw-r--r--pixman/pixman/pixman-arm-common.h586
-rw-r--r--pixman/pixman/pixman-arm-neon-asm.S100
-rw-r--r--pixman/pixman/pixman-arm-neon-asm.h216
-rw-r--r--pixman/pixman/pixman-arm-neon.c30
-rw-r--r--pixman/pixman/pixman-arm-simd-asm.S70
-rw-r--r--pixman/pixman/pixman-arm-simd.c7
-rw-r--r--pixman/pixman/pixman-conical-gradient.c17
-rw-r--r--pixman/pixman/pixman-image.c75
-rw-r--r--pixman/pixman/pixman-linear-gradient.c30
-rw-r--r--pixman/pixman/pixman-mmx.c4
-rw-r--r--pixman/pixman/pixman-private.h15
-rw-r--r--pixman/pixman/pixman-radial-gradient.c19
-rw-r--r--pixman/pixman/pixman.c90
-rw-r--r--pixman/pixman/pixman.h22
-rw-r--r--pixman/test/Makefile.am2
-rw-r--r--pixman/test/window-test.c173
17 files changed, 814 insertions, 669 deletions
diff --git a/pixman/configure.ac b/pixman/configure.ac
index ad975f494..d1265ab11 100644
--- a/pixman/configure.ac
+++ b/pixman/configure.ac
@@ -740,6 +740,33 @@ AC_SUBST(HAVE_PTHREAD_SETSPECIFIC)
AC_SUBST(PTHREAD_LDFLAGS)
AC_SUBST(PTHREAD_LIBS)
+dnl =====================================
+dnl __attribute__((constructor))
+
+support_for_attribute_constructor=no
+
+AC_MSG_CHECKING(for __attribute__((constructor)))
+AC_LINK_IFELSE([
+#if defined(__GNUC__) && (__GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 7))
+/* attribute 'constructor' is supported since gcc 2.7, but some compilers
+ * may only pretend to be gcc, so let's try to actually use it
+ */
+static int x = 1;
+static void __attribute__((constructor)) constructor_function () { x = 0; }
+int main (void) { return x; }
+#else
+#error not gcc or gcc version is older than 2.7
+#endif
+], support_for_attribute_constructor=yes)
+
+if test x$support_for_attribute_constructor = xyes; then
+ AC_DEFINE([TOOLCHAIN_SUPPORTS_ATTRIBUTE_CONSTRUCTOR],
+ [],[Whether the tool chain supports __attribute__((constructor))])
+fi
+
+AC_MSG_RESULT($support_for_attribute_constructor)
+AC_SUBST(TOOLCHAIN_SUPPORTS_ATTRIBUTE_CONSTRUCTOR)
+
AC_OUTPUT([pixman-1.pc
pixman-1-uninstalled.pc
Makefile
diff --git a/pixman/pixman/pixman-arm-common.h b/pixman/pixman/pixman-arm-common.h
index 8d432b1de..08f34cc20 100644
--- a/pixman/pixman/pixman-arm-common.h
+++ b/pixman/pixman/pixman-arm-common.h
@@ -1,273 +1,313 @@
-/*
- * Copyright © 2010 Nokia Corporation
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * Author: Siarhei Siamashka (siarhei.siamashka@nokia.com)
- */
-
-#ifndef PIXMAN_ARM_COMMON_H
-#define PIXMAN_ARM_COMMON_H
-
-/* Define some macros which can expand into proxy functions between
- * ARM assembly optimized functions and the rest of pixman fast path API.
- *
- * All the low level ARM assembly functions have to use ARM EABI
- * calling convention and take up to 8 arguments:
- * width, height, dst, dst_stride, src, src_stride, mask, mask_stride
- *
- * The arguments are ordered with the most important coming first (the
- * first 4 arguments are passed to function in registers, the rest are
- * on stack). The last arguments are optional, for example if the
- * function is not using mask, then 'mask' and 'mask_stride' can be
- * omitted when doing a function call.
- *
- * Arguments 'src' and 'mask' contain either a pointer to the top left
- * pixel of the composited rectangle or a pixel color value depending
- * on the function type. In the case of just a color value (solid source
- * or mask), the corresponding stride argument is unused.
- */
-
-#define PIXMAN_ARM_BIND_FAST_PATH_SRC_DST(cputype, name, \
- src_type, src_cnt, \
- dst_type, dst_cnt) \
-void \
-pixman_composite_##name##_asm_##cputype (int32_t w, \
- int32_t h, \
- dst_type *dst, \
- int32_t dst_stride, \
- src_type *src, \
- int32_t src_stride); \
- \
-static void \
-cputype##_composite_##name (pixman_implementation_t *imp, \
- pixman_op_t op, \
- pixman_image_t * src_image, \
- pixman_image_t * mask_image, \
- pixman_image_t * dst_image, \
- int32_t src_x, \
- int32_t src_y, \
- int32_t mask_x, \
- int32_t mask_y, \
- int32_t dest_x, \
- int32_t dest_y, \
- int32_t width, \
- int32_t height) \
-{ \
- dst_type *dst_line; \
- src_type *src_line; \
- int32_t dst_stride, src_stride; \
- \
- PIXMAN_IMAGE_GET_LINE (src_image, src_x, src_y, src_type, \
- src_stride, src_line, src_cnt); \
- PIXMAN_IMAGE_GET_LINE (dst_image, dest_x, dest_y, dst_type, \
- dst_stride, dst_line, dst_cnt); \
- \
- pixman_composite_##name##_asm_##cputype (width, height, \
- dst_line, dst_stride, \
- src_line, src_stride); \
-}
-
-#define PIXMAN_ARM_BIND_FAST_PATH_N_DST(cputype, name, \
- dst_type, dst_cnt) \
-void \
-pixman_composite_##name##_asm_##cputype (int32_t w, \
- int32_t h, \
- dst_type *dst, \
- int32_t dst_stride, \
- uint32_t src); \
- \
-static void \
-cputype##_composite_##name (pixman_implementation_t *imp, \
- pixman_op_t op, \
- pixman_image_t * src_image, \
- pixman_image_t * mask_image, \
- pixman_image_t * dst_image, \
- int32_t src_x, \
- int32_t src_y, \
- int32_t mask_x, \
- int32_t mask_y, \
- int32_t dest_x, \
- int32_t dest_y, \
- int32_t width, \
- int32_t height) \
-{ \
- dst_type *dst_line; \
- int32_t dst_stride; \
- uint32_t src; \
- \
- src = _pixman_image_get_solid (src_image, dst_image->bits.format); \
- \
- if (src == 0) \
- return; \
- \
- PIXMAN_IMAGE_GET_LINE (dst_image, dest_x, dest_y, dst_type, \
- dst_stride, dst_line, dst_cnt); \
- \
- pixman_composite_##name##_asm_##cputype (width, height, \
- dst_line, dst_stride, \
- src); \
-}
-
-#define PIXMAN_ARM_BIND_FAST_PATH_N_MASK_DST(cputype, name, \
- mask_type, mask_cnt, \
- dst_type, dst_cnt) \
-void \
-pixman_composite_##name##_asm_##cputype (int32_t w, \
- int32_t h, \
- dst_type *dst, \
- int32_t dst_stride, \
- uint32_t src, \
- int32_t unused, \
- mask_type *mask, \
- int32_t mask_stride); \
- \
-static void \
-cputype##_composite_##name (pixman_implementation_t *imp, \
- pixman_op_t op, \
- pixman_image_t * src_image, \
- pixman_image_t * mask_image, \
- pixman_image_t * dst_image, \
- int32_t src_x, \
- int32_t src_y, \
- int32_t mask_x, \
- int32_t mask_y, \
- int32_t dest_x, \
- int32_t dest_y, \
- int32_t width, \
- int32_t height) \
-{ \
- dst_type *dst_line; \
- mask_type *mask_line; \
- int32_t dst_stride, mask_stride; \
- uint32_t src; \
- \
- src = _pixman_image_get_solid (src_image, dst_image->bits.format); \
- \
- if (src == 0) \
- return; \
- \
- PIXMAN_IMAGE_GET_LINE (dst_image, dest_x, dest_y, dst_type, \
- dst_stride, dst_line, dst_cnt); \
- PIXMAN_IMAGE_GET_LINE (mask_image, mask_x, mask_y, mask_type, \
- mask_stride, mask_line, mask_cnt); \
- \
- pixman_composite_##name##_asm_##cputype (width, height, \
- dst_line, dst_stride, \
- src, 0, \
- mask_line, mask_stride); \
-}
-
-#define PIXMAN_ARM_BIND_FAST_PATH_SRC_N_DST(cputype, name, \
- src_type, src_cnt, \
- dst_type, dst_cnt) \
-void \
-pixman_composite_##name##_asm_##cputype (int32_t w, \
- int32_t h, \
- dst_type *dst, \
- int32_t dst_stride, \
- src_type *src, \
- int32_t src_stride, \
- uint32_t mask); \
- \
-static void \
-cputype##_composite_##name (pixman_implementation_t *imp, \
- pixman_op_t op, \
- pixman_image_t * src_image, \
- pixman_image_t * mask_image, \
- pixman_image_t * dst_image, \
- int32_t src_x, \
- int32_t src_y, \
- int32_t mask_x, \
- int32_t mask_y, \
- int32_t dest_x, \
- int32_t dest_y, \
- int32_t width, \
- int32_t height) \
-{ \
- dst_type *dst_line; \
- src_type *src_line; \
- int32_t dst_stride, src_stride; \
- uint32_t mask; \
- \
- mask = _pixman_image_get_solid (mask_image, dst_image->bits.format);\
- \
- if (mask == 0) \
- return; \
- \
- PIXMAN_IMAGE_GET_LINE (dst_image, dest_x, dest_y, dst_type, \
- dst_stride, dst_line, dst_cnt); \
- PIXMAN_IMAGE_GET_LINE (src_image, src_x, src_y, src_type, \
- src_stride, src_line, src_cnt); \
- \
- pixman_composite_##name##_asm_##cputype (width, height, \
- dst_line, dst_stride, \
- src_line, src_stride, \
- mask); \
-}
-
-#define PIXMAN_ARM_BIND_FAST_PATH_SRC_MASK_DST(cputype, name, \
- src_type, src_cnt, \
- mask_type, mask_cnt, \
- dst_type, dst_cnt) \
-void \
-pixman_composite_##name##_asm_##cputype (int32_t w, \
- int32_t h, \
- dst_type *dst, \
- int32_t dst_stride, \
- src_type *src, \
- int32_t src_stride, \
- mask_type *mask, \
- int32_t mask_stride); \
- \
-static void \
-cputype##_composite_##name (pixman_implementation_t *imp, \
- pixman_op_t op, \
- pixman_image_t * src_image, \
- pixman_image_t * mask_image, \
- pixman_image_t * dst_image, \
- int32_t src_x, \
- int32_t src_y, \
- int32_t mask_x, \
- int32_t mask_y, \
- int32_t dest_x, \
- int32_t dest_y, \
- int32_t width, \
- int32_t height) \
-{ \
- dst_type *dst_line; \
- src_type *src_line; \
- mask_type *mask_line; \
- int32_t dst_stride, src_stride, mask_stride; \
- \
- PIXMAN_IMAGE_GET_LINE (dst_image, dest_x, dest_y, dst_type, \
- dst_stride, dst_line, dst_cnt); \
- PIXMAN_IMAGE_GET_LINE (src_image, src_x, src_y, src_type, \
- src_stride, src_line, src_cnt); \
- PIXMAN_IMAGE_GET_LINE (mask_image, mask_x, mask_y, mask_type, \
- mask_stride, mask_line, mask_cnt); \
- \
- pixman_composite_##name##_asm_##cputype (width, height, \
- dst_line, dst_stride, \
- src_line, src_stride, \
- mask_line, mask_stride); \
-}
-
-#endif
+/*
+ * Copyright © 2010 Nokia Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Author: Siarhei Siamashka (siarhei.siamashka@nokia.com)
+ */
+
+#ifndef PIXMAN_ARM_COMMON_H
+#define PIXMAN_ARM_COMMON_H
+
+#include "pixman-fast-path.h"
+
+/* Define some macros which can expand into proxy functions between
+ * ARM assembly optimized functions and the rest of pixman fast path API.
+ *
+ * All the low level ARM assembly functions have to use ARM EABI
+ * calling convention and take up to 8 arguments:
+ * width, height, dst, dst_stride, src, src_stride, mask, mask_stride
+ *
+ * The arguments are ordered with the most important coming first (the
+ * first 4 arguments are passed to function in registers, the rest are
+ * on stack). The last arguments are optional, for example if the
+ * function is not using mask, then 'mask' and 'mask_stride' can be
+ * omitted when doing a function call.
+ *
+ * Arguments 'src' and 'mask' contain either a pointer to the top left
+ * pixel of the composited rectangle or a pixel color value depending
+ * on the function type. In the case of just a color value (solid source
+ * or mask), the corresponding stride argument is unused.
+ */
+
+#define PIXMAN_ARM_BIND_FAST_PATH_SRC_DST(cputype, name, \
+ src_type, src_cnt, \
+ dst_type, dst_cnt) \
+void \
+pixman_composite_##name##_asm_##cputype (int32_t w, \
+ int32_t h, \
+ dst_type *dst, \
+ int32_t dst_stride, \
+ src_type *src, \
+ int32_t src_stride); \
+ \
+static void \
+cputype##_composite_##name (pixman_implementation_t *imp, \
+ pixman_op_t op, \
+ pixman_image_t * src_image, \
+ pixman_image_t * mask_image, \
+ pixman_image_t * dst_image, \
+ int32_t src_x, \
+ int32_t src_y, \
+ int32_t mask_x, \
+ int32_t mask_y, \
+ int32_t dest_x, \
+ int32_t dest_y, \
+ int32_t width, \
+ int32_t height) \
+{ \
+ dst_type *dst_line; \
+ src_type *src_line; \
+ int32_t dst_stride, src_stride; \
+ \
+ PIXMAN_IMAGE_GET_LINE (src_image, src_x, src_y, src_type, \
+ src_stride, src_line, src_cnt); \
+ PIXMAN_IMAGE_GET_LINE (dst_image, dest_x, dest_y, dst_type, \
+ dst_stride, dst_line, dst_cnt); \
+ \
+ pixman_composite_##name##_asm_##cputype (width, height, \
+ dst_line, dst_stride, \
+ src_line, src_stride); \
+}
+
+#define PIXMAN_ARM_BIND_FAST_PATH_N_DST(cputype, name, \
+ dst_type, dst_cnt) \
+void \
+pixman_composite_##name##_asm_##cputype (int32_t w, \
+ int32_t h, \
+ dst_type *dst, \
+ int32_t dst_stride, \
+ uint32_t src); \
+ \
+static void \
+cputype##_composite_##name (pixman_implementation_t *imp, \
+ pixman_op_t op, \
+ pixman_image_t * src_image, \
+ pixman_image_t * mask_image, \
+ pixman_image_t * dst_image, \
+ int32_t src_x, \
+ int32_t src_y, \
+ int32_t mask_x, \
+ int32_t mask_y, \
+ int32_t dest_x, \
+ int32_t dest_y, \
+ int32_t width, \
+ int32_t height) \
+{ \
+ dst_type *dst_line; \
+ int32_t dst_stride; \
+ uint32_t src; \
+ \
+ src = _pixman_image_get_solid (src_image, dst_image->bits.format); \
+ \
+ if (src == 0) \
+ return; \
+ \
+ PIXMAN_IMAGE_GET_LINE (dst_image, dest_x, dest_y, dst_type, \
+ dst_stride, dst_line, dst_cnt); \
+ \
+ pixman_composite_##name##_asm_##cputype (width, height, \
+ dst_line, dst_stride, \
+ src); \
+}
+
+#define PIXMAN_ARM_BIND_FAST_PATH_N_MASK_DST(cputype, name, \
+ mask_type, mask_cnt, \
+ dst_type, dst_cnt) \
+void \
+pixman_composite_##name##_asm_##cputype (int32_t w, \
+ int32_t h, \
+ dst_type *dst, \
+ int32_t dst_stride, \
+ uint32_t src, \
+ int32_t unused, \
+ mask_type *mask, \
+ int32_t mask_stride); \
+ \
+static void \
+cputype##_composite_##name (pixman_implementation_t *imp, \
+ pixman_op_t op, \
+ pixman_image_t * src_image, \
+ pixman_image_t * mask_image, \
+ pixman_image_t * dst_image, \
+ int32_t src_x, \
+ int32_t src_y, \
+ int32_t mask_x, \
+ int32_t mask_y, \
+ int32_t dest_x, \
+ int32_t dest_y, \
+ int32_t width, \
+ int32_t height) \
+{ \
+ dst_type *dst_line; \
+ mask_type *mask_line; \
+ int32_t dst_stride, mask_stride; \
+ uint32_t src; \
+ \
+ src = _pixman_image_get_solid (src_image, dst_image->bits.format); \
+ \
+ if (src == 0) \
+ return; \
+ \
+ PIXMAN_IMAGE_GET_LINE (dst_image, dest_x, dest_y, dst_type, \
+ dst_stride, dst_line, dst_cnt); \
+ PIXMAN_IMAGE_GET_LINE (mask_image, mask_x, mask_y, mask_type, \
+ mask_stride, mask_line, mask_cnt); \
+ \
+ pixman_composite_##name##_asm_##cputype (width, height, \
+ dst_line, dst_stride, \
+ src, 0, \
+ mask_line, mask_stride); \
+}
+
+#define PIXMAN_ARM_BIND_FAST_PATH_SRC_N_DST(cputype, name, \
+ src_type, src_cnt, \
+ dst_type, dst_cnt) \
+void \
+pixman_composite_##name##_asm_##cputype (int32_t w, \
+ int32_t h, \
+ dst_type *dst, \
+ int32_t dst_stride, \
+ src_type *src, \
+ int32_t src_stride, \
+ uint32_t mask); \
+ \
+static void \
+cputype##_composite_##name (pixman_implementation_t *imp, \
+ pixman_op_t op, \
+ pixman_image_t * src_image, \
+ pixman_image_t * mask_image, \
+ pixman_image_t * dst_image, \
+ int32_t src_x, \
+ int32_t src_y, \
+ int32_t mask_x, \
+ int32_t mask_y, \
+ int32_t dest_x, \
+ int32_t dest_y, \
+ int32_t width, \
+ int32_t height) \
+{ \
+ dst_type *dst_line; \
+ src_type *src_line; \
+ int32_t dst_stride, src_stride; \
+ uint32_t mask; \
+ \
+ mask = _pixman_image_get_solid (mask_image, dst_image->bits.format);\
+ \
+ if (mask == 0) \
+ return; \
+ \
+ PIXMAN_IMAGE_GET_LINE (dst_image, dest_x, dest_y, dst_type, \
+ dst_stride, dst_line, dst_cnt); \
+ PIXMAN_IMAGE_GET_LINE (src_image, src_x, src_y, src_type, \
+ src_stride, src_line, src_cnt); \
+ \
+ pixman_composite_##name##_asm_##cputype (width, height, \
+ dst_line, dst_stride, \
+ src_line, src_stride, \
+ mask); \
+}
+
+#define PIXMAN_ARM_BIND_FAST_PATH_SRC_MASK_DST(cputype, name, \
+ src_type, src_cnt, \
+ mask_type, mask_cnt, \
+ dst_type, dst_cnt) \
+void \
+pixman_composite_##name##_asm_##cputype (int32_t w, \
+ int32_t h, \
+ dst_type *dst, \
+ int32_t dst_stride, \
+ src_type *src, \
+ int32_t src_stride, \
+ mask_type *mask, \
+ int32_t mask_stride); \
+ \
+static void \
+cputype##_composite_##name (pixman_implementation_t *imp, \
+ pixman_op_t op, \
+ pixman_image_t * src_image, \
+ pixman_image_t * mask_image, \
+ pixman_image_t * dst_image, \
+ int32_t src_x, \
+ int32_t src_y, \
+ int32_t mask_x, \
+ int32_t mask_y, \
+ int32_t dest_x, \
+ int32_t dest_y, \
+ int32_t width, \
+ int32_t height) \
+{ \
+ dst_type *dst_line; \
+ src_type *src_line; \
+ mask_type *mask_line; \
+ int32_t dst_stride, src_stride, mask_stride; \
+ \
+ PIXMAN_IMAGE_GET_LINE (dst_image, dest_x, dest_y, dst_type, \
+ dst_stride, dst_line, dst_cnt); \
+ PIXMAN_IMAGE_GET_LINE (src_image, src_x, src_y, src_type, \
+ src_stride, src_line, src_cnt); \
+ PIXMAN_IMAGE_GET_LINE (mask_image, mask_x, mask_y, mask_type, \
+ mask_stride, mask_line, mask_cnt); \
+ \
+ pixman_composite_##name##_asm_##cputype (width, height, \
+ dst_line, dst_stride, \
+ src_line, src_stride, \
+ mask_line, mask_stride); \
+}
+
+#define PIXMAN_ARM_BIND_SCALED_NEAREST_SRC_DST(cputype, name, op, \
+ src_type, dst_type) \
+void \
+pixman_scaled_nearest_scanline_##name##_##op##_asm_##cputype ( \
+ int32_t w, \
+ dst_type * dst, \
+ src_type * src, \
+ pixman_fixed_t vx, \
+ pixman_fixed_t unit_x);\
+ \
+static force_inline void \
+scaled_nearest_scanline_##cputype##_##name##_##op (dst_type * pd, \
+ src_type * ps, \
+ int32_t w, \
+ pixman_fixed_t vx, \
+ pixman_fixed_t unit_x, \
+ pixman_fixed_t max_vx) \
+{ \
+ pixman_scaled_nearest_scanline_##name##_##op##_asm_##cputype (w, pd, ps, \
+ vx, unit_x);\
+} \
+ \
+FAST_NEAREST_MAINLOOP (cputype##_##name##_cover_##op, \
+ scaled_nearest_scanline_##cputype##_##name##_##op, \
+ src_type, dst_type, COVER) \
+FAST_NEAREST_MAINLOOP (cputype##_##name##_none_##op, \
+ scaled_nearest_scanline_##cputype##_##name##_##op, \
+ src_type, dst_type, NONE) \
+FAST_NEAREST_MAINLOOP (cputype##_##name##_pad_##op, \
+ scaled_nearest_scanline_##cputype##_##name##_##op, \
+ src_type, dst_type, PAD)
+
+/* Provide entries for the fast path table */
+#define PIXMAN_ARM_SIMPLE_NEAREST_FAST_PATH(op,s,d,func) \
+ SIMPLE_NEAREST_FAST_PATH_COVER (op,s,d,func), \
+ SIMPLE_NEAREST_FAST_PATH_NONE (op,s,d,func), \
+ SIMPLE_NEAREST_FAST_PATH_PAD (op,s,d,func)
+
+#endif
diff --git a/pixman/pixman/pixman-arm-neon-asm.S b/pixman/pixman/pixman-arm-neon-asm.S
index 8ddbefc87..0229bedfa 100644
--- a/pixman/pixman/pixman-arm-neon-asm.S
+++ b/pixman/pixman/pixman-arm-neon-asm.S
@@ -253,7 +253,7 @@
vld1.16 {d4, d5}, [DST_R, :128]!
vqadd.u8 q9, q0, q11
vshrn.u16 d6, q2, #8
- vld4.8 {d0, d1, d2, d3}, [SRC]!
+ fetch_src_pixblock
vshrn.u16 d7, q2, #3
vsli.u16 q2, q2, #5
vshll.u8 q14, d16, #8
@@ -295,7 +295,7 @@
pixman_composite_over_8888_0565_process_pixblock_tail
vst1.16 {d28, d29}, [DST_W, :128]!
vld1.16 {d4, d5}, [DST_R, :128]!
- vld4.32 {d0, d1, d2, d3}, [SRC]!
+ fetch_src_pixblock
pixman_composite_over_8888_0565_process_pixblock_head
cache_preload 8, 8
.endm
@@ -433,7 +433,7 @@ generate_composite_function \
vsri.u16 q14, q8, #5
PF add PF_X, PF_X, #8
PF tst PF_CTL, #0xF
- vld4.8 {d0, d1, d2, d3}, [SRC]!
+ fetch_src_pixblock
PF addne PF_X, PF_X, #8
PF subne PF_CTL, PF_CTL, #1
vsri.u16 q14, q9, #11
@@ -478,7 +478,7 @@ generate_composite_function \
.macro pixman_composite_src_0565_8888_process_pixblock_tail_head
pixman_composite_src_0565_8888_process_pixblock_tail
vst4.8 {d28, d29, d30, d31}, [DST_W, :128]!
- vld1.16 {d0, d1}, [SRC]!
+ fetch_src_pixblock
pixman_composite_src_0565_8888_process_pixblock_head
cache_preload 8, 8
.endm
@@ -505,7 +505,7 @@ generate_composite_function \
.endm
.macro pixman_composite_add_8_8_process_pixblock_tail_head
- vld1.8 {d0, d1, d2, d3}, [SRC]!
+ fetch_src_pixblock
PF add PF_X, PF_X, #32
PF tst PF_CTL, #0xF
vld1.8 {d4, d5, d6, d7}, [DST_R, :128]!
@@ -537,13 +537,13 @@ generate_composite_function \
/******************************************************************************/
.macro pixman_composite_add_8888_8888_process_pixblock_tail_head
- vld1.8 {d0, d1, d2, d3}, [SRC]!
+ fetch_src_pixblock
PF add PF_X, PF_X, #8
PF tst PF_CTL, #0xF
- vld1.8 {d4, d5, d6, d7}, [DST_R, :128]!
+ vld1.32 {d4, d5, d6, d7}, [DST_R, :128]!
PF addne PF_X, PF_X, #8
PF subne PF_CTL, PF_CTL, #1
- vst1.8 {d28, d29, d30, d31}, [DST_W, :128]!
+ vst1.32 {d28, d29, d30, d31}, [DST_W, :128]!
PF cmp PF_X, ORIG_W
PF pld, [PF_SRC, PF_X, lsl #src_bpp_shift]
PF pld, [PF_DST, PF_X, lsl #dst_bpp_shift]
@@ -613,7 +613,7 @@ generate_composite_function_single_scanline \
PF cmp PF_X, ORIG_W
vraddhn.u16 d30, q12, q10
vraddhn.u16 d31, q13, q11
- vld4.8 {d0, d1, d2, d3}, [SRC]!
+ fetch_src_pixblock
PF pld, [PF_SRC, PF_X, lsl #src_bpp_shift]
vmvn.8 d22, d3
PF pld, [PF_DST, PF_X, lsl #dst_bpp_shift]
@@ -667,7 +667,7 @@ generate_composite_function_single_scanline \
vraddhn.u16 d31, q13, q11
vqadd.u8 q14, q0, q14
vqadd.u8 q15, q1, q15
- vld4.8 {d0, d1, d2, d3}, [SRC]!
+ fetch_src_pixblock
PF pld, [PF_SRC, PF_X, lsl #src_bpp_shift]
vmvn.8 d22, d3
PF pld, [PF_DST, PF_X, lsl #dst_bpp_shift]
@@ -887,7 +887,7 @@ generate_composite_function \
.macro pixman_composite_over_8888_8_0565_process_pixblock_tail_head
vld1.16 {d4, d5}, [DST_R, :128]!
pixman_composite_over_n_8_0565_process_pixblock_tail
- vld4.8 {d8, d9, d10, d11}, [SRC]!
+ fetch_src_pixblock
cache_preload 8, 8
vld1.8 {d24}, [MASK]!
pixman_composite_over_n_8_0565_process_pixblock_head
@@ -919,7 +919,7 @@ generate_composite_function \
.macro pixman_composite_src_0565_0565_process_pixblock_tail_head
vst1.16 {d0, d1, d2, d3}, [DST_W, :128]!
- vld1.16 {d0, d1, d2, d3}, [SRC]!
+ fetch_src_pixblock
cache_preload 16, 16
.endm
@@ -1065,7 +1065,7 @@ generate_composite_function \
.macro pixman_composite_src_8888_8888_process_pixblock_tail_head
vst1.32 {d0, d1, d2, d3}, [DST_W, :128]!
- vld1.32 {d0, d1, d2, d3}, [SRC]!
+ fetch_src_pixblock
cache_preload 8, 8
.endm
@@ -1096,7 +1096,7 @@ generate_composite_function \
.macro pixman_composite_src_x888_8888_process_pixblock_tail_head
vst1.32 {d0, d1, d2, d3}, [DST_W, :128]!
- vld1.32 {d0, d1, d2, d3}, [SRC]!
+ fetch_src_pixblock
vorr q0, q0, q2
vorr q1, q1, q2
cache_preload 8, 8
@@ -1395,7 +1395,7 @@ generate_composite_function \
vst1.8 {d28, d29, d30, d31}, [DST_W, :128]!
vld1.8 {d4, d5, d6, d7}, [DST_R, :128]!
vld1.8 {d24, d25, d26, d27}, [MASK]!
- vld1.8 {d0, d1, d2, d3}, [SRC]!
+ fetch_src_pixblock
cache_preload 32, 32
pixman_composite_add_8_8_8_process_pixblock_head
.endm
@@ -1448,7 +1448,7 @@ generate_composite_function \
vst4.8 {d28, d29, d30, d31}, [DST_W, :128]!
vld4.8 {d4, d5, d6, d7}, [DST_R, :128]!
vld4.8 {d24, d25, d26, d27}, [MASK]!
- vld4.8 {d0, d1, d2, d3}, [SRC]!
+ fetch_src_pixblock
cache_preload 8, 8
pixman_composite_add_8888_8888_8888_process_pixblock_head
.endm
@@ -1517,7 +1517,7 @@ generate_composite_function_single_scanline \
.macro pixman_composite_out_reverse_8888_8888_8888_process_pixblock_tail_head
vld4.8 {d4, d5, d6, d7}, [DST_R, :128]!
pixman_composite_out_reverse_8888_n_8888_process_pixblock_tail
- vld4.8 {d0, d1, d2, d3}, [SRC]!
+ fetch_src_pixblock
cache_preload 8, 8
vld4.8 {d12, d13, d14, d15}, [MASK]!
pixman_composite_out_reverse_8888_n_8888_process_pixblock_head
@@ -1554,7 +1554,7 @@ generate_composite_function_single_scanline \
.macro pixman_composite_over_8888_n_8888_process_pixblock_tail_head
vld4.8 {d4, d5, d6, d7}, [DST_R, :128]!
pixman_composite_over_8888_n_8888_process_pixblock_tail
- vld4.8 {d0, d1, d2, d3}, [SRC]!
+ fetch_src_pixblock
cache_preload 8, 8
pixman_composite_over_8888_n_8888_process_pixblock_head
vst4.8 {d28, d29, d30, d31}, [DST_W, :128]!
@@ -1588,7 +1588,7 @@ generate_composite_function \
.macro pixman_composite_over_8888_8888_8888_process_pixblock_tail_head
vld4.8 {d4, d5, d6, d7}, [DST_R, :128]!
pixman_composite_over_8888_n_8888_process_pixblock_tail
- vld4.8 {d0, d1, d2, d3}, [SRC]!
+ fetch_src_pixblock
cache_preload 8, 8
vld4.8 {d12, d13, d14, d15}, [MASK]!
pixman_composite_over_8888_n_8888_process_pixblock_head
@@ -1630,7 +1630,7 @@ generate_composite_function_single_scanline \
.macro pixman_composite_over_8888_8_8888_process_pixblock_tail_head
vld4.8 {d4, d5, d6, d7}, [DST_R, :128]!
pixman_composite_over_8888_n_8888_process_pixblock_tail
- vld4.8 {d0, d1, d2, d3}, [SRC]!
+ fetch_src_pixblock
cache_preload 8, 8
vld1.8 {d15}, [MASK]!
pixman_composite_over_8888_n_8888_process_pixblock_head
@@ -1662,7 +1662,7 @@ generate_composite_function \
.macro pixman_composite_src_0888_0888_process_pixblock_tail_head
vst3.8 {d0, d1, d2}, [DST_W]!
- vld3.8 {d0, d1, d2}, [SRC]!
+ fetch_src_pixblock
cache_preload 8, 8
.endm
@@ -1692,7 +1692,7 @@ generate_composite_function \
.macro pixman_composite_src_0888_8888_rev_process_pixblock_tail_head
vst4.8 {d0, d1, d2, d3}, [DST_W]!
- vld3.8 {d0, d1, d2}, [SRC]!
+ fetch_src_pixblock
vswp d0, d2
cache_preload 8, 8
.endm
@@ -1731,7 +1731,7 @@ generate_composite_function \
.macro pixman_composite_src_0888_0565_rev_process_pixblock_tail_head
vshll.u8 q14, d0, #8
- vld3.8 {d0, d1, d2}, [SRC]!
+ fetch_src_pixblock
vsri.u16 q14, q8, #5
vsri.u16 q14, q9, #11
vshll.u8 q8, d1, #8
@@ -1777,7 +1777,7 @@ generate_composite_function \
vswp d3, d31
vrshr.u16 q12, q9, #8
vrshr.u16 q13, q10, #8
- vld4.8 {d0, d1, d2, d3}, [SRC]!
+ fetch_src_pixblock
vraddhn.u16 d30, q11, q8
PF add PF_X, PF_X, #8
PF tst PF_CTL, #0xF
@@ -1851,7 +1851,7 @@ generate_composite_function \
.macro pixman_composite_over_0565_8_0565_process_pixblock_tail_head
vld1.8 {d15}, [MASK]!
pixman_composite_over_0565_8_0565_process_pixblock_tail
- vld1.16 {d8, d9}, [SRC]!
+ fetch_src_pixblock
vld1.16 {d10, d11}, [DST_R, :128]!
cache_preload 8, 8
pixman_composite_over_0565_8_0565_process_pixblock_head
@@ -1903,7 +1903,7 @@ generate_composite_function \
.macro pixman_composite_add_0565_8_0565_process_pixblock_tail_head
vld1.8 {d15}, [MASK]!
pixman_composite_add_0565_8_0565_process_pixblock_tail
- vld1.16 {d8, d9}, [SRC]!
+ fetch_src_pixblock
vld1.16 {d10, d11}, [DST_R, :128]!
cache_preload 8, 8
pixman_composite_add_0565_8_0565_process_pixblock_head
@@ -1951,7 +1951,7 @@ generate_composite_function \
/* TODO: expand macros and do better instructions scheduling */
.macro pixman_composite_out_reverse_8_0565_process_pixblock_tail_head
- vld1.8 {d15}, [SRC]!
+ fetch_src_pixblock
pixman_composite_out_reverse_8_0565_process_pixblock_tail
vld1.16 {d10, d11}, [DST_R, :128]!
cache_preload 8, 8
@@ -1973,3 +1973,49 @@ generate_composite_function \
10, /* dst_r_basereg */ \
15, /* src_basereg */ \
0 /* mask_basereg */
+
+/******************************************************************************/
+
+generate_composite_function_nearest_scanline \
+ pixman_scaled_nearest_scanline_8888_8888_OVER_asm_neon, 32, 0, 32, \
+ FLAG_DST_READWRITE | FLAG_DEINTERLEAVE_32BPP, \
+ 8, /* number of pixels, processed in a single block */ \
+ default_init, \
+ default_cleanup, \
+ pixman_composite_over_8888_8888_process_pixblock_head, \
+ pixman_composite_over_8888_8888_process_pixblock_tail, \
+ pixman_composite_over_8888_8888_process_pixblock_tail_head
+
+generate_composite_function_nearest_scanline \
+ pixman_scaled_nearest_scanline_8888_0565_OVER_asm_neon, 32, 0, 16, \
+ FLAG_DST_READWRITE | FLAG_DEINTERLEAVE_32BPP, \
+ 8, /* number of pixels, processed in a single block */ \
+ default_init, \
+ default_cleanup, \
+ pixman_composite_over_8888_0565_process_pixblock_head, \
+ pixman_composite_over_8888_0565_process_pixblock_tail, \
+ pixman_composite_over_8888_0565_process_pixblock_tail_head, \
+ 28, /* dst_w_basereg */ \
+ 4, /* dst_r_basereg */ \
+ 0, /* src_basereg */ \
+ 24 /* mask_basereg */
+
+generate_composite_function_nearest_scanline \
+ pixman_scaled_nearest_scanline_8888_0565_SRC_asm_neon, 32, 0, 16, \
+ FLAG_DST_WRITEONLY | FLAG_DEINTERLEAVE_32BPP, \
+ 8, /* number of pixels, processed in a single block */ \
+ default_init, \
+ default_cleanup, \
+ pixman_composite_src_8888_0565_process_pixblock_head, \
+ pixman_composite_src_8888_0565_process_pixblock_tail, \
+ pixman_composite_src_8888_0565_process_pixblock_tail_head
+
+generate_composite_function_nearest_scanline \
+ pixman_scaled_nearest_scanline_0565_8888_SRC_asm_neon, 16, 0, 32, \
+ FLAG_DST_WRITEONLY | FLAG_DEINTERLEAVE_32BPP, \
+ 8, /* number of pixels, processed in a single block */ \
+ default_init, \
+ default_cleanup, \
+ pixman_composite_src_0565_8888_process_pixblock_head, \
+ pixman_composite_src_0565_8888_process_pixblock_tail, \
+ pixman_composite_src_0565_8888_process_pixblock_tail_head
diff --git a/pixman/pixman/pixman-arm-neon-asm.h b/pixman/pixman/pixman-arm-neon-asm.h
index 84706d7fe..1d8a31c1e 100644
--- a/pixman/pixman/pixman-arm-neon-asm.h
+++ b/pixman/pixman/pixman-arm-neon-asm.h
@@ -205,6 +205,121 @@
.endif
.endm
+/*
+ * Pixel fetcher for nearest scaling (needs TMP1, TMP2, VX, UNIT_X register
+ * aliases to be defined)
+ */
+.macro pixld1_s elem_size, reg1, mem_operand
+.if elem_size == 16
+ mov TMP1, VX, asr #16
+ add VX, VX, UNIT_X
+ add TMP1, mem_operand, TMP1, asl #1
+ mov TMP2, VX, asr #16
+ add VX, VX, UNIT_X
+ add TMP2, mem_operand, TMP2, asl #1
+ vld1.16 {d&reg1&[0]}, [TMP1, :16]
+ mov TMP1, VX, asr #16
+ add VX, VX, UNIT_X
+ add TMP1, mem_operand, TMP1, asl #1
+ vld1.16 {d&reg1&[1]}, [TMP2, :16]
+ mov TMP2, VX, asr #16
+ add VX, VX, UNIT_X
+ add TMP2, mem_operand, TMP2, asl #1
+ vld1.16 {d&reg1&[2]}, [TMP1, :16]
+ vld1.16 {d&reg1&[3]}, [TMP2, :16]
+.elseif elem_size == 32
+ mov TMP1, VX, asr #16
+ add VX, VX, UNIT_X
+ add TMP1, mem_operand, TMP1, asl #2
+ mov TMP2, VX, asr #16
+ add VX, VX, UNIT_X
+ add TMP2, mem_operand, TMP2, asl #2
+ vld1.32 {d&reg1&[0]}, [TMP1, :32]
+ vld1.32 {d&reg1&[1]}, [TMP2, :32]
+.else
+ .error "unsupported"
+.endif
+.endm
+
+.macro pixld2_s elem_size, reg1, reg2, mem_operand
+.if elem_size == 32
+ mov TMP1, VX, asr #16
+ add VX, VX, UNIT_X, asl #1
+ add TMP1, mem_operand, TMP1, asl #2
+ mov TMP2, VX, asr #16
+ sub VX, VX, UNIT_X
+ add TMP2, mem_operand, TMP2, asl #2
+ vld1.32 {d&reg1&[0]}, [TMP1, :32]
+ mov TMP1, VX, asr #16
+ add VX, VX, UNIT_X, asl #1
+ add TMP1, mem_operand, TMP1, asl #2
+ vld1.32 {d&reg2&[0]}, [TMP2, :32]
+ mov TMP2, VX, asr #16
+ add VX, VX, UNIT_X
+ add TMP2, mem_operand, TMP2, asl #2
+ vld1.32 {d&reg1&[1]}, [TMP1, :32]
+ vld1.32 {d&reg2&[1]}, [TMP2, :32]
+.else
+ pixld1_s elem_size, reg1, mem_operand
+ pixld1_s elem_size, reg2, mem_operand
+.endif
+.endm
+
+.macro pixld0_s elem_size, reg1, idx, mem_operand
+.if elem_size == 16
+ mov TMP1, VX, asr #16
+ add VX, VX, UNIT_X
+ add TMP1, mem_operand, TMP1, asl #1
+ vld1.16 {d&reg1&[idx]}, [TMP1, :16]
+.elseif elem_size == 32
+ mov TMP1, VX, asr #16
+ add VX, VX, UNIT_X
+ add TMP1, mem_operand, TMP1, asl #2
+ vld1.32 {d&reg1&[idx]}, [TMP1, :32]
+.endif
+.endm
+
+.macro pixld_s_internal numbytes, elem_size, basereg, mem_operand
+.if numbytes == 32
+ pixld2_s elem_size, %(basereg+4), %(basereg+5), mem_operand
+ pixld2_s elem_size, %(basereg+6), %(basereg+7), mem_operand
+ pixdeinterleave elem_size, %(basereg+4)
+.elseif numbytes == 16
+ pixld2_s elem_size, %(basereg+2), %(basereg+3), mem_operand
+.elseif numbytes == 8
+ pixld1_s elem_size, %(basereg+1), mem_operand
+.elseif numbytes == 4
+ .if elem_size == 32
+ pixld0_s elem_size, %(basereg+0), 1, mem_operand
+ .elseif elem_size == 16
+ pixld0_s elem_size, %(basereg+0), 2, mem_operand
+ pixld0_s elem_size, %(basereg+0), 3, mem_operand
+ .else
+ pixld0_s elem_size, %(basereg+0), 4, mem_operand
+ pixld0_s elem_size, %(basereg+0), 5, mem_operand
+ pixld0_s elem_size, %(basereg+0), 6, mem_operand
+ pixld0_s elem_size, %(basereg+0), 7, mem_operand
+ .endif
+.elseif numbytes == 2
+ .if elem_size == 16
+ pixld0_s elem_size, %(basereg+0), 1, mem_operand
+ .else
+ pixld0_s elem_size, %(basereg+0), 2, mem_operand
+ pixld0_s elem_size, %(basereg+0), 3, mem_operand
+ .endif
+.elseif numbytes == 1
+ pixld0_s elem_size, %(basereg+0), 1, mem_operand
+.else
+ .error "unsupported size: numbytes"
+.endif
+.endm
+
+.macro pixld_s numpix, bpp, basereg, mem_operand
+.if bpp > 0
+ pixld_s_internal %(numpix * bpp / 8), %(bpp), basereg, mem_operand
+.endif
+.endm
+
.macro vuzp8 reg1, reg2
vuzp.8 d&reg1, d&reg2
.endm
@@ -335,7 +450,7 @@ local skip1
tst DST_R, #lowbit
beq 1f
.endif
- pixld (lowbit * 8 / dst_w_bpp), src_bpp, src_basereg, SRC
+ pixld_src (lowbit * 8 / dst_w_bpp), src_bpp, src_basereg, SRC
pixld (lowbit * 8 / dst_w_bpp), mask_bpp, mask_basereg, MASK
.if dst_r_bpp > 0
pixld_a (lowbit * 8 / dst_r_bpp), dst_r_bpp, dst_r_basereg, DST_R
@@ -397,7 +512,7 @@ local skip1
.if pixblock_size > chunk_size
tst W, #chunk_size
beq 1f
- pixld chunk_size, src_bpp, src_basereg, SRC
+ pixld_src chunk_size, src_bpp, src_basereg, SRC
pixld chunk_size, mask_bpp, mask_basereg, MASK
.if dst_aligned_flag != 0
pixld_a chunk_size, dst_r_bpp, dst_r_basereg, DST_R
@@ -531,6 +646,13 @@ fname:
.set src_basereg, src_basereg_
.set mask_basereg, mask_basereg_
+ .macro pixld_src x:vararg
+ pixld x
+ .endm
+ .macro fetch_src_pixblock
+ pixld_src pixblock_size, src_bpp, \
+ (src_basereg - pixblock_size * src_bpp / 64), SRC
+ .endm
/*
* Assign symbolic names to registers
*/
@@ -696,8 +818,7 @@ fname:
/* Implement "head (tail_head) ... (tail_head) tail" loop pattern */
pixld_a pixblock_size, dst_r_bpp, \
(dst_r_basereg - pixblock_size * dst_r_bpp / 64), DST_R
- pixld pixblock_size, src_bpp, \
- (src_basereg - pixblock_size * src_bpp / 64), SRC
+ fetch_src_pixblock
pixld pixblock_size, mask_bpp, \
(mask_basereg - pixblock_size * mask_bpp / 64), MASK
PF add PF_X, PF_X, #pixblock_size
@@ -739,8 +860,7 @@ fname:
beq 1f
pixld pixblock_size, dst_r_bpp, \
(dst_r_basereg - pixblock_size * dst_r_bpp / 64), DST_R
- pixld pixblock_size, src_bpp, \
- (src_basereg - pixblock_size * src_bpp / 64), SRC
+ fetch_src_pixblock
pixld pixblock_size, mask_bpp, \
(mask_basereg - pixblock_size * mask_bpp / 64), MASK
process_pixblock_head
@@ -761,6 +881,9 @@ fname:
cleanup
pop {r4-r12, pc} /* exit */
+ .purgem fetch_src_pixblock
+ .purgem pixld_src
+
.unreq SRC
.unreq MASK
.unreq DST_R
@@ -784,7 +907,8 @@ fname:
* A simplified variant of function generation template for a single
* scanline processing (for implementing pixman combine functions)
*/
-.macro generate_composite_function_single_scanline fname, \
+.macro generate_composite_function_scanline use_nearest_scaling, \
+ fname, \
src_bpp_, \
mask_bpp_, \
dst_w_bpp_, \
@@ -821,15 +945,45 @@ fname:
.set dst_r_basereg, dst_r_basereg_
.set src_basereg, src_basereg_
.set mask_basereg, mask_basereg_
-/*
- * Assign symbolic names to registers
- */
+
+.if use_nearest_scaling != 0
+ /*
+ * Assign symbolic names to registers for nearest scaling
+ */
+ W .req r0
+ DST_W .req r1
+ SRC .req r2
+ VX .req r3
+ UNIT_X .req ip
+ MASK .req lr
+ TMP1 .req r4
+ TMP2 .req r5
+ DST_R .req r6
+
+ .macro pixld_src x:vararg
+ pixld_s x
+ .endm
+
+ ldr UNIT_X, [sp]
+ push {r4-r6, lr}
+ .if mask_bpp != 0
+ ldr MASK, [sp, #(16 + 4)]
+ .endif
+.else
+ /*
+ * Assign symbolic names to registers
+ */
W .req r0 /* width (is updated during processing) */
DST_W .req r1 /* destination buffer pointer for writes */
SRC .req r2 /* source buffer pointer */
DST_R .req ip /* destination buffer pointer for reads */
MASK .req r3 /* mask pointer */
+ .macro pixld_src x:vararg
+ pixld x
+ .endm
+.endif
+
.if (((flags) & FLAG_DST_READWRITE) != 0)
.set dst_r_bpp, dst_w_bpp
.else
@@ -841,6 +995,11 @@ fname:
.set DEINTERLEAVE_32BPP_ENABLED, 0
.endif
+ .macro fetch_src_pixblock
+ pixld_src pixblock_size, src_bpp, \
+ (src_basereg - pixblock_size * src_bpp / 64), SRC
+ .endm
+
init
mov DST_R, DST_W
@@ -857,8 +1016,7 @@ fname:
/* Implement "head (tail_head) ... (tail_head) tail" loop pattern */
pixld_a pixblock_size, dst_r_bpp, \
(dst_r_basereg - pixblock_size * dst_r_bpp / 64), DST_R
- pixld pixblock_size, src_bpp, \
- (src_basereg - pixblock_size * src_bpp / 64), SRC
+ fetch_src_pixblock
pixld pixblock_size, mask_bpp, \
(mask_basereg - pixblock_size * mask_bpp / 64), MASK
process_pixblock_head
@@ -880,7 +1038,11 @@ fname:
process_pixblock_tail_head
cleanup
- bx lr /* exit */
+.if use_nearest_scaling != 0
+ pop {r4-r6, pc} /* exit */
+.else
+ bx lr /* exit */
+.endif
8:
/* Process the remaining trailing pixels in the scanline (dst unaligned) */
process_trailing_pixels 0, 0, \
@@ -889,6 +1051,21 @@ fname:
process_pixblock_tail_head
cleanup
+
+.if use_nearest_scaling != 0
+ pop {r4-r6, pc} /* exit */
+
+ .unreq DST_R
+ .unreq SRC
+ .unreq W
+ .unreq VX
+ .unreq UNIT_X
+ .unreq TMP1
+ .unreq TMP2
+ .unreq DST_W
+ .unreq MASK
+
+.else
bx lr /* exit */
.unreq SRC
@@ -896,9 +1073,22 @@ fname:
.unreq DST_R
.unreq DST_W
.unreq W
+.endif
+
+ .purgem fetch_src_pixblock
+ .purgem pixld_src
+
.endfunc
.endm
+.macro generate_composite_function_single_scanline x:vararg
+ generate_composite_function_scanline 0, x
+.endm
+
+.macro generate_composite_function_nearest_scanline x:vararg
+ generate_composite_function_scanline 1, x
+.endm
+
/* Default prologue/epilogue, nothing special needs to be done */
.macro default_init
diff --git a/pixman/pixman/pixman-arm-neon.c b/pixman/pixman/pixman-arm-neon.c
index d22922a4a..858bb071e 100644
--- a/pixman/pixman/pixman-arm-neon.c
+++ b/pixman/pixman/pixman-arm-neon.c
@@ -97,6 +97,15 @@ PIXMAN_ARM_BIND_FAST_PATH_SRC_MASK_DST (neon, over_8888_8_0565,
PIXMAN_ARM_BIND_FAST_PATH_SRC_MASK_DST (neon, over_0565_8_0565,
uint16_t, 1, uint8_t, 1, uint16_t, 1)
+PIXMAN_ARM_BIND_SCALED_NEAREST_SRC_DST (neon, 8888_8888, OVER,
+ uint32_t, uint32_t)
+PIXMAN_ARM_BIND_SCALED_NEAREST_SRC_DST (neon, 8888_0565, OVER,
+ uint32_t, uint16_t)
+PIXMAN_ARM_BIND_SCALED_NEAREST_SRC_DST (neon, 8888_0565, SRC,
+ uint32_t, uint16_t)
+PIXMAN_ARM_BIND_SCALED_NEAREST_SRC_DST (neon, 0565_8888, SRC,
+ uint16_t, uint32_t)
+
void
pixman_composite_src_n_8_asm_neon (int32_t w,
int32_t h,
@@ -271,6 +280,27 @@ static const pixman_fast_path_t arm_neon_fast_paths[] =
PIXMAN_STD_FAST_PATH (OUT_REVERSE, a8, null, r5g6b5, neon_composite_out_reverse_8_0565),
PIXMAN_STD_FAST_PATH (OUT_REVERSE, a8, null, b5g6r5, neon_composite_out_reverse_8_0565),
+ PIXMAN_ARM_SIMPLE_NEAREST_FAST_PATH (OVER, a8r8g8b8, a8r8g8b8, neon_8888_8888),
+ PIXMAN_ARM_SIMPLE_NEAREST_FAST_PATH (OVER, a8b8g8r8, a8b8g8r8, neon_8888_8888),
+ PIXMAN_ARM_SIMPLE_NEAREST_FAST_PATH (OVER, a8r8g8b8, x8r8g8b8, neon_8888_8888),
+ PIXMAN_ARM_SIMPLE_NEAREST_FAST_PATH (OVER, a8b8g8r8, x8b8g8r8, neon_8888_8888),
+
+ PIXMAN_ARM_SIMPLE_NEAREST_FAST_PATH (OVER, a8r8g8b8, r5g6b5, neon_8888_0565),
+ PIXMAN_ARM_SIMPLE_NEAREST_FAST_PATH (OVER, a8b8g8r8, b5g6r5, neon_8888_0565),
+
+ PIXMAN_ARM_SIMPLE_NEAREST_FAST_PATH (SRC, a8r8g8b8, r5g6b5, neon_8888_0565),
+ PIXMAN_ARM_SIMPLE_NEAREST_FAST_PATH (SRC, x8r8g8b8, r5g6b5, neon_8888_0565),
+ PIXMAN_ARM_SIMPLE_NEAREST_FAST_PATH (SRC, a8b8g8r8, b5g6r5, neon_8888_0565),
+ PIXMAN_ARM_SIMPLE_NEAREST_FAST_PATH (SRC, x8b8g8r8, b5g6r5, neon_8888_0565),
+
+ PIXMAN_ARM_SIMPLE_NEAREST_FAST_PATH (SRC, b5g6r5, x8b8g8r8, neon_0565_8888),
+ PIXMAN_ARM_SIMPLE_NEAREST_FAST_PATH (SRC, r5g6b5, x8r8g8b8, neon_0565_8888),
+ /* Note: NONE repeat is not supported yet */
+ SIMPLE_NEAREST_FAST_PATH_COVER (SRC, r5g6b5, a8r8g8b8, neon_0565_8888),
+ SIMPLE_NEAREST_FAST_PATH_COVER (SRC, b5g6r5, a8b8g8r8, neon_0565_8888),
+ SIMPLE_NEAREST_FAST_PATH_PAD (SRC, r5g6b5, a8r8g8b8, neon_0565_8888),
+ SIMPLE_NEAREST_FAST_PATH_PAD (SRC, b5g6r5, a8b8g8r8, neon_0565_8888),
+
{ PIXMAN_OP_NONE },
};
diff --git a/pixman/pixman/pixman-arm-simd-asm.S b/pixman/pixman/pixman-arm-simd-asm.S
index 76647c6bc..d97545c1b 100644
--- a/pixman/pixman/pixman-arm-simd-asm.S
+++ b/pixman/pixman/pixman-arm-simd-asm.S
@@ -1,5 +1,6 @@
/*
* Copyright © 2008 Mozilla Corporation
+ * Copyright © 2010 Nokia Corporation
*
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that
@@ -328,3 +329,72 @@ pixman_asm_function pixman_composite_over_n_8_8888_asm_armv6
pop {r4, r5, r6, r7, r8, r9, r10, r11}
bx lr
.endfunc
+
+/*
+ * Note: This function is only using armv4t instructions (not even armv6),
+ * but is scheduled for ARM Cortex-A8 pipeline. So it might need to
+ * be split into a few variants, tuned for each microarchitecture.
+ *
+ * TODO: In order to get good performance on ARM9/ARM11 cores (which don't
+ * have efficient write combining), it needs to be changed to use 16-byte
+ * aligned writes using STM instruction.
+ */
+pixman_asm_function pixman_scaled_nearest_scanline_0565_0565_SRC_asm_armv6
+ W .req r0
+ DST .req r1
+ SRC .req r2
+ VX .req r3
+ UNIT_X .req ip
+ TMP1 .req r4
+ TMP2 .req r5
+ VXMASK .req r6
+
+ ldr UNIT_X, [sp]
+ push {r4, r5, r6, r7}
+ mvn VXMASK, #1
+
+ /* define helper macro */
+ .macro scale_2_pixels
+ ldrh TMP1, [SRC, TMP1]
+ and TMP2, VXMASK, VX, lsr #15
+ add VX, VX, UNIT_X
+ strh TMP1, [DST], #2
+
+ ldrh TMP2, [SRC, TMP2]
+ and TMP1, VXMASK, VX, lsr #15
+ add VX, VX, UNIT_X
+ strh TMP2, [DST], #2
+ .endm
+
+ /* now do the scaling */
+ and TMP1, VXMASK, VX, lsr #15
+ add VX, VX, UNIT_X
+ subs W, #4
+ blt 2f
+1: /* main loop, process 4 pixels per iteration */
+ scale_2_pixels
+ scale_2_pixels
+ subs W, W, #4
+ bge 1b
+2:
+ tst W, #2
+ beq 2f
+ scale_2_pixels
+2:
+ tst W, #1
+ ldrneh TMP1, [SRC, TMP1]
+ strneh TMP1, [DST], #2
+ /* cleanup helper macro */
+ .purgem scale_2_pixels
+ .unreq DST
+ .unreq SRC
+ .unreq W
+ .unreq VX
+ .unreq UNIT_X
+ .unreq TMP1
+ .unreq TMP2
+ .unreq VXMASK
+ /* return */
+ pop {r4, r5, r6, r7}
+ bx lr
+.endfunc
diff --git a/pixman/pixman/pixman-arm-simd.c b/pixman/pixman/pixman-arm-simd.c
index 76a7ffeab..7f789ceab 100644
--- a/pixman/pixman/pixman-arm-simd.c
+++ b/pixman/pixman/pixman-arm-simd.c
@@ -29,6 +29,7 @@
#include "pixman-private.h"
#include "pixman-arm-common.h"
+#include "pixman-fast-path.h"
#if 0 /* This code was moved to 'pixman-arm-simd-asm.S' */
@@ -386,6 +387,9 @@ PIXMAN_ARM_BIND_FAST_PATH_SRC_N_DST (armv6, over_8888_n_8888,
PIXMAN_ARM_BIND_FAST_PATH_N_MASK_DST (armv6, over_n_8_8888,
uint8_t, 1, uint32_t, 1)
+PIXMAN_ARM_BIND_SCALED_NEAREST_SRC_DST (armv6, 0565_0565, SRC,
+ uint16_t, uint16_t)
+
static const pixman_fast_path_t arm_simd_fast_paths[] =
{
PIXMAN_STD_FAST_PATH (OVER, a8r8g8b8, null, a8r8g8b8, armv6_composite_over_8888_8888),
@@ -404,6 +408,9 @@ static const pixman_fast_path_t arm_simd_fast_paths[] =
PIXMAN_STD_FAST_PATH (OVER, solid, a8, a8b8g8r8, armv6_composite_over_n_8_8888),
PIXMAN_STD_FAST_PATH (OVER, solid, a8, x8b8g8r8, armv6_composite_over_n_8_8888),
+ PIXMAN_ARM_SIMPLE_NEAREST_FAST_PATH (SRC, r5g6b5, r5g6b5, armv6_0565_0565),
+ PIXMAN_ARM_SIMPLE_NEAREST_FAST_PATH (SRC, b5g6r5, b5g6r5, armv6_0565_0565),
+
{ PIXMAN_OP_NONE },
};
diff --git a/pixman/pixman/pixman-conical-gradient.c b/pixman/pixman/pixman-conical-gradient.c
index 648f3569d..769b984d1 100644
--- a/pixman/pixman/pixman-conical-gradient.c
+++ b/pixman/pixman/pixman-conical-gradient.c
@@ -58,8 +58,7 @@ conical_gradient_get_scanline_32 (pixman_image_t *image,
uint32_t * buffer,
const uint32_t *mask)
{
- source_image_t *source = (source_image_t *)image;
- gradient_t *gradient = (gradient_t *)source;
+ gradient_t *gradient = (gradient_t *)image;
conical_gradient_t *conical = (conical_gradient_t *)image;
uint32_t *end = buffer + width;
pixman_gradient_walker_t walker;
@@ -71,9 +70,9 @@ conical_gradient_get_scanline_32 (pixman_image_t *image,
double ry = y + 0.5;
double rz = 1.;
- _pixman_gradient_walker_init (&walker, gradient, source->common.repeat);
+ _pixman_gradient_walker_init (&walker, gradient, image->common.repeat);
- if (source->common.transform)
+ if (image->common.transform)
{
pixman_vector_t v;
@@ -82,19 +81,19 @@ conical_gradient_get_scanline_32 (pixman_image_t *image,
v.vector[1] = pixman_int_to_fixed (y) + pixman_fixed_1 / 2;
v.vector[2] = pixman_fixed_1;
- if (!pixman_transform_point_3d (source->common.transform, &v))
+ if (!pixman_transform_point_3d (image->common.transform, &v))
return;
- cx = source->common.transform->matrix[0][0] / 65536.;
- cy = source->common.transform->matrix[1][0] / 65536.;
- cz = source->common.transform->matrix[2][0] / 65536.;
+ cx = image->common.transform->matrix[0][0] / 65536.;
+ cy = image->common.transform->matrix[1][0] / 65536.;
+ cz = image->common.transform->matrix[2][0] / 65536.;
rx = v.vector[0] / 65536.;
ry = v.vector[1] / 65536.;
rz = v.vector[2] / 65536.;
affine =
- source->common.transform->matrix[2][0] == 0 &&
+ image->common.transform->matrix[2][0] == 0 &&
v.vector[2] == pixman_fixed_1;
}
diff --git a/pixman/pixman/pixman-image.c b/pixman/pixman/pixman-image.c
index ac7bccc5d..48faa3a10 100644
--- a/pixman/pixman/pixman-image.c
+++ b/pixman/pixman/pixman-image.c
@@ -47,8 +47,6 @@ _pixman_init_gradient (gradient_t * gradient,
gradient->n_stops = n_stops;
- gradient->stop_range = 0xffff;
-
return TRUE;
}
@@ -238,54 +236,27 @@ _pixman_image_reset_clip_region (pixman_image_t *image)
image->common.have_clip_region = FALSE;
}
-static pixman_bool_t out_of_bounds_workaround = TRUE;
-
-/* Old X servers rely on out-of-bounds accesses when they are asked
- * to composite with a window as the source. They create a pixman image
- * pointing to some bogus position in memory, but then they set a clip
- * region to the position where the actual bits are.
+/* Executive Summary: This function is a no-op that only exists
+ * for historical reasons.
+ *
+ * There used to be a bug in the X server where it would rely on
+ * out-of-bounds accesses when it was asked to composite with a
+ * window as the source. It would create a pixman image pointing
+ * to some bogus position in memory, but then set a clip region
+ * to the position where the actual bits were.
*
* Due to a bug in old versions of pixman, where it would not clip
* against the image bounds when a clip region was set, this would
- * actually work. So by default we allow certain out-of-bound access
- * to happen unless explicitly disabled.
+ * actually work. So when the pixman bug was fixed, a workaround was
+ * added to allow certain out-of-bound accesses. This function disabled
+ * those workarounds.
*
- * Fixed X servers should call this function to disable the workaround.
+ * Since 0.21.2, pixman doesn't do these workarounds anymore, so now
+ * this function is a no-op.
*/
PIXMAN_EXPORT void
pixman_disable_out_of_bounds_workaround (void)
{
- out_of_bounds_workaround = FALSE;
-}
-
-static pixman_bool_t
-source_image_needs_out_of_bounds_workaround (bits_image_t *image)
-{
- if (image->common.clip_sources &&
- image->common.repeat == PIXMAN_REPEAT_NONE &&
- image->common.have_clip_region &&
- out_of_bounds_workaround)
- {
- if (!image->common.client_clip)
- {
- /* There is no client clip, so if the clip region extends beyond the
- * drawable geometry, it must be because the X server generated the
- * bogus clip region.
- */
- const pixman_box32_t *extents =
- pixman_region32_extents (&image->common.clip_region);
-
- if (extents->x1 >= 0 && extents->x2 <= image->width &&
- extents->y1 >= 0 && extents->y2 <= image->height)
- {
- return FALSE;
- }
- }
-
- return TRUE;
- }
-
- return FALSE;
}
static void
@@ -420,9 +391,6 @@ compute_image_info (pixman_image_t *image)
flags |= FAST_PATH_IS_OPAQUE;
}
- if (source_image_needs_out_of_bounds_workaround (&image->bits))
- flags |= FAST_PATH_NEEDS_WORKAROUND;
-
if (image->bits.read_func || image->bits.write_func)
flags &= ~FAST_PATH_NO_ACCESSORS;
@@ -430,10 +398,25 @@ compute_image_info (pixman_image_t *image)
flags &= ~FAST_PATH_NARROW_FORMAT;
break;
- case LINEAR:
case RADIAL:
code = PIXMAN_unknown;
+ /*
+ * As explained in pixman-radial-gradient.c, every point of
+ * the plane has a valid associated radius (and thus will be
+ * colored) if and only if a is negative (i.e. one of the two
+ * circles contains the other one).
+ */
+
+ if (image->radial.a >= 0)
+ break;
+
+ /* Fall through */
+
+ case CONICAL:
+ case LINEAR:
+ code = PIXMAN_unknown;
+
if (image->common.repeat != PIXMAN_REPEAT_NONE)
{
int i;
diff --git a/pixman/pixman/pixman-linear-gradient.c b/pixman/pixman/pixman-linear-gradient.c
index 9ccb688ff..1756b4a0e 100644
--- a/pixman/pixman/pixman-linear-gradient.c
+++ b/pixman/pixman/pixman-linear-gradient.c
@@ -38,7 +38,6 @@ linear_gradient_classify (pixman_image_t *image,
int width,
int height)
{
- source_image_t *source = (source_image_t *)image;
linear_gradient_t *linear = (linear_gradient_t *)image;
pixman_vector_t v;
pixman_fixed_32_32_t l;
@@ -48,19 +47,19 @@ linear_gradient_classify (pixman_image_t *image,
class = SOURCE_IMAGE_CLASS_UNKNOWN;
- if (source->common.transform)
+ if (image->common.transform)
{
/* projective transformation */
- if (source->common.transform->matrix[2][0] != 0 ||
- source->common.transform->matrix[2][1] != 0 ||
- source->common.transform->matrix[2][2] == 0)
+ if (image->common.transform->matrix[2][0] != 0 ||
+ image->common.transform->matrix[2][1] != 0 ||
+ image->common.transform->matrix[2][2] == 0)
{
return class;
}
- v.vector[0] = source->common.transform->matrix[0][1];
- v.vector[1] = source->common.transform->matrix[1][1];
- v.vector[2] = source->common.transform->matrix[2][2];
+ v.vector[0] = image->common.transform->matrix[0][1];
+ v.vector[1] = image->common.transform->matrix[1][1];
+ v.vector[2] = image->common.transform->matrix[2][2];
}
else
{
@@ -104,26 +103,25 @@ linear_gradient_get_scanline_32 (pixman_image_t *image,
pixman_fixed_32_32_t l;
pixman_fixed_48_16_t dx, dy;
gradient_t *gradient = (gradient_t *)image;
- source_image_t *source = (source_image_t *)image;
linear_gradient_t *linear = (linear_gradient_t *)image;
uint32_t *end = buffer + width;
pixman_gradient_walker_t walker;
- _pixman_gradient_walker_init (&walker, gradient, source->common.repeat);
+ _pixman_gradient_walker_init (&walker, gradient, image->common.repeat);
/* reference point is the center of the pixel */
v.vector[0] = pixman_int_to_fixed (x) + pixman_fixed_1 / 2;
v.vector[1] = pixman_int_to_fixed (y) + pixman_fixed_1 / 2;
v.vector[2] = pixman_fixed_1;
- if (source->common.transform)
+ if (image->common.transform)
{
- if (!pixman_transform_point_3d (source->common.transform, &v))
+ if (!pixman_transform_point_3d (image->common.transform, &v))
return;
-
- unit.vector[0] = source->common.transform->matrix[0][0];
- unit.vector[1] = source->common.transform->matrix[1][0];
- unit.vector[2] = source->common.transform->matrix[2][0];
+
+ unit.vector[0] = image->common.transform->matrix[0][0];
+ unit.vector[1] = image->common.transform->matrix[1][0];
+ unit.vector[2] = image->common.transform->matrix[2][0];
}
else
{
diff --git a/pixman/pixman/pixman-mmx.c b/pixman/pixman/pixman-mmx.c
index 8284fe480..d05a185ea 100644
--- a/pixman/pixman/pixman-mmx.c
+++ b/pixman/pixman/pixman-mmx.c
@@ -1921,8 +1921,8 @@ pixman_fill_mmx (uint32_t *bits,
"movq %7, %4\n"
"movq %7, %5\n"
"movq %7, %6\n"
- : "=y" (v1), "=y" (v2), "=y" (v3),
- "=y" (v4), "=y" (v5), "=y" (v6), "=y" (v7)
+ : "=&y" (v1), "=&y" (v2), "=&y" (v3),
+ "=&y" (v4), "=&y" (v5), "=&y" (v6), "=y" (v7)
: "y" (vfill));
#endif
diff --git a/pixman/pixman/pixman-private.h b/pixman/pixman/pixman-private.h
index b0faf2c08..b6eb24835 100644
--- a/pixman/pixman/pixman-private.h
+++ b/pixman/pixman/pixman-private.h
@@ -20,7 +20,6 @@
* Images
*/
typedef struct image_common image_common_t;
-typedef struct source_image source_image_t;
typedef struct solid_fill solid_fill_t;
typedef struct gradient gradient_t;
typedef struct linear_gradient linear_gradient_t;
@@ -108,14 +107,9 @@ struct image_common
pixman_format_code_t extended_format_code;
};
-struct source_image
-{
- image_common_t common;
-};
-
struct solid_fill
{
- source_image_t common;
+ image_common_t common;
pixman_color_t color;
uint32_t color_32;
@@ -124,10 +118,9 @@ struct solid_fill
struct gradient
{
- source_image_t common;
+ image_common_t common;
int n_stops;
pixman_gradient_stop_t *stops;
- int stop_range;
};
struct linear_gradient
@@ -193,7 +186,6 @@ union pixman_image
image_type_t type;
image_common_t common;
bits_image_t bits;
- source_image_t source;
gradient_t gradient;
linear_gradient_t linear;
conical_gradient_t conical;
@@ -561,14 +553,13 @@ _pixman_choose_implementation (void);
#define FAST_PATH_NEAREST_FILTER (1 << 11)
#define FAST_PATH_HAS_TRANSFORM (1 << 12)
#define FAST_PATH_IS_OPAQUE (1 << 13)
-#define FAST_PATH_NEEDS_WORKAROUND (1 << 14)
+#define FAST_PATH_NO_NORMAL_REPEAT (1 << 14)
#define FAST_PATH_NO_NONE_REPEAT (1 << 15)
#define FAST_PATH_SAMPLES_COVER_CLIP (1 << 16)
#define FAST_PATH_X_UNIT_POSITIVE (1 << 17)
#define FAST_PATH_AFFINE_TRANSFORM (1 << 18)
#define FAST_PATH_Y_UNIT_ZERO (1 << 19)
#define FAST_PATH_BILINEAR_FILTER (1 << 20)
-#define FAST_PATH_NO_NORMAL_REPEAT (1 << 21)
#define FAST_PATH_PAD_REPEAT \
(FAST_PATH_NO_NONE_REPEAT | \
diff --git a/pixman/pixman/pixman-radial-gradient.c b/pixman/pixman/pixman-radial-gradient.c
index 2d9e46a39..7dfc1d04e 100644
--- a/pixman/pixman/pixman-radial-gradient.c
+++ b/pixman/pixman/pixman-radial-gradient.c
@@ -219,7 +219,6 @@ radial_gradient_get_scanline_32 (pixman_image_t *image,
*/
gradient_t *gradient = (gradient_t *)image;
- source_image_t *source = (source_image_t *)image;
radial_gradient_t *radial = (radial_gradient_t *)image;
uint32_t *end = buffer + width;
pixman_gradient_walker_t walker;
@@ -230,16 +229,16 @@ radial_gradient_get_scanline_32 (pixman_image_t *image,
v.vector[1] = pixman_int_to_fixed (y) + pixman_fixed_1 / 2;
v.vector[2] = pixman_fixed_1;
- _pixman_gradient_walker_init (&walker, gradient, source->common.repeat);
+ _pixman_gradient_walker_init (&walker, gradient, image->common.repeat);
- if (source->common.transform)
+ if (image->common.transform)
{
- if (!pixman_transform_point_3d (source->common.transform, &v))
+ if (!pixman_transform_point_3d (image->common.transform, &v))
return;
- unit.vector[0] = source->common.transform->matrix[0][0];
- unit.vector[1] = source->common.transform->matrix[1][0];
- unit.vector[2] = source->common.transform->matrix[2][0];
+ unit.vector[0] = image->common.transform->matrix[0][0];
+ unit.vector[1] = image->common.transform->matrix[1][0];
+ unit.vector[2] = image->common.transform->matrix[2][0];
}
else
{
@@ -309,7 +308,7 @@ radial_gradient_get_scanline_32 (pixman_image_t *image,
radial->delta.radius,
radial->mindr,
&walker,
- source->common.repeat);
+ image->common.repeat);
}
b += db;
@@ -354,14 +353,14 @@ radial_gradient_get_scanline_32 (pixman_image_t *image,
radial->delta.radius,
radial->mindr,
&walker,
- source->common.repeat);
+ image->common.repeat);
}
else
{
*buffer = 0;
}
}
-
+
++buffer;
v.vector[0] += unit.vector[0];
diff --git a/pixman/pixman/pixman.c b/pixman/pixman/pixman.c
index 4857e30ce..d41e7bd26 100644
--- a/pixman/pixman/pixman.c
+++ b/pixman/pixman/pixman.c
@@ -30,14 +30,23 @@
#include <stdlib.h>
+static pixman_implementation_t *global_implementation;
+
+#ifdef TOOLCHAIN_SUPPORTS_ATTRIBUTE_CONSTRUCTOR
+static void __attribute__((constructor))
+pixman_constructor (void)
+{
+ global_implementation = _pixman_choose_implementation ();
+}
+#endif
+
static force_inline pixman_implementation_t *
get_implementation (void)
{
- static pixman_implementation_t *global_implementation;
-
+#ifndef TOOLCHAIN_SUPPORTS_ATTRIBUTE_CONSTRUCTOR
if (!global_implementation)
global_implementation = _pixman_choose_implementation ();
-
+#endif
return global_implementation;
}
@@ -153,57 +162,6 @@ optimize_operator (pixman_op_t op,
return operator_table[op].opaque_info[is_dest_opaque | is_source_opaque];
}
-static void
-apply_workaround (pixman_image_t *image,
- int32_t * x,
- int32_t * y,
- uint32_t ** save_bits,
- int * save_dx,
- int * save_dy)
-{
- if (image && (image->common.flags & FAST_PATH_NEEDS_WORKAROUND))
- {
- /* Some X servers generate images that point to the
- * wrong place in memory, but then set the clip region
- * to point to the right place. Because of an old bug
- * in pixman, this would actually work.
- *
- * Here we try and undo the damage
- */
- int bpp = PIXMAN_FORMAT_BPP (image->bits.format) / 8;
- pixman_box32_t *extents;
- uint8_t *t;
- int dx, dy;
-
- extents = pixman_region32_extents (&(image->common.clip_region));
- dx = extents->x1;
- dy = extents->y1;
-
- *save_bits = image->bits.bits;
-
- *x -= dx;
- *y -= dy;
- pixman_region32_translate (&(image->common.clip_region), -dx, -dy);
-
- t = (uint8_t *)image->bits.bits;
- t += dy * image->bits.rowstride * 4 + dx * bpp;
- image->bits.bits = (uint32_t *)t;
-
- *save_dx = dx;
- *save_dy = dy;
- }
-}
-
-static void
-unapply_workaround (pixman_image_t *image, uint32_t *bits, int dx, int dy)
-{
- if (image && (image->common.flags & FAST_PATH_NEEDS_WORKAROUND))
- {
- image->bits.bits = bits;
- pixman_region32_translate (&image->common.clip_region, dx, dy);
- }
-}
-
/*
* Computing composite region
*/
@@ -732,13 +690,6 @@ pixman_image_composite32 (pixman_op_t op,
uint32_t src_flags, mask_flags, dest_flags;
pixman_region32_t region;
pixman_box32_t *extents;
- uint32_t *src_bits;
- int src_dx, src_dy;
- uint32_t *mask_bits;
- int mask_dx, mask_dy;
- uint32_t *dest_bits;
- int dest_dx, dest_dy;
- pixman_bool_t need_workaround;
pixman_implementation_t *imp;
pixman_composite_func_t func;
@@ -776,16 +727,6 @@ pixman_image_composite32 (pixman_op_t op,
src_format = mask_format = PIXMAN_rpixbuf;
}
- /* Check for workaround */
- need_workaround = (src_flags | mask_flags | dest_flags) & FAST_PATH_NEEDS_WORKAROUND;
-
- if (need_workaround)
- {
- apply_workaround (src, &src_x, &src_y, &src_bits, &src_dx, &src_dy);
- apply_workaround (mask, &mask_x, &mask_y, &mask_bits, &mask_dx, &mask_dy);
- apply_workaround (dest, &dest_x, &dest_y, &dest_bits, &dest_dx, &dest_dy);
- }
-
pixman_region32_init (&region);
if (!pixman_compute_composite_region32 (
@@ -852,13 +793,6 @@ pixman_image_composite32 (pixman_op_t op,
}
out:
- if (need_workaround)
- {
- unapply_workaround (src, src_bits, src_dx, src_dy);
- unapply_workaround (mask, mask_bits, mask_dx, mask_dy);
- unapply_workaround (dest, dest_bits, dest_dx, dest_dy);
- }
-
pixman_region32_fini (&region);
}
diff --git a/pixman/pixman/pixman.h b/pixman/pixman/pixman.h
index 08494c467..27eeeee4e 100644
--- a/pixman/pixman/pixman.h
+++ b/pixman/pixman/pixman.h
@@ -841,19 +841,25 @@ void pixman_image_composite32 (pixman_op_t op,
int32_t width,
int32_t height);
-/* Old X servers rely on out-of-bounds accesses when they are asked
- * to composite with a window as the source. They create a pixman image
- * pointing to some bogus position in memory, but then they set a clip
- * region to the position where the actual bits are.
+/* Executive Summary: This function is a no-op that only exists
+ * for historical reasons.
+ *
+ * There used to be a bug in the X server where it would rely on
+ * out-of-bounds accesses when it was asked to composite with a
+ * window as the source. It would create a pixman image pointing
+ * to some bogus position in memory, but then set a clip region
+ * to the position where the actual bits were.
*
* Due to a bug in old versions of pixman, where it would not clip
* against the image bounds when a clip region was set, this would
- * actually work. So by default we allow certain out-of-bound access
- * to happen unless explicitly disabled.
+ * actually work. So when the pixman bug was fixed, a workaround was
+ * added to allow certain out-of-bound accesses. This function disabled
+ * those workarounds.
*
- * Fixed X servers should call this function to disable the workaround.
+ * Since 0.21.2, pixman doesn't do these workarounds anymore, so now this
+ * function is a no-op.
*/
-void pixman_disable_out_of_bounds_workaround (void);
+void pixman_disable_out_of_bounds_workaround (void);
/*
* Trapezoids
diff --git a/pixman/test/Makefile.am b/pixman/test/Makefile.am
index 32b1d6327..98bf94ef0 100644
--- a/pixman/test/Makefile.am
+++ b/pixman/test/Makefile.am
@@ -10,7 +10,6 @@ TESTPROGRAMS = \
region-translate-test \
fetch-test \
oob-test \
- window-test \
gradient-crash-test \
trap-crasher \
alpha-loop \
@@ -26,7 +25,6 @@ fetch_test_LDADD = $(TEST_LDADD)
gradient_crash_test_LDADD = $(TEST_LDADD)
trap_crasher_LDADD = $(TEST_LDADD)
oob_test_LDADD = $(TEST_LDADD)
-window_test_LDADD = $(TEST_LDADD)
scaling_crash_test_LDADD = $(TEST_LDADD)
region_translate_test_LDADD = $(TEST_LDADD)
diff --git a/pixman/test/window-test.c b/pixman/test/window-test.c
deleted file mode 100644
index 919fc16ed..000000000
--- a/pixman/test/window-test.c
+++ /dev/null
@@ -1,173 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <config.h>
-#include "pixman-private.h"
-#include "pixman.h"
-
-#define FALSE 0
-#define TRUE 1
-
-/* Randomly decide between 32 and 16 bit
- *
- * Allocate bits with random width, stride and height
- *
- * Then make up some random offset (dx, dy)
- *
- * Then make an image with those values.
- *
- * Do this for both source and destination
- *
- * Composite them together using OVER.
- *
- * The bits in the source and the destination should have
- * recognizable colors so that the result can be verified.
- *
- * Ie., walk the bits and verify that they have been composited.
- */
-
-static int
-get_rand (int bound)
-{
- return rand () % bound;
-}
-
-static pixman_image_t *
-make_image (int width, int height, pixman_bool_t src, int *rx, int *ry)
-{
- pixman_format_code_t format;
- pixman_image_t *image;
- pixman_region32_t region;
- uint8_t *bits;
- int stride;
- int bpp;
- int dx, dy;
- int i, j;
-
- if (src)
- format = PIXMAN_a8r8g8b8;
- else
- format = PIXMAN_r5g6b5;
-
- bpp = PIXMAN_FORMAT_BPP (format) / 8;
-
- stride = width + get_rand (width);
- stride += (stride & 1); /* Make it an even number */
-
- bits = malloc (height * stride * bpp);
-
- for (j = 0; j < height; ++j)
- {
- for (i = 0; i < width; ++i)
- {
- uint8_t *pixel = bits + (stride * j + i) * bpp;
-
- if (src)
- *(uint32_t *)pixel = 0x7f00007f;
- else
- *(uint16_t *)pixel = 0xf100;
- }
- }
-
- dx = dy = 0;
-
- dx = get_rand (500);
- dy = get_rand (500);
-
- if (!src)
- {
- /* Now simulate the bogus X server translations */
- bits -= (dy * stride + dx) * bpp;
- }
-
- image = pixman_image_create_bits (
- format, width, height, (uint32_t *)bits, stride * bpp);
-
- if (!src)
- {
- /* And add the bogus clip region */
- pixman_region32_init_rect (&region, dx, dy, dx + width, dy + height);
-
- pixman_image_set_clip_region32 (image, &region);
- }
-
- pixman_image_set_source_clipping (image, TRUE);
-
- if (src)
- {
- pixman_transform_t trans;
-
- pixman_transform_init_identity (&trans);
-
- pixman_transform_translate (&trans,
- NULL,
- - pixman_int_to_fixed (width / 2),
- - pixman_int_to_fixed (height / 2));
-
- pixman_transform_scale (&trans,
- NULL,
- pixman_double_to_fixed (0.5),
- pixman_double_to_fixed (0.5));
-
- pixman_transform_translate (&trans,
- NULL,
- pixman_int_to_fixed (width / 2),
- pixman_int_to_fixed (height / 2));
-
- pixman_image_set_transform (image, &trans);
- pixman_image_set_filter (image, PIXMAN_FILTER_BILINEAR, NULL, 0);
- pixman_image_set_repeat (image, PIXMAN_REPEAT_PAD);
- }
-
- if (!src)
- {
- *rx = dx;
- *ry = dy;
- }
- else
- {
- *rx = *ry = 0;
- }
-
- return image;
-}
-
-int
-main ()
-{
- pixman_image_t *src, *dest;
- int src_x, src_y, dest_x, dest_y;
- int i, j;
- int width = get_rand (499) + 1;
- int height = get_rand (499) + 1;
-
- src = make_image (width, height, TRUE, &src_x, &src_y);
- dest = make_image (width, height, FALSE, &dest_x, &dest_y);
-
- pixman_image_composite (
- PIXMAN_OP_OVER, src, NULL, dest,
- src_x, src_y,
- -1, -1,
- dest_x, dest_y,
- width, height);
-
- for (i = 0; i < height; ++i)
- {
- for (j = 0; j < width; ++j)
- {
- uint8_t *bits = (uint8_t *)dest->bits.bits;
- int bpp = PIXMAN_FORMAT_BPP (dest->bits.format) / 8;
- int stride = dest->bits.rowstride * 4;
-
- uint8_t *pixel =
- bits + (i + dest_y) * stride + (j + dest_x) * bpp;
-
- if (*(uint16_t *)pixel != 0x788f)
- {
- printf ("bad pixel %x\n", *(uint16_t *)pixel);
- assert (*(uint16_t *)pixel == 0x788f);
- }
- }
- }
-
- return 0;
-}