Faster unorm_to_unorm for wide processing.
authorAntti S. Lankila <alankila@bel.fi>
Sun, 10 Jun 2012 16:22:56 +0000 (19:22 +0300)
committerSøren Sandmann Pedersen <ssp@redhat.com>
Sun, 10 Jun 2012 18:23:17 +0000 (14:23 -0400)
commitfd175f9d02f36b1e91973e4264519228547f5dc7
tree9f1b530f34836625d8841c39bdfcb74a4f4607bc
parent367b78fd5c57ee05298eb11370b68d01613961e5
Faster unorm_to_unorm for wide processing.

Optimizing the unorm_to_unorm functions allows a speedup from:

src_8888_2x10 =  L1:  62.08  L2:  60.73  M: 59.61 (  4.30%)  HT: 46.81
VT: 42.17  R: 43.18  RT: 26.01 (325Kops/s)

to:

src_8888_2x10 =  L1:  76.94  L2:  78.43  M: 75.87 (  5.59%)  HT: 56.73
VT: 52.39  R: 53.00  RT: 29.29 (363Kops/s)

on a i7 Q720 -based laptop.

The key of the patch is the observation that unorm_to_unorm's work can
more easily be done with a simple multiplication and shift, when the
function is applied repeatedly and the parameters are not compile-time
constants. For instance, converting from 0xfe to 0xfefe (expanding
from 8 bits to 16 bits) can be done by calculating

c = c * 0x101

However, sometimes the result is not a neat replication of all the
bits. For instance, going from 10 bits to 16 bits can be done by
calculating

c = c * 0x401UL >> 4

where the intermediate result is 20 bit wide repetition of the 10-bit
pattern followed by shifting off the unnecessary lowest bits.

The patch has the algorithm to calculate the factor and the shift, and
converts the code to use it.
pixman/pixman-utils.c