# [cairo-bugs] [Bug 10151] Add mediaLib support

bugzilla-daemon at freedesktop.org bugzilla-daemon at freedesktop.org
Thu Dec 13 17:23:58 PST 2007

```http://bugs.freedesktop.org/show_bug.cgi?id=10151

------- Comment #28 from brian.cameron at sun.com  2007-12-13 17:23 PST -------

With some help from James Cheng from the mediaLib team I found out why the two
places where my mediaLib patch was breaking the regression tests
(fbCombineMaskU and fbCombineInU).  The problem is that both of these functions
use the macro
FbByteMul, which is defined as follows:

/*
x_c = (x_c * a) / 255 + y
*/
#define FbByteMulAdd(x, a, y) do {                                \
CARD32 t = ((x & 0xff00ff) * a) + 0x800080;               \
t = (t + ((t >> 8) & 0xff00ff)) >> 8;                     \
t &= 0xff00ff;                                            \
t += y & 0xff00ff;                                        \
t |= 0x1000100 - ((t >> 8) & 0xff00ff);                   \
t &= 0xff00ff;                                            \
\
x = (((x >> 8) & 0xff00ff) * a) + 0x800080;                 \
x = (x + ((x >> 8) & 0xff00ff)) >> 8;                       \
x &= 0xff00ff;                                              \
x += (y >> 8) & 0xff00ff;                                   \
x |= 0x1000100 - ((t >> 8) & 0xff00ff);                     \
x &= 0xff00ff;                                              \
x <<= 8;                                                    \
x += t;                                                     \
} while (0)

As far as I can see, it actually has +0.5 for rounding, i.e.,

d1 = (x * a)/255.0 + 0.5;

Currently, the mediaLib function does this:

d2 = (x * a)/256.0;

This is the result

max12 = 2, max13 = 0, max23 = 2

i.e., the maximum difference is 2 between d1 and d2.

BTW, if d1 doesn't have +0.5, then max12 = max13 = 1.

Looking into why the mediaLib integration for fbCombineOverU does work without
causing any reguression tests, here is some information:

As far as I can see, it is actually equivalent to the following:

x_c = (x_c * a) / 255.0 + y + 0.5;
if (x_c > 255) x_c = 255;

In other words, fbCombineOverU does something like this (simplified
for one channel):

d1 = (d * (255 - a))/255.0 + s + 0.5;
if (d1 > 0xff) d1 = 0xff;

while the mediaLib function mlib_ImageBlend_OMSA_ONE_Inp does this:

d2 = (d * (256 - a))/256.0 + s;    /* mediaLib */
if (d2 > 0xff) d2 = 0xff;

Here is the result of test2:

max12 = 1, max13 = 0, max23 = 1

i.e., the maximum difference between d1 and d2 is 1, better than the
other case.

There is a performance benefit for doing /256 instead of /255,
especially for VIS implementation.  So is not doing +0.5.  FbByteMul
seems to be a relatively expensive macro for doing /255, although it
might be faster than doing /255 directly on most platforms, which
explains why a mediaLib function call could beat a macro on performance
in some cases.  As you know, mediaLib is mostly opt to performance when
there is a trade-off between precision and performance.

So it seems that the regression tests are failing due to reasonable off-by-one
issues.  Would it make sense to fix the regression tests to allow a bit more
fuzz in these cases where these mediaLib tests cause failure?  Or might it make
sense for cairo to adopt the "/256" method since it should work faster in
general, according to James?

Any thoughs appreciated.

--
Configure bugmail: http://bugs.freedesktop.org/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are the QA contact for the bug, or are watching the QA contact.
```