summaryrefslogtreecommitdiff log msg author committer range
diff options
 context: 12345678910152025303540 space: includeignore mode: unifiedssdiffstat only
author committer Søren Sandmann 2013-11-23 19:38:50 -0500 Søren Sandmann 2014-01-04 16:13:27 -0500 15aa37adeca79a22b393ff451e6d29f484c3b0ef (patch) 748bc2d67e1ef7b3ac11b5085ced82601e86c1a8 8f3824316300e257a3698daa13db802e32489236 (diff)
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.
-rw-r--r--pixman/pixman-general.c21
-rw-r--r--test/blitters-test.c20