mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 746695. Update libpixman to 0.24.4 a=joe
Alan Coopersmith (2): Change MMX ldq_u to return _m64 instead of forcing all callers to cast Make mmx code compatible with Solaris Studio 12.3 compilers Andrea Canciani (13): Include noop in win32 builds Silence autoconf warnings radial: Improve documentation and naming radial: Fix typos and trailing whitespace win32: Build benchmarks Workaround bug in llvm-gcc test: Fix compilation on win32 build: Reuse sources and pixman-combine build rules build: Reuse test sources build-win32: Share targets and variables across win32 makefiles build-win32: Add root Makefile.win32 test: Do not include config.h unless HAVE_CONFIG_H is defined build-win32: Add 'check' target Benjamin Otte (2): tests: Add PNG_CFLAGS/LIBS to tests build: replace @VAR@ with $(VAR) in makefiles Bobby Salazar (1): Android Runtime Detection Support For ARM NEON Chris Wilson (1): bits: optimise fetching width==1 repeats Colin Walters (1): autogen.sh: Support GNOME Build API Jeff Muizelaar (1): Add definitions of INT64_MIN and INT64_MAX Jon TURNEY (1): Fix build on cygwin after commit efdf65c0c4fff551fb3cd9104deda9adb6261e22 Matt Turner (11): lowlevel-blt: add over_x888_8_8888 mmx: fix formats in commented code mmx: convert while (w) to if (w) when possible mmx: rename USE_MMX to USE_X86_MMX mmx: wrap x86/MMX inline assembly in ifdef USE_X86_MMX mmx: fix unaligned accesses mmx: prepare pixman-mmx.c to be compiled for ARM/iwmmxt mmx: compile on ARM for iwmmxt optimizations mmx: optimize unaligned 64-bit ARM/iwmmxt loads Make sure iwMMXt is only detected on ARM Correct the minimum gcc version needed for iwmmxt Naohiro Aota (1): Don't use non-POSIX test Nis Martensen (1): Fix a few typos in pixman-combine.c.template Siarhei Siamashka (4): C fast path for scaled src_x888_8888 with nearest filter ARM: workaround binutils bug #12931 (code sections alignment) test: better coverage for BILINEAR->NEAREST filter optimization BILINEAR->NEAREST filter optimization for simple rotation and translation Søren Sandmann (5): mmx: Delete some unused variables sse2: Delete some unused variables demos: Comment out some unused variables ARM: Fix two bugs in neon_composite_over_n_8888_0565_ca(). test: Make fuzzer-find-diff.pl executable Søren Sandmann Pedersen (63): Add a "noop" implementation. Add a noop composite function for the DST operator Move noop dest fetching to noop implementation Add a noop src iterator Move NULL iterator into pixman-noop.c Move NOP src iterator into noop implementation. Replace instances of "dst_*" with "dest_*" In pixman-general.c rename image_parameters to {src, mask, dest}_image Replace argumentxs to composite functions with a pointer to a struct blitters-test: Make common formats more likely to be tested. Pre-release version bump to 0.23.2 Post-release version bump to 0.23.3 Makefile.am: Add pixman@lists.freedesktop.org to RELEASE_ANNOUNCE_LIST Fix lcg_rand_u32() to return 32 random bits. New test of pixman_region_contains_{rectangle,point} Speed up pixman_region{,32}_contains_rectangle() Use find_box_for_y() in pixman_region_contains_point() too Don't include stdint.h in lowlevel-blt-bench.c In pixman_image_create_bits() allow images larger than 2GB Rename pixman-fast-path.h to pixman-inlines.h Use repeat() function from pixman-inlines.h in pixman-bits-image.c Move bilinear interpolation to pixman-inlines.h Pre-release version bump to 0.23.4 Post-release version bump to 0.23.5 test: New function to save a pixman image to .png Use pkg-config to determine the flags to use with libpng test: Use smaller boxes in region_contains_test() A few tweaks to a comment in pixman-combine.c.template Add a generic unorm_to_unorm() conversion utility Add general pixel converter Add initial version of the MAKE_ACCESSORS() macro Use MAKE_ACCESSORS() to generate all the 32 bit accessors Use MAKE_ACCESSORS() to generate accessors for all the 16bpp formats Use MAKE_ACCESSORS() to generate accessors for 8bpp RGB formats Use MAKE_ACCESSORS() to generate accessors for 4 bpp RGB formats Use MAKE_ACCESSORS() to generate accessors for 24bpp formats Use MAKE_ACCESSORS() to generate accessors for the a1 format. Use MAKE_ACCESSORS() to generate accessors for paletted formats Remove x and y coordinates from analyze_extents() and compute_sample_extents() Split computation of sample area into own function Eliminate compute_sample_extents() function test: Occasionally use a BILINEAR filter in blitters-test Strength-reduce BILINEAR filter to NEAREST filter for identity transforms Don't include stdint.h in scaling-helpers-test. Add src, mask, and dest flags to the composite args struct. Pre-release version bump to 0.23.6 Post-release version bump to 0.23.7 Add stable release / development snapshot to draft release notes gradient walker: Correct types and fix formatting Use sentinels instead of special casing first and last stops Simplify gradient_walker_reset() Merge branch 'gradients' Fix use of uninitialized fields reported by valgrind Pre-release version bump to 0.23.8 Post-release version bump to 0.23.9 Pre-release version bump to 0.24.0 Post-release version bump to 0.24.1 gradient-walker: For NONE repeats, when x < 0 or x > 1, set both colors to 0 pixman-image.c: Fix typo in pixman_image_set_transform() Fix some signed overflow bugs Reject trapezoids where top (botttom) is above (below) the edges Fix bugs with alpha maps Pre-release version bump to 0.24.2 Taekyun Kim (25): Replace boolean arguments with flags for bilinear fast path template REPEAT_NORMAL support for bilinear fast path template sse2: Declare bilinear src_8888_8888 REPEAT_NORMAL composite function ARM: Add REPEAT_NORMAL functions to bilinear BIND macros Enable REPEAT_NORMAL bilinear fast path entries Bilinear REPEAT_NORMAL source line extension for too short src_width ARM NEON: Standard fast path out_reverse_8_8888 ARM: NEON better instruction scheduling of over_n_8_8888 ARM: NEON better instruction scheduling of over_n_8888 sse2: Macros for assembling bilinear interpolation code fractions sse2: Bilinear scaled over_8888_8888 sse2: Bilinear scaled over_8888_8_8888 init/fini functions for pixman_image_t Add new fast path flag FAST_PATH_BITS_IMAGE Move _pixman_lookup_composite_function() to pixman-utils.c Simple repeat fast path Simple repeat: Extend too short source scanlines into temporary buffer ARM: NEON: Some cleanup of bilinear scanline functions ARM: NEON: Bilinear macro template for instruction scheduling ARM: NEON: Replace old bilinear scanline generator with new template ARM: NEON: Instruction scheduling of bilinear over_8888_8888 ARM: NEON: Instruction scheduling of bilinear over_8888_8_8888 ARM: NEON: Standard fast path src_n_8_8888 ARM: NEON: Standard fast path src_n_8_8 ARM: NEON: Fix assembly typo error in src_n_8_8888
This commit is contained in:
parent
33464ca392
commit
4277a03964
@ -8,7 +8,7 @@ http://www.cairographics.org/.
|
||||
VERSIONS:
|
||||
|
||||
cairo (12d521df8acc483b2daa844d4f05dc2fe2765ba6)
|
||||
pixman (2f4f2fb4859931bf6dc5632d8c919e7296736427)
|
||||
pixman (0.24.2)
|
||||
|
||||
==== Patches ====
|
||||
|
||||
@ -188,7 +188,7 @@ NOTE: we previously supported ARM assembler on MSVC, this has been removed becau
|
||||
|
||||
pixman-export.patch: use cairo_public for PIXMAN_EXPORT to make sure pixman symbols are not exported in libxul
|
||||
|
||||
bad-memset.patch: Fix third argument in memcmp call in pixman-image.c
|
||||
pixman-limits.patch: include limits.h for SIZE_MAX
|
||||
|
||||
==== disable printing patch ====
|
||||
|
||||
|
@ -1,28 +0,0 @@
|
||||
# HG changeset patch
|
||||
# Parent a968f1430c74282c673c01a2c0a4417e238f2de7
|
||||
# User Thomas Prip Vestergaard <thomas@prip.nu>
|
||||
Bug 710992 - Fix third argument in memcmp call in pixman-image.c
|
||||
|
||||
|
||||
diff --git a/gfx/cairo/libpixman/src/pixman-image.c b/gfx/cairo/libpixman/src/pixman-image.c
|
||||
--- a/gfx/cairo/libpixman/src/pixman-image.c
|
||||
+++ b/gfx/cairo/libpixman/src/pixman-image.c
|
||||
@@ -512,17 +512,17 @@ pixman_image_set_transform (pixman_image
|
||||
free (common->transform);
|
||||
common->transform = NULL;
|
||||
result = TRUE;
|
||||
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (common->transform &&
|
||||
- memcmp (common->transform, transform, sizeof (pixman_transform_t) == 0))
|
||||
+ memcmp (common->transform, transform, sizeof (pixman_transform_t)) == 0)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (common->transform == NULL)
|
||||
common->transform = malloc (sizeof (pixman_transform_t));
|
||||
|
||||
if (common->transform == NULL)
|
@ -129,6 +129,7 @@ CSRCS = \
|
||||
pixman-implementation.c \
|
||||
pixman-linear-gradient.c \
|
||||
pixman-matrix.c \
|
||||
pixman-noop.c \
|
||||
pixman-radial-gradient.c \
|
||||
pixman-region16.c \
|
||||
pixman-region32.c \
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,21 +1,10 @@
|
||||
#ifdef PIXMAN_FB_ACCESSORS
|
||||
|
||||
#define ACCESS(sym) sym##_accessors
|
||||
|
||||
#define READ(img, ptr) \
|
||||
(((bits_image_t *)(img))->read_func ((ptr), sizeof(*(ptr))))
|
||||
#define WRITE(img, ptr,val) \
|
||||
(((bits_image_t *)(img))->write_func ((ptr), (val), sizeof (*(ptr))))
|
||||
|
||||
#define MEMCPY_WRAPPED(img, dst, src, size) \
|
||||
do { \
|
||||
size_t _i; \
|
||||
uint8_t *_dst = (uint8_t*)(dst), *_src = (uint8_t*)(src); \
|
||||
for(_i = 0; _i < size; _i++) { \
|
||||
WRITE((img), _dst +_i, READ((img), _src + _i)); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define MEMSET_WRAPPED(img, dst, val, size) \
|
||||
do { \
|
||||
size_t _i; \
|
||||
@ -27,12 +16,8 @@
|
||||
|
||||
#else
|
||||
|
||||
#define ACCESS(sym) sym
|
||||
|
||||
#define READ(img, ptr) (*(ptr))
|
||||
#define WRITE(img, ptr, val) (*(ptr) = (val))
|
||||
#define MEMCPY_WRAPPED(img, dst, src, size) \
|
||||
memcpy(dst, src, size)
|
||||
#define MEMSET_WRAPPED(img, dst, val, size) \
|
||||
memset(dst, val, size)
|
||||
|
||||
|
@ -26,7 +26,7 @@
|
||||
#ifndef PIXMAN_ARM_COMMON_H
|
||||
#define PIXMAN_ARM_COMMON_H
|
||||
|
||||
#include "pixman-fast-path.h"
|
||||
#include "pixman-inlines.h"
|
||||
|
||||
/* Define some macros which can expand into proxy functions between
|
||||
* ARM assembly optimized functions and the rest of pixman fast path API.
|
||||
@ -63,26 +63,16 @@ pixman_composite_##name##_asm_##cputype (int32_t w, \
|
||||
\
|
||||
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) \
|
||||
pixman_composite_info_t *info) \
|
||||
{ \
|
||||
dst_type *dst_line; \
|
||||
PIXMAN_COMPOSITE_ARGS (info); \
|
||||
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, \
|
||||
PIXMAN_IMAGE_GET_LINE (dest_image, dest_x, dest_y, dst_type, \
|
||||
dst_stride, dst_line, dst_cnt); \
|
||||
\
|
||||
pixman_composite_##name##_asm_##cputype (width, height, \
|
||||
@ -101,30 +91,20 @@ pixman_composite_##name##_asm_##cputype (int32_t w, \
|
||||
\
|
||||
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) \
|
||||
pixman_composite_info_t *info) \
|
||||
{ \
|
||||
PIXMAN_COMPOSITE_ARGS (info); \
|
||||
dst_type *dst_line; \
|
||||
int32_t dst_stride; \
|
||||
uint32_t src; \
|
||||
\
|
||||
src = _pixman_image_get_solid ( \
|
||||
imp, src_image, dst_image->bits.format); \
|
||||
imp, src_image, dest_image->bits.format); \
|
||||
\
|
||||
if ((flags & SKIP_ZERO_SRC) && src == 0) \
|
||||
return; \
|
||||
\
|
||||
PIXMAN_IMAGE_GET_LINE (dst_image, dest_x, dest_y, dst_type, \
|
||||
PIXMAN_IMAGE_GET_LINE (dest_image, dest_x, dest_y, dst_type, \
|
||||
dst_stride, dst_line, dst_cnt); \
|
||||
\
|
||||
pixman_composite_##name##_asm_##cputype (width, height, \
|
||||
@ -147,31 +127,21 @@ pixman_composite_##name##_asm_##cputype (int32_t w, \
|
||||
\
|
||||
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) \
|
||||
pixman_composite_info_t *info) \
|
||||
{ \
|
||||
dst_type *dst_line; \
|
||||
PIXMAN_COMPOSITE_ARGS (info); \
|
||||
dst_type *dst_line; \
|
||||
mask_type *mask_line; \
|
||||
int32_t dst_stride, mask_stride; \
|
||||
uint32_t src; \
|
||||
\
|
||||
src = _pixman_image_get_solid ( \
|
||||
imp, src_image, dst_image->bits.format); \
|
||||
imp, src_image, dest_image->bits.format); \
|
||||
\
|
||||
if ((flags & SKIP_ZERO_SRC) && src == 0) \
|
||||
return; \
|
||||
\
|
||||
PIXMAN_IMAGE_GET_LINE (dst_image, dest_x, dest_y, dst_type, \
|
||||
PIXMAN_IMAGE_GET_LINE (dest_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); \
|
||||
@ -196,31 +166,21 @@ pixman_composite_##name##_asm_##cputype (int32_t w, \
|
||||
\
|
||||
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) \
|
||||
pixman_composite_info_t *info) \
|
||||
{ \
|
||||
dst_type *dst_line; \
|
||||
PIXMAN_COMPOSITE_ARGS (info); \
|
||||
dst_type *dst_line; \
|
||||
src_type *src_line; \
|
||||
int32_t dst_stride, src_stride; \
|
||||
uint32_t mask; \
|
||||
\
|
||||
mask = _pixman_image_get_solid ( \
|
||||
imp, mask_image, dst_image->bits.format); \
|
||||
imp, mask_image, dest_image->bits.format); \
|
||||
\
|
||||
if ((flags & SKIP_ZERO_MASK) && mask == 0) \
|
||||
return; \
|
||||
\
|
||||
PIXMAN_IMAGE_GET_LINE (dst_image, dest_x, dest_y, dst_type, \
|
||||
PIXMAN_IMAGE_GET_LINE (dest_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); \
|
||||
@ -247,25 +207,15 @@ pixman_composite_##name##_asm_##cputype (int32_t w, \
|
||||
\
|
||||
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) \
|
||||
pixman_composite_info_t *info) \
|
||||
{ \
|
||||
dst_type *dst_line; \
|
||||
PIXMAN_COMPOSITE_ARGS (info); \
|
||||
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, \
|
||||
PIXMAN_IMAGE_GET_LINE (dest_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); \
|
||||
@ -398,13 +348,17 @@ scaled_bilinear_scanline_##cputype##_##name##_##op ( \
|
||||
\
|
||||
FAST_BILINEAR_MAINLOOP_COMMON (cputype##_##name##_cover_##op, \
|
||||
scaled_bilinear_scanline_##cputype##_##name##_##op, \
|
||||
src_type, uint32_t, dst_type, COVER, FALSE, FALSE) \
|
||||
src_type, uint32_t, dst_type, COVER, FLAG_NONE) \
|
||||
FAST_BILINEAR_MAINLOOP_COMMON (cputype##_##name##_none_##op, \
|
||||
scaled_bilinear_scanline_##cputype##_##name##_##op, \
|
||||
src_type, uint32_t, dst_type, NONE, FALSE, FALSE) \
|
||||
src_type, uint32_t, dst_type, NONE, FLAG_NONE) \
|
||||
FAST_BILINEAR_MAINLOOP_COMMON (cputype##_##name##_pad_##op, \
|
||||
scaled_bilinear_scanline_##cputype##_##name##_##op, \
|
||||
src_type, uint32_t, dst_type, PAD, FALSE, FALSE)
|
||||
src_type, uint32_t, dst_type, PAD, FLAG_NONE) \
|
||||
FAST_BILINEAR_MAINLOOP_COMMON (cputype##_##name##_normal_##op, \
|
||||
scaled_bilinear_scanline_##cputype##_##name##_##op, \
|
||||
src_type, uint32_t, dst_type, NORMAL, \
|
||||
FLAG_NONE)
|
||||
|
||||
|
||||
#define PIXMAN_ARM_BIND_SCALED_BILINEAR_SRC_A8_DST(flags, cputype, name, op, \
|
||||
@ -443,12 +397,20 @@ scaled_bilinear_scanline_##cputype##_##name##_##op ( \
|
||||
\
|
||||
FAST_BILINEAR_MAINLOOP_COMMON (cputype##_##name##_cover_##op, \
|
||||
scaled_bilinear_scanline_##cputype##_##name##_##op, \
|
||||
src_type, uint8_t, dst_type, COVER, TRUE, FALSE) \
|
||||
src_type, uint8_t, dst_type, COVER, \
|
||||
FLAG_HAVE_NON_SOLID_MASK) \
|
||||
FAST_BILINEAR_MAINLOOP_COMMON (cputype##_##name##_none_##op, \
|
||||
scaled_bilinear_scanline_##cputype##_##name##_##op, \
|
||||
src_type, uint8_t, dst_type, NONE, TRUE, FALSE) \
|
||||
src_type, uint8_t, dst_type, NONE, \
|
||||
FLAG_HAVE_NON_SOLID_MASK) \
|
||||
FAST_BILINEAR_MAINLOOP_COMMON (cputype##_##name##_pad_##op, \
|
||||
scaled_bilinear_scanline_##cputype##_##name##_##op, \
|
||||
src_type, uint8_t, dst_type, PAD, TRUE, FALSE)
|
||||
src_type, uint8_t, dst_type, PAD, \
|
||||
FLAG_HAVE_NON_SOLID_MASK) \
|
||||
FAST_BILINEAR_MAINLOOP_COMMON (cputype##_##name##_normal_##op, \
|
||||
scaled_bilinear_scanline_##cputype##_##name##_##op, \
|
||||
src_type, uint8_t, dst_type, NORMAL, \
|
||||
FLAG_HAVE_NON_SOLID_MASK)
|
||||
|
||||
|
||||
#endif
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -706,13 +706,55 @@ generate_composite_function_single_scanline \
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
/* TODO: expand macros and do better instructions scheduling */
|
||||
.macro pixman_composite_over_n_8888_process_pixblock_head
|
||||
/* deinterleaved source pixels in {d0, d1, d2, d3} */
|
||||
/* inverted alpha in {d24} */
|
||||
/* destination pixels in {d4, d5, d6, d7} */
|
||||
vmull.u8 q8, d24, d4
|
||||
vmull.u8 q9, d24, d5
|
||||
vmull.u8 q10, d24, d6
|
||||
vmull.u8 q11, d24, d7
|
||||
.endm
|
||||
|
||||
.macro pixman_composite_over_n_8888_process_pixblock_tail
|
||||
vrshr.u16 q14, q8, #8
|
||||
vrshr.u16 q15, q9, #8
|
||||
vrshr.u16 q2, q10, #8
|
||||
vrshr.u16 q3, q11, #8
|
||||
vraddhn.u16 d28, q14, q8
|
||||
vraddhn.u16 d29, q15, q9
|
||||
vraddhn.u16 d30, q2, q10
|
||||
vraddhn.u16 d31, q3, q11
|
||||
vqadd.u8 q14, q0, q14
|
||||
vqadd.u8 q15, q1, q15
|
||||
.endm
|
||||
|
||||
.macro pixman_composite_over_n_8888_process_pixblock_tail_head
|
||||
pixman_composite_over_8888_8888_process_pixblock_tail
|
||||
vrshr.u16 q14, q8, #8
|
||||
vrshr.u16 q15, q9, #8
|
||||
vrshr.u16 q2, q10, #8
|
||||
vrshr.u16 q3, q11, #8
|
||||
vraddhn.u16 d28, q14, q8
|
||||
vraddhn.u16 d29, q15, q9
|
||||
vraddhn.u16 d30, q2, q10
|
||||
vraddhn.u16 d31, q3, q11
|
||||
vld4.8 {d4, d5, d6, d7}, [DST_R, :128]!
|
||||
vst4.8 {d28, d29, d30, d31}, [DST_W, :128]!
|
||||
pixman_composite_over_8888_8888_process_pixblock_head
|
||||
cache_preload 8, 8
|
||||
vqadd.u8 q14, q0, q14
|
||||
PF add PF_X, PF_X, #8
|
||||
PF tst PF_CTL, #0x0F
|
||||
PF addne PF_X, PF_X, #8
|
||||
PF subne PF_CTL, PF_CTL, #1
|
||||
vqadd.u8 q15, q1, q15
|
||||
PF cmp PF_X, ORIG_W
|
||||
vmull.u8 q8, d24, d4
|
||||
PF pld, [PF_DST, PF_X, lsl #dst_bpp_shift]
|
||||
vmull.u8 q9, d24, d5
|
||||
PF subge PF_X, PF_X, ORIG_W
|
||||
vmull.u8 q10, d24, d6
|
||||
PF subges PF_CTL, PF_CTL, #0x10
|
||||
vmull.u8 q11, d24, d7
|
||||
PF ldrgeb DUMMY, [PF_DST, DST_STRIDE, lsl #dst_bpp_shift]!
|
||||
vst4.8 {d28, d29, d30, d31}, [DST_W, :128]!
|
||||
.endm
|
||||
|
||||
.macro pixman_composite_over_n_8888_init
|
||||
@ -722,6 +764,7 @@ generate_composite_function_single_scanline \
|
||||
vdup.8 d1, d3[1]
|
||||
vdup.8 d2, d3[2]
|
||||
vdup.8 d3, d3[3]
|
||||
vmvn.8 d24, d3 /* get inverted alpha */
|
||||
.endm
|
||||
|
||||
generate_composite_function \
|
||||
@ -1176,6 +1219,145 @@ generate_composite_function \
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
.macro pixman_composite_src_n_8_8888_process_pixblock_head
|
||||
/* expecting solid source in {d0, d1, d2, d3} */
|
||||
/* mask is in d24 (d25, d26, d27 are unused) */
|
||||
|
||||
/* in */
|
||||
vmull.u8 q8, d24, d0
|
||||
vmull.u8 q9, d24, d1
|
||||
vmull.u8 q10, d24, d2
|
||||
vmull.u8 q11, d24, d3
|
||||
vrsra.u16 q8, q8, #8
|
||||
vrsra.u16 q9, q9, #8
|
||||
vrsra.u16 q10, q10, #8
|
||||
vrsra.u16 q11, q11, #8
|
||||
.endm
|
||||
|
||||
.macro pixman_composite_src_n_8_8888_process_pixblock_tail
|
||||
vrshrn.u16 d28, q8, #8
|
||||
vrshrn.u16 d29, q9, #8
|
||||
vrshrn.u16 d30, q10, #8
|
||||
vrshrn.u16 d31, q11, #8
|
||||
.endm
|
||||
|
||||
.macro pixman_composite_src_n_8_8888_process_pixblock_tail_head
|
||||
fetch_mask_pixblock
|
||||
PF add PF_X, PF_X, #8
|
||||
vrshrn.u16 d28, q8, #8
|
||||
PF tst PF_CTL, #0x0F
|
||||
vrshrn.u16 d29, q9, #8
|
||||
PF addne PF_X, PF_X, #8
|
||||
vrshrn.u16 d30, q10, #8
|
||||
PF subne PF_CTL, PF_CTL, #1
|
||||
vrshrn.u16 d31, q11, #8
|
||||
PF cmp PF_X, ORIG_W
|
||||
vmull.u8 q8, d24, d0
|
||||
PF pld, [PF_MASK, PF_X, lsl #mask_bpp_shift]
|
||||
vmull.u8 q9, d24, d1
|
||||
PF subge PF_X, PF_X, ORIG_W
|
||||
vmull.u8 q10, d24, d2
|
||||
PF subges PF_CTL, PF_CTL, #0x10
|
||||
vmull.u8 q11, d24, d3
|
||||
PF ldrgeb DUMMY, [PF_MASK, MASK_STRIDE, lsl #mask_bpp_shift]!
|
||||
vst4.8 {d28, d29, d30, d31}, [DST_W, :128]!
|
||||
vrsra.u16 q8, q8, #8
|
||||
vrsra.u16 q9, q9, #8
|
||||
vrsra.u16 q10, q10, #8
|
||||
vrsra.u16 q11, q11, #8
|
||||
.endm
|
||||
|
||||
.macro pixman_composite_src_n_8_8888_init
|
||||
add DUMMY, sp, #ARGS_STACK_OFFSET
|
||||
vld1.32 {d3[0]}, [DUMMY]
|
||||
vdup.8 d0, d3[0]
|
||||
vdup.8 d1, d3[1]
|
||||
vdup.8 d2, d3[2]
|
||||
vdup.8 d3, d3[3]
|
||||
.endm
|
||||
|
||||
.macro pixman_composite_src_n_8_8888_cleanup
|
||||
.endm
|
||||
|
||||
generate_composite_function \
|
||||
pixman_composite_src_n_8_8888_asm_neon, 0, 8, 32, \
|
||||
FLAG_DST_WRITEONLY | FLAG_DEINTERLEAVE_32BPP, \
|
||||
8, /* number of pixels, processed in a single block */ \
|
||||
5, /* prefetch distance */ \
|
||||
pixman_composite_src_n_8_8888_init, \
|
||||
pixman_composite_src_n_8_8888_cleanup, \
|
||||
pixman_composite_src_n_8_8888_process_pixblock_head, \
|
||||
pixman_composite_src_n_8_8888_process_pixblock_tail, \
|
||||
pixman_composite_src_n_8_8888_process_pixblock_tail_head, \
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
.macro pixman_composite_src_n_8_8_process_pixblock_head
|
||||
vmull.u8 q0, d24, d16
|
||||
vmull.u8 q1, d25, d16
|
||||
vmull.u8 q2, d26, d16
|
||||
vmull.u8 q3, d27, d16
|
||||
vrsra.u16 q0, q0, #8
|
||||
vrsra.u16 q1, q1, #8
|
||||
vrsra.u16 q2, q2, #8
|
||||
vrsra.u16 q3, q3, #8
|
||||
.endm
|
||||
|
||||
.macro pixman_composite_src_n_8_8_process_pixblock_tail
|
||||
vrshrn.u16 d28, q0, #8
|
||||
vrshrn.u16 d29, q1, #8
|
||||
vrshrn.u16 d30, q2, #8
|
||||
vrshrn.u16 d31, q3, #8
|
||||
.endm
|
||||
|
||||
.macro pixman_composite_src_n_8_8_process_pixblock_tail_head
|
||||
fetch_mask_pixblock
|
||||
PF add PF_X, PF_X, #8
|
||||
vrshrn.u16 d28, q0, #8
|
||||
PF tst PF_CTL, #0x0F
|
||||
vrshrn.u16 d29, q1, #8
|
||||
PF addne PF_X, PF_X, #8
|
||||
vrshrn.u16 d30, q2, #8
|
||||
PF subne PF_CTL, PF_CTL, #1
|
||||
vrshrn.u16 d31, q3, #8
|
||||
PF cmp PF_X, ORIG_W
|
||||
vmull.u8 q0, d24, d16
|
||||
PF pld, [PF_MASK, PF_X, lsl #mask_bpp_shift]
|
||||
vmull.u8 q1, d25, d16
|
||||
PF subge PF_X, PF_X, ORIG_W
|
||||
vmull.u8 q2, d26, d16
|
||||
PF subges PF_CTL, PF_CTL, #0x10
|
||||
vmull.u8 q3, d27, d16
|
||||
PF ldrgeb DUMMY, [PF_MASK, MASK_STRIDE, lsl #mask_bpp_shift]!
|
||||
vst1.8 {d28, d29, d30, d31}, [DST_W, :128]!
|
||||
vrsra.u16 q0, q0, #8
|
||||
vrsra.u16 q1, q1, #8
|
||||
vrsra.u16 q2, q2, #8
|
||||
vrsra.u16 q3, q3, #8
|
||||
.endm
|
||||
|
||||
.macro pixman_composite_src_n_8_8_init
|
||||
add DUMMY, sp, #ARGS_STACK_OFFSET
|
||||
vld1.32 {d16[0]}, [DUMMY]
|
||||
vdup.8 d16, d16[3]
|
||||
.endm
|
||||
|
||||
.macro pixman_composite_src_n_8_8_cleanup
|
||||
.endm
|
||||
|
||||
generate_composite_function \
|
||||
pixman_composite_src_n_8_8_asm_neon, 0, 8, 8, \
|
||||
FLAG_DST_WRITEONLY, \
|
||||
32, /* number of pixels, processed in a single block */ \
|
||||
5, /* prefetch distance */ \
|
||||
pixman_composite_src_n_8_8_init, \
|
||||
pixman_composite_src_n_8_8_cleanup, \
|
||||
pixman_composite_src_n_8_8_process_pixblock_head, \
|
||||
pixman_composite_src_n_8_8_process_pixblock_tail, \
|
||||
pixman_composite_src_n_8_8_process_pixblock_tail_head
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
.macro pixman_composite_over_n_8_8888_process_pixblock_head
|
||||
/* expecting deinterleaved source data in {d8, d9, d10, d11} */
|
||||
/* d8 - blue, d9 - green, d10 - red, d11 - alpha */
|
||||
@ -1183,49 +1365,83 @@ generate_composite_function \
|
||||
/* mask is in d24 (d25, d26, d27 are unused) */
|
||||
|
||||
/* in */
|
||||
vmull.u8 q0, d24, d8
|
||||
vmull.u8 q1, d24, d9
|
||||
vmull.u8 q6, d24, d10
|
||||
vmull.u8 q7, d24, d11
|
||||
vrshr.u16 q10, q0, #8
|
||||
vrshr.u16 q11, q1, #8
|
||||
vrshr.u16 q12, q6, #8
|
||||
vrshr.u16 q13, q7, #8
|
||||
vraddhn.u16 d0, q0, q10
|
||||
vraddhn.u16 d1, q1, q11
|
||||
vraddhn.u16 d2, q6, q12
|
||||
vraddhn.u16 d3, q7, q13
|
||||
vmvn.8 d24, d3 /* get inverted alpha */
|
||||
vmull.u8 q6, d24, d8
|
||||
vmull.u8 q7, d24, d9
|
||||
vmull.u8 q8, d24, d10
|
||||
vmull.u8 q9, d24, d11
|
||||
vrshr.u16 q10, q6, #8
|
||||
vrshr.u16 q11, q7, #8
|
||||
vrshr.u16 q12, q8, #8
|
||||
vrshr.u16 q13, q9, #8
|
||||
vraddhn.u16 d0, q6, q10
|
||||
vraddhn.u16 d1, q7, q11
|
||||
vraddhn.u16 d2, q8, q12
|
||||
vraddhn.u16 d3, q9, q13
|
||||
vmvn.8 d25, d3 /* get inverted alpha */
|
||||
/* source: d0 - blue, d1 - green, d2 - red, d3 - alpha */
|
||||
/* destination: d4 - blue, d5 - green, d6 - red, d7 - alpha */
|
||||
/* now do alpha blending */
|
||||
vmull.u8 q8, d24, d4
|
||||
vmull.u8 q9, d24, d5
|
||||
vmull.u8 q10, d24, d6
|
||||
vmull.u8 q11, d24, d7
|
||||
vmull.u8 q8, d25, d4
|
||||
vmull.u8 q9, d25, d5
|
||||
vmull.u8 q10, d25, d6
|
||||
vmull.u8 q11, d25, d7
|
||||
.endm
|
||||
|
||||
.macro pixman_composite_over_n_8_8888_process_pixblock_tail
|
||||
vrshr.u16 q14, q8, #8
|
||||
vrshr.u16 q15, q9, #8
|
||||
vrshr.u16 q12, q10, #8
|
||||
vrshr.u16 q13, q11, #8
|
||||
vrshr.u16 q6, q10, #8
|
||||
vrshr.u16 q7, q11, #8
|
||||
vraddhn.u16 d28, q14, q8
|
||||
vraddhn.u16 d29, q15, q9
|
||||
vraddhn.u16 d30, q12, q10
|
||||
vraddhn.u16 d31, q13, q11
|
||||
vraddhn.u16 d30, q6, q10
|
||||
vraddhn.u16 d31, q7, q11
|
||||
vqadd.u8 q14, q0, q14
|
||||
vqadd.u8 q15, q1, q15
|
||||
.endm
|
||||
|
||||
/* TODO: expand macros and do better instructions scheduling */
|
||||
.macro pixman_composite_over_n_8_8888_process_pixblock_tail_head
|
||||
pixman_composite_over_n_8_8888_process_pixblock_tail
|
||||
vst4.8 {d28, d29, d30, d31}, [DST_W, :128]!
|
||||
vrshr.u16 q14, q8, #8
|
||||
vld4.8 {d4, d5, d6, d7}, [DST_R, :128]!
|
||||
vrshr.u16 q15, q9, #8
|
||||
fetch_mask_pixblock
|
||||
cache_preload 8, 8
|
||||
pixman_composite_over_n_8_8888_process_pixblock_head
|
||||
vrshr.u16 q6, q10, #8
|
||||
PF add PF_X, PF_X, #8
|
||||
vrshr.u16 q7, q11, #8
|
||||
PF tst PF_CTL, #0x0F
|
||||
vraddhn.u16 d28, q14, q8
|
||||
PF addne PF_X, PF_X, #8
|
||||
vraddhn.u16 d29, q15, q9
|
||||
PF subne PF_CTL, PF_CTL, #1
|
||||
vraddhn.u16 d30, q6, q10
|
||||
PF cmp PF_X, ORIG_W
|
||||
vraddhn.u16 d31, q7, q11
|
||||
PF pld, [PF_DST, PF_X, lsl #dst_bpp_shift]
|
||||
vmull.u8 q6, d24, d8
|
||||
PF pld, [PF_MASK, PF_X, lsl #mask_bpp_shift]
|
||||
vmull.u8 q7, d24, d9
|
||||
PF subge PF_X, PF_X, ORIG_W
|
||||
vmull.u8 q8, d24, d10
|
||||
PF subges PF_CTL, PF_CTL, #0x10
|
||||
vmull.u8 q9, d24, d11
|
||||
PF ldrgeb DUMMY, [PF_DST, DST_STRIDE, lsl #dst_bpp_shift]!
|
||||
vqadd.u8 q14, q0, q14
|
||||
PF ldrgeb DUMMY, [PF_MASK, MASK_STRIDE, lsl #mask_bpp_shift]!
|
||||
vqadd.u8 q15, q1, q15
|
||||
vrshr.u16 q10, q6, #8
|
||||
vrshr.u16 q11, q7, #8
|
||||
vrshr.u16 q12, q8, #8
|
||||
vrshr.u16 q13, q9, #8
|
||||
vraddhn.u16 d0, q6, q10
|
||||
vraddhn.u16 d1, q7, q11
|
||||
vraddhn.u16 d2, q8, q12
|
||||
vraddhn.u16 d3, q9, q13
|
||||
vst4.8 {d28, d29, d30, d31}, [DST_W, :128]!
|
||||
vmvn.8 d25, d3
|
||||
vmull.u8 q8, d25, d4
|
||||
vmull.u8 q9, d25, d5
|
||||
vmull.u8 q10, d25, d6
|
||||
vmull.u8 q11, d25, d7
|
||||
.endm
|
||||
|
||||
.macro pixman_composite_over_n_8_8888_init
|
||||
@ -1515,11 +1731,11 @@ generate_composite_function \
|
||||
* output: updated src in {d0, d1, d2 } [B, G, R]
|
||||
* updated mask in {d24, d25, d26} [B, G, R]
|
||||
*/
|
||||
vmull.u8 q1, d25, d9
|
||||
vmull.u8 q6, d26, d10
|
||||
vqadd.u8 q8, q0, q8
|
||||
vmull.u8 q0, d24, d8
|
||||
vqadd.u8 d22, d2, d22
|
||||
vmull.u8 q6, d26, d10
|
||||
vmull.u8 q1, d25, d9
|
||||
/*
|
||||
* convert the result in d16, d17, d22 to r5g6b5 and store
|
||||
* it into {d28, d29}
|
||||
@ -1542,6 +1758,7 @@ generate_composite_function \
|
||||
vrshr.u16 q11, q12, #8
|
||||
vrshr.u16 q8, q9, #8
|
||||
vrshr.u16 q6, q13, #8
|
||||
vraddhn.u16 d24, q12, q11
|
||||
vraddhn.u16 d25, q9, q8
|
||||
/*
|
||||
* convert 8 r5g6b5 pixel data from {d4, d5} to planar
|
||||
@ -1550,11 +1767,10 @@ generate_composite_function \
|
||||
*/
|
||||
vshrn.u16 d17, q2, #3
|
||||
vshrn.u16 d18, q2, #8
|
||||
vraddhn.u16 d24, q12, q11
|
||||
vraddhn.u16 d26, q13, q6
|
||||
vsli.u16 q2, q2, #5
|
||||
vsri.u8 d18, d18, #5
|
||||
vsri.u8 d17, d17, #6
|
||||
vsri.u8 d18, d18, #5
|
||||
/*
|
||||
* 'combine_over_ca' replacement
|
||||
*
|
||||
@ -2489,6 +2705,56 @@ generate_composite_function \
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
.macro pixman_composite_out_reverse_8_8888_process_pixblock_head
|
||||
/* src is in d0 */
|
||||
/* destination pixel data is in {d4, d5, d6, d7} */
|
||||
vmvn.8 d1, d0 /* get inverted alpha */
|
||||
/* now do alpha blending */
|
||||
vmull.u8 q8, d1, d4
|
||||
vmull.u8 q9, d1, d5
|
||||
vmull.u8 q10, d1, d6
|
||||
vmull.u8 q11, d1, d7
|
||||
.endm
|
||||
|
||||
.macro pixman_composite_out_reverse_8_8888_process_pixblock_tail
|
||||
vrshr.u16 q14, q8, #8
|
||||
vrshr.u16 q15, q9, #8
|
||||
vrshr.u16 q12, q10, #8
|
||||
vrshr.u16 q13, q11, #8
|
||||
vraddhn.u16 d28, q14, q8
|
||||
vraddhn.u16 d29, q15, q9
|
||||
vraddhn.u16 d30, q12, q10
|
||||
vraddhn.u16 d31, q13, q11
|
||||
/* 32bpp result is in {d28, d29, d30, d31} */
|
||||
.endm
|
||||
|
||||
/* TODO: expand macros and do better instructions scheduling */
|
||||
.macro pixman_composite_out_reverse_8_8888_process_pixblock_tail_head
|
||||
fetch_src_pixblock
|
||||
pixman_composite_out_reverse_8_8888_process_pixblock_tail
|
||||
vld4.8 {d4, d5, d6, d7}, [DST_R, :128]!
|
||||
cache_preload 8, 8
|
||||
pixman_composite_out_reverse_8_8888_process_pixblock_head
|
||||
vst4.8 {d28, d29, d30, d31}, [DST_W, :128]!
|
||||
.endm
|
||||
|
||||
generate_composite_function \
|
||||
pixman_composite_out_reverse_8_8888_asm_neon, 8, 0, 32, \
|
||||
FLAG_DST_READWRITE | FLAG_DEINTERLEAVE_32BPP, \
|
||||
8, /* number of pixels, processed in a single block */ \
|
||||
5, /* prefetch distance */ \
|
||||
default_init, \
|
||||
default_cleanup, \
|
||||
pixman_composite_out_reverse_8_8888_process_pixblock_head, \
|
||||
pixman_composite_out_reverse_8_8888_process_pixblock_tail, \
|
||||
pixman_composite_out_reverse_8_8888_process_pixblock_tail_head, \
|
||||
28, /* dst_w_basereg */ \
|
||||
4, /* dst_r_basereg */ \
|
||||
0, /* 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, \
|
||||
|
@ -64,6 +64,8 @@ PIXMAN_ARM_BIND_FAST_PATH_SRC_DST (neon, over_8888_8888,
|
||||
uint32_t, 1, uint32_t, 1)
|
||||
PIXMAN_ARM_BIND_FAST_PATH_SRC_DST (neon, out_reverse_8_0565,
|
||||
uint8_t, 1, uint16_t, 1)
|
||||
PIXMAN_ARM_BIND_FAST_PATH_SRC_DST (neon, out_reverse_8_8888,
|
||||
uint8_t, 1, uint32_t, 1)
|
||||
|
||||
PIXMAN_ARM_BIND_FAST_PATH_N_DST (SKIP_ZERO_SRC, neon, over_n_0565,
|
||||
uint16_t, 1)
|
||||
@ -88,6 +90,10 @@ PIXMAN_ARM_BIND_FAST_PATH_N_MASK_DST (SKIP_ZERO_SRC, neon, add_n_8_8,
|
||||
uint8_t, 1, uint8_t, 1)
|
||||
PIXMAN_ARM_BIND_FAST_PATH_N_MASK_DST (SKIP_ZERO_SRC, neon, add_n_8_8888,
|
||||
uint8_t, 1, uint32_t, 1)
|
||||
PIXMAN_ARM_BIND_FAST_PATH_N_MASK_DST (0, neon, src_n_8_8888,
|
||||
uint8_t, 1, uint32_t, 1)
|
||||
PIXMAN_ARM_BIND_FAST_PATH_N_MASK_DST (0, neon, src_n_8_8,
|
||||
uint8_t, 1, uint8_t, 1)
|
||||
|
||||
PIXMAN_ARM_BIND_FAST_PATH_SRC_N_DST (SKIP_ZERO_MASK, neon, over_8888_n_8888,
|
||||
uint32_t, 1, uint32_t, 1)
|
||||
@ -229,8 +235,8 @@ pixman_blt_neon (uint32_t *src_bits,
|
||||
int dst_bpp,
|
||||
int src_x,
|
||||
int src_y,
|
||||
int dst_x,
|
||||
int dst_y,
|
||||
int dest_x,
|
||||
int dest_y,
|
||||
int width,
|
||||
int height)
|
||||
{
|
||||
@ -243,7 +249,7 @@ pixman_blt_neon (uint32_t *src_bits,
|
||||
pixman_composite_src_0565_0565_asm_neon (
|
||||
width, height,
|
||||
(uint16_t *)(((char *) dst_bits) +
|
||||
dst_y * dst_stride * 4 + dst_x * 2), dst_stride * 2,
|
||||
dest_y * dst_stride * 4 + dest_x * 2), dst_stride * 2,
|
||||
(uint16_t *)(((char *) src_bits) +
|
||||
src_y * src_stride * 4 + src_x * 2), src_stride * 2);
|
||||
return TRUE;
|
||||
@ -251,7 +257,7 @@ pixman_blt_neon (uint32_t *src_bits,
|
||||
pixman_composite_src_8888_8888_asm_neon (
|
||||
width, height,
|
||||
(uint32_t *)(((char *) dst_bits) +
|
||||
dst_y * dst_stride * 4 + dst_x * 4), dst_stride,
|
||||
dest_y * dst_stride * 4 + dest_x * 4), dst_stride,
|
||||
(uint32_t *)(((char *) src_bits) +
|
||||
src_y * src_stride * 4 + src_x * 4), src_stride);
|
||||
return TRUE;
|
||||
@ -287,6 +293,12 @@ static const pixman_fast_path_t arm_neon_fast_paths[] =
|
||||
PIXMAN_STD_FAST_PATH (SRC, pixbuf, pixbuf, a8b8g8r8, neon_composite_src_rpixbuf_8888),
|
||||
PIXMAN_STD_FAST_PATH (SRC, rpixbuf, rpixbuf, a8r8g8b8, neon_composite_src_rpixbuf_8888),
|
||||
PIXMAN_STD_FAST_PATH (SRC, rpixbuf, rpixbuf, a8b8g8r8, neon_composite_src_pixbuf_8888),
|
||||
PIXMAN_STD_FAST_PATH (SRC, solid, a8, a8r8g8b8, neon_composite_src_n_8_8888),
|
||||
PIXMAN_STD_FAST_PATH (SRC, solid, a8, x8r8g8b8, neon_composite_src_n_8_8888),
|
||||
PIXMAN_STD_FAST_PATH (SRC, solid, a8, a8b8g8r8, neon_composite_src_n_8_8888),
|
||||
PIXMAN_STD_FAST_PATH (SRC, solid, a8, x8b8g8r8, neon_composite_src_n_8_8888),
|
||||
PIXMAN_STD_FAST_PATH (SRC, solid, a8, a8, neon_composite_src_n_8_8),
|
||||
|
||||
PIXMAN_STD_FAST_PATH (OVER, solid, a8, a8, neon_composite_over_n_8_8),
|
||||
PIXMAN_STD_FAST_PATH (OVER, solid, a8, r5g6b5, neon_composite_over_n_8_0565),
|
||||
PIXMAN_STD_FAST_PATH (OVER, solid, a8, b5g6r5, neon_composite_over_n_8_0565),
|
||||
@ -345,6 +357,8 @@ static const pixman_fast_path_t arm_neon_fast_paths[] =
|
||||
PIXMAN_STD_FAST_PATH (OVER_REVERSE, solid, null, a8b8g8r8, neon_composite_over_reverse_n_8888),
|
||||
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_STD_FAST_PATH (OUT_REVERSE, a8, null, a8r8g8b8, neon_composite_out_reverse_8_8888),
|
||||
PIXMAN_STD_FAST_PATH (OUT_REVERSE, a8, null, a8b8g8r8, neon_composite_out_reverse_8_8888),
|
||||
|
||||
PIXMAN_ARM_SIMPLE_NEAREST_FAST_PATH (OVER, a8r8g8b8, a8r8g8b8, neon_8888_8888),
|
||||
PIXMAN_ARM_SIMPLE_NEAREST_FAST_PATH (OVER, a8b8g8r8, a8b8g8r8, neon_8888_8888),
|
||||
@ -418,20 +432,20 @@ arm_neon_blt (pixman_implementation_t *imp,
|
||||
int dst_bpp,
|
||||
int src_x,
|
||||
int src_y,
|
||||
int dst_x,
|
||||
int dst_y,
|
||||
int dest_x,
|
||||
int dest_y,
|
||||
int width,
|
||||
int height)
|
||||
{
|
||||
if (!pixman_blt_neon (
|
||||
src_bits, dst_bits, src_stride, dst_stride, src_bpp, dst_bpp,
|
||||
src_x, src_y, dst_x, dst_y, width, height))
|
||||
src_x, src_y, dest_x, dest_y, width, height))
|
||||
|
||||
{
|
||||
return _pixman_implementation_blt (
|
||||
imp->delegate,
|
||||
src_bits, dst_bits, src_stride, dst_stride, src_bpp, dst_bpp,
|
||||
src_x, src_y, dst_x, dst_y, width, height);
|
||||
src_x, src_y, dest_x, dest_y, width, height);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
|
@ -29,7 +29,7 @@
|
||||
|
||||
#include "pixman-private.h"
|
||||
#include "pixman-arm-common.h"
|
||||
#include "pixman-fast-path.h"
|
||||
#include "pixman-inlines.h"
|
||||
|
||||
#if 0 /* This code was moved to 'pixman-arm-simd-asm.S' */
|
||||
|
||||
|
@ -34,6 +34,7 @@
|
||||
#include <string.h>
|
||||
#include "pixman-private.h"
|
||||
#include "pixman-combine32.h"
|
||||
#include "pixman-inlines.h"
|
||||
|
||||
/*
|
||||
* By default, just evaluate the image at 32bpp and expand. Individual image
|
||||
@ -90,34 +91,6 @@ fetch_pixel_no_alpha (bits_image_t *image,
|
||||
typedef uint32_t (* get_pixel_t) (bits_image_t *image,
|
||||
int x, int y, pixman_bool_t check_bounds);
|
||||
|
||||
static force_inline void
|
||||
repeat (pixman_repeat_t repeat, int size, int *coord)
|
||||
{
|
||||
switch (repeat)
|
||||
{
|
||||
case PIXMAN_REPEAT_NORMAL:
|
||||
*coord = MOD (*coord, size);
|
||||
break;
|
||||
|
||||
case PIXMAN_REPEAT_PAD:
|
||||
*coord = CLIP (*coord, 0, size - 1);
|
||||
break;
|
||||
|
||||
case PIXMAN_REPEAT_REFLECT:
|
||||
*coord = MOD (*coord, size * 2);
|
||||
|
||||
if (*coord >= size)
|
||||
*coord = size * 2 - *coord - 1;
|
||||
break;
|
||||
|
||||
case PIXMAN_REPEAT_NONE:
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static force_inline uint32_t
|
||||
bits_image_fetch_pixel_nearest (bits_image_t *image,
|
||||
pixman_fixed_t x,
|
||||
@ -129,8 +102,8 @@ bits_image_fetch_pixel_nearest (bits_image_t *image,
|
||||
|
||||
if (image->common.repeat != PIXMAN_REPEAT_NONE)
|
||||
{
|
||||
repeat (image->common.repeat, image->width, &x0);
|
||||
repeat (image->common.repeat, image->height, &y0);
|
||||
repeat (image->common.repeat, &x0, image->width);
|
||||
repeat (image->common.repeat, &y0, image->height);
|
||||
|
||||
return get_pixel (image, x0, y0, FALSE);
|
||||
}
|
||||
@ -140,97 +113,6 @@ bits_image_fetch_pixel_nearest (bits_image_t *image,
|
||||
}
|
||||
}
|
||||
|
||||
#if SIZEOF_LONG > 4
|
||||
|
||||
static force_inline uint32_t
|
||||
bilinear_interpolation (uint32_t tl, uint32_t tr,
|
||||
uint32_t bl, uint32_t br,
|
||||
int distx, int disty)
|
||||
{
|
||||
uint64_t distxy, distxiy, distixy, distixiy;
|
||||
uint64_t tl64, tr64, bl64, br64;
|
||||
uint64_t f, r;
|
||||
|
||||
distxy = distx * disty;
|
||||
distxiy = distx * (256 - disty);
|
||||
distixy = (256 - distx) * disty;
|
||||
distixiy = (256 - distx) * (256 - disty);
|
||||
|
||||
/* Alpha and Blue */
|
||||
tl64 = tl & 0xff0000ff;
|
||||
tr64 = tr & 0xff0000ff;
|
||||
bl64 = bl & 0xff0000ff;
|
||||
br64 = br & 0xff0000ff;
|
||||
|
||||
f = tl64 * distixiy + tr64 * distxiy + bl64 * distixy + br64 * distxy;
|
||||
r = f & 0x0000ff0000ff0000ull;
|
||||
|
||||
/* Red and Green */
|
||||
tl64 = tl;
|
||||
tl64 = ((tl64 << 16) & 0x000000ff00000000ull) | (tl64 & 0x0000ff00ull);
|
||||
|
||||
tr64 = tr;
|
||||
tr64 = ((tr64 << 16) & 0x000000ff00000000ull) | (tr64 & 0x0000ff00ull);
|
||||
|
||||
bl64 = bl;
|
||||
bl64 = ((bl64 << 16) & 0x000000ff00000000ull) | (bl64 & 0x0000ff00ull);
|
||||
|
||||
br64 = br;
|
||||
br64 = ((br64 << 16) & 0x000000ff00000000ull) | (br64 & 0x0000ff00ull);
|
||||
|
||||
f = tl64 * distixiy + tr64 * distxiy + bl64 * distixy + br64 * distxy;
|
||||
r |= ((f >> 16) & 0x000000ff00000000ull) | (f & 0xff000000ull);
|
||||
|
||||
return (uint32_t)(r >> 16);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
static force_inline uint32_t
|
||||
bilinear_interpolation (uint32_t tl, uint32_t tr,
|
||||
uint32_t bl, uint32_t br,
|
||||
int distx, int disty)
|
||||
{
|
||||
int distxy, distxiy, distixy, distixiy;
|
||||
uint32_t f, r;
|
||||
|
||||
distxy = distx * disty;
|
||||
distxiy = (distx << 8) - distxy; /* distx * (256 - disty) */
|
||||
distixy = (disty << 8) - distxy; /* disty * (256 - distx) */
|
||||
distixiy =
|
||||
256 * 256 - (disty << 8) -
|
||||
(distx << 8) + distxy; /* (256 - distx) * (256 - disty) */
|
||||
|
||||
/* Blue */
|
||||
r = (tl & 0x000000ff) * distixiy + (tr & 0x000000ff) * distxiy
|
||||
+ (bl & 0x000000ff) * distixy + (br & 0x000000ff) * distxy;
|
||||
|
||||
/* Green */
|
||||
f = (tl & 0x0000ff00) * distixiy + (tr & 0x0000ff00) * distxiy
|
||||
+ (bl & 0x0000ff00) * distixy + (br & 0x0000ff00) * distxy;
|
||||
r |= f & 0xff000000;
|
||||
|
||||
tl >>= 16;
|
||||
tr >>= 16;
|
||||
bl >>= 16;
|
||||
br >>= 16;
|
||||
r >>= 16;
|
||||
|
||||
/* Red */
|
||||
f = (tl & 0x000000ff) * distixiy + (tr & 0x000000ff) * distxiy
|
||||
+ (bl & 0x000000ff) * distixy + (br & 0x000000ff) * distxy;
|
||||
r |= f & 0x00ff0000;
|
||||
|
||||
/* Alpha */
|
||||
f = (tl & 0x0000ff00) * distixiy + (tr & 0x0000ff00) * distxiy
|
||||
+ (bl & 0x0000ff00) * distixy + (br & 0x0000ff00) * distxy;
|
||||
r |= f & 0xff000000;
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static force_inline uint32_t
|
||||
bits_image_fetch_pixel_bilinear (bits_image_t *image,
|
||||
pixman_fixed_t x,
|
||||
@ -257,10 +139,10 @@ bits_image_fetch_pixel_bilinear (bits_image_t *image,
|
||||
|
||||
if (repeat_mode != PIXMAN_REPEAT_NONE)
|
||||
{
|
||||
repeat (repeat_mode, width, &x1);
|
||||
repeat (repeat_mode, height, &y1);
|
||||
repeat (repeat_mode, width, &x2);
|
||||
repeat (repeat_mode, height, &y2);
|
||||
repeat (repeat_mode, &x1, width);
|
||||
repeat (repeat_mode, &y1, height);
|
||||
repeat (repeat_mode, &x2, width);
|
||||
repeat (repeat_mode, &y2, height);
|
||||
|
||||
tl = get_pixel (image, x1, y1, FALSE);
|
||||
bl = get_pixel (image, x1, y2, FALSE);
|
||||
@ -529,8 +411,8 @@ bits_image_fetch_pixel_convolution (bits_image_t *image,
|
||||
|
||||
if (repeat_mode != PIXMAN_REPEAT_NONE)
|
||||
{
|
||||
repeat (repeat_mode, width, &rx);
|
||||
repeat (repeat_mode, height, &ry);
|
||||
repeat (repeat_mode, &rx, width);
|
||||
repeat (repeat_mode, &ry, height);
|
||||
|
||||
pixel = get_pixel (image, rx, ry, FALSE);
|
||||
}
|
||||
@ -812,10 +694,10 @@ bits_image_fetch_bilinear_affine (pixman_image_t * image,
|
||||
|
||||
mask = PIXMAN_FORMAT_A (format)? 0 : 0xff000000;
|
||||
|
||||
repeat (repeat_mode, width, &x1);
|
||||
repeat (repeat_mode, height, &y1);
|
||||
repeat (repeat_mode, width, &x2);
|
||||
repeat (repeat_mode, height, &y2);
|
||||
repeat (repeat_mode, &x1, width);
|
||||
repeat (repeat_mode, &y1, height);
|
||||
repeat (repeat_mode, &x2, width);
|
||||
repeat (repeat_mode, &y2, height);
|
||||
|
||||
row1 = (uint8_t *)bits->bits + bits->rowstride * 4 * y1;
|
||||
row2 = (uint8_t *)bits->bits + bits->rowstride * 4 * y2;
|
||||
@ -960,8 +842,8 @@ bits_image_fetch_nearest_affine (pixman_image_t * image,
|
||||
|
||||
if (repeat_mode != PIXMAN_REPEAT_NONE)
|
||||
{
|
||||
repeat (repeat_mode, width, &x0);
|
||||
repeat (repeat_mode, height, &y0);
|
||||
repeat (repeat_mode, &x0, width);
|
||||
repeat (repeat_mode, &y0, height);
|
||||
}
|
||||
|
||||
row = (uint8_t *)bits->bits + bits->rowstride * 4 * y0;
|
||||
@ -1053,17 +935,16 @@ MAKE_FETCHERS (reflect_r5g6b5, r5g6b5, PIXMAN_REPEAT_REFLECT)
|
||||
MAKE_FETCHERS (normal_r5g6b5, r5g6b5, PIXMAN_REPEAT_NORMAL)
|
||||
|
||||
static void
|
||||
bits_image_fetch_solid_32 (pixman_image_t * image,
|
||||
int x,
|
||||
int y,
|
||||
int width,
|
||||
uint32_t * buffer,
|
||||
const uint32_t * mask)
|
||||
replicate_pixel_32 (bits_image_t * bits,
|
||||
int x,
|
||||
int y,
|
||||
int width,
|
||||
uint32_t * buffer)
|
||||
{
|
||||
uint32_t color;
|
||||
uint32_t *end;
|
||||
|
||||
color = image->bits.fetch_pixel_32 (&image->bits, 0, 0);
|
||||
color = bits->fetch_pixel_32 (bits, x, y);
|
||||
|
||||
end = buffer + width;
|
||||
while (buffer < end)
|
||||
@ -1071,18 +952,17 @@ bits_image_fetch_solid_32 (pixman_image_t * image,
|
||||
}
|
||||
|
||||
static void
|
||||
bits_image_fetch_solid_64 (pixman_image_t * image,
|
||||
int x,
|
||||
int y,
|
||||
int width,
|
||||
uint32_t * b,
|
||||
const uint32_t * unused)
|
||||
replicate_pixel_64 (bits_image_t * bits,
|
||||
int x,
|
||||
int y,
|
||||
int width,
|
||||
uint32_t * b)
|
||||
{
|
||||
uint64_t color;
|
||||
uint64_t *buffer = (uint64_t *)b;
|
||||
uint64_t *end;
|
||||
|
||||
color = image->bits.fetch_pixel_64 (&image->bits, 0, 0);
|
||||
color = bits->fetch_pixel_64 (bits, x, y);
|
||||
|
||||
end = buffer + width;
|
||||
while (buffer < end)
|
||||
@ -1149,6 +1029,16 @@ bits_image_fetch_untransformed_repeat_normal (bits_image_t *image,
|
||||
while (y >= image->height)
|
||||
y -= image->height;
|
||||
|
||||
if (image->width == 1)
|
||||
{
|
||||
if (wide)
|
||||
replicate_pixel_64 (image, 0, y, width, buffer);
|
||||
else
|
||||
replicate_pixel_32 (image, 0, y, width, buffer);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
while (width)
|
||||
{
|
||||
while (x < 0)
|
||||
@ -1219,12 +1109,6 @@ typedef struct
|
||||
|
||||
static const fetcher_info_t fetcher_info[] =
|
||||
{
|
||||
{ PIXMAN_solid,
|
||||
FAST_PATH_NO_ALPHA_MAP,
|
||||
bits_image_fetch_solid_32,
|
||||
bits_image_fetch_solid_64
|
||||
},
|
||||
|
||||
{ PIXMAN_any,
|
||||
(FAST_PATH_NO_ALPHA_MAP |
|
||||
FAST_PATH_ID_TRANSFORM |
|
||||
@ -1382,12 +1266,27 @@ dest_get_scanline_narrow (pixman_iter_t *iter, const uint32_t *mask)
|
||||
image->bits.fetch_scanline_32 (image, x, y, width, buffer, mask);
|
||||
if (image->common.alpha_map)
|
||||
{
|
||||
x -= image->common.alpha_origin_x;
|
||||
y -= image->common.alpha_origin_y;
|
||||
uint32_t *alpha;
|
||||
|
||||
image->common.alpha_map->fetch_scanline_32 (
|
||||
(pixman_image_t *)image->common.alpha_map,
|
||||
x, y, width, buffer, mask);
|
||||
if ((alpha = malloc (width * sizeof (uint32_t))))
|
||||
{
|
||||
int i;
|
||||
|
||||
x -= image->common.alpha_origin_x;
|
||||
y -= image->common.alpha_origin_y;
|
||||
|
||||
image->common.alpha_map->fetch_scanline_32 (
|
||||
(pixman_image_t *)image->common.alpha_map,
|
||||
x, y, width, alpha, mask);
|
||||
|
||||
for (i = 0; i < width; ++i)
|
||||
{
|
||||
buffer[i] &= ~0xff000000;
|
||||
buffer[i] |= (alpha[i] & 0xff000000);
|
||||
}
|
||||
|
||||
free (alpha);
|
||||
}
|
||||
}
|
||||
|
||||
return iter->buffer;
|
||||
@ -1400,17 +1299,33 @@ dest_get_scanline_wide (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;
|
||||
uint64_t * buffer = (uint64_t *)iter->buffer;
|
||||
|
||||
image->fetch_scanline_64 (
|
||||
(pixman_image_t *)image, x, y, width, buffer, mask);
|
||||
(pixman_image_t *)image, x, y, width, (uint32_t *)buffer, mask);
|
||||
if (image->common.alpha_map)
|
||||
{
|
||||
x -= image->common.alpha_origin_x;
|
||||
y -= image->common.alpha_origin_y;
|
||||
uint64_t *alpha;
|
||||
|
||||
image->common.alpha_map->fetch_scanline_64 (
|
||||
(pixman_image_t *)image->common.alpha_map, x, y, width, buffer, mask);
|
||||
if ((alpha = malloc (width * sizeof (uint64_t))))
|
||||
{
|
||||
int i;
|
||||
|
||||
x -= image->common.alpha_origin_x;
|
||||
y -= image->common.alpha_origin_y;
|
||||
|
||||
image->common.alpha_map->fetch_scanline_64 (
|
||||
(pixman_image_t *)image->common.alpha_map,
|
||||
x, y, width, (uint32_t *)alpha, mask);
|
||||
|
||||
for (i = 0; i < width; ++i)
|
||||
{
|
||||
buffer[i] &= ~0xffff000000000000ULL;
|
||||
buffer[i] |= (alpha[i] & 0xffff000000000000ULL);
|
||||
}
|
||||
|
||||
free (alpha);
|
||||
}
|
||||
}
|
||||
|
||||
return iter->buffer;
|
||||
@ -1462,43 +1377,22 @@ dest_write_back_wide (pixman_iter_t *iter)
|
||||
iter->y++;
|
||||
}
|
||||
|
||||
static void
|
||||
dest_write_back_direct (pixman_iter_t *iter)
|
||||
{
|
||||
iter->buffer += iter->image->bits.rowstride;
|
||||
}
|
||||
|
||||
void
|
||||
_pixman_bits_image_dest_iter_init (pixman_image_t *image, pixman_iter_t *iter)
|
||||
{
|
||||
if (iter->flags & ITER_NARROW)
|
||||
{
|
||||
if (((image->common.flags &
|
||||
(FAST_PATH_NO_ALPHA_MAP | FAST_PATH_NO_ACCESSORS)) ==
|
||||
(FAST_PATH_NO_ALPHA_MAP | FAST_PATH_NO_ACCESSORS)) &&
|
||||
(image->bits.format == PIXMAN_a8r8g8b8 ||
|
||||
(image->bits.format == PIXMAN_x8r8g8b8 &&
|
||||
(iter->flags & ITER_LOCALIZED_ALPHA))))
|
||||
if ((iter->flags & (ITER_IGNORE_RGB | ITER_IGNORE_ALPHA)) ==
|
||||
(ITER_IGNORE_RGB | ITER_IGNORE_ALPHA))
|
||||
{
|
||||
iter->buffer = image->bits.bits + iter->y * image->bits.rowstride + iter->x;
|
||||
|
||||
iter->get_scanline = _pixman_iter_get_scanline_noop;
|
||||
iter->write_back = dest_write_back_direct;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((iter->flags & (ITER_IGNORE_RGB | ITER_IGNORE_ALPHA)) ==
|
||||
(ITER_IGNORE_RGB | ITER_IGNORE_ALPHA))
|
||||
{
|
||||
iter->get_scanline = _pixman_iter_get_scanline_noop;
|
||||
}
|
||||
else
|
||||
{
|
||||
iter->get_scanline = dest_get_scanline_narrow;
|
||||
}
|
||||
|
||||
iter->write_back = dest_write_back_narrow;
|
||||
iter->get_scanline = dest_get_scanline_narrow;
|
||||
}
|
||||
|
||||
iter->write_back = dest_write_back_narrow;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1511,10 +1405,10 @@ static uint32_t *
|
||||
create_bits (pixman_format_code_t format,
|
||||
int width,
|
||||
int height,
|
||||
int * rowstride_bytes)
|
||||
int * rowstride_bytes)
|
||||
{
|
||||
int stride;
|
||||
int buf_size;
|
||||
size_t buf_size;
|
||||
int bpp;
|
||||
|
||||
/* what follows is a long-winded way, avoiding any possibility of integer
|
||||
@ -1523,11 +1417,11 @@ create_bits (pixman_format_code_t format,
|
||||
*/
|
||||
|
||||
bpp = PIXMAN_FORMAT_BPP (format);
|
||||
if (pixman_multiply_overflows_int (width, bpp))
|
||||
if (_pixman_multiply_overflows_int (width, bpp))
|
||||
return NULL;
|
||||
|
||||
stride = width * bpp;
|
||||
if (pixman_addition_overflows_int (stride, 0x1f))
|
||||
if (_pixman_addition_overflows_int (stride, 0x1f))
|
||||
return NULL;
|
||||
|
||||
stride += 0x1f;
|
||||
@ -1535,7 +1429,7 @@ create_bits (pixman_format_code_t format,
|
||||
|
||||
stride *= sizeof (uint32_t);
|
||||
|
||||
if (pixman_multiply_overflows_int (height, stride))
|
||||
if (_pixman_multiply_overflows_size (height, stride))
|
||||
return NULL;
|
||||
|
||||
buf_size = height * stride;
|
||||
@ -1546,39 +1440,29 @@ create_bits (pixman_format_code_t format,
|
||||
return calloc (buf_size, 1);
|
||||
}
|
||||
|
||||
PIXMAN_EXPORT pixman_image_t *
|
||||
pixman_image_create_bits (pixman_format_code_t format,
|
||||
int width,
|
||||
int height,
|
||||
uint32_t * bits,
|
||||
int rowstride_bytes)
|
||||
pixman_bool_t
|
||||
_pixman_bits_image_init (pixman_image_t * image,
|
||||
pixman_format_code_t format,
|
||||
int width,
|
||||
int height,
|
||||
uint32_t * bits,
|
||||
int rowstride)
|
||||
{
|
||||
pixman_image_t *image;
|
||||
uint32_t *free_me = NULL;
|
||||
|
||||
/* must be a whole number of uint32_t's
|
||||
*/
|
||||
return_val_if_fail (
|
||||
bits == NULL || (rowstride_bytes % sizeof (uint32_t)) == 0, NULL);
|
||||
|
||||
return_val_if_fail (PIXMAN_FORMAT_BPP (format) >= PIXMAN_FORMAT_DEPTH (format), NULL);
|
||||
|
||||
if (!bits && width && height)
|
||||
{
|
||||
int rowstride_bytes;
|
||||
|
||||
free_me = bits = create_bits (format, width, height, &rowstride_bytes);
|
||||
|
||||
if (!bits)
|
||||
return NULL;
|
||||
return FALSE;
|
||||
|
||||
rowstride = rowstride_bytes / (int) sizeof (uint32_t);
|
||||
}
|
||||
|
||||
image = _pixman_image_allocate ();
|
||||
|
||||
if (!image)
|
||||
{
|
||||
if (free_me)
|
||||
free (free_me);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
_pixman_image_init (image);
|
||||
|
||||
image->type = BITS;
|
||||
image->bits.format = format;
|
||||
@ -1588,15 +1472,43 @@ pixman_image_create_bits (pixman_format_code_t format,
|
||||
image->bits.free_me = free_me;
|
||||
image->bits.read_func = NULL;
|
||||
image->bits.write_func = NULL;
|
||||
|
||||
/* The rowstride is stored in number of uint32_t */
|
||||
image->bits.rowstride = rowstride_bytes / (int) sizeof (uint32_t);
|
||||
|
||||
image->bits.rowstride = rowstride;
|
||||
image->bits.indexed = NULL;
|
||||
|
||||
image->common.property_changed = bits_image_property_changed;
|
||||
|
||||
_pixman_image_reset_clip_region (image);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
PIXMAN_EXPORT pixman_image_t *
|
||||
pixman_image_create_bits (pixman_format_code_t format,
|
||||
int width,
|
||||
int height,
|
||||
uint32_t * bits,
|
||||
int rowstride_bytes)
|
||||
{
|
||||
pixman_image_t *image;
|
||||
|
||||
/* must be a whole number of uint32_t's
|
||||
*/
|
||||
return_val_if_fail (
|
||||
bits == NULL || (rowstride_bytes % sizeof (uint32_t)) == 0, NULL);
|
||||
|
||||
return_val_if_fail (PIXMAN_FORMAT_BPP (format) >= PIXMAN_FORMAT_DEPTH (format), NULL);
|
||||
|
||||
image = _pixman_image_allocate ();
|
||||
|
||||
if (!image)
|
||||
return NULL;
|
||||
|
||||
if (!_pixman_bits_image_init (image, format, width, height, bits,
|
||||
rowstride_bytes / (int) sizeof (uint32_t)))
|
||||
{
|
||||
free (image);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return image;
|
||||
}
|
||||
|
@ -437,7 +437,7 @@ combine_saturate_u (pixman_implementation_t *imp,
|
||||
* PDF_NON_SEPARABLE_BLEND_MODE macros, which take the blend function as an
|
||||
* argument. Note that this implementation operates on premultiplied colors,
|
||||
* while the PDF specification does not. Therefore the code uses the formula
|
||||
* ar.Cra = (1 – as) . Dca + (1 – ad) . Sca + B(Dca, ad, Sca, as)
|
||||
* Cra = (1 – as) . Dca + (1 – ad) . Sca + B(Dca, ad, Sca, as)
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -522,7 +522,7 @@ combine_multiply_ca (pixman_implementation_t *imp,
|
||||
UNcx4_MUL_UNc_ADD_UNcx4_MUL_UNc (result, isa, s, ida); \
|
||||
\
|
||||
*(dest + i) = result + \
|
||||
(DIV_ONE_UNc (sa * da) << A_SHIFT) + \
|
||||
(DIV_ONE_UNc (sa * (comp4_t)da) << A_SHIFT) + \
|
||||
(blend_ ## name (RED_c (d), da, RED_c (s), sa) << R_SHIFT) + \
|
||||
(blend_ ## name (GREEN_c (d), da, GREEN_c (s), sa) << G_SHIFT) + \
|
||||
(blend_ ## name (BLUE_c (d), da, BLUE_c (s), sa)); \
|
||||
@ -552,7 +552,7 @@ combine_multiply_ca (pixman_implementation_t *imp,
|
||||
UNcx4_MUL_UNcx4_ADD_UNcx4_MUL_UNc (result, ~m, s, ida); \
|
||||
\
|
||||
result += \
|
||||
(DIV_ONE_UNc (ALPHA_c (m) * da) << A_SHIFT) + \
|
||||
(DIV_ONE_UNc (ALPHA_c (m) * (comp4_t)da) << A_SHIFT) + \
|
||||
(blend_ ## name (RED_c (d), da, RED_c (s), RED_c (m)) << R_SHIFT) + \
|
||||
(blend_ ## name (GREEN_c (d), da, GREEN_c (s), GREEN_c (m)) << G_SHIFT) + \
|
||||
(blend_ ## name (BLUE_c (d), da, BLUE_c (s), BLUE_c (m))); \
|
||||
@ -849,7 +849,7 @@ PDF_SEPARABLE_BLEND_MODE (exclusion)
|
||||
*
|
||||
* r * set_sat (C, s) = set_sat (x * C, r * s)
|
||||
*
|
||||
* The above holds for all non-zero x, because they x'es in the fraction for
|
||||
* The above holds for all non-zero x, because the x'es in the fraction for
|
||||
* C_mid cancel out. Specifically, it holds for x = r:
|
||||
*
|
||||
* r * set_sat (C, s) = set_sat (r_c, rs)
|
||||
@ -885,8 +885,7 @@ PDF_SEPARABLE_BLEND_MODE (exclusion)
|
||||
*
|
||||
* a_s * a_d * B(s, d)
|
||||
* = a_s * a_d * set_lum (set_sat (S/a_s, SAT (D/a_d)), LUM (D/a_d), 1)
|
||||
* = a_s * a_d * set_lum (set_sat (a_d * S, a_s * SAT (D)),
|
||||
* a_s * LUM (D), a_s * a_d)
|
||||
* = set_lum (set_sat (a_d * S, a_s * SAT (D)), a_s * LUM (D), a_s * a_d)
|
||||
*
|
||||
*/
|
||||
|
||||
@ -927,7 +926,7 @@ PDF_SEPARABLE_BLEND_MODE (exclusion)
|
||||
blend_ ## name (c, dc, da, sc, sa); \
|
||||
\
|
||||
*(dest + i) = result + \
|
||||
(DIV_ONE_UNc (sa * da) << A_SHIFT) + \
|
||||
(DIV_ONE_UNc (sa * (comp4_t)da) << A_SHIFT) + \
|
||||
(DIV_ONE_UNc (c[0]) << R_SHIFT) + \
|
||||
(DIV_ONE_UNc (c[1]) << G_SHIFT) + \
|
||||
(DIV_ONE_UNc (c[2])); \
|
||||
@ -1144,9 +1143,7 @@ PDF_NON_SEPARABLE_BLEND_MODE (hsl_luminosity)
|
||||
#undef CH_MIN
|
||||
#undef PDF_NON_SEPARABLE_BLEND_MODE
|
||||
|
||||
/* Overlay
|
||||
*
|
||||
* All of the disjoint composing functions
|
||||
/* All of the disjoint/conjoint composing functions
|
||||
*
|
||||
* The four entries in the first column indicate what source contributions
|
||||
* come from each of the four areas of the picture -- areas covered by neither
|
||||
@ -1167,6 +1164,9 @@ PDF_NON_SEPARABLE_BLEND_MODE (hsl_luminosity)
|
||||
* (0,0,B,A) max(1-(1-b)/a,0) min(1,(1-a)/b) min(1,b/a) max(1-a/b,0)
|
||||
* (0,A,0,B) min(1,(1-b)/a) max(1-(1-a)/b,0) max(1-b/a,0) min(1,a/b)
|
||||
* (0,A,B,0) min(1,(1-b)/a) min(1,(1-a)/b) max(1-b/a,0) max(1-a/b,0)
|
||||
*
|
||||
* See http://marc.info/?l=xfree-render&m=99792000027857&w=2 for more
|
||||
* information about these operators.
|
||||
*/
|
||||
|
||||
#define COMBINE_A_OUT 1
|
||||
|
@ -25,10 +25,10 @@
|
||||
*/
|
||||
|
||||
#define MUL_UNc(a, b, t) \
|
||||
((t) = (a) * (b) + ONE_HALF, ((((t) >> G_SHIFT ) + (t) ) >> G_SHIFT ))
|
||||
((t) = (a) * (comp2_t)(b) + ONE_HALF, ((((t) >> G_SHIFT ) + (t) ) >> G_SHIFT ))
|
||||
|
||||
#define DIV_UNc(a, b) \
|
||||
(((comp2_t) (a) * MASK) / (b))
|
||||
(((comp2_t) (a) * MASK + ((b) / 2)) / (b))
|
||||
|
||||
#define ADD_UNc(x, y, t) \
|
||||
((t) = (x) + (y), \
|
||||
|
@ -18,6 +18,12 @@
|
||||
# define FUNC ((const char*) ("???"))
|
||||
#endif
|
||||
|
||||
#if defined (__GNUC__)
|
||||
# define MAYBE_UNUSED __attribute__((unused))
|
||||
#else
|
||||
# define MAYBE_UNUSED
|
||||
#endif
|
||||
|
||||
#ifndef INT16_MIN
|
||||
# define INT16_MIN (-32767-1)
|
||||
#endif
|
||||
@ -42,6 +48,15 @@
|
||||
# define UINT32_MAX (4294967295U)
|
||||
#endif
|
||||
|
||||
#ifndef INT64_MIN
|
||||
# define INT64_MIN (-9223372036854775807-1)
|
||||
#endif
|
||||
|
||||
#ifndef INT64_MAX
|
||||
# define INT64_MAX (9223372036854775807)
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef M_PI
|
||||
# define M_PI 3.14159265358979323846
|
||||
#endif
|
||||
@ -89,10 +104,10 @@
|
||||
# define PIXMAN_GET_THREAD_LOCAL(name) \
|
||||
(&name)
|
||||
|
||||
#elif defined(TOOLCHAIN_SUPPORTS__THREAD)
|
||||
#elif defined(TLS)
|
||||
|
||||
# define PIXMAN_DEFINE_THREAD_LOCAL(type, name) \
|
||||
static __thread type name
|
||||
static TLS type name
|
||||
# define PIXMAN_GET_THREAD_LOCAL(name) \
|
||||
(&name)
|
||||
|
||||
|
@ -24,12 +24,17 @@
|
||||
#endif
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#if defined(USE_ARM_SIMD) && defined(_MSC_VER)
|
||||
/* Needed for EXCEPTION_ILLEGAL_INSTRUCTION */
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
#if defined(__APPLE__)
|
||||
#include "TargetConditionals.h"
|
||||
#endif
|
||||
|
||||
#include "pixman-private.h"
|
||||
|
||||
#ifdef USE_VMX
|
||||
@ -187,7 +192,7 @@ pixman_have_vmx (void)
|
||||
#endif /* __APPLE__ */
|
||||
#endif /* USE_VMX */
|
||||
|
||||
#if defined(USE_ARM_SIMD) || defined(USE_ARM_NEON)
|
||||
#if defined(USE_ARM_SIMD) || defined(USE_ARM_NEON) || defined(USE_ARM_IWMMXT)
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
|
||||
@ -244,16 +249,48 @@ pixman_have_arm_neon (void)
|
||||
|
||||
#endif /* USE_ARM_NEON */
|
||||
|
||||
#elif defined (__linux__) || defined(ANDROID) /* linux ELF */
|
||||
#elif (defined (__APPLE__) && defined(TARGET_OS_IPHONE)) /* iOS (iPhone/iPad/iPod touch) */
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/mman.h>
|
||||
#include <fcntl.h>
|
||||
#include <string.h>
|
||||
#include <elf.h>
|
||||
/* Detection of ARM NEON on iOS is fairly simple because iOS binaries
|
||||
* contain separate executable images for each processor architecture.
|
||||
* So all we have to do is detect the armv7 architecture build. The
|
||||
* operating system automatically runs the armv7 binary for armv7 devices
|
||||
* and the armv6 binary for armv6 devices.
|
||||
*/
|
||||
|
||||
pixman_bool_t
|
||||
pixman_have_arm_simd (void)
|
||||
{
|
||||
#if defined(USE_ARM_SIMD)
|
||||
return TRUE;
|
||||
#else
|
||||
return FALSE;
|
||||
#endif
|
||||
}
|
||||
|
||||
pixman_bool_t
|
||||
pixman_have_arm_neon (void)
|
||||
{
|
||||
#if defined(USE_ARM_NEON) && defined(__ARM_NEON__)
|
||||
/* This is an armv7 cpu build */
|
||||
return TRUE;
|
||||
#else
|
||||
/* This is an armv6 cpu build */
|
||||
return FALSE;
|
||||
#endif
|
||||
}
|
||||
|
||||
pixman_bool_t
|
||||
pixman_have_arm_iwmmxt (void)
|
||||
{
|
||||
#if defined(USE_ARM_IWMMXT)
|
||||
return FALSE;
|
||||
#else
|
||||
return FALSE;
|
||||
#endif
|
||||
}
|
||||
|
||||
#elif defined (__linux__) || defined(__ANDROID__) || defined(ANDROID) /* linux ELF or ANDROID */
|
||||
|
||||
static pixman_bool_t arm_has_v7 = FALSE;
|
||||
static pixman_bool_t arm_has_v6 = FALSE;
|
||||
@ -262,15 +299,10 @@ static pixman_bool_t arm_has_neon = FALSE;
|
||||
static pixman_bool_t arm_has_iwmmxt = FALSE;
|
||||
static pixman_bool_t arm_tests_initialized = FALSE;
|
||||
|
||||
#ifdef ANDROID
|
||||
|
||||
/* on Android, we can't reliably access /proc/self/auxv,
|
||||
* so instead read the text version in /proc/cpuinfo and
|
||||
* parse that instead.
|
||||
*/
|
||||
#if defined(__ANDROID__) || defined(ANDROID) /* Android device support */
|
||||
|
||||
static void
|
||||
pixman_arm_detect_cpu_features (void)
|
||||
pixman_arm_read_auxv_or_cpu_features ()
|
||||
{
|
||||
char buf[1024];
|
||||
char* pos;
|
||||
@ -298,10 +330,18 @@ pixman_arm_detect_cpu_features (void)
|
||||
arm_tests_initialized = TRUE;
|
||||
}
|
||||
|
||||
#else
|
||||
#elif defined (__linux__) /* linux ELF */
|
||||
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/mman.h>
|
||||
#include <fcntl.h>
|
||||
#include <string.h>
|
||||
#include <elf.h>
|
||||
|
||||
static void
|
||||
pixman_arm_detect_cpu_features (void)
|
||||
pixman_arm_read_auxv_or_cpu_features ()
|
||||
{
|
||||
int fd;
|
||||
Elf32_auxv_t aux;
|
||||
@ -341,14 +381,15 @@ pixman_arm_detect_cpu_features (void)
|
||||
|
||||
arm_tests_initialized = TRUE;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* Linux elf */
|
||||
|
||||
#if defined(USE_ARM_SIMD)
|
||||
pixman_bool_t
|
||||
pixman_have_arm_simd (void)
|
||||
{
|
||||
if (!arm_tests_initialized)
|
||||
pixman_arm_detect_cpu_features ();
|
||||
pixman_arm_read_auxv_or_cpu_features ();
|
||||
|
||||
return arm_has_v6;
|
||||
}
|
||||
@ -360,23 +401,84 @@ pixman_bool_t
|
||||
pixman_have_arm_neon (void)
|
||||
{
|
||||
if (!arm_tests_initialized)
|
||||
pixman_arm_detect_cpu_features ();
|
||||
pixman_arm_read_auxv_or_cpu_features ();
|
||||
|
||||
return arm_has_neon;
|
||||
}
|
||||
|
||||
#endif /* USE_ARM_NEON */
|
||||
|
||||
#else /* linux ELF */
|
||||
#if defined(USE_ARM_IWMMXT)
|
||||
pixman_bool_t
|
||||
pixman_have_arm_iwmmxt (void)
|
||||
{
|
||||
if (!arm_tests_initialized)
|
||||
pixman_arm_read_auxv_or_cpu_features ();
|
||||
|
||||
return arm_has_iwmmxt;
|
||||
}
|
||||
|
||||
#endif /* USE_ARM_IWMMXT */
|
||||
|
||||
#else /* !_MSC_VER && !Linux elf && !Android */
|
||||
|
||||
#define pixman_have_arm_simd() FALSE
|
||||
#define pixman_have_arm_neon() FALSE
|
||||
#define pixman_have_arm_iwmmxt() FALSE
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* USE_ARM_SIMD || USE_ARM_NEON */
|
||||
#endif /* USE_ARM_SIMD || USE_ARM_NEON || USE_ARM_IWMMXT */
|
||||
|
||||
#if defined(USE_MMX) || defined(USE_SSE2)
|
||||
#if defined(USE_MIPS_DSPR2)
|
||||
|
||||
#if defined (__linux__) /* linux ELF */
|
||||
|
||||
pixman_bool_t
|
||||
pixman_have_mips_dspr2 (void)
|
||||
{
|
||||
const char *search_string = "MIPS 74K";
|
||||
const char *file_name = "/proc/cpuinfo";
|
||||
/* Simple detection of MIPS DSP ASE (revision 2) at runtime for Linux.
|
||||
* It is based on /proc/cpuinfo, which reveals hardware configuration
|
||||
* to user-space applications. According to MIPS (early 2010), no similar
|
||||
* facility is universally available on the MIPS architectures, so it's up
|
||||
* to individual OSes to provide such.
|
||||
*
|
||||
* Only currently available MIPS core that supports DSPr2 is 74K.
|
||||
*/
|
||||
|
||||
char cpuinfo_line[256];
|
||||
|
||||
FILE *f = NULL;
|
||||
|
||||
if ((f = fopen (file_name, "r")) == NULL)
|
||||
return FALSE;
|
||||
|
||||
while (fgets (cpuinfo_line, sizeof (cpuinfo_line), f) != NULL)
|
||||
{
|
||||
if (strstr (cpuinfo_line, search_string) != NULL)
|
||||
{
|
||||
fclose (f);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
fclose (f);
|
||||
|
||||
/* Did not find string in the proc file. */
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
#else /* linux ELF */
|
||||
|
||||
#define pixman_have_mips_dspr2() FALSE
|
||||
|
||||
#endif /* linux ELF */
|
||||
|
||||
#endif /* USE_MIPS_DSPR2 */
|
||||
|
||||
#if defined(USE_X86_MMX) || defined(USE_SSE2)
|
||||
/* The CPU detection code needs to be in a file not compiled with
|
||||
* "-mmmx -msse", as gcc would generate CMOV instructions otherwise
|
||||
* that would lead to SIGILL instructions on old CPUs that don't have
|
||||
@ -567,6 +669,7 @@ detect_cpu_features (void)
|
||||
return features;
|
||||
}
|
||||
|
||||
#ifdef USE_X86_MMX
|
||||
static pixman_bool_t
|
||||
pixman_have_mmx (void)
|
||||
{
|
||||
@ -582,6 +685,7 @@ pixman_have_mmx (void)
|
||||
|
||||
return mmx_present;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef USE_SSE2
|
||||
static pixman_bool_t
|
||||
@ -603,7 +707,7 @@ pixman_have_sse2 (void)
|
||||
#endif
|
||||
|
||||
#else /* __amd64__ */
|
||||
#ifdef USE_MMX
|
||||
#ifdef USE_X86_MMX
|
||||
#define pixman_have_mmx() TRUE
|
||||
#endif
|
||||
#ifdef USE_SSE2
|
||||
@ -612,39 +716,84 @@ pixman_have_sse2 (void)
|
||||
#endif /* __amd64__ */
|
||||
#endif
|
||||
|
||||
static pixman_bool_t
|
||||
disabled (const char *name)
|
||||
{
|
||||
const char *env;
|
||||
|
||||
if ((env = getenv ("PIXMAN_DISABLE")))
|
||||
{
|
||||
do
|
||||
{
|
||||
const char *end;
|
||||
int len;
|
||||
|
||||
if ((end = strchr (env, ' ')))
|
||||
len = end - env;
|
||||
else
|
||||
len = strlen (env);
|
||||
|
||||
if (strlen (name) == len && strncmp (name, env, len) == 0)
|
||||
{
|
||||
printf ("pixman: Disabled %s implementation\n", name);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
env += len;
|
||||
}
|
||||
while (*env++);
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
pixman_implementation_t *
|
||||
_pixman_choose_implementation (void)
|
||||
{
|
||||
pixman_implementation_t *imp;
|
||||
|
||||
imp = _pixman_implementation_create_general();
|
||||
imp = _pixman_implementation_create_fast_path (imp);
|
||||
|
||||
#ifdef USE_MMX
|
||||
if (pixman_have_mmx ())
|
||||
|
||||
if (!disabled ("fast"))
|
||||
imp = _pixman_implementation_create_fast_path (imp);
|
||||
|
||||
#ifdef USE_X86_MMX
|
||||
if (!disabled ("mmx") && pixman_have_mmx ())
|
||||
imp = _pixman_implementation_create_mmx (imp);
|
||||
#endif
|
||||
|
||||
#ifdef USE_SSE2
|
||||
if (pixman_have_sse2 ())
|
||||
if (!disabled ("sse2") && pixman_have_sse2 ())
|
||||
imp = _pixman_implementation_create_sse2 (imp);
|
||||
#endif
|
||||
|
||||
#ifdef USE_ARM_SIMD
|
||||
if (pixman_have_arm_simd ())
|
||||
if (!disabled ("arm-simd") && pixman_have_arm_simd ())
|
||||
imp = _pixman_implementation_create_arm_simd (imp);
|
||||
#endif
|
||||
|
||||
#ifdef USE_ARM_IWMMXT
|
||||
if (!disabled ("arm-iwmmxt") && pixman_have_arm_iwmmxt ())
|
||||
imp = _pixman_implementation_create_mmx (imp);
|
||||
#endif
|
||||
|
||||
#ifdef USE_ARM_NEON
|
||||
if (pixman_have_arm_neon ())
|
||||
if (!disabled ("arm-neon") && pixman_have_arm_neon ())
|
||||
imp = _pixman_implementation_create_arm_neon (imp);
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef USE_MIPS_DSPR2
|
||||
if (!disabled ("mips-dspr2") && pixman_have_mips_dspr2 ())
|
||||
imp = _pixman_implementation_create_mips_dspr2 (imp);
|
||||
#endif
|
||||
|
||||
#ifdef USE_VMX
|
||||
if (pixman_have_vmx ())
|
||||
if (!disabled ("vmx") && pixman_have_vmx ())
|
||||
imp = _pixman_implementation_create_vmx (imp);
|
||||
#endif
|
||||
|
||||
imp = _pixman_implementation_create_noop (imp);
|
||||
|
||||
return imp;
|
||||
}
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -101,19 +101,9 @@ static const op_info_t op_flags[PIXMAN_N_OPERATORS] =
|
||||
|
||||
static void
|
||||
general_composite_rect (pixman_implementation_t *imp,
|
||||
pixman_op_t op,
|
||||
pixman_image_t * src,
|
||||
pixman_image_t * mask,
|
||||
pixman_image_t * dest,
|
||||
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)
|
||||
pixman_composite_info_t *info)
|
||||
{
|
||||
PIXMAN_COMPOSITE_ARGS (info);
|
||||
uint64_t stack_scanline_buffer[(SCANLINE_BUFFER_LENGTH * 3 + 7) / 8];
|
||||
uint8_t *scanline_buffer = (uint8_t *) stack_scanline_buffer;
|
||||
uint8_t *src_buffer, *mask_buffer, *dest_buffer;
|
||||
@ -124,9 +114,9 @@ general_composite_rect (pixman_implementation_t *imp,
|
||||
int Bpp;
|
||||
int i;
|
||||
|
||||
if ((src->common.flags & FAST_PATH_NARROW_FORMAT) &&
|
||||
(!mask || mask->common.flags & FAST_PATH_NARROW_FORMAT) &&
|
||||
(dest->common.flags & FAST_PATH_NARROW_FORMAT))
|
||||
if ((src_image->common.flags & FAST_PATH_NARROW_FORMAT) &&
|
||||
(!mask_image || mask_image->common.flags & FAST_PATH_NARROW_FORMAT) &&
|
||||
(dest_image->common.flags & FAST_PATH_NARROW_FORMAT))
|
||||
{
|
||||
narrow = ITER_NARROW;
|
||||
Bpp = 4;
|
||||
@ -152,7 +142,7 @@ general_composite_rect (pixman_implementation_t *imp,
|
||||
/* src iter */
|
||||
src_flags = narrow | op_flags[op].src;
|
||||
|
||||
_pixman_implementation_src_iter_init (imp->toplevel, &src_iter, src,
|
||||
_pixman_implementation_src_iter_init (imp->toplevel, &src_iter, src_image,
|
||||
src_x, src_y, width, height,
|
||||
src_buffer, src_flags);
|
||||
|
||||
@ -163,39 +153,26 @@ general_composite_rect (pixman_implementation_t *imp,
|
||||
/* If it doesn't matter what the source is, then it doesn't matter
|
||||
* what the mask is
|
||||
*/
|
||||
mask = NULL;
|
||||
mask_image = NULL;
|
||||
}
|
||||
|
||||
component_alpha =
|
||||
mask &&
|
||||
mask->common.type == BITS &&
|
||||
mask->common.component_alpha &&
|
||||
PIXMAN_FORMAT_RGB (mask->bits.format);
|
||||
mask_image &&
|
||||
mask_image->common.type == BITS &&
|
||||
mask_image->common.component_alpha &&
|
||||
PIXMAN_FORMAT_RGB (mask_image->bits.format);
|
||||
|
||||
_pixman_implementation_src_iter_init (
|
||||
imp->toplevel, &mask_iter, mask, mask_x, mask_y, width, height,
|
||||
imp->toplevel, &mask_iter, mask_image, mask_x, mask_y, width, height,
|
||||
mask_buffer, narrow | (component_alpha? 0 : ITER_IGNORE_RGB));
|
||||
|
||||
/* dest iter */
|
||||
_pixman_implementation_dest_iter_init (imp->toplevel, &dest_iter, dest,
|
||||
dest_x, dest_y, width, height,
|
||||
dest_buffer,
|
||||
narrow | op_flags[op].dst);
|
||||
_pixman_implementation_dest_iter_init (
|
||||
imp->toplevel, &dest_iter, dest_image, dest_x, dest_y, width, height,
|
||||
dest_buffer, narrow | op_flags[op].dst);
|
||||
|
||||
if (narrow)
|
||||
{
|
||||
if (component_alpha)
|
||||
compose = _pixman_implementation_combine_32_ca;
|
||||
else
|
||||
compose = _pixman_implementation_combine_32;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (component_alpha)
|
||||
compose = (pixman_combine_32_func_t)_pixman_implementation_combine_64_ca;
|
||||
else
|
||||
compose = (pixman_combine_32_func_t)_pixman_implementation_combine_64;
|
||||
}
|
||||
compose = _pixman_implementation_lookup_combiner (
|
||||
imp->toplevel, op, component_alpha, narrow);
|
||||
|
||||
if (!compose)
|
||||
return;
|
||||
@ -233,8 +210,8 @@ general_blt (pixman_implementation_t *imp,
|
||||
int dst_bpp,
|
||||
int src_x,
|
||||
int src_y,
|
||||
int dst_x,
|
||||
int dst_y,
|
||||
int dest_x,
|
||||
int dest_y,
|
||||
int width,
|
||||
int height)
|
||||
{
|
||||
|
@ -31,7 +31,7 @@
|
||||
void
|
||||
_pixman_gradient_walker_init (pixman_gradient_walker_t *walker,
|
||||
gradient_t * gradient,
|
||||
unsigned int spread)
|
||||
pixman_repeat_t repeat)
|
||||
{
|
||||
walker->num_stops = gradient->n_stops;
|
||||
walker->stops = gradient->stops;
|
||||
@ -42,112 +42,54 @@ _pixman_gradient_walker_init (pixman_gradient_walker_t *walker,
|
||||
walker->left_rb = 0;
|
||||
walker->right_ag = 0;
|
||||
walker->right_rb = 0;
|
||||
walker->spread = spread;
|
||||
walker->repeat = repeat;
|
||||
|
||||
walker->need_reset = TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
_pixman_gradient_walker_reset (pixman_gradient_walker_t *walker,
|
||||
pixman_fixed_32_32_t pos)
|
||||
static void
|
||||
gradient_walker_reset (pixman_gradient_walker_t *walker,
|
||||
pixman_fixed_48_16_t pos)
|
||||
{
|
||||
int32_t x, left_x, right_x;
|
||||
pixman_color_t *left_c, *right_c;
|
||||
pixman_color_t *left_c, *right_c;
|
||||
int n, count = walker->num_stops;
|
||||
pixman_gradient_stop_t * stops = walker->stops;
|
||||
pixman_gradient_stop_t *stops = walker->stops;
|
||||
|
||||
static const pixman_color_t transparent_black = { 0, 0, 0, 0 };
|
||||
|
||||
switch (walker->spread)
|
||||
if (walker->repeat == PIXMAN_REPEAT_NORMAL)
|
||||
{
|
||||
case PIXMAN_REPEAT_NORMAL:
|
||||
x = (int32_t)pos & 0xFFFF;
|
||||
for (n = 0; n < count; n++)
|
||||
if (x < stops[n].x)
|
||||
break;
|
||||
if (n == 0)
|
||||
{
|
||||
left_x = stops[count - 1].x - 0x10000;
|
||||
left_c = &stops[count - 1].color;
|
||||
}
|
||||
else
|
||||
{
|
||||
left_x = stops[n - 1].x;
|
||||
left_c = &stops[n - 1].color;
|
||||
}
|
||||
|
||||
if (n == count)
|
||||
{
|
||||
right_x = stops[0].x + 0x10000;
|
||||
right_c = &stops[0].color;
|
||||
}
|
||||
else
|
||||
{
|
||||
right_x = stops[n].x;
|
||||
right_c = &stops[n].color;
|
||||
}
|
||||
left_x += (pos - x);
|
||||
right_x += (pos - x);
|
||||
break;
|
||||
|
||||
case PIXMAN_REPEAT_PAD:
|
||||
for (n = 0; n < count; n++)
|
||||
if (pos < stops[n].x)
|
||||
break;
|
||||
|
||||
if (n == 0)
|
||||
{
|
||||
left_x = INT32_MIN;
|
||||
left_c = &stops[0].color;
|
||||
}
|
||||
else
|
||||
{
|
||||
left_x = stops[n - 1].x;
|
||||
left_c = &stops[n - 1].color;
|
||||
}
|
||||
|
||||
if (n == count)
|
||||
{
|
||||
right_x = INT32_MAX;
|
||||
right_c = &stops[n - 1].color;
|
||||
}
|
||||
else
|
||||
{
|
||||
right_x = stops[n].x;
|
||||
right_c = &stops[n].color;
|
||||
}
|
||||
break;
|
||||
|
||||
case PIXMAN_REPEAT_REFLECT:
|
||||
x = (int32_t)pos & 0xFFFF;
|
||||
x = (int32_t)pos & 0xffff;
|
||||
}
|
||||
else if (walker->repeat == PIXMAN_REPEAT_REFLECT)
|
||||
{
|
||||
x = (int32_t)pos & 0xffff;
|
||||
if ((int32_t)pos & 0x10000)
|
||||
x = 0x10000 - x;
|
||||
for (n = 0; n < count; n++)
|
||||
if (x < stops[n].x)
|
||||
break;
|
||||
|
||||
if (n == 0)
|
||||
{
|
||||
left_x = -stops[0].x;
|
||||
left_c = &stops[0].color;
|
||||
}
|
||||
else
|
||||
{
|
||||
left_x = stops[n - 1].x;
|
||||
left_c = &stops[n - 1].color;
|
||||
}
|
||||
|
||||
if (n == count)
|
||||
{
|
||||
right_x = 0x20000 - stops[n - 1].x;
|
||||
right_c = &stops[n - 1].color;
|
||||
}
|
||||
else
|
||||
{
|
||||
right_x = stops[n].x;
|
||||
right_c = &stops[n].color;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
x = pos;
|
||||
}
|
||||
|
||||
for (n = 0; n < count; n++)
|
||||
{
|
||||
if (x < stops[n].x)
|
||||
break;
|
||||
}
|
||||
|
||||
left_x = stops[n - 1].x;
|
||||
left_c = &stops[n - 1].color;
|
||||
|
||||
right_x = stops[n].x;
|
||||
right_c = &stops[n].color;
|
||||
|
||||
if (walker->repeat == PIXMAN_REPEAT_NORMAL)
|
||||
{
|
||||
left_x += (pos - x);
|
||||
right_x += (pos - x);
|
||||
}
|
||||
else if (walker->repeat == PIXMAN_REPEAT_REFLECT)
|
||||
{
|
||||
if ((int32_t)pos & 0x10000)
|
||||
{
|
||||
pixman_color_t *tmp_c;
|
||||
@ -165,32 +107,13 @@ _pixman_gradient_walker_reset (pixman_gradient_walker_t *walker,
|
||||
}
|
||||
left_x += (pos - x);
|
||||
right_x += (pos - x);
|
||||
break;
|
||||
|
||||
default: /* REPEAT_NONE */
|
||||
for (n = 0; n < count; n++)
|
||||
if (pos < stops[n].x)
|
||||
break;
|
||||
|
||||
}
|
||||
else if (walker->repeat == PIXMAN_REPEAT_NONE)
|
||||
{
|
||||
if (n == 0)
|
||||
{
|
||||
left_x = INT32_MIN;
|
||||
right_x = stops[0].x;
|
||||
left_c = right_c = (pixman_color_t*) &transparent_black;
|
||||
}
|
||||
right_c = left_c;
|
||||
else if (n == count)
|
||||
{
|
||||
left_x = stops[n - 1].x;
|
||||
right_x = INT32_MAX;
|
||||
left_c = right_c = (pixman_color_t*) &transparent_black;
|
||||
}
|
||||
else
|
||||
{
|
||||
left_x = stops[n - 1].x;
|
||||
right_x = stops[n].x;
|
||||
left_c = &stops[n - 1].color;
|
||||
right_c = &stops[n].color;
|
||||
}
|
||||
left_c = right_c;
|
||||
}
|
||||
|
||||
walker->left_x = left_x;
|
||||
@ -201,8 +124,8 @@ _pixman_gradient_walker_reset (pixman_gradient_walker_t *walker,
|
||||
walker->right_rb = ((right_c->red & 0xff00) << 8) | (right_c->blue >> 8);
|
||||
|
||||
if (walker->left_x == walker->right_x ||
|
||||
( walker->left_ag == walker->right_ag &&
|
||||
walker->left_rb == walker->right_rb ) )
|
||||
(walker->left_ag == walker->right_ag &&
|
||||
walker->left_rb == walker->right_rb))
|
||||
{
|
||||
walker->stepper = 0;
|
||||
}
|
||||
@ -215,20 +138,15 @@ _pixman_gradient_walker_reset (pixman_gradient_walker_t *walker,
|
||||
walker->need_reset = FALSE;
|
||||
}
|
||||
|
||||
#define PIXMAN_GRADIENT_WALKER_NEED_RESET(w, x) \
|
||||
( (w)->need_reset || (x) < (w)->left_x || (x) >= (w)->right_x)
|
||||
|
||||
|
||||
/* the following assumes that PIXMAN_GRADIENT_WALKER_NEED_RESET(w,x) is FALSE */
|
||||
uint32_t
|
||||
_pixman_gradient_walker_pixel (pixman_gradient_walker_t *walker,
|
||||
pixman_fixed_32_32_t x)
|
||||
pixman_fixed_48_16_t x)
|
||||
{
|
||||
int dist, idist;
|
||||
uint32_t t1, t2, a, color;
|
||||
|
||||
if (PIXMAN_GRADIENT_WALKER_NEED_RESET (walker, x))
|
||||
_pixman_gradient_walker_reset (walker, x);
|
||||
if (walker->need_reset || x < walker->left_x || x >= walker->right_x)
|
||||
gradient_walker_reset (walker, x);
|
||||
|
||||
dist = ((int)(x - walker->left_x) * walker->stepper) >> 16;
|
||||
idist = 256 - dist;
|
||||
|
@ -31,6 +31,50 @@
|
||||
|
||||
#include "pixman-private.h"
|
||||
|
||||
static const pixman_color_t transparent_black = { 0, 0, 0, 0 };
|
||||
|
||||
static void
|
||||
gradient_property_changed (pixman_image_t *image)
|
||||
{
|
||||
gradient_t *gradient = &image->gradient;
|
||||
int n = gradient->n_stops;
|
||||
pixman_gradient_stop_t *stops = gradient->stops;
|
||||
pixman_gradient_stop_t *begin = &(gradient->stops[-1]);
|
||||
pixman_gradient_stop_t *end = &(gradient->stops[n]);
|
||||
|
||||
switch (gradient->common.repeat)
|
||||
{
|
||||
default:
|
||||
case PIXMAN_REPEAT_NONE:
|
||||
begin->x = INT32_MIN;
|
||||
begin->color = transparent_black;
|
||||
end->x = INT32_MAX;
|
||||
end->color = transparent_black;
|
||||
break;
|
||||
|
||||
case PIXMAN_REPEAT_NORMAL:
|
||||
begin->x = stops[n - 1].x - pixman_fixed_1;
|
||||
begin->color = stops[n - 1].color;
|
||||
end->x = stops[0].x + pixman_fixed_1;
|
||||
end->color = stops[0].color;
|
||||
break;
|
||||
|
||||
case PIXMAN_REPEAT_REFLECT:
|
||||
begin->x = - stops[0].x;
|
||||
begin->color = stops[0].color;
|
||||
end->x = pixman_int_to_fixed (2) - stops[n - 1].x;
|
||||
end->color = stops[n - 1].color;
|
||||
break;
|
||||
|
||||
case PIXMAN_REPEAT_PAD:
|
||||
begin->x = INT32_MIN;
|
||||
begin->color = stops[0].color;
|
||||
end->x = INT32_MAX;
|
||||
end->color = stops[n - 1].color;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
pixman_bool_t
|
||||
_pixman_init_gradient (gradient_t * gradient,
|
||||
const pixman_gradient_stop_t *stops,
|
||||
@ -38,45 +82,109 @@ _pixman_init_gradient (gradient_t * gradient,
|
||||
{
|
||||
return_val_if_fail (n_stops > 0, FALSE);
|
||||
|
||||
gradient->stops = pixman_malloc_ab (n_stops, sizeof (pixman_gradient_stop_t));
|
||||
/* We allocate two extra stops, one before the beginning of the stop list,
|
||||
* and one after the end. These stops are initialized to whatever color
|
||||
* would be used for positions outside the range of the stop list.
|
||||
*
|
||||
* This saves a bit of computation in the gradient walker.
|
||||
*
|
||||
* The pointer we store in the gradient_t struct still points to the
|
||||
* first user-supplied struct, so when freeing, we will have to
|
||||
* subtract one.
|
||||
*/
|
||||
gradient->stops =
|
||||
pixman_malloc_ab (n_stops + 2, sizeof (pixman_gradient_stop_t));
|
||||
if (!gradient->stops)
|
||||
return FALSE;
|
||||
|
||||
gradient->stops += 1;
|
||||
memcpy (gradient->stops, stops, n_stops * sizeof (pixman_gradient_stop_t));
|
||||
|
||||
gradient->n_stops = n_stops;
|
||||
|
||||
gradient->common.property_changed = gradient_property_changed;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
_pixman_image_init (pixman_image_t *image)
|
||||
{
|
||||
image_common_t *common = &image->common;
|
||||
|
||||
pixman_region32_init (&common->clip_region);
|
||||
|
||||
common->alpha_count = 0;
|
||||
common->have_clip_region = FALSE;
|
||||
common->clip_sources = FALSE;
|
||||
common->transform = NULL;
|
||||
common->repeat = PIXMAN_REPEAT_NONE;
|
||||
common->filter = PIXMAN_FILTER_NEAREST;
|
||||
common->filter_params = NULL;
|
||||
common->n_filter_params = 0;
|
||||
common->alpha_map = NULL;
|
||||
common->component_alpha = FALSE;
|
||||
common->ref_count = 1;
|
||||
common->property_changed = NULL;
|
||||
common->client_clip = FALSE;
|
||||
common->destroy_func = NULL;
|
||||
common->destroy_data = NULL;
|
||||
common->dirty = TRUE;
|
||||
}
|
||||
|
||||
pixman_bool_t
|
||||
_pixman_image_fini (pixman_image_t *image)
|
||||
{
|
||||
image_common_t *common = (image_common_t *)image;
|
||||
|
||||
common->ref_count--;
|
||||
|
||||
if (common->ref_count == 0)
|
||||
{
|
||||
if (image->common.destroy_func)
|
||||
image->common.destroy_func (image, image->common.destroy_data);
|
||||
|
||||
pixman_region32_fini (&common->clip_region);
|
||||
|
||||
free (common->transform);
|
||||
free (common->filter_params);
|
||||
|
||||
if (common->alpha_map)
|
||||
pixman_image_unref ((pixman_image_t *)common->alpha_map);
|
||||
|
||||
if (image->type == LINEAR ||
|
||||
image->type == RADIAL ||
|
||||
image->type == CONICAL)
|
||||
{
|
||||
if (image->gradient.stops)
|
||||
{
|
||||
/* See _pixman_init_gradient() for an explanation of the - 1 */
|
||||
free (image->gradient.stops - 1);
|
||||
}
|
||||
|
||||
/* This will trigger if someone adds a property_changed
|
||||
* method to the linear/radial/conical gradient overwriting
|
||||
* the general one.
|
||||
*/
|
||||
assert (
|
||||
image->common.property_changed == gradient_property_changed);
|
||||
}
|
||||
|
||||
if (image->type == BITS && image->bits.free_me)
|
||||
free (image->bits.free_me);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
pixman_image_t *
|
||||
_pixman_image_allocate (void)
|
||||
{
|
||||
pixman_image_t *image = malloc (sizeof (pixman_image_t));
|
||||
|
||||
if (image)
|
||||
{
|
||||
image_common_t *common = &image->common;
|
||||
|
||||
pixman_region32_init (&common->clip_region);
|
||||
|
||||
common->alpha_count = 0;
|
||||
common->have_clip_region = FALSE;
|
||||
common->clip_sources = FALSE;
|
||||
common->transform = NULL;
|
||||
common->repeat = PIXMAN_REPEAT_NONE;
|
||||
common->filter = PIXMAN_FILTER_NEAREST;
|
||||
common->filter_params = NULL;
|
||||
common->n_filter_params = 0;
|
||||
common->alpha_map = NULL;
|
||||
common->component_alpha = FALSE;
|
||||
common->ref_count = 1;
|
||||
common->property_changed = NULL;
|
||||
common->client_clip = FALSE;
|
||||
common->destroy_func = NULL;
|
||||
common->destroy_data = NULL;
|
||||
common->dirty = TRUE;
|
||||
}
|
||||
_pixman_image_init (image);
|
||||
|
||||
return image;
|
||||
}
|
||||
@ -100,39 +208,9 @@ pixman_image_ref (pixman_image_t *image)
|
||||
PIXMAN_EXPORT pixman_bool_t
|
||||
pixman_image_unref (pixman_image_t *image)
|
||||
{
|
||||
image_common_t *common = (image_common_t *)image;
|
||||
|
||||
common->ref_count--;
|
||||
|
||||
if (common->ref_count == 0)
|
||||
if (_pixman_image_fini (image))
|
||||
{
|
||||
if (image->common.destroy_func)
|
||||
image->common.destroy_func (image, image->common.destroy_data);
|
||||
|
||||
pixman_region32_fini (&common->clip_region);
|
||||
|
||||
if (common->transform)
|
||||
free (common->transform);
|
||||
|
||||
if (common->filter_params)
|
||||
free (common->filter_params);
|
||||
|
||||
if (common->alpha_map)
|
||||
pixman_image_unref ((pixman_image_t *)common->alpha_map);
|
||||
|
||||
if (image->type == LINEAR ||
|
||||
image->type == RADIAL ||
|
||||
image->type == CONICAL)
|
||||
{
|
||||
if (image->gradient.stops)
|
||||
free (image->gradient.stops);
|
||||
}
|
||||
|
||||
if (image->type == BITS && image->bits.free_me)
|
||||
free (image->bits.free_me);
|
||||
|
||||
free (image);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@ -221,13 +299,12 @@ compute_image_info (pixman_image_t *image)
|
||||
image->common.transform->matrix[1][1] == 0)
|
||||
{
|
||||
pixman_fixed_t m01 = image->common.transform->matrix[0][1];
|
||||
if (m01 == -image->common.transform->matrix[1][0])
|
||||
{
|
||||
if (m01 == -pixman_fixed_1)
|
||||
flags |= FAST_PATH_ROTATE_90_TRANSFORM;
|
||||
else if (m01 == pixman_fixed_1)
|
||||
flags |= FAST_PATH_ROTATE_270_TRANSFORM;
|
||||
}
|
||||
pixman_fixed_t m10 = image->common.transform->matrix[1][0];
|
||||
|
||||
if (m01 == -1 && m10 == 1)
|
||||
flags |= FAST_PATH_ROTATE_90_TRANSFORM;
|
||||
else if (m01 == 1 && m10 == -1)
|
||||
flags |= FAST_PATH_ROTATE_270_TRANSFORM;
|
||||
}
|
||||
}
|
||||
|
||||
@ -250,6 +327,47 @@ compute_image_info (pixman_image_t *image)
|
||||
case PIXMAN_FILTER_GOOD:
|
||||
case PIXMAN_FILTER_BEST:
|
||||
flags |= (FAST_PATH_BILINEAR_FILTER | FAST_PATH_NO_CONVOLUTION_FILTER);
|
||||
|
||||
/* Here we have a chance to optimize BILINEAR filter to NEAREST if
|
||||
* they are equivalent for the currently used transformation matrix.
|
||||
*/
|
||||
if (flags & FAST_PATH_ID_TRANSFORM)
|
||||
{
|
||||
flags |= FAST_PATH_NEAREST_FILTER;
|
||||
}
|
||||
else if (
|
||||
/* affine and integer translation components in matrix ... */
|
||||
((flags & FAST_PATH_AFFINE_TRANSFORM) &&
|
||||
!pixman_fixed_frac (image->common.transform->matrix[0][2] |
|
||||
image->common.transform->matrix[1][2])) &&
|
||||
(
|
||||
/* ... combined with a simple rotation */
|
||||
(flags & (FAST_PATH_ROTATE_90_TRANSFORM |
|
||||
FAST_PATH_ROTATE_180_TRANSFORM |
|
||||
FAST_PATH_ROTATE_270_TRANSFORM)) ||
|
||||
/* ... or combined with a simple non-rotated translation */
|
||||
(image->common.transform->matrix[0][0] == pixman_fixed_1 &&
|
||||
image->common.transform->matrix[1][1] == pixman_fixed_1 &&
|
||||
image->common.transform->matrix[0][1] == 0 &&
|
||||
image->common.transform->matrix[1][0] == 0)
|
||||
)
|
||||
)
|
||||
{
|
||||
/* FIXME: there are some affine-test failures, showing that
|
||||
* handling of BILINEAR and NEAREST filter is not quite
|
||||
* equivalent when getting close to 32K for the translation
|
||||
* components of the matrix. That's likely some bug, but for
|
||||
* now just skip BILINEAR->NEAREST optimization in this case.
|
||||
*/
|
||||
pixman_fixed_t magic_limit = pixman_int_to_fixed (30000);
|
||||
if (image->common.transform->matrix[0][2] <= magic_limit &&
|
||||
image->common.transform->matrix[1][2] <= magic_limit &&
|
||||
image->common.transform->matrix[0][2] >= -magic_limit &&
|
||||
image->common.transform->matrix[1][2] >= -magic_limit)
|
||||
{
|
||||
flags |= FAST_PATH_NEAREST_FILTER;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case PIXMAN_FILTER_CONVOLUTION:
|
||||
@ -320,12 +438,7 @@ compute_image_info (pixman_image_t *image)
|
||||
else
|
||||
{
|
||||
code = image->bits.format;
|
||||
|
||||
if (!image->common.transform &&
|
||||
image->common.repeat == PIXMAN_REPEAT_NORMAL)
|
||||
{
|
||||
flags |= FAST_PATH_SIMPLE_REPEAT | FAST_PATH_SAMPLES_COVER_CLIP;
|
||||
}
|
||||
flags |= FAST_PATH_BITS_IMAGE;
|
||||
}
|
||||
|
||||
if (!PIXMAN_FORMAT_A (image->bits.format) &&
|
||||
|
@ -27,54 +27,6 @@
|
||||
#include <stdlib.h>
|
||||
#include "pixman-private.h"
|
||||
|
||||
static void
|
||||
delegate_combine_32 (pixman_implementation_t * imp,
|
||||
pixman_op_t op,
|
||||
uint32_t * dest,
|
||||
const uint32_t * src,
|
||||
const uint32_t * mask,
|
||||
int width)
|
||||
{
|
||||
_pixman_implementation_combine_32 (imp->delegate,
|
||||
op, dest, src, mask, width);
|
||||
}
|
||||
|
||||
static void
|
||||
delegate_combine_64 (pixman_implementation_t * imp,
|
||||
pixman_op_t op,
|
||||
uint64_t * dest,
|
||||
const uint64_t * src,
|
||||
const uint64_t * mask,
|
||||
int width)
|
||||
{
|
||||
_pixman_implementation_combine_64 (imp->delegate,
|
||||
op, dest, src, mask, width);
|
||||
}
|
||||
|
||||
static void
|
||||
delegate_combine_32_ca (pixman_implementation_t * imp,
|
||||
pixman_op_t op,
|
||||
uint32_t * dest,
|
||||
const uint32_t * src,
|
||||
const uint32_t * mask,
|
||||
int width)
|
||||
{
|
||||
_pixman_implementation_combine_32_ca (imp->delegate,
|
||||
op, dest, src, mask, width);
|
||||
}
|
||||
|
||||
static void
|
||||
delegate_combine_64_ca (pixman_implementation_t * imp,
|
||||
pixman_op_t op,
|
||||
uint64_t * dest,
|
||||
const uint64_t * src,
|
||||
const uint64_t * mask,
|
||||
int width)
|
||||
{
|
||||
_pixman_implementation_combine_64_ca (imp->delegate,
|
||||
op, dest, src, mask, width);
|
||||
}
|
||||
|
||||
static pixman_bool_t
|
||||
delegate_blt (pixman_implementation_t * imp,
|
||||
uint32_t * src_bits,
|
||||
@ -85,14 +37,14 @@ delegate_blt (pixman_implementation_t * imp,
|
||||
int dst_bpp,
|
||||
int src_x,
|
||||
int src_y,
|
||||
int dst_x,
|
||||
int dst_y,
|
||||
int dest_x,
|
||||
int dest_y,
|
||||
int width,
|
||||
int height)
|
||||
{
|
||||
return _pixman_implementation_blt (
|
||||
imp->delegate, src_bits, dst_bits, src_stride, dst_stride,
|
||||
src_bpp, dst_bpp, src_x, src_y, dst_x, dst_y,
|
||||
src_bpp, dst_bpp, src_x, src_y, dest_x, dest_y,
|
||||
width, height);
|
||||
}
|
||||
|
||||
@ -150,61 +102,44 @@ _pixman_implementation_create (pixman_implementation_t *delegate,
|
||||
imp->src_iter_init = delegate_src_iter_init;
|
||||
imp->dest_iter_init = delegate_dest_iter_init;
|
||||
|
||||
imp->fast_paths = fast_paths;
|
||||
|
||||
for (i = 0; i < PIXMAN_N_OPERATORS; ++i)
|
||||
{
|
||||
imp->combine_32[i] = delegate_combine_32;
|
||||
imp->combine_64[i] = delegate_combine_64;
|
||||
imp->combine_32_ca[i] = delegate_combine_32_ca;
|
||||
imp->combine_64_ca[i] = delegate_combine_64_ca;
|
||||
imp->combine_32[i] = NULL;
|
||||
imp->combine_64[i] = NULL;
|
||||
imp->combine_32_ca[i] = NULL;
|
||||
imp->combine_64_ca[i] = NULL;
|
||||
}
|
||||
|
||||
imp->fast_paths = fast_paths;
|
||||
|
||||
return imp;
|
||||
}
|
||||
|
||||
void
|
||||
_pixman_implementation_combine_32 (pixman_implementation_t * imp,
|
||||
pixman_op_t op,
|
||||
uint32_t * dest,
|
||||
const uint32_t * src,
|
||||
const uint32_t * mask,
|
||||
int width)
|
||||
pixman_combine_32_func_t
|
||||
_pixman_implementation_lookup_combiner (pixman_implementation_t *imp,
|
||||
pixman_op_t op,
|
||||
pixman_bool_t component_alpha,
|
||||
pixman_bool_t narrow)
|
||||
{
|
||||
(*imp->combine_32[op]) (imp, op, dest, src, mask, width);
|
||||
}
|
||||
pixman_combine_32_func_t f;
|
||||
|
||||
void
|
||||
_pixman_implementation_combine_64 (pixman_implementation_t * imp,
|
||||
pixman_op_t op,
|
||||
uint64_t * dest,
|
||||
const uint64_t * src,
|
||||
const uint64_t * mask,
|
||||
int width)
|
||||
{
|
||||
(*imp->combine_64[op]) (imp, op, dest, src, mask, width);
|
||||
}
|
||||
do
|
||||
{
|
||||
pixman_combine_32_func_t (*combiners[]) =
|
||||
{
|
||||
(pixman_combine_32_func_t *)imp->combine_64,
|
||||
(pixman_combine_32_func_t *)imp->combine_64_ca,
|
||||
imp->combine_32,
|
||||
imp->combine_32_ca,
|
||||
};
|
||||
|
||||
void
|
||||
_pixman_implementation_combine_32_ca (pixman_implementation_t * imp,
|
||||
pixman_op_t op,
|
||||
uint32_t * dest,
|
||||
const uint32_t * src,
|
||||
const uint32_t * mask,
|
||||
int width)
|
||||
{
|
||||
(*imp->combine_32_ca[op]) (imp, op, dest, src, mask, width);
|
||||
}
|
||||
f = combiners[component_alpha | (narrow << 1)][op];
|
||||
|
||||
void
|
||||
_pixman_implementation_combine_64_ca (pixman_implementation_t * imp,
|
||||
pixman_op_t op,
|
||||
uint64_t * dest,
|
||||
const uint64_t * src,
|
||||
const uint64_t * mask,
|
||||
int width)
|
||||
{
|
||||
(*imp->combine_64_ca[op]) (imp, op, dest, src, mask, width);
|
||||
imp = imp->delegate;
|
||||
}
|
||||
while (!f);
|
||||
|
||||
return f;
|
||||
}
|
||||
|
||||
pixman_bool_t
|
||||
@ -217,13 +152,13 @@ _pixman_implementation_blt (pixman_implementation_t * imp,
|
||||
int dst_bpp,
|
||||
int src_x,
|
||||
int src_y,
|
||||
int dst_x,
|
||||
int dst_y,
|
||||
int dest_x,
|
||||
int dest_y,
|
||||
int width,
|
||||
int height)
|
||||
{
|
||||
return (*imp->blt) (imp, src_bits, dst_bits, src_stride, dst_stride,
|
||||
src_bpp, dst_bpp, src_x, src_y, dst_x, dst_y,
|
||||
src_bpp, dst_bpp, src_x, src_y, dest_x, dest_y,
|
||||
width, height);
|
||||
}
|
||||
|
||||
@ -241,12 +176,6 @@ _pixman_implementation_fill (pixman_implementation_t *imp,
|
||||
return (*imp->fill) (imp, bits, stride, bpp, x, y, width, height, xor);
|
||||
}
|
||||
|
||||
static uint32_t *
|
||||
get_scanline_null (pixman_iter_t *iter, const uint32_t *mask)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
_pixman_implementation_src_iter_init (pixman_implementation_t *imp,
|
||||
pixman_iter_t *iter,
|
||||
@ -266,19 +195,7 @@ _pixman_implementation_src_iter_init (pixman_implementation_t *imp,
|
||||
iter->height = height;
|
||||
iter->flags = flags;
|
||||
|
||||
if (!image)
|
||||
{
|
||||
iter->get_scanline = get_scanline_null;
|
||||
}
|
||||
else if ((flags & (ITER_IGNORE_ALPHA | ITER_IGNORE_RGB)) ==
|
||||
(ITER_IGNORE_ALPHA | ITER_IGNORE_RGB))
|
||||
{
|
||||
iter->get_scanline = _pixman_iter_get_scanline_noop;
|
||||
}
|
||||
else
|
||||
{
|
||||
(*imp->src_iter_init) (imp, iter);
|
||||
}
|
||||
(*imp->src_iter_init) (imp, iter);
|
||||
}
|
||||
|
||||
void
|
||||
|
1280
gfx/cairo/libpixman/src/pixman-inlines.h
Normal file
1280
gfx/cairo/libpixman/src/pixman-inlines.h
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
164
gfx/cairo/libpixman/src/pixman-noop.c
Normal file
164
gfx/cairo/libpixman/src/pixman-noop.c
Normal file
@ -0,0 +1,164 @@
|
||||
/* -*- Mode: c; c-basic-offset: 4; tab-width: 8; indent-tabs-mode: t; -*- */
|
||||
/*
|
||||
* Copyright © 2011 Red Hat, Inc.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include "pixman-private.h"
|
||||
#include "pixman-combine32.h"
|
||||
#include "pixman-inlines.h"
|
||||
|
||||
static void
|
||||
noop_composite (pixman_implementation_t *imp,
|
||||
pixman_composite_info_t *info)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
static void
|
||||
dest_write_back_direct (pixman_iter_t *iter)
|
||||
{
|
||||
iter->buffer += iter->image->bits.rowstride;
|
||||
}
|
||||
|
||||
static uint32_t *
|
||||
noop_get_scanline (pixman_iter_t *iter, const uint32_t *mask)
|
||||
{
|
||||
uint32_t *result = iter->buffer;
|
||||
|
||||
iter->buffer += iter->image->bits.rowstride;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static uint32_t *
|
||||
get_scanline_null (pixman_iter_t *iter, const uint32_t *mask)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
noop_src_iter_init (pixman_implementation_t *imp, pixman_iter_t *iter)
|
||||
{
|
||||
pixman_image_t *image = iter->image;
|
||||
|
||||
#define FLAGS \
|
||||
(FAST_PATH_STANDARD_FLAGS | FAST_PATH_ID_TRANSFORM)
|
||||
|
||||
if (!image)
|
||||
{
|
||||
iter->get_scanline = get_scanline_null;
|
||||
}
|
||||
else if ((iter->flags & (ITER_IGNORE_ALPHA | ITER_IGNORE_RGB)) ==
|
||||
(ITER_IGNORE_ALPHA | ITER_IGNORE_RGB))
|
||||
{
|
||||
iter->get_scanline = _pixman_iter_get_scanline_noop;
|
||||
}
|
||||
else if (image->common.extended_format_code == PIXMAN_solid &&
|
||||
((image->common.flags & (FAST_PATH_BITS_IMAGE | FAST_PATH_NO_ALPHA_MAP)) ==
|
||||
(FAST_PATH_BITS_IMAGE | FAST_PATH_NO_ALPHA_MAP)))
|
||||
{
|
||||
bits_image_t *bits = &image->bits;
|
||||
|
||||
if (iter->flags & ITER_NARROW)
|
||||
{
|
||||
uint32_t color = bits->fetch_pixel_32 (bits, 0, 0);
|
||||
uint32_t *buffer = iter->buffer;
|
||||
uint32_t *end = buffer + iter->width;
|
||||
|
||||
while (buffer < end)
|
||||
*(buffer++) = color;
|
||||
}
|
||||
else
|
||||
{
|
||||
uint64_t color = bits->fetch_pixel_64 (bits, 0, 0);
|
||||
uint64_t *buffer = (uint64_t *)iter->buffer;
|
||||
uint64_t *end = buffer + iter->width;
|
||||
|
||||
while (buffer < end)
|
||||
*(buffer++) = color;
|
||||
}
|
||||
|
||||
iter->get_scanline = _pixman_iter_get_scanline_noop;
|
||||
}
|
||||
else if (image->common.extended_format_code == PIXMAN_a8r8g8b8 &&
|
||||
(iter->flags & ITER_NARROW) &&
|
||||
(image->common.flags & FLAGS) == FLAGS &&
|
||||
iter->x >= 0 && iter->y >= 0 &&
|
||||
iter->x + iter->width <= image->bits.width &&
|
||||
iter->y + iter->height <= image->bits.height)
|
||||
{
|
||||
iter->buffer =
|
||||
image->bits.bits + iter->y * image->bits.rowstride + iter->x;
|
||||
|
||||
iter->get_scanline = noop_get_scanline;
|
||||
}
|
||||
else
|
||||
{
|
||||
(* imp->delegate->src_iter_init) (imp->delegate, iter);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
noop_dest_iter_init (pixman_implementation_t *imp, pixman_iter_t *iter)
|
||||
{
|
||||
pixman_image_t *image = iter->image;
|
||||
uint32_t image_flags = image->common.flags;
|
||||
uint32_t iter_flags = iter->flags;
|
||||
|
||||
if ((image_flags & FAST_PATH_STD_DEST_FLAGS) == FAST_PATH_STD_DEST_FLAGS &&
|
||||
(iter_flags & ITER_NARROW) == ITER_NARROW &&
|
||||
((image->common.extended_format_code == PIXMAN_a8r8g8b8) ||
|
||||
(image->common.extended_format_code == PIXMAN_x8r8g8b8 &&
|
||||
(iter_flags & (ITER_LOCALIZED_ALPHA)))))
|
||||
{
|
||||
iter->buffer = image->bits.bits + iter->y * image->bits.rowstride + iter->x;
|
||||
|
||||
iter->get_scanline = _pixman_iter_get_scanline_noop;
|
||||
iter->write_back = dest_write_back_direct;
|
||||
}
|
||||
else
|
||||
{
|
||||
(* imp->delegate->dest_iter_init) (imp->delegate, iter);
|
||||
}
|
||||
}
|
||||
|
||||
static const pixman_fast_path_t noop_fast_paths[] =
|
||||
{
|
||||
{ PIXMAN_OP_DST, PIXMAN_any, 0, PIXMAN_any, 0, PIXMAN_any, 0, noop_composite },
|
||||
{ PIXMAN_OP_NONE },
|
||||
};
|
||||
|
||||
pixman_implementation_t *
|
||||
_pixman_implementation_create_noop (pixman_implementation_t *fallback)
|
||||
{
|
||||
pixman_implementation_t *imp =
|
||||
_pixman_implementation_create (fallback, noop_fast_paths);
|
||||
|
||||
imp->src_iter_init = noop_src_iter_init;
|
||||
imp->dest_iter_init = noop_dest_iter_init;
|
||||
|
||||
return imp;
|
||||
}
|
@ -250,6 +250,19 @@ _pixman_radial_gradient_iter_init (pixman_image_t *image, pixman_iter_t *iter);
|
||||
void
|
||||
_pixman_conical_gradient_iter_init (pixman_image_t *image, pixman_iter_t *iter);
|
||||
|
||||
void
|
||||
_pixman_image_init (pixman_image_t *image);
|
||||
|
||||
pixman_bool_t
|
||||
_pixman_bits_image_init (pixman_image_t * image,
|
||||
pixman_format_code_t format,
|
||||
int width,
|
||||
int height,
|
||||
uint32_t * bits,
|
||||
int rowstride);
|
||||
pixman_bool_t
|
||||
_pixman_image_fini (pixman_image_t *image);
|
||||
|
||||
pixman_image_t *
|
||||
_pixman_image_allocate (void);
|
||||
|
||||
@ -286,29 +299,29 @@ typedef struct
|
||||
uint32_t left_rb;
|
||||
uint32_t right_ag;
|
||||
uint32_t right_rb;
|
||||
int32_t left_x;
|
||||
int32_t right_x;
|
||||
int32_t stepper;
|
||||
pixman_fixed_t left_x;
|
||||
pixman_fixed_t right_x;
|
||||
pixman_fixed_t stepper;
|
||||
|
||||
pixman_gradient_stop_t *stops;
|
||||
int num_stops;
|
||||
unsigned int spread;
|
||||
pixman_repeat_t repeat;
|
||||
|
||||
int need_reset;
|
||||
pixman_bool_t need_reset;
|
||||
} pixman_gradient_walker_t;
|
||||
|
||||
void
|
||||
_pixman_gradient_walker_init (pixman_gradient_walker_t *walker,
|
||||
gradient_t * gradient,
|
||||
unsigned int spread);
|
||||
pixman_repeat_t repeat);
|
||||
|
||||
void
|
||||
_pixman_gradient_walker_reset (pixman_gradient_walker_t *walker,
|
||||
pixman_fixed_32_32_t pos);
|
||||
pixman_fixed_48_16_t pos);
|
||||
|
||||
uint32_t
|
||||
_pixman_gradient_walker_pixel (pixman_gradient_walker_t *walker,
|
||||
pixman_fixed_32_32_t x);
|
||||
pixman_fixed_48_16_t x);
|
||||
|
||||
/*
|
||||
* Edges
|
||||
@ -346,6 +359,40 @@ pixman_rasterize_edges_accessors (pixman_image_t *image,
|
||||
*/
|
||||
typedef struct pixman_implementation_t pixman_implementation_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
pixman_op_t op;
|
||||
pixman_image_t * src_image;
|
||||
pixman_image_t * mask_image;
|
||||
pixman_image_t * dest_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;
|
||||
|
||||
uint32_t src_flags;
|
||||
uint32_t mask_flags;
|
||||
uint32_t dest_flags;
|
||||
} pixman_composite_info_t;
|
||||
|
||||
#define PIXMAN_COMPOSITE_ARGS(info) \
|
||||
MAYBE_UNUSED pixman_op_t op = info->op; \
|
||||
MAYBE_UNUSED pixman_image_t * src_image = info->src_image; \
|
||||
MAYBE_UNUSED pixman_image_t * mask_image = info->mask_image; \
|
||||
MAYBE_UNUSED pixman_image_t * dest_image = info->dest_image; \
|
||||
MAYBE_UNUSED int32_t src_x = info->src_x; \
|
||||
MAYBE_UNUSED int32_t src_y = info->src_y; \
|
||||
MAYBE_UNUSED int32_t mask_x = info->mask_x; \
|
||||
MAYBE_UNUSED int32_t mask_y = info->mask_y; \
|
||||
MAYBE_UNUSED int32_t dest_x = info->dest_x; \
|
||||
MAYBE_UNUSED int32_t dest_y = info->dest_y; \
|
||||
MAYBE_UNUSED int32_t width = info->width; \
|
||||
MAYBE_UNUSED int32_t height = info->height
|
||||
|
||||
typedef void (*pixman_combine_32_func_t) (pixman_implementation_t *imp,
|
||||
pixman_op_t op,
|
||||
uint32_t * dest,
|
||||
@ -361,18 +408,7 @@ typedef void (*pixman_combine_64_func_t) (pixman_implementation_t *imp,
|
||||
int width);
|
||||
|
||||
typedef void (*pixman_composite_func_t) (pixman_implementation_t *imp,
|
||||
pixman_op_t op,
|
||||
pixman_image_t * src,
|
||||
pixman_image_t * mask,
|
||||
pixman_image_t * dest,
|
||||
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);
|
||||
pixman_composite_info_t *info);
|
||||
typedef pixman_bool_t (*pixman_blt_func_t) (pixman_implementation_t *imp,
|
||||
uint32_t * src_bits,
|
||||
uint32_t * dst_bits,
|
||||
@ -382,8 +418,8 @@ typedef pixman_bool_t (*pixman_blt_func_t) (pixman_implementation_t *imp,
|
||||
int dst_bpp,
|
||||
int src_x,
|
||||
int src_y,
|
||||
int dst_x,
|
||||
int dst_y,
|
||||
int dest_x,
|
||||
int dest_y,
|
||||
int width,
|
||||
int height);
|
||||
typedef pixman_bool_t (*pixman_fill_func_t) (pixman_implementation_t *imp,
|
||||
@ -439,34 +475,11 @@ pixman_implementation_t *
|
||||
_pixman_implementation_create (pixman_implementation_t *delegate,
|
||||
const pixman_fast_path_t *fast_paths);
|
||||
|
||||
void
|
||||
_pixman_implementation_combine_32 (pixman_implementation_t *imp,
|
||||
pixman_op_t op,
|
||||
uint32_t * dest,
|
||||
const uint32_t * src,
|
||||
const uint32_t * mask,
|
||||
int width);
|
||||
void
|
||||
_pixman_implementation_combine_64 (pixman_implementation_t *imp,
|
||||
pixman_op_t op,
|
||||
uint64_t * dest,
|
||||
const uint64_t * src,
|
||||
const uint64_t * mask,
|
||||
int width);
|
||||
void
|
||||
_pixman_implementation_combine_32_ca (pixman_implementation_t *imp,
|
||||
pixman_op_t op,
|
||||
uint32_t * dest,
|
||||
const uint32_t * src,
|
||||
const uint32_t * mask,
|
||||
int width);
|
||||
void
|
||||
_pixman_implementation_combine_64_ca (pixman_implementation_t *imp,
|
||||
pixman_op_t op,
|
||||
uint64_t * dest,
|
||||
const uint64_t * src,
|
||||
const uint64_t * mask,
|
||||
int width);
|
||||
pixman_combine_32_func_t
|
||||
_pixman_implementation_lookup_combiner (pixman_implementation_t *imp,
|
||||
pixman_op_t op,
|
||||
pixman_bool_t component_alpha,
|
||||
pixman_bool_t wide);
|
||||
|
||||
pixman_bool_t
|
||||
_pixman_implementation_blt (pixman_implementation_t *imp,
|
||||
@ -478,8 +491,8 @@ _pixman_implementation_blt (pixman_implementation_t *imp,
|
||||
int dst_bpp,
|
||||
int src_x,
|
||||
int src_y,
|
||||
int dst_x,
|
||||
int dst_y,
|
||||
int dest_x,
|
||||
int dest_y,
|
||||
int width,
|
||||
int height);
|
||||
|
||||
@ -523,7 +536,10 @@ _pixman_implementation_create_general (void);
|
||||
pixman_implementation_t *
|
||||
_pixman_implementation_create_fast_path (pixman_implementation_t *fallback);
|
||||
|
||||
#ifdef USE_MMX
|
||||
pixman_implementation_t *
|
||||
_pixman_implementation_create_noop (pixman_implementation_t *fallback);
|
||||
|
||||
#if defined USE_X86_MMX || defined USE_ARM_IWMMXT
|
||||
pixman_implementation_t *
|
||||
_pixman_implementation_create_mmx (pixman_implementation_t *fallback);
|
||||
#endif
|
||||
@ -543,6 +559,11 @@ pixman_implementation_t *
|
||||
_pixman_implementation_create_arm_neon (pixman_implementation_t *fallback);
|
||||
#endif
|
||||
|
||||
#ifdef USE_MIPS_DSPR2
|
||||
pixman_implementation_t *
|
||||
_pixman_implementation_create_mips_dspr2 (pixman_implementation_t *fallback);
|
||||
#endif
|
||||
|
||||
#ifdef USE_VMX
|
||||
pixman_implementation_t *
|
||||
_pixman_implementation_create_vmx (pixman_implementation_t *fallback);
|
||||
@ -587,15 +608,16 @@ _pixman_iter_get_scanline_noop (pixman_iter_t *iter, const uint32_t *mask);
|
||||
#define FAST_PATH_IS_OPAQUE (1 << 13)
|
||||
#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_ROTATE_90_TRANSFORM (1 << 21)
|
||||
#define FAST_PATH_ROTATE_180_TRANSFORM (1 << 22)
|
||||
#define FAST_PATH_ROTATE_270_TRANSFORM (1 << 23)
|
||||
#define FAST_PATH_SIMPLE_REPEAT (1 << 24)
|
||||
#define FAST_PATH_X_UNIT_POSITIVE (1 << 16)
|
||||
#define FAST_PATH_AFFINE_TRANSFORM (1 << 17)
|
||||
#define FAST_PATH_Y_UNIT_ZERO (1 << 18)
|
||||
#define FAST_PATH_BILINEAR_FILTER (1 << 19)
|
||||
#define FAST_PATH_ROTATE_90_TRANSFORM (1 << 20)
|
||||
#define FAST_PATH_ROTATE_180_TRANSFORM (1 << 21)
|
||||
#define FAST_PATH_ROTATE_270_TRANSFORM (1 << 22)
|
||||
#define FAST_PATH_SAMPLES_COVER_CLIP_NEAREST (1 << 23)
|
||||
#define FAST_PATH_SAMPLES_COVER_CLIP_BILINEAR (1 << 24)
|
||||
#define FAST_PATH_BITS_IMAGE (1 << 25)
|
||||
|
||||
#define FAST_PATH_PAD_REPEAT \
|
||||
(FAST_PATH_NO_NONE_REPEAT | \
|
||||
@ -631,7 +653,7 @@ _pixman_iter_get_scanline_noop (pixman_iter_t *iter, const uint32_t *mask);
|
||||
#define SOURCE_FLAGS(format) \
|
||||
(FAST_PATH_STANDARD_FLAGS | \
|
||||
((PIXMAN_ ## format == PIXMAN_solid) ? \
|
||||
0 : (FAST_PATH_SAMPLES_COVER_CLIP | FAST_PATH_ID_TRANSFORM)))
|
||||
0 : (FAST_PATH_SAMPLES_COVER_CLIP_NEAREST | FAST_PATH_NEAREST_FILTER | FAST_PATH_ID_TRANSFORM)))
|
||||
|
||||
#define MASK_FLAGS(format, extra) \
|
||||
((PIXMAN_ ## format == PIXMAN_null) ? 0 : (SOURCE_FLAGS (format) | extra))
|
||||
@ -670,10 +692,13 @@ void *
|
||||
pixman_malloc_abc (unsigned int a, unsigned int b, unsigned int c);
|
||||
|
||||
pixman_bool_t
|
||||
pixman_multiply_overflows_int (unsigned int a, unsigned int b);
|
||||
_pixman_multiply_overflows_size (size_t a, size_t b);
|
||||
|
||||
pixman_bool_t
|
||||
pixman_addition_overflows_int (unsigned int a, unsigned int b);
|
||||
_pixman_multiply_overflows_int (unsigned int a, unsigned int b);
|
||||
|
||||
pixman_bool_t
|
||||
_pixman_addition_overflows_int (unsigned int a, unsigned int b);
|
||||
|
||||
/* Compositing utilities */
|
||||
void
|
||||
@ -687,6 +712,17 @@ pixman_contract (uint32_t * dst,
|
||||
const uint64_t *src,
|
||||
int width);
|
||||
|
||||
pixman_bool_t
|
||||
_pixman_lookup_composite_function (pixman_implementation_t *toplevel,
|
||||
pixman_op_t op,
|
||||
pixman_format_code_t src_format,
|
||||
uint32_t src_flags,
|
||||
pixman_format_code_t mask_format,
|
||||
uint32_t mask_flags,
|
||||
pixman_format_code_t dest_format,
|
||||
uint32_t dest_flags,
|
||||
pixman_implementation_t **out_imp,
|
||||
pixman_composite_func_t *out_func);
|
||||
|
||||
/* Region Helpers */
|
||||
pixman_bool_t
|
||||
@ -742,6 +778,7 @@ pixman_region16_copy_from_region32 (pixman_region16_t *dst,
|
||||
|
||||
/* Trivial versions that are useful in macros */
|
||||
#define CONVERT_8888_TO_8888(s) (s)
|
||||
#define CONVERT_x888_TO_8888(s) ((s) | 0xff000000)
|
||||
#define CONVERT_0565_TO_0565(s) (s)
|
||||
|
||||
#define PIXMAN_FORMAT_IS_WIDE(f) \
|
||||
@ -758,6 +795,49 @@ pixman_region16_copy_from_region32 (pixman_region16_t *dst,
|
||||
# define SCREEN_SHIFT_RIGHT(x,n) ((x) << (n))
|
||||
#endif
|
||||
|
||||
static force_inline uint32_t
|
||||
unorm_to_unorm (uint32_t val, int from_bits, int to_bits)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
if (from_bits == 0)
|
||||
return 0;
|
||||
|
||||
/* Delete any extra bits */
|
||||
val &= ((1 << from_bits) - 1);
|
||||
|
||||
if (from_bits >= to_bits)
|
||||
return val >> (from_bits - to_bits);
|
||||
|
||||
/* Start out with the high bit of val in the high bit of result. */
|
||||
result = val << (to_bits - from_bits);
|
||||
|
||||
/* Copy the bits in result, doubling the number of bits each time, until
|
||||
* we fill all to_bits. Unrolled manually because from_bits and to_bits
|
||||
* are usually known statically, so the compiler can turn all of this
|
||||
* into a few shifts.
|
||||
*/
|
||||
#define REPLICATE() \
|
||||
do \
|
||||
{ \
|
||||
if (from_bits < to_bits) \
|
||||
{ \
|
||||
result |= result >> from_bits; \
|
||||
\
|
||||
from_bits *= 2; \
|
||||
} \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
REPLICATE();
|
||||
REPLICATE();
|
||||
REPLICATE();
|
||||
REPLICATE();
|
||||
REPLICATE();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* Various debugging code
|
||||
*/
|
||||
@ -856,10 +936,11 @@ _pixman_log_error (const char *function, const char *message);
|
||||
static inline uint64_t
|
||||
oil_profile_stamp_rdtsc (void)
|
||||
{
|
||||
uint64_t ts;
|
||||
uint32_t hi, lo;
|
||||
|
||||
__asm__ __volatile__ ("rdtsc\n" : "=A" (ts));
|
||||
return ts;
|
||||
__asm__ __volatile__ ("rdtsc\n" : "=a" (lo), "=d" (hi));
|
||||
|
||||
return lo | (((uint64_t)hi) << 32);
|
||||
}
|
||||
|
||||
#define OIL_STAMP oil_profile_stamp_rdtsc
|
||||
|
@ -78,11 +78,11 @@ radial_compute_color (double a,
|
||||
{
|
||||
/*
|
||||
* In this function error propagation can lead to bad results:
|
||||
* - det can have an unbound error (if b*b-a*c is very small),
|
||||
* - discr can have an unbound error (if b*b-a*c is very small),
|
||||
* potentially making it the opposite sign of what it should have been
|
||||
* (thus clearing a pixel that would have been colored or vice-versa)
|
||||
* or propagating the error to sqrtdet;
|
||||
* if det has the wrong sign or b is very small, this can lead to bad
|
||||
* or propagating the error to sqrtdiscr;
|
||||
* if discr has the wrong sign or b is very small, this can lead to bad
|
||||
* results
|
||||
*
|
||||
* - the algorithm used to compute the solutions of the quadratic
|
||||
@ -92,7 +92,7 @@ radial_compute_color (double a,
|
||||
*
|
||||
* - the above problems are worse if a is small (as inva becomes bigger)
|
||||
*/
|
||||
double det;
|
||||
double discr;
|
||||
|
||||
if (a == 0)
|
||||
{
|
||||
@ -116,15 +116,26 @@ radial_compute_color (double a,
|
||||
return 0;
|
||||
}
|
||||
|
||||
det = fdot (b, a, 0, b, -c, 0);
|
||||
if (det >= 0)
|
||||
discr = fdot (b, a, 0, b, -c, 0);
|
||||
if (discr >= 0)
|
||||
{
|
||||
double sqrtdet, t0, t1;
|
||||
double sqrtdiscr, t0, t1;
|
||||
|
||||
sqrtdet = sqrt (det);
|
||||
t0 = (b + sqrtdet) * inva;
|
||||
t1 = (b - sqrtdet) * inva;
|
||||
sqrtdiscr = sqrt (discr);
|
||||
t0 = (b + sqrtdiscr) * inva;
|
||||
t1 = (b - sqrtdiscr) * inva;
|
||||
|
||||
/*
|
||||
* The root that must be used is the biggest one that belongs
|
||||
* to the valid range ([0,1] for PIXMAN_REPEAT_NONE, any
|
||||
* solution that results in a positive radius otherwise).
|
||||
*
|
||||
* If a > 0, t0 is the biggest solution, so if it is valid, it
|
||||
* is the correct result.
|
||||
*
|
||||
* If a < 0, only one of the solutions can be valid, so the
|
||||
* order in which they are tested is not important.
|
||||
*/
|
||||
if (repeat == PIXMAN_REPEAT_NONE)
|
||||
{
|
||||
if (0 <= t0 && t0 <= pixman_fixed_1)
|
||||
@ -151,7 +162,7 @@ radial_get_scanline_narrow (pixman_iter_t *iter, const uint32_t *mask)
|
||||
* Implementation of radial gradients following the PDF specification.
|
||||
* See section 8.7.4.5.4 Type 3 (Radial) Shadings of the PDF Reference
|
||||
* Manual (PDF 32000-1:2008 at the time of this writing).
|
||||
*
|
||||
*
|
||||
* In the radial gradient problem we are given two circles (c₁,r₁) and
|
||||
* (c₂,r₂) that define the gradient itself.
|
||||
*
|
||||
@ -168,7 +179,7 @@ radial_get_scanline_narrow (pixman_iter_t *iter, const uint32_t *mask)
|
||||
*
|
||||
* The graphical result is the same as drawing the valid (radius > 0)
|
||||
* circles with increasing t in [-inf, +inf] (or in [0,1] if the gradient
|
||||
* is not repeated) using SOURCE operatior composition.
|
||||
* is not repeated) using SOURCE operator composition.
|
||||
*
|
||||
* It looks like a cone pointing towards the viewer if the ending circle
|
||||
* is smaller than the starting one, a cone pointing inside the page if
|
||||
@ -179,14 +190,14 @@ radial_get_scanline_narrow (pixman_iter_t *iter, const uint32_t *mask)
|
||||
* in, compute the t values for that point, solving for t in:
|
||||
*
|
||||
* length((1-t)·c₁ + t·(c₂) - p) = (1-t)·r₁ + t·r₂
|
||||
*
|
||||
*
|
||||
* Let's rewrite it in a simpler way, by defining some auxiliary
|
||||
* variables:
|
||||
*
|
||||
* cd = c₂ - c₁
|
||||
* pd = p - c₁
|
||||
* dr = r₂ - r₁
|
||||
* lenght(t·cd - pd) = r₁ + t·dr
|
||||
* length(t·cd - pd) = r₁ + t·dr
|
||||
*
|
||||
* which actually means
|
||||
*
|
||||
@ -212,7 +223,7 @@ radial_get_scanline_narrow (pixman_iter_t *iter, const uint32_t *mask)
|
||||
* B = pdx·cdx + pdy·cdy + r₁·dr
|
||||
* C = pdx² + pdy² - r₁²
|
||||
* At² - 2Bt + C = 0
|
||||
*
|
||||
*
|
||||
* The solutions (unless the equation degenerates because of A = 0) are:
|
||||
*
|
||||
* t = (B ± ⎷(B² - A·C)) / A
|
||||
@ -251,7 +262,7 @@ radial_get_scanline_narrow (pixman_iter_t *iter, const uint32_t *mask)
|
||||
{
|
||||
if (!pixman_transform_point_3d (image->common.transform, &v))
|
||||
return iter->buffer;
|
||||
|
||||
|
||||
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];
|
||||
@ -457,4 +468,3 @@ pixman_image_create_radial_gradient (pixman_point_fixed_t * inner,
|
||||
|
||||
return image;
|
||||
}
|
||||
|
||||
|
@ -102,7 +102,11 @@
|
||||
|
||||
static const box_type_t PREFIX (_empty_box_) = { 0, 0, 0, 0 };
|
||||
static const region_data_type_t PREFIX (_empty_data_) = { 0, 0 };
|
||||
#if defined (__llvm__) && !defined (__clang__)
|
||||
static const volatile region_data_type_t PREFIX (_broken_data_) = { 0, 0 };
|
||||
#else
|
||||
static const region_data_type_t PREFIX (_broken_data_) = { 0, 0 };
|
||||
#endif
|
||||
|
||||
static box_type_t *pixman_region_empty_box =
|
||||
(box_type_t *)&PREFIX (_empty_box_);
|
||||
@ -824,8 +828,7 @@ pixman_op (region_type_t * new_reg, /* Place to store result
|
||||
{
|
||||
if (!pixman_rect_alloc (new_reg, new_size))
|
||||
{
|
||||
if (old_data)
|
||||
free (old_data);
|
||||
free (old_data);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
@ -1001,8 +1004,7 @@ pixman_op (region_type_t * new_reg, /* Place to store result
|
||||
APPEND_REGIONS (new_reg, r2_band_end, r2_end);
|
||||
}
|
||||
|
||||
if (old_data)
|
||||
free (old_data);
|
||||
free (old_data);
|
||||
|
||||
if (!(numRects = new_reg->data->numRects))
|
||||
{
|
||||
@ -1023,8 +1025,7 @@ pixman_op (region_type_t * new_reg, /* Place to store result
|
||||
return TRUE;
|
||||
|
||||
bail:
|
||||
if (old_data)
|
||||
free (old_data);
|
||||
free (old_data);
|
||||
|
||||
return pixman_break (new_reg);
|
||||
}
|
||||
@ -2086,6 +2087,40 @@ PIXMAN_EXPORT PREFIX (_inverse) (region_type_t *new_reg, /* Destination region
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* In time O(log n), locate the first box whose y2 is greater than y.
|
||||
* Return @end if no such box exists.
|
||||
*/
|
||||
static box_type_t *
|
||||
find_box_for_y (box_type_t *begin, box_type_t *end, int y)
|
||||
{
|
||||
box_type_t *mid;
|
||||
|
||||
if (end == begin)
|
||||
return end;
|
||||
|
||||
if (end - begin == 1)
|
||||
{
|
||||
if (begin->y2 > y)
|
||||
return begin;
|
||||
else
|
||||
return end;
|
||||
}
|
||||
|
||||
mid = begin + (end - begin) / 2;
|
||||
if (mid->y2 > y)
|
||||
{
|
||||
/* If no box is found in [begin, mid], the function
|
||||
* will return @mid, which is then known to be the
|
||||
* correct answer.
|
||||
*/
|
||||
return find_box_for_y (begin, mid, y);
|
||||
}
|
||||
else
|
||||
{
|
||||
return find_box_for_y (mid, end, y);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* rect_in(region, rect)
|
||||
* This routine takes a pointer to a region and a pointer to a box
|
||||
@ -2102,7 +2137,6 @@ PIXMAN_EXPORT PREFIX (_inverse) (region_type_t *new_reg, /* Destination region
|
||||
* partially in the region) or is outside the region (we reached a band
|
||||
* that doesn't overlap the box at all and part_in is false)
|
||||
*/
|
||||
|
||||
pixman_region_overlap_t
|
||||
PIXMAN_EXPORT PREFIX (_contains_rectangle) (region_type_t * region,
|
||||
box_type_t * prect)
|
||||
@ -2139,12 +2173,15 @@ PIXMAN_EXPORT PREFIX (_contains_rectangle) (region_type_t * region,
|
||||
|
||||
/* can stop when both part_out and part_in are TRUE, or we reach prect->y2 */
|
||||
for (pbox = PIXREGION_BOXPTR (region), pbox_end = pbox + numRects;
|
||||
pbox != pbox_end;
|
||||
pbox++)
|
||||
pbox != pbox_end;
|
||||
pbox++)
|
||||
{
|
||||
|
||||
if (pbox->y2 <= y)
|
||||
continue; /* getting up to speed or skipping remainder of band */
|
||||
/* getting up to speed or skipping remainder of band */
|
||||
if (pbox->y2 <= y)
|
||||
{
|
||||
if ((pbox = find_box_for_y (pbox, pbox_end, y)) == pbox_end)
|
||||
break;
|
||||
}
|
||||
|
||||
if (pbox->y1 > y)
|
||||
{
|
||||
@ -2319,6 +2356,16 @@ PREFIX (_reset) (region_type_t *region, box_type_t *box)
|
||||
region->data = NULL;
|
||||
}
|
||||
|
||||
PIXMAN_EXPORT void
|
||||
PREFIX (_clear) (region_type_t *region)
|
||||
{
|
||||
GOOD (region);
|
||||
FREE_DATA (region);
|
||||
|
||||
region->extents = *pixman_region_empty_box;
|
||||
region->data = pixman_region_empty_data;
|
||||
}
|
||||
|
||||
/* box is "return" value */
|
||||
PIXMAN_EXPORT int
|
||||
PREFIX (_contains_point) (region_type_t * region,
|
||||
@ -2342,13 +2389,13 @@ PREFIX (_contains_point) (region_type_t * region,
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
for (pbox = PIXREGION_BOXPTR (region), pbox_end = pbox + numRects;
|
||||
pbox != pbox_end;
|
||||
pbox++)
|
||||
{
|
||||
if (y >= pbox->y2)
|
||||
continue; /* not there yet */
|
||||
pbox = PIXREGION_BOXPTR (region);
|
||||
pbox_end = pbox + numRects;
|
||||
|
||||
pbox = find_box_for_y (pbox, pbox_end, y);
|
||||
|
||||
for (;pbox != pbox_end; pbox++)
|
||||
{
|
||||
if ((y < pbox->y1) || (x < pbox->x1))
|
||||
break; /* missed it */
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -139,7 +139,7 @@ _pixman_edge_multi_init (pixman_edge_t * e,
|
||||
if (ne > 0)
|
||||
{
|
||||
int nx = ne / e->dy;
|
||||
ne -= nx * e->dy;
|
||||
ne -= nx * (pixman_fixed_48_16_t)e->dy;
|
||||
stepx += nx * e->signdx;
|
||||
}
|
||||
|
||||
|
@ -27,19 +27,136 @@
|
||||
#endif
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <limits.h>
|
||||
|
||||
#include "pixman-private.h"
|
||||
|
||||
#define N_CACHED_FAST_PATHS 8
|
||||
|
||||
typedef struct
|
||||
{
|
||||
struct
|
||||
{
|
||||
pixman_implementation_t * imp;
|
||||
pixman_fast_path_t fast_path;
|
||||
} cache [N_CACHED_FAST_PATHS];
|
||||
} cache_t;
|
||||
|
||||
PIXMAN_DEFINE_THREAD_LOCAL (cache_t, fast_path_cache);
|
||||
|
||||
pixman_bool_t
|
||||
pixman_multiply_overflows_int (unsigned int a,
|
||||
unsigned int b)
|
||||
_pixman_lookup_composite_function (pixman_implementation_t *toplevel,
|
||||
pixman_op_t op,
|
||||
pixman_format_code_t src_format,
|
||||
uint32_t src_flags,
|
||||
pixman_format_code_t mask_format,
|
||||
uint32_t mask_flags,
|
||||
pixman_format_code_t dest_format,
|
||||
uint32_t dest_flags,
|
||||
pixman_implementation_t **out_imp,
|
||||
pixman_composite_func_t *out_func)
|
||||
{
|
||||
pixman_implementation_t *imp;
|
||||
cache_t *cache;
|
||||
int i;
|
||||
|
||||
/* Check cache for fast paths */
|
||||
cache = PIXMAN_GET_THREAD_LOCAL (fast_path_cache);
|
||||
|
||||
for (i = 0; i < N_CACHED_FAST_PATHS; ++i)
|
||||
{
|
||||
const pixman_fast_path_t *info = &(cache->cache[i].fast_path);
|
||||
|
||||
/* Note that we check for equality here, not whether
|
||||
* the cached fast path matches. This is to prevent
|
||||
* us from selecting an overly general fast path
|
||||
* when a more specific one would work.
|
||||
*/
|
||||
if (info->op == op &&
|
||||
info->src_format == src_format &&
|
||||
info->mask_format == mask_format &&
|
||||
info->dest_format == dest_format &&
|
||||
info->src_flags == src_flags &&
|
||||
info->mask_flags == mask_flags &&
|
||||
info->dest_flags == dest_flags &&
|
||||
info->func)
|
||||
{
|
||||
*out_imp = cache->cache[i].imp;
|
||||
*out_func = cache->cache[i].fast_path.func;
|
||||
|
||||
goto update_cache;
|
||||
}
|
||||
}
|
||||
|
||||
for (imp = toplevel; imp != NULL; imp = imp->delegate)
|
||||
{
|
||||
const pixman_fast_path_t *info = imp->fast_paths;
|
||||
|
||||
while (info->op != PIXMAN_OP_NONE)
|
||||
{
|
||||
if ((info->op == op || info->op == PIXMAN_OP_any) &&
|
||||
/* Formats */
|
||||
((info->src_format == src_format) ||
|
||||
(info->src_format == PIXMAN_any)) &&
|
||||
((info->mask_format == mask_format) ||
|
||||
(info->mask_format == PIXMAN_any)) &&
|
||||
((info->dest_format == dest_format) ||
|
||||
(info->dest_format == PIXMAN_any)) &&
|
||||
/* Flags */
|
||||
(info->src_flags & src_flags) == info->src_flags &&
|
||||
(info->mask_flags & mask_flags) == info->mask_flags &&
|
||||
(info->dest_flags & dest_flags) == info->dest_flags)
|
||||
{
|
||||
*out_imp = imp;
|
||||
*out_func = info->func;
|
||||
|
||||
/* Set i to the last spot in the cache so that the
|
||||
* move-to-front code below will work
|
||||
*/
|
||||
i = N_CACHED_FAST_PATHS - 1;
|
||||
|
||||
goto update_cache;
|
||||
}
|
||||
|
||||
++info;
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
|
||||
update_cache:
|
||||
if (i)
|
||||
{
|
||||
while (i--)
|
||||
cache->cache[i + 1] = cache->cache[i];
|
||||
|
||||
cache->cache[0].imp = *out_imp;
|
||||
cache->cache[0].fast_path.op = op;
|
||||
cache->cache[0].fast_path.src_format = src_format;
|
||||
cache->cache[0].fast_path.src_flags = src_flags;
|
||||
cache->cache[0].fast_path.mask_format = mask_format;
|
||||
cache->cache[0].fast_path.mask_flags = mask_flags;
|
||||
cache->cache[0].fast_path.dest_format = dest_format;
|
||||
cache->cache[0].fast_path.dest_flags = dest_flags;
|
||||
cache->cache[0].fast_path.func = *out_func;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
pixman_bool_t
|
||||
_pixman_multiply_overflows_size (size_t a, size_t b)
|
||||
{
|
||||
return a >= SIZE_MAX / b;
|
||||
}
|
||||
|
||||
pixman_bool_t
|
||||
_pixman_multiply_overflows_int (unsigned int a, unsigned int b)
|
||||
{
|
||||
return a >= INT32_MAX / b;
|
||||
}
|
||||
|
||||
pixman_bool_t
|
||||
pixman_addition_overflows_int (unsigned int a,
|
||||
unsigned int b)
|
||||
_pixman_addition_overflows_int (unsigned int a, unsigned int b)
|
||||
{
|
||||
return a > INT32_MAX - b;
|
||||
}
|
||||
@ -67,31 +184,6 @@ pixman_malloc_abc (unsigned int a,
|
||||
return malloc (a * b * c);
|
||||
}
|
||||
|
||||
/*
|
||||
* Helper routine to expand a color component from 0 < n <= 8 bits to 16
|
||||
* bits by replication.
|
||||
*/
|
||||
static inline uint64_t
|
||||
expand16 (const uint8_t val, int nbits)
|
||||
{
|
||||
/* Start out with the high bit of val in the high bit of result. */
|
||||
uint16_t result = (uint16_t)val << (16 - nbits);
|
||||
|
||||
if (nbits == 0)
|
||||
return 0;
|
||||
|
||||
/* Copy the bits in result, doubling the number of bits each time, until
|
||||
* we fill all 16 bits.
|
||||
*/
|
||||
while (nbits < 16)
|
||||
{
|
||||
result |= result >> nbits;
|
||||
nbits *= 2;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* This function expands images from ARGB8 format to ARGB16. To preserve
|
||||
* precision, it needs to know the original source format. For example, if the
|
||||
@ -129,15 +221,33 @@ pixman_expand (uint64_t * dst,
|
||||
for (i = width - 1; i >= 0; i--)
|
||||
{
|
||||
const uint32_t pixel = src[i];
|
||||
const uint8_t a = (pixel >> a_shift) & a_mask,
|
||||
r = (pixel >> r_shift) & r_mask,
|
||||
g = (pixel >> g_shift) & g_mask,
|
||||
b = (pixel >> b_shift) & b_mask;
|
||||
const uint64_t a16 = a_size ? expand16 (a, a_size) : 0xffff,
|
||||
r16 = expand16 (r, r_size),
|
||||
g16 = expand16 (g, g_size),
|
||||
b16 = expand16 (b, b_size);
|
||||
uint8_t a, r, g, b;
|
||||
uint64_t a16, r16, g16, b16;
|
||||
|
||||
if (a_size)
|
||||
{
|
||||
a = (pixel >> a_shift) & a_mask;
|
||||
a16 = unorm_to_unorm (a, a_size, 16);
|
||||
}
|
||||
else
|
||||
{
|
||||
a16 = 0xffff;
|
||||
}
|
||||
|
||||
if (r_size)
|
||||
{
|
||||
r = (pixel >> r_shift) & r_mask;
|
||||
g = (pixel >> g_shift) & g_mask;
|
||||
b = (pixel >> b_shift) & b_mask;
|
||||
r16 = unorm_to_unorm (r, r_size, 16);
|
||||
g16 = unorm_to_unorm (g, g_size, 16);
|
||||
b16 = unorm_to_unorm (b, b_size, 16);
|
||||
}
|
||||
else
|
||||
{
|
||||
r16 = g16 = b16 = 0;
|
||||
}
|
||||
|
||||
dst[i] = a16 << 48 | r16 << 32 | g16 << 16 | b16;
|
||||
}
|
||||
}
|
||||
|
@ -238,7 +238,7 @@ static pixman_bool_t
|
||||
pixman_compute_composite_region32 (pixman_region32_t * region,
|
||||
pixman_image_t * src_image,
|
||||
pixman_image_t * mask_image,
|
||||
pixman_image_t * dst_image,
|
||||
pixman_image_t * dest_image,
|
||||
int32_t src_x,
|
||||
int32_t src_y,
|
||||
int32_t mask_x,
|
||||
@ -255,8 +255,8 @@ pixman_compute_composite_region32 (pixman_region32_t * region,
|
||||
|
||||
region->extents.x1 = MAX (region->extents.x1, 0);
|
||||
region->extents.y1 = MAX (region->extents.y1, 0);
|
||||
region->extents.x2 = MIN (region->extents.x2, dst_image->bits.width);
|
||||
region->extents.y2 = MIN (region->extents.y2, dst_image->bits.height);
|
||||
region->extents.x2 = MIN (region->extents.x2, dest_image->bits.width);
|
||||
region->extents.y2 = MIN (region->extents.y2, dest_image->bits.height);
|
||||
|
||||
region->data = 0;
|
||||
|
||||
@ -271,29 +271,29 @@ pixman_compute_composite_region32 (pixman_region32_t * region,
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (dst_image->common.have_clip_region)
|
||||
if (dest_image->common.have_clip_region)
|
||||
{
|
||||
if (!clip_general_image (region, &dst_image->common.clip_region, 0, 0))
|
||||
if (!clip_general_image (region, &dest_image->common.clip_region, 0, 0))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (dst_image->common.alpha_map)
|
||||
if (dest_image->common.alpha_map)
|
||||
{
|
||||
if (!pixman_region32_intersect_rect (region, region,
|
||||
dst_image->common.alpha_origin_x,
|
||||
dst_image->common.alpha_origin_y,
|
||||
dst_image->common.alpha_map->width,
|
||||
dst_image->common.alpha_map->height))
|
||||
dest_image->common.alpha_origin_x,
|
||||
dest_image->common.alpha_origin_y,
|
||||
dest_image->common.alpha_map->width,
|
||||
dest_image->common.alpha_map->height))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
if (!pixman_region32_not_empty (region))
|
||||
return FALSE;
|
||||
if (dst_image->common.alpha_map->common.have_clip_region)
|
||||
if (dest_image->common.alpha_map->common.have_clip_region)
|
||||
{
|
||||
if (!clip_general_image (region, &dst_image->common.alpha_map->common.clip_region,
|
||||
-dst_image->common.alpha_origin_x,
|
||||
-dst_image->common.alpha_origin_y))
|
||||
if (!clip_general_image (region, &dest_image->common.alpha_map->common.clip_region,
|
||||
-dest_image->common.alpha_origin_x,
|
||||
-dest_image->common.alpha_origin_y))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
@ -335,340 +335,89 @@ pixman_compute_composite_region32 (pixman_region32_t * region,
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
walk_region_internal (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,
|
||||
pixman_bool_t src_repeat,
|
||||
pixman_bool_t mask_repeat,
|
||||
pixman_region32_t * region,
|
||||
pixman_composite_func_t composite_rect)
|
||||
{
|
||||
int w, h, w_this, h_this;
|
||||
int x_msk, y_msk, x_src, y_src, x_dst, y_dst;
|
||||
int src_dy = src_y - dest_y;
|
||||
int src_dx = src_x - dest_x;
|
||||
int mask_dy = mask_y - dest_y;
|
||||
int mask_dx = mask_x - dest_x;
|
||||
const pixman_box32_t *pbox;
|
||||
int n;
|
||||
|
||||
pbox = pixman_region32_rectangles (region, &n);
|
||||
|
||||
/* Fast path for non-repeating sources */
|
||||
if (!src_repeat && !mask_repeat)
|
||||
{
|
||||
while (n--)
|
||||
{
|
||||
(*composite_rect) (imp, op,
|
||||
src_image, mask_image, dst_image,
|
||||
pbox->x1 + src_dx,
|
||||
pbox->y1 + src_dy,
|
||||
pbox->x1 + mask_dx,
|
||||
pbox->y1 + mask_dy,
|
||||
pbox->x1,
|
||||
pbox->y1,
|
||||
pbox->x2 - pbox->x1,
|
||||
pbox->y2 - pbox->y1);
|
||||
|
||||
pbox++;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
while (n--)
|
||||
{
|
||||
h = pbox->y2 - pbox->y1;
|
||||
y_src = pbox->y1 + src_dy;
|
||||
y_msk = pbox->y1 + mask_dy;
|
||||
y_dst = pbox->y1;
|
||||
|
||||
while (h)
|
||||
{
|
||||
h_this = h;
|
||||
w = pbox->x2 - pbox->x1;
|
||||
x_src = pbox->x1 + src_dx;
|
||||
x_msk = pbox->x1 + mask_dx;
|
||||
x_dst = pbox->x1;
|
||||
|
||||
if (mask_repeat)
|
||||
{
|
||||
y_msk = MOD (y_msk, mask_image->bits.height);
|
||||
if (h_this > mask_image->bits.height - y_msk)
|
||||
h_this = mask_image->bits.height - y_msk;
|
||||
}
|
||||
|
||||
if (src_repeat)
|
||||
{
|
||||
y_src = MOD (y_src, src_image->bits.height);
|
||||
if (h_this > src_image->bits.height - y_src)
|
||||
h_this = src_image->bits.height - y_src;
|
||||
}
|
||||
|
||||
while (w)
|
||||
{
|
||||
w_this = w;
|
||||
|
||||
if (mask_repeat)
|
||||
{
|
||||
x_msk = MOD (x_msk, mask_image->bits.width);
|
||||
if (w_this > mask_image->bits.width - x_msk)
|
||||
w_this = mask_image->bits.width - x_msk;
|
||||
}
|
||||
|
||||
if (src_repeat)
|
||||
{
|
||||
x_src = MOD (x_src, src_image->bits.width);
|
||||
if (w_this > src_image->bits.width - x_src)
|
||||
w_this = src_image->bits.width - x_src;
|
||||
}
|
||||
|
||||
(*composite_rect) (imp, op,
|
||||
src_image, mask_image, dst_image,
|
||||
x_src, y_src, x_msk, y_msk, x_dst, y_dst,
|
||||
w_this, h_this);
|
||||
w -= w_this;
|
||||
|
||||
x_src += w_this;
|
||||
x_msk += w_this;
|
||||
x_dst += w_this;
|
||||
}
|
||||
|
||||
h -= h_this;
|
||||
y_src += h_this;
|
||||
y_msk += h_this;
|
||||
y_dst += h_this;
|
||||
}
|
||||
|
||||
pbox++;
|
||||
}
|
||||
}
|
||||
|
||||
#define N_CACHED_FAST_PATHS 8
|
||||
|
||||
typedef struct
|
||||
{
|
||||
struct
|
||||
{
|
||||
pixman_implementation_t * imp;
|
||||
pixman_fast_path_t fast_path;
|
||||
} cache [N_CACHED_FAST_PATHS];
|
||||
} cache_t;
|
||||
pixman_fixed_48_16_t x1;
|
||||
pixman_fixed_48_16_t y1;
|
||||
pixman_fixed_48_16_t x2;
|
||||
pixman_fixed_48_16_t y2;
|
||||
} box_48_16_t;
|
||||
|
||||
PIXMAN_DEFINE_THREAD_LOCAL (cache_t, fast_path_cache);
|
||||
|
||||
static force_inline pixman_bool_t
|
||||
lookup_composite_function (pixman_op_t op,
|
||||
pixman_format_code_t src_format,
|
||||
uint32_t src_flags,
|
||||
pixman_format_code_t mask_format,
|
||||
uint32_t mask_flags,
|
||||
pixman_format_code_t dest_format,
|
||||
uint32_t dest_flags,
|
||||
pixman_implementation_t **out_imp,
|
||||
pixman_composite_func_t *out_func)
|
||||
static pixman_bool_t
|
||||
compute_transformed_extents (pixman_transform_t *transform,
|
||||
const pixman_box32_t *extents,
|
||||
box_48_16_t *transformed)
|
||||
{
|
||||
pixman_implementation_t *imp;
|
||||
cache_t *cache;
|
||||
pixman_fixed_48_16_t tx1, ty1, tx2, ty2;
|
||||
pixman_fixed_t x1, y1, x2, y2;
|
||||
int i;
|
||||
|
||||
/* Check cache for fast paths */
|
||||
cache = PIXMAN_GET_THREAD_LOCAL (fast_path_cache);
|
||||
x1 = pixman_int_to_fixed (extents->x1) + pixman_fixed_1 / 2;
|
||||
y1 = pixman_int_to_fixed (extents->y1) + pixman_fixed_1 / 2;
|
||||
x2 = pixman_int_to_fixed (extents->x2) - pixman_fixed_1 / 2;
|
||||
y2 = pixman_int_to_fixed (extents->y2) - pixman_fixed_1 / 2;
|
||||
|
||||
for (i = 0; i < N_CACHED_FAST_PATHS; ++i)
|
||||
if (!transform)
|
||||
{
|
||||
const pixman_fast_path_t *info = &(cache->cache[i].fast_path);
|
||||
transformed->x1 = x1;
|
||||
transformed->y1 = y1;
|
||||
transformed->x2 = x2;
|
||||
transformed->y2 = y2;
|
||||
|
||||
/* Note that we check for equality here, not whether
|
||||
* the cached fast path matches. This is to prevent
|
||||
* us from selecting an overly general fast path
|
||||
* when a more specific one would work.
|
||||
*/
|
||||
if (info->op == op &&
|
||||
info->src_format == src_format &&
|
||||
info->mask_format == mask_format &&
|
||||
info->dest_format == dest_format &&
|
||||
info->src_flags == src_flags &&
|
||||
info->mask_flags == mask_flags &&
|
||||
info->dest_flags == dest_flags &&
|
||||
info->func)
|
||||
{
|
||||
*out_imp = cache->cache[i].imp;
|
||||
*out_func = cache->cache[i].fast_path.func;
|
||||
|
||||
goto update_cache;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
for (imp = get_implementation (); imp != NULL; imp = imp->delegate)
|
||||
tx1 = ty1 = INT64_MAX;
|
||||
tx2 = ty2 = INT64_MIN;
|
||||
|
||||
for (i = 0; i < 4; ++i)
|
||||
{
|
||||
const pixman_fast_path_t *info = imp->fast_paths;
|
||||
pixman_fixed_48_16_t tx, ty;
|
||||
pixman_vector_t v;
|
||||
|
||||
while (info->op != PIXMAN_OP_NONE)
|
||||
{
|
||||
if ((info->op == op || info->op == PIXMAN_OP_any) &&
|
||||
/* Formats */
|
||||
((info->src_format == src_format) ||
|
||||
(info->src_format == PIXMAN_any)) &&
|
||||
((info->mask_format == mask_format) ||
|
||||
(info->mask_format == PIXMAN_any)) &&
|
||||
((info->dest_format == dest_format) ||
|
||||
(info->dest_format == PIXMAN_any)) &&
|
||||
/* Flags */
|
||||
(info->src_flags & src_flags) == info->src_flags &&
|
||||
(info->mask_flags & mask_flags) == info->mask_flags &&
|
||||
(info->dest_flags & dest_flags) == info->dest_flags)
|
||||
{
|
||||
*out_imp = imp;
|
||||
*out_func = info->func;
|
||||
v.vector[0] = (i & 0x01)? x1 : x2;
|
||||
v.vector[1] = (i & 0x02)? y1 : y2;
|
||||
v.vector[2] = pixman_fixed_1;
|
||||
|
||||
/* Set i to the last spot in the cache so that the
|
||||
* move-to-front code below will work
|
||||
*/
|
||||
i = N_CACHED_FAST_PATHS - 1;
|
||||
if (!pixman_transform_point (transform, &v))
|
||||
return FALSE;
|
||||
|
||||
goto update_cache;
|
||||
}
|
||||
tx = (pixman_fixed_48_16_t)v.vector[0];
|
||||
ty = (pixman_fixed_48_16_t)v.vector[1];
|
||||
|
||||
++info;
|
||||
}
|
||||
if (tx < tx1)
|
||||
tx1 = tx;
|
||||
if (ty < ty1)
|
||||
ty1 = ty;
|
||||
if (tx > tx2)
|
||||
tx2 = tx;
|
||||
if (ty > ty2)
|
||||
ty2 = ty;
|
||||
}
|
||||
return FALSE;
|
||||
|
||||
update_cache:
|
||||
if (i)
|
||||
{
|
||||
while (i--)
|
||||
cache->cache[i + 1] = cache->cache[i];
|
||||
|
||||
cache->cache[0].imp = *out_imp;
|
||||
cache->cache[0].fast_path.op = op;
|
||||
cache->cache[0].fast_path.src_format = src_format;
|
||||
cache->cache[0].fast_path.src_flags = src_flags;
|
||||
cache->cache[0].fast_path.mask_format = mask_format;
|
||||
cache->cache[0].fast_path.mask_flags = mask_flags;
|
||||
cache->cache[0].fast_path.dest_format = dest_format;
|
||||
cache->cache[0].fast_path.dest_flags = dest_flags;
|
||||
cache->cache[0].fast_path.func = *out_func;
|
||||
}
|
||||
transformed->x1 = tx1;
|
||||
transformed->y1 = ty1;
|
||||
transformed->x2 = tx2;
|
||||
transformed->y2 = ty2;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static pixman_bool_t
|
||||
compute_sample_extents (pixman_transform_t *transform,
|
||||
pixman_box32_t *extents, int x, int y,
|
||||
pixman_fixed_t x_off, pixman_fixed_t y_off,
|
||||
pixman_fixed_t width, pixman_fixed_t height)
|
||||
{
|
||||
pixman_fixed_t x1, y1, x2, y2;
|
||||
pixman_fixed_48_16_t tx1, ty1, tx2, ty2;
|
||||
|
||||
/* We have checked earlier that (extents->x1 - x) etc. fit in a pixman_fixed_t */
|
||||
x1 = (pixman_fixed_48_16_t)pixman_int_to_fixed (extents->x1 - x) + pixman_fixed_1 / 2;
|
||||
y1 = (pixman_fixed_48_16_t)pixman_int_to_fixed (extents->y1 - y) + pixman_fixed_1 / 2;
|
||||
x2 = (pixman_fixed_48_16_t)pixman_int_to_fixed (extents->x2 - x) - pixman_fixed_1 / 2;
|
||||
y2 = (pixman_fixed_48_16_t)pixman_int_to_fixed (extents->y2 - y) - pixman_fixed_1 / 2;
|
||||
|
||||
if (!transform)
|
||||
{
|
||||
tx1 = (pixman_fixed_48_16_t)x1;
|
||||
ty1 = (pixman_fixed_48_16_t)y1;
|
||||
tx2 = (pixman_fixed_48_16_t)x2;
|
||||
ty2 = (pixman_fixed_48_16_t)y2;
|
||||
}
|
||||
else
|
||||
{
|
||||
int i;
|
||||
|
||||
/* Silence GCC */
|
||||
tx1 = ty1 = tx2 = ty2 = 0;
|
||||
|
||||
for (i = 0; i < 4; ++i)
|
||||
{
|
||||
pixman_fixed_48_16_t tx, ty;
|
||||
pixman_vector_t v;
|
||||
|
||||
v.vector[0] = (i & 0x01)? x1 : x2;
|
||||
v.vector[1] = (i & 0x02)? y1 : y2;
|
||||
v.vector[2] = pixman_fixed_1;
|
||||
|
||||
if (!pixman_transform_point (transform, &v))
|
||||
return FALSE;
|
||||
|
||||
tx = (pixman_fixed_48_16_t)v.vector[0];
|
||||
ty = (pixman_fixed_48_16_t)v.vector[1];
|
||||
|
||||
if (i == 0)
|
||||
{
|
||||
tx1 = tx;
|
||||
ty1 = ty;
|
||||
tx2 = tx;
|
||||
ty2 = ty;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (tx < tx1)
|
||||
tx1 = tx;
|
||||
if (ty < ty1)
|
||||
ty1 = ty;
|
||||
if (tx > tx2)
|
||||
tx2 = tx;
|
||||
if (ty > ty2)
|
||||
ty2 = ty;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Expand the source area by a tiny bit so account of different rounding that
|
||||
* may happen during sampling. Note that (8 * pixman_fixed_e) is very far from
|
||||
* 0.5 so this won't cause the area computed to be overly pessimistic.
|
||||
*/
|
||||
tx1 += x_off - 8 * pixman_fixed_e;
|
||||
ty1 += y_off - 8 * pixman_fixed_e;
|
||||
tx2 += x_off + width + 8 * pixman_fixed_e;
|
||||
ty2 += y_off + height + 8 * pixman_fixed_e;
|
||||
|
||||
if (tx1 < pixman_min_fixed_48_16 || tx1 > pixman_max_fixed_48_16 ||
|
||||
ty1 < pixman_min_fixed_48_16 || ty1 > pixman_max_fixed_48_16 ||
|
||||
tx2 < pixman_min_fixed_48_16 || tx2 > pixman_max_fixed_48_16 ||
|
||||
ty2 < pixman_min_fixed_48_16 || ty2 > pixman_max_fixed_48_16)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
extents->x1 = pixman_fixed_to_int (tx1);
|
||||
extents->y1 = pixman_fixed_to_int (ty1);
|
||||
extents->x2 = pixman_fixed_to_int (tx2) + 1;
|
||||
extents->y2 = pixman_fixed_to_int (ty2) + 1;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
#define IS_16BIT(x) (((x) >= INT16_MIN) && ((x) <= INT16_MAX))
|
||||
#define ABS(f) (((f) < 0)? (-(f)) : (f))
|
||||
#define IS_16_16(f) (((f) >= pixman_min_fixed_48_16 && ((f) <= pixman_max_fixed_48_16)))
|
||||
|
||||
static pixman_bool_t
|
||||
analyze_extent (pixman_image_t *image, int x, int y,
|
||||
const pixman_box32_t *extents, uint32_t *flags)
|
||||
analyze_extent (pixman_image_t *image,
|
||||
const pixman_box32_t *extents,
|
||||
uint32_t *flags)
|
||||
{
|
||||
pixman_transform_t *transform;
|
||||
pixman_fixed_t *params;
|
||||
pixman_fixed_t x_off, y_off;
|
||||
pixman_fixed_t width, height;
|
||||
pixman_box32_t ex;
|
||||
pixman_fixed_t *params;
|
||||
box_48_16_t transformed;
|
||||
pixman_box32_t exp_extents;
|
||||
|
||||
if (!image)
|
||||
return TRUE;
|
||||
@ -678,10 +427,10 @@ analyze_extent (pixman_image_t *image, int x, int y,
|
||||
* check here that the expanded-by-one source
|
||||
* extents in destination space fits in 16 bits
|
||||
*/
|
||||
if (!IS_16BIT (extents->x1 - x - 1) ||
|
||||
!IS_16BIT (extents->y1 - y - 1) ||
|
||||
!IS_16BIT (extents->x2 - x + 1) ||
|
||||
!IS_16BIT (extents->y2 - y + 1))
|
||||
if (!IS_16BIT (extents->x1 - 1) ||
|
||||
!IS_16BIT (extents->y1 - 1) ||
|
||||
!IS_16BIT (extents->x2 + 1) ||
|
||||
!IS_16BIT (extents->y2 + 1))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
@ -696,18 +445,16 @@ analyze_extent (pixman_image_t *image, int x, int y,
|
||||
if (image->bits.width >= 0x7fff || image->bits.height >= 0x7fff)
|
||||
return FALSE;
|
||||
|
||||
#define ID_AND_NEAREST (FAST_PATH_ID_TRANSFORM | FAST_PATH_NEAREST_FILTER)
|
||||
|
||||
if ((image->common.flags & ID_AND_NEAREST) == ID_AND_NEAREST &&
|
||||
extents->x1 - x >= 0 &&
|
||||
extents->y1 - y >= 0 &&
|
||||
extents->x2 - x <= image->bits.width &&
|
||||
extents->y2 - y <= image->bits.height)
|
||||
if ((image->common.flags & FAST_PATH_ID_TRANSFORM) == FAST_PATH_ID_TRANSFORM &&
|
||||
extents->x1 >= 0 &&
|
||||
extents->y1 >= 0 &&
|
||||
extents->x2 <= image->bits.width &&
|
||||
extents->y2 <= image->bits.height)
|
||||
{
|
||||
*flags |= FAST_PATH_SAMPLES_COVER_CLIP;
|
||||
*flags |= FAST_PATH_SAMPLES_COVER_CLIP_NEAREST;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
switch (image->common.filter)
|
||||
{
|
||||
case PIXMAN_FILTER_CONVOLUTION:
|
||||
@ -738,17 +485,6 @@ analyze_extent (pixman_image_t *image, int x, int y,
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Check whether the non-expanded, transformed extent is entirely within
|
||||
* the source image, and set the FAST_PATH_SAMPLES_COVER_CLIP if it is.
|
||||
*/
|
||||
ex = *extents;
|
||||
if (compute_sample_extents (transform, &ex, x, y, x_off, y_off, width, height) &&
|
||||
ex.x1 >= 0 && ex.y1 >= 0 &&
|
||||
ex.x2 <= image->bits.width && ex.y2 <= image->bits.height)
|
||||
{
|
||||
*flags |= FAST_PATH_SAMPLES_COVER_CLIP;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -758,18 +494,58 @@ analyze_extent (pixman_image_t *image, int x, int y,
|
||||
height = 0;
|
||||
}
|
||||
|
||||
/* Check that the extents expanded by one don't overflow. This ensures that
|
||||
* compositing functions can simply walk the source space using 16.16
|
||||
* variables without worrying about overflow.
|
||||
*/
|
||||
ex.x1 = extents->x1 - 1;
|
||||
ex.y1 = extents->y1 - 1;
|
||||
ex.x2 = extents->x2 + 1;
|
||||
ex.y2 = extents->y2 + 1;
|
||||
|
||||
if (!compute_sample_extents (transform, &ex, x, y, x_off, y_off, width, height))
|
||||
if (!compute_transformed_extents (transform, extents, &transformed))
|
||||
return FALSE;
|
||||
|
||||
/* Expand the source area by a tiny bit so account of different rounding that
|
||||
* may happen during sampling. Note that (8 * pixman_fixed_e) is very far from
|
||||
* 0.5 so this won't cause the area computed to be overly pessimistic.
|
||||
*/
|
||||
transformed.x1 -= 8 * pixman_fixed_e;
|
||||
transformed.y1 -= 8 * pixman_fixed_e;
|
||||
transformed.x2 += 8 * pixman_fixed_e;
|
||||
transformed.y2 += 8 * pixman_fixed_e;
|
||||
|
||||
if (image->common.type == BITS)
|
||||
{
|
||||
if (pixman_fixed_to_int (transformed.x1) >= 0 &&
|
||||
pixman_fixed_to_int (transformed.y1) >= 0 &&
|
||||
pixman_fixed_to_int (transformed.x2) < image->bits.width &&
|
||||
pixman_fixed_to_int (transformed.y2) < image->bits.height)
|
||||
{
|
||||
*flags |= FAST_PATH_SAMPLES_COVER_CLIP_NEAREST;
|
||||
}
|
||||
|
||||
if (pixman_fixed_to_int (transformed.x1 - pixman_fixed_1 / 2) >= 0 &&
|
||||
pixman_fixed_to_int (transformed.y1 - pixman_fixed_1 / 2) >= 0 &&
|
||||
pixman_fixed_to_int (transformed.x2 + pixman_fixed_1 / 2) < image->bits.width &&
|
||||
pixman_fixed_to_int (transformed.y2 + pixman_fixed_1 / 2) < image->bits.height)
|
||||
{
|
||||
*flags |= FAST_PATH_SAMPLES_COVER_CLIP_BILINEAR;
|
||||
}
|
||||
}
|
||||
|
||||
/* Check we don't overflow when the destination extents are expanded by one.
|
||||
* This ensures that compositing functions can simply walk the source space
|
||||
* using 16.16 variables without worrying about overflow.
|
||||
*/
|
||||
exp_extents = *extents;
|
||||
exp_extents.x1 -= 1;
|
||||
exp_extents.y1 -= 1;
|
||||
exp_extents.x2 += 1;
|
||||
exp_extents.y2 += 1;
|
||||
|
||||
if (!compute_transformed_extents (transform, &exp_extents, &transformed))
|
||||
return FALSE;
|
||||
|
||||
if (!IS_16_16 (transformed.x1 + x_off - 8 * pixman_fixed_e) ||
|
||||
!IS_16_16 (transformed.y1 + y_off - 8 * pixman_fixed_e) ||
|
||||
!IS_16_16 (transformed.x2 + x_off + 8 * pixman_fixed_e + width) ||
|
||||
!IS_16_16 (transformed.y2 + y_off + 8 * pixman_fixed_e + height))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@ -809,7 +585,7 @@ pixman_image_composite32 (pixman_op_t op,
|
||||
pixman_format_code_t src_format, mask_format, dest_format;
|
||||
uint32_t src_flags, mask_flags, dest_flags;
|
||||
pixman_region32_t region;
|
||||
pixman_box32_t *extents;
|
||||
pixman_box32_t extents;
|
||||
pixman_implementation_t *imp;
|
||||
pixman_composite_func_t func;
|
||||
|
||||
@ -856,48 +632,87 @@ pixman_image_composite32 (pixman_op_t op,
|
||||
goto out;
|
||||
}
|
||||
|
||||
extents = pixman_region32_extents (®ion);
|
||||
extents = *pixman_region32_extents (®ion);
|
||||
|
||||
if (!analyze_extent (src, dest_x - src_x, dest_y - src_y, extents, &src_flags))
|
||||
extents.x1 -= dest_x - src_x;
|
||||
extents.y1 -= dest_y - src_y;
|
||||
extents.x2 -= dest_x - src_x;
|
||||
extents.y2 -= dest_y - src_y;
|
||||
|
||||
if (!analyze_extent (src, &extents, &src_flags))
|
||||
goto out;
|
||||
|
||||
if (!analyze_extent (mask, dest_x - mask_x, dest_y - mask_y, extents, &mask_flags))
|
||||
extents.x1 -= src_x - mask_x;
|
||||
extents.y1 -= src_y - mask_y;
|
||||
extents.x2 -= src_x - mask_x;
|
||||
extents.y2 -= src_y - mask_y;
|
||||
|
||||
if (!analyze_extent (mask, &extents, &mask_flags))
|
||||
goto out;
|
||||
|
||||
/* If the clip is within the source samples, and the samples are opaque,
|
||||
* then the source is effectively opaque.
|
||||
/* If the clip is within the source samples, and the samples are
|
||||
* opaque, then the source is effectively opaque.
|
||||
*/
|
||||
#define BOTH (FAST_PATH_SAMPLES_OPAQUE | FAST_PATH_SAMPLES_COVER_CLIP)
|
||||
#define NEAREST_OPAQUE (FAST_PATH_SAMPLES_OPAQUE | \
|
||||
FAST_PATH_NEAREST_FILTER | \
|
||||
FAST_PATH_SAMPLES_COVER_CLIP_NEAREST)
|
||||
#define BILINEAR_OPAQUE (FAST_PATH_SAMPLES_OPAQUE | \
|
||||
FAST_PATH_BILINEAR_FILTER | \
|
||||
FAST_PATH_SAMPLES_COVER_CLIP_BILINEAR)
|
||||
|
||||
if ((src_flags & BOTH) == BOTH)
|
||||
if ((src_flags & NEAREST_OPAQUE) == NEAREST_OPAQUE ||
|
||||
(src_flags & BILINEAR_OPAQUE) == BILINEAR_OPAQUE)
|
||||
{
|
||||
src_flags |= FAST_PATH_IS_OPAQUE;
|
||||
|
||||
if ((mask_flags & BOTH) == BOTH)
|
||||
}
|
||||
|
||||
if ((mask_flags & NEAREST_OPAQUE) == NEAREST_OPAQUE ||
|
||||
(mask_flags & BILINEAR_OPAQUE) == BILINEAR_OPAQUE)
|
||||
{
|
||||
mask_flags |= FAST_PATH_IS_OPAQUE;
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Check if we can replace our operator by a simpler one
|
||||
* if the src or dest are opaque. The output operator should be
|
||||
* mathematically equivalent to the source.
|
||||
*/
|
||||
op = optimize_operator (op, src_flags, mask_flags, dest_flags);
|
||||
if (op == PIXMAN_OP_DST)
|
||||
goto out;
|
||||
|
||||
if (lookup_composite_function (op,
|
||||
src_format, src_flags,
|
||||
mask_format, mask_flags,
|
||||
dest_format, dest_flags,
|
||||
&imp, &func))
|
||||
if (_pixman_lookup_composite_function (
|
||||
get_implementation (), op,
|
||||
src_format, src_flags, mask_format, mask_flags, dest_format, dest_flags,
|
||||
&imp, &func))
|
||||
{
|
||||
walk_region_internal (imp, op,
|
||||
src, mask, dest,
|
||||
src_x, src_y, mask_x, mask_y,
|
||||
dest_x, dest_y,
|
||||
width, height,
|
||||
(src_flags & FAST_PATH_SIMPLE_REPEAT),
|
||||
(mask_flags & FAST_PATH_SIMPLE_REPEAT),
|
||||
®ion, func);
|
||||
pixman_composite_info_t info;
|
||||
const pixman_box32_t *pbox;
|
||||
int n;
|
||||
|
||||
info.op = op;
|
||||
info.src_image = src;
|
||||
info.mask_image = mask;
|
||||
info.dest_image = dest;
|
||||
info.src_flags = src_flags;
|
||||
info.mask_flags = mask_flags;
|
||||
info.dest_flags = dest_flags;
|
||||
|
||||
pbox = pixman_region32_rectangles (®ion, &n);
|
||||
|
||||
while (n--)
|
||||
{
|
||||
info.src_x = pbox->x1 + src_x - dest_x;
|
||||
info.src_y = pbox->y1 + src_y - dest_y;
|
||||
info.mask_x = pbox->x1 + mask_x - dest_x;
|
||||
info.mask_y = pbox->y1 + mask_y - dest_y;
|
||||
info.dest_x = pbox->x1;
|
||||
info.dest_y = pbox->y1;
|
||||
info.width = pbox->x2 - pbox->x1;
|
||||
info.height = pbox->y2 - pbox->y1;
|
||||
|
||||
func (imp, &info);
|
||||
|
||||
pbox++;
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
@ -931,8 +746,8 @@ pixman_blt (uint32_t *src_bits,
|
||||
int dst_bpp,
|
||||
int src_x,
|
||||
int src_y,
|
||||
int dst_x,
|
||||
int dst_y,
|
||||
int dest_x,
|
||||
int dest_y,
|
||||
int width,
|
||||
int height)
|
||||
{
|
||||
@ -940,7 +755,7 @@ pixman_blt (uint32_t *src_bits,
|
||||
src_bits, dst_bits, src_stride, dst_stride,
|
||||
src_bpp, dst_bpp,
|
||||
src_x, src_y,
|
||||
dst_x, dst_y,
|
||||
dest_x, dest_y,
|
||||
width, height);
|
||||
}
|
||||
|
||||
@ -1294,7 +1109,7 @@ PIXMAN_EXPORT pixman_bool_t
|
||||
pixman_compute_composite_region (pixman_region16_t * region,
|
||||
pixman_image_t * src_image,
|
||||
pixman_image_t * mask_image,
|
||||
pixman_image_t * dst_image,
|
||||
pixman_image_t * dest_image,
|
||||
int16_t src_x,
|
||||
int16_t src_y,
|
||||
int16_t mask_x,
|
||||
@ -1310,7 +1125,7 @@ pixman_compute_composite_region (pixman_region16_t * region,
|
||||
pixman_region32_init (&r32);
|
||||
|
||||
retval = pixman_compute_composite_region32 (
|
||||
&r32, src_image, mask_image, dst_image,
|
||||
&r32, src_image, mask_image, dest_image,
|
||||
src_x, src_y, mask_x, mask_y, dest_x, dest_y,
|
||||
width, height);
|
||||
|
||||
|
@ -468,6 +468,7 @@ pixman_bool_t pixman_region_equal (pixman_region16_t *reg
|
||||
pixman_bool_t pixman_region_selfcheck (pixman_region16_t *region);
|
||||
void pixman_region_reset (pixman_region16_t *region,
|
||||
pixman_box16_t *box);
|
||||
void pixman_region_clear (pixman_region16_t *region);
|
||||
/*
|
||||
* 32 bit regions
|
||||
*/
|
||||
@ -562,6 +563,7 @@ pixman_bool_t pixman_region32_equal (pixman_region32_t *r
|
||||
pixman_bool_t pixman_region32_selfcheck (pixman_region32_t *region);
|
||||
void pixman_region32_reset (pixman_region32_t *region,
|
||||
pixman_box32_t *box);
|
||||
void pixman_region32_clear (pixman_region32_t *region);
|
||||
|
||||
|
||||
/* Copy / Fill / Misc */
|
||||
@ -573,8 +575,8 @@ pixman_bool_t pixman_blt (uint32_t *src_bits,
|
||||
int dst_bpp,
|
||||
int src_x,
|
||||
int src_y,
|
||||
int dst_x,
|
||||
int dst_y,
|
||||
int dest_x,
|
||||
int dest_y,
|
||||
int width,
|
||||
int height);
|
||||
pixman_bool_t pixman_fill (uint32_t *bits,
|
||||
@ -813,7 +815,7 @@ pixman_bool_t pixman_image_fill_boxes (pixman_op_t
|
||||
pixman_bool_t pixman_compute_composite_region (pixman_region16_t *region,
|
||||
pixman_image_t *src_image,
|
||||
pixman_image_t *mask_image,
|
||||
pixman_image_t *dst_image,
|
||||
pixman_image_t *dest_image,
|
||||
int16_t src_x,
|
||||
int16_t src_y,
|
||||
int16_t mask_x,
|
||||
|
18
gfx/cairo/pixman-limits.patch
Normal file
18
gfx/cairo/pixman-limits.patch
Normal file
@ -0,0 +1,18 @@
|
||||
commit 3c275c75e381184fb3fa0537c4bfce50b44690e7
|
||||
Author: Jeff Muizelaar <jmuizelaar@mozilla.com>
|
||||
Date: Fri Apr 20 00:12:32 2012 -0400
|
||||
|
||||
limits
|
||||
|
||||
diff --git a/pixman/pixman-utils.c b/pixman/pixman-utils.c
|
||||
index 2ec2594..de05c0e 100644
|
||||
--- a/pixman/pixman-utils.c
|
||||
+++ b/pixman/pixman-utils.c
|
||||
@@ -27,6 +27,7 @@
|
||||
#endif
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
+#include <limits.h>
|
||||
|
||||
#include "pixman-private.h"
|
||||
|
Loading…
Reference in New Issue
Block a user