Commit Graph

60 Commits

Author SHA1 Message Date
Søren Sandmann
15aa37adec Use floating point combiners for all operators that involve divisions
Consider a DISJOINT_ATOP operation with the following pixels:

- source:	0xff (8 bits)
- source alpha:	0x01 (8 bits)
- mask alpha:	0x7b (8 bits)
- dest:		0x00 (8 bits)
- dest alpha:	0xff (8 bits)

When (src IN mask) is computed in 8 bits, the resulting alpha channel
is 0 due to rounding:

     floor ((0x01 * 0x7b) / 255.0 + 0.5) = floor (0.9823) = 0

which means that since Render defines any division by zero as
infinity, the Fa and Fb for this operator end up as follows:

     Fa = max (1 - (1 - 1) / 0, 0) = 0

     Fb = min (1, (1 - 0) / 1) = 1

and so since dest is 0x00, the overall result is 0.

However, when computed in full precision, the alpha value no longer
rounds to 0, and so Fa ends up being

     Fa = max (1 - (1 - 1) / 0.0001, 0) = 1

and so the result is now

     s * ma * Fa + d * Fb

   = (1.0 * (0x7b / 255.0) * 1) + d * 0

   = 0x7b / 255.0

   = 0.4823

so the error in this case ends up being 0.48235294, which is clearly
not something that can be considered acceptable.

In order to avoid this problem, we need to do all arithmetic in such a
way that a multiplication of two tiny numbers can never end up being
zero unless one of the input numbers is itself zero.

This patch makes all computations that involve divisions take place in
floating point, which is sufficient to fix the test cases

This brings the number of failures in pixel-test down to 14.
2014-01-04 16:13:27 -05:00
Søren Sandmann Pedersen
89662adf77 pixman-combine32.c: Fix bugs related to integer promotion
In the component alpha part of the PDF_SEPARABLE_BLEND_MODE macro, the
expression ~RED_8 (m) is used. Because RED_8(m) gets promoted to int
before ~ is applied, the whole expression typically becomes some
negative value rather than (255 - RED_8(m)) as desired.

Fix this by using unsigned temporary variables.

This reduces the number of failures in pixel-test to 363.
2014-01-04 16:13:27 -05:00
Søren Sandmann Pedersen
e7a99b3b0f pixman/pixman-combine32.c: Bug fixes for separable blend modes
This commit fixes four separate bugs:

1. In the computation

      (1 - sa) * d + (1 - da) * s + sa * da * B(s, d)

   we were using regular addition for all four channels, but for
   superluminescent pixels, the addition could overflow causing
   nonsensical results.

2. The variables and return types used for the results of the blend
   mode calculations were unsigned, but for various blend modes (and
   especially with superluminescent pixels), the blend mode
   calculations could be negative, resulting in underflows.

3. The blend mode computations were returned as 8-bit values, which is
   not sufficient precision (especially considering that we need
   signed results).

4. The value before the final division by 255 was not properly clamped
   to [0, 255].

This patch fixes all those bugs. The blend mode computations are now
returned as signed 16 bit values with 1 represented as 255 * 255.

With these fixes, the number of failing pixels in pixel-test goes down
from 431 to 384.
2014-01-04 16:13:27 -05:00
Søren Sandmann
9ba3a34797 general: Support component alpha for all image types
Currently, if you attempt to use component alpha on source images or
images without RGB channels, Pixman will silently just use unified
alpha instead. This patch makes such images supported for component
alpha.

There is no particularly compelling usecase at the moment, but this
patch does get rid of a bit of special-case code both in
pixman-general.c and in test/composite.c.
2013-11-23 20:30:33 -05:00
Søren Sandmann Pedersen
9367243801 pixman-combine32.c: Make Color Burn routine follow the math more closely
For superluminescent destinations, the old code could underflow in

    uint32_t r = (ad - d) * as / s;

when (ad - d) was negative. The new code avoids this problem (and
therefore causes changes in the checksums of thread-test and
blitters-test), but it is likely still buggy due to the use of
unsigned variables and other issues in the blend mode code.
2013-10-12 15:04:27 -04:00
Søren Sandmann Pedersen
105fa74fad pixman-combine32: Make Color Dodge routine follow the math more closely
Change blend_color_dodge() to follow the math in the comment more
closely.

Note, the new code here is in some sense worse than the old code
because it can now underflow the unsigned variables when the source is
superluminescent and (as - s) is therefore negative. The old code was
careful to clamp to 0.

But for superluminescent variables we really need the ability for the
blend function to become negative, and so the solution the underflow
problem is to just use signed variables. The use of unsigned variables
is a general problem in all of the blend mode code that will have to
be solved later.

The CRC32 values in thread-test and blitters-test are updated to
account for the changes in output.
2013-10-12 15:04:27 -04:00
Søren Sandmann Pedersen
b513b3dffe blitters-test: Remove unused variable 2013-09-29 16:47:53 -04:00
Søren Sandmann Pedersen
aa5c45254e test: Test negative strides
Pixman supports negative strides, but up until now they haven't been
tested outside of stress-test. This commit adds testing of negative
strides to blitters-test, scaling-test, affine-test, rotate-test, and
composite-traps-test.
2013-09-19 21:37:56 -04:00
Søren Sandmann Pedersen
4312f07736 test: Share the image printing code
The affine-test, blitters-test, and scaling-test all have the ability
to print out the bytes of the destination image. Share this code by
moving it to utils.c.

At the same time make the code work correctly with negative strides.
2013-09-19 21:37:56 -04:00
Siarhei Siamashka
59109f3293 test: larger 0xFF/0x00 filled clusters in random images for blitters-test
Current blitters-test program had difficulties detecting a bug in
over_n_8888_8888_ca implementation for MIPS DSPr2:

    http://lists.freedesktop.org/archives/pixman/2013-March/002645.html

In order to hit the buggy code path, two consecutive mask values had
to be equal to 0xFFFFFFFF because of loop unrolling. The current
blitters-test generates random images in such a way that each byte
has 25% probability for having 0xFF value. Hence each 32-bit mask
value has ~0.4% probability for 0xFFFFFFFF. Because we are testing
many compositing operations with many pixels, encountering at least
one 0xFFFFFFFF mask value reasonably fast is not a problem. If a
bug related to 0xFFFFFFFF mask value is artificialy introduced into
over_n_8888_8888_ca generic C function, it gets detected on 675591
iteration in blitters-test (out of 2000000).

However two consecutive 0xFFFFFFFF mask values are much less likely
to be generated, so the bug was missed by blitters-test.

This patch addresses the problem by also randomly setting the 32-bit
values in images to either 0xFFFFFFFF or 0x00000000 (also with 25%
probability). It allows to have larger clusters of consecutive 0x00
or 0xFF bytes in images which may have special shortcuts for handling
them in unrolled or SIMD optimized code.
2013-04-28 22:14:47 +03:00
Søren Sandmann Pedersen
4eb9a24aba utils.[ch]: Add new format_name() function
This function returns the name of the given format code, which is
useful for printing out debug information. The function is written as
a switch without a default value so that the compiler will warn if new
formats are added in the future. The fake formats used in the fast
path tables are also recognized.

The function is used in alpha_map.c, where it replaces an existing
format_name() function, and in blitters-test.c, affine-test.c, and
scaling-test.c.
2013-01-23 12:24:31 -05:00
Søren Sandmann Pedersen
1676b49389 test/utils.[ch]: Add new function operator_name()
This function returns the name of the given operator, which is useful
for printing out debug information. The function is done as a switch
without a default value so that the compiler will warn if new
operators are added in the future.

The function is used in affine-test.c, scaling-test.c, and
blitters-test.c.
2013-01-23 12:24:31 -05:00
Siarhei Siamashka
b31a696263 test: Switch to the new PRNG instead of old LCG
Wallclock time for running pixman "make check" (compile time not included):

----------------------------+----------------+-----------------------------+
                            | old PRNG (LCG) |   new PRNG (Bob Jenkins)    |
       Processor type       +----------------+------------+----------------+
                            |    gcc 4.5     |  gcc 4.5   | gcc 4.7 (simd) |
----------------------------+----------------+------------+----------------+
quad Intel Core i7  @2.8GHz |    0m49.494s   |  0m43.722s |    0m37.560s   |
dual ARM Cortex-A15 @1.7GHz |     5m8.465s   |  4m37.375s |    3m45.819s   |
     IBM Cell PPU   @3.2GHz |    23m0.821s   | 20m38.316s |   16m37.513s   |
----------------------------+----------------+------------+----------------+

But some tests got a particularly large boost. For example benchmarking and
profiling blitters-test on Core i7:

=== before ===

$ time ./blitters-test

real    0m10.907s
user    0m55.650s
sys     0m0.000s

  70.45%  blitters-test  blitters-test       [.] create_random_image
  15.81%  blitters-test  blitters-test       [.] compute_crc32_for_image_internal
   2.26%  blitters-test  blitters-test       [.] _pixman_implementation_lookup_composite
   1.07%  blitters-test  libc-2.15.so        [.] _int_free
   0.89%  blitters-test  libc-2.15.so        [.] malloc_consolidate
   0.87%  blitters-test  libc-2.15.so        [.] _int_malloc
   0.75%  blitters-test  blitters-test       [.] combine_conjoint_general_u
   0.61%  blitters-test  blitters-test       [.] combine_disjoint_general_u
   0.40%  blitters-test  blitters-test       [.] test_composite
   0.31%  blitters-test  libc-2.15.so        [.] _int_memalign
   0.31%  blitters-test  blitters-test       [.] _pixman_bits_image_setup_accessors
   0.28%  blitters-test  libc-2.15.so        [.] malloc

=== after ===

$ time ./blitters-test

real    0m3.655s
user    0m20.550s
sys     0m0.000s

  41.77%  blitters-test.n  blitters-test.new  [.] compute_crc32_for_image_internal
  15.77%  blitters-test.n  blitters-test.new  [.] prng_randmemset_r
   6.15%  blitters-test.n  blitters-test.new  [.] _pixman_implementation_lookup_composite
   3.09%  blitters-test.n  libc-2.15.so       [.] _int_free
   2.68%  blitters-test.n  libc-2.15.so       [.] malloc_consolidate
   2.39%  blitters-test.n  libc-2.15.so       [.] _int_malloc
   2.27%  blitters-test.n  blitters-test.new  [.] create_random_image
   2.22%  blitters-test.n  blitters-test.new  [.] combine_conjoint_general_u
   1.52%  blitters-test.n  blitters-test.new  [.] combine_disjoint_general_u
   1.40%  blitters-test.n  blitters-test.new  [.] test_composite
   1.02%  blitters-test.n  blitters-test.new  [.] prng_srand_r
   1.00%  blitters-test.n  blitters-test.new  [.] _pixman_image_validate
   0.96%  blitters-test.n  blitters-test.new  [.] _pixman_bits_image_setup_accessors
   0.90%  blitters-test.n  libc-2.15.so       [.] malloc
2012-12-06 17:20:35 +02:00
Siarhei Siamashka
309e66f047 test: Search/replace 'lcg_*' -> 'prng_*'
The 'lcg' prefix is going to be misleading if we replace
PRNG algorithm.
2012-12-06 17:20:31 +02:00
Søren Sandmann Pedersen
7a9c2d586b blitters-test: Prepare for floating point
Comment out some formats in blitters-test that are going to rely on
floating point in some upcoming patches.
2012-10-01 12:56:09 -04:00
Søren Sandmann Pedersen
2ab77c97a5 Fix bugs in component alpha combiners for separable PDF operators
In general, the component alpha version of an operator is supposed to
do this:

       - multiply source with mask in all channels
       - multiply mask with source alpha in all channels
       - compute the regular operator in all channels using the
         mask value whenever source alpha is called for

The first two steps are usually accomplished with the function
combine_mask_ca(), but for operators where source alpha is not used,
such as SRC, ADD and OUT, the simpler function
combine_mask_value_ca(), which doesn't compute the new mask values,
can be used.

However, the PDF blend modes generally *do* make use of source alpha,
so they can't use combine_mask_value_ca() as they do now. They have to
use combine_mask_ca().

This patch fixes this in combine_multiply_ca() and the CA combiners
generated by PDF_SEPARABLE_BLEND_MODE.
2012-09-22 23:41:19 -04:00
Søren Sandmann Pedersen
43e029d525 Move CRC32 computation from blitters-test.c into utils.c
This way it can be used in other tests.
2012-06-02 07:55:11 -04:00
Søren Sandmann Pedersen
3757245586 Fix rounding for DIV_UNc()
We need to compute floor (a/b * 255 + 0.5), not floor (a / b * 255),
so add b/2 to the numerator in the DIV_UNc() macro.
2012-01-09 05:40:34 -05:00
Søren Sandmann Pedersen
33ac0a9084 Fix a bunch of signed overflow issues
In pixman-fast-path.c: (1 << 31) - 1 causes a signed overflow, so
change to (1U << n) - 1.

In pixman-image.c: The check for whether m10 == -m01 will overflow
when -m01 == INT_MIN. Instead just check whether the variables are 1
and -1.

In pixman-utils.c: When the depth of the topmost channel is 0, we can
end up shifting by 32.

In blitters-test.c: Replicating the mask would end up shifting more
than 32.

In region-contains-test.c: Computing the average of two large integers
could overflow. Instead add half the difference between them to the
first integer.

In stress-test.c: Masking the value in fake_reader() would sometimes
shift by 32. Instead just use the most significant bits instead of
the least significant.

All these issues were found by the IOC tool:

    http://embed.cs.utah.edu/ioc/
2012-01-09 05:40:33 -05:00
Søren Sandmann Pedersen
4f3fe9c909 Fix some signed overflow bugs
In the macros for the PDF blend modes, two comp1_t variables are
multiplied together and then used as if the result were a
comp4_t. When comp1_t is a uint8_t, this is fine because they are
promoted to int, and the product of two uint8_ts fits in an
int. However, when comp1_t is uint16, the product does not necessarily
fit in an int, so casts are necessary.

Fix for bug 43906, reported by Siarhei Siamashka.
2012-01-09 05:40:33 -05:00
Andrea Canciani
97b9fa090c Use the ARRAY_LENGTH() macro when possible
This patch has been generated by the following Coccinelle semantic patch:

// Use the ARRAY_LENGTH() macro when possible
//
// Replace open-coded array length computations with the
// ARRAY_LENGTH() macro

@@
type T;
T[] E;
@@
- (sizeof(E)/sizeof(T))
+ ARRAY_LENGTH (E)
2011-11-09 09:17:00 +01:00
Andrea Canciani
06760f5cb0 test: Cleanup includes
All the tests are linked to libutil, hence it makes sence to always
include utils.h and reuse what it provides (config.h inclusion, access
to private pixman APIs, ARRAY_LENGTH, ...).
2011-11-09 09:17:00 +01:00
Søren Sandmann Pedersen
eb2e7ed81b test: Occasionally use a BILINEAR filter in blitters-test
To test that reductions of BILINEAR->NEAREST for identity
transformations happen correctly, occasionally use a bilinear filter
in blitters test.
2011-09-21 18:55:25 -04:00
Andrea Canciani
479d094485 test: Do not include config.h unless HAVE_CONFIG_H is defined
The win32 build system does not generate config.h and correctly runs
the compiler without defining HAVE_CONFIG_H. Nevertheless some files
include config.h without checking for its availability, breaking the
build from a clean directory:

test\utils.h(2) : fatal error C1083: Cannot open include file:
'config.h': No such file or directory
...
2011-09-14 07:03:35 -07:00
Søren Sandmann Pedersen
5715a394c4 blitters-test: Make common formats more likely to be tested.
Move the eight most common formats to the top of the list of image
formats and make create_random_image() much more likely to select one
of those eight formats.

This should help catch more bugs in SIMD optimized operations.
2011-06-25 10:17:05 -04:00
Alexandros Frantzis
b514e63cfc Add support for the r8g8b8a8 and r8g8b8x8 formats to the tests. 2011-03-22 13:43:29 -04:00
Søren Sandmann Pedersen
84f3c5a71a test: In image_endian_swap() use pixman_image_get_format() to get the bpp.
There is no reason to pass in the bpp as an argument; it can be gotten
directly from the image.
2011-03-07 14:07:44 -05:00
Rolland Dudemaine
32e556df33 test: Use the right enum types instead of int to fix warnings
Green Hills Software MULTI compiler was producing a number
of warnings due to incorrect uses of int instead of the correct
corresponding pixman_*_t type.
2011-01-26 15:05:18 +02:00
Søren Sandmann Pedersen
337f0bff0d test: Move palette initialization to utils.[ch] 2010-12-17 16:57:53 -05:00
Søren Sandmann Pedersen
4e89a5b7f3 Remove broken optimizations in combine_disjoint_over_u()
The first broken optimization is that it checks "a != 0x00" where it
should check "s != 0x00". The other is that it skips the computation
when alpha is 0xff. That is wrong because in the formula:

     min (1, (1 - Aa)/Ab)

the render specification states that if Ab is 0, the quotient is
defined to positive infinity. That is the case even if (1 - Aa) is 0.
2010-10-11 12:06:20 -04:00
Dmitri Vorobiev
fd3c87d460 Move aligned_malloc() to utils
The aligned_malloc() routine will be used in more than one test utility.
At least, a low-level blitter benchmark needs it. Therefore, let's make
this function a part of common test utilities code.
2010-09-21 08:50:17 -04:00
Siarhei Siamashka
ba6c98fc4b test: detection of possible floating point registers corruption
Added a pair of macros which can help to detect corruption
of floating point registers after a function call. This may
happen if _mm_empty() call is forgotten in MMX/SSE2 fast
path code, or ARM NEON assembly optimized function
forgets to save/restore d8-d15 registers before use.
2010-09-13 18:12:31 +03:00
Søren Sandmann Pedersen
b243a66041 Add x14r6g6b6 format to blitters-test 2010-08-04 08:58:51 -04:00
Søren Sandmann Pedersen
2e7fb66553 When converting indexed formats to 64 bits, don't correct for channel widths
Indexed formats are mapped to a8r8g8b8 with full precision, so when
expanding we shouldn't correct for the width of the channels
2010-07-11 09:43:56 -04:00
Søren Sandmann Pedersen
2df6dac0be test: Make sure the palettes for indexed format roundtrip properly
The palettes for indexed formats must satisfy the condition that if
some index maps to a color C, then the 15 bit version of that color
must map back to the index. This ensures that the destination operator
is always a no-op, which seems like a reasonable assumption to make.
2010-07-11 09:43:56 -04:00
Søren Sandmann Pedersen
66365b5ef1 Make separate gray scanline storers.
For gray formats the palettes are indexed by luminance, not RGB, so we
can't use the color storers for gray too.
2010-06-18 20:33:02 -04:00
Søren Sandmann Pedersen
4e1d4847c9 When storing a g1 pixel, store the lowest bit, rather than comparing with 0. 2010-06-18 20:33:02 -04:00
Siarhei Siamashka
be387701a5 test: blitters-test updated to use new fuzzer_test_main() function 2010-05-13 21:04:31 +03:00
Søren Sandmann Pedersen
2d65fb033b Don't consider indexed formats opaque.
The indexed formats have 0 bits of alpha, but can't be considered
opaque because there may be non-opaque colors in the palette.
2010-05-03 10:59:36 +03:00
Søren Sandmann Pedersen
de27f45ddd Ensure that only the low 4 bit of 4 bit pixels are stored.
In some cases we end up trying to use the STORE_4 macro with an 8 bit
values, which resulted in other pixels getting overwritten. Fix this
by always masking off the low 4 bits.

This fixes blitters-test on big-endian machines.
2010-03-17 11:02:58 -04:00
Søren Sandmann Pedersen
ff30a5cbb9 test: Add support for indexed formats to blitters-test
These formats work fine, they just need to have a palette set.
2010-03-14 12:25:17 -04:00
Søren Sandmann Pedersen
9a8e404d44 test: Remove obsolete comment 2010-03-03 13:37:20 -05:00
Siarhei Siamashka
dce6e1bd68 test: support for testing pixbuf fast path functions in blitters-test 2009-11-27 15:50:26 +02:00
Søren Sandmann Pedersen
95a08dece3 Remove stray semicolon from blitters-test.c
Pointed out by scottmc2@gmail.com in bug 25137.
2009-11-20 11:18:58 +01:00
Søren Sandmann Pedersen
13f4e02b14 test: Move image_endian_swap() from blitters-test.c to utils.[ch] 2009-11-17 00:32:03 -05:00
Søren Sandmann Pedersen
24e203a8a8 test: Move random number generator from blitters/scaling-test to utils.[ch] 2009-11-17 00:32:03 -05:00
Søren Sandmann Pedersen
b465b8b79d test: Move CRC32 code from blitters-test to new files utils.[ch] 2009-11-17 00:32:03 -05:00
Siarhei Siamashka
5f429e4510 blitters-test updated to also randomly generate mask_x/mask_y 2009-10-27 12:31:55 +02:00
Benjamin Otte
5c3ef4e979 Fix compile warnings 2009-10-20 00:40:40 +02:00
Søren Sandmann Pedersen
358f96d202 Fix double semicolon; pointed out by Travis Griggs 2009-10-08 13:01:27 -04:00