On Thu, 24 Jan 2013 10:52:59 -0500 Søren Sandmann <[email protected]> wrote:
> From: Søren Sandmann Pedersen <[email protected]> > > The check-formats programs reveals that the 8 bit pipeline cannot meet > the current 0.004 acceptable deviation specified in utils.c, so we > have to increase it. Some of the failing pixels were captured in > pixel-test, which with this commit now passes. > > == a4r4g4b4 DISJOINT_XOR a8r8g8b8 == > > The DISJOINT_XOR operator applied to an a4r4g4b4 source pixel of > 0xd0c0 and a destination pixel of 0x5300ea00 results in the exact > value: > > fa = (1 - da) / sa = (1 - 0x53 / 255.0) / (0xd / 15.0) = 0.7782 > fb = (1 - sa) / da = (1 - 0xd / 15.0) / (0x53 / 255.0) = 0.4096 > > r = fa * (0xc / 15.0) + fb * (0xea / 255.0) = 0.99853 > > But when computing in 8 bits, we get: > > fa8 = ((255 - 0x53) * 255 + 0xdd / 2) / 0xdd = 0xc6 > fb8 = ((255 - 0xdd) * 255 + 0x53 / 3) / 0x53 = 0x68 > > r8 = (fa8 * 0xcc + 127) / 255 + (fb8 * 0xea + 127) / 255 = 0xfd > > and > > 0xfd / 255.0 = 0.9921568627450981 > > for a deviation of 0.00637118610187, which we then have to consider > acceptable given the current implementation. > > By switching to computing the result with > > r = (fa * s + fb * d + 127) / 255 > > rather than > > r = (fa * s + 127) / 255 + (fb * d + 127) / 255 > > the deviation would be only 0.00244961747442, so at some point it may > be worth doing either this, or switching to floating point for > operators that involve divisions. This reminds me of http://cgit.freedesktop.org/pixman/commit/?id=a075a870fd7e1fa7 Both performance and accuracy were sacrificed to get bitexact results when compared to generic C implementation. > Note that the conversion from 4 bits to 8 bits does not cause any > error in this case because both rounding and bit replication produces > an exact result when the number of from-bits divide the number of > to-bits. > > == a8r8g8b8 OVER r5g6b5 == > > When OVER compositing the a8r8g8b8 pixel 0x0f00c300 with the x14r5g6b5 Did you actually mean x14r6g6b6? > pixel 0x03c0, the true floating point value of the resulting green > channel is: > > 0xc3 / 255.0 + (1.0 - 0x0f / 255.0) * (0x0f / 63.0) = 0.9887955 > > but when compositing 8 bit values, where the 6-bit green channel is > converted to 8 bit through bit replication, the 8-bit result is: > > 0xc3 + ((255 - 0x0f) * 0x3c + 127) / 255 = 251 > > which corresponds to a real value of 0.984314. The difference from the > true value is 0.004482 which is bigger than the acceptable deviation > of 0.004. So, if we were to compute all the CONJOINT/DISJOINT > operators in floating point, or otherwise make them more accurate, the > acceptable deviation could be set at 0.0045. > > If we were doing the 6-bit conversion with rounding: > > (x / 63.0 * 255.0 + 0.5) > > instead of bit replication, the deviation in this particular case > would be only 0.0005, so we may want to consider this at some > point. This has been also discussed here: http://comments.gmane.org/gmane.comp.graphics.pixman/1891 Though the bit replication when converting to 8-bit is not so bad. Dropping lower bits when converting back introduces a bigger error. Anyway, if I remember correctly, the accuracy loss has been well known since the time when bitexact testing was introduced. Other than using less accurate but faster conversion approximations, currently there is also an assumption that separate "fetch -> combine -> store" steps must provide exactly the same results as the fast path functions doing the same operations in one go. This restriction surely inhibits performance and accuracy. Certain platforms (ARM11 and MIPS32) should be able to improve performance a bit if we go away from bitexact correctness testing and allow more freedom in implementations. So this patchset indeed looks rather useful. However I think that we may need to come to an agreement on the primary purpose of the 8-bit pipeline, especially now that we also have a floating point pipeline. In my opinion, the 8-bit integer pipeline should always favour performance over accuracy in the case of doubt. Moreover, anyone using r5g6b5 format is most likely either memory or performance constrained, so they would not particularly appreciate the more accurate, but slower conversion between a8r8g8b8 and r5g6b5. There are also other libraries and alternative solutions out there. The competition between different mobile browsers and UI toolkits for the embedded systems seems to be heavily focused on performance. Every little bit is relevant. And while we are talking about this, bilinear interpolation precision is also somewhat related here (the choice of 7-bit vs. 4-bit) and whether we can avoid doing correct rounding for it or not. On the other hand, the floating point pipeline is a good place to implement sRGB, accurate format conversions and the other nice things. In other words, it can favour accuracy over performance. -- Best regards, Siarhei Siamashka _______________________________________________ Pixman mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/pixman
