1#include "Test.h" 2#include "SkColorPriv.h" 3#include "SkXfermode.h" 4 5// our std SkAlpha255To256 6static int test_srcover0(unsigned dst, unsigned alpha) { 7 return alpha + SkAlphaMul(dst, SkAlpha255To256(255 - alpha)); 8} 9 10// faster hack +1 11static int test_srcover1(unsigned dst, unsigned alpha) { 12 return alpha + SkAlphaMul(dst, 256 - alpha); 13} 14 15// slower "correct" 16static int test_srcover2(unsigned dst, unsigned alpha) { 17 return alpha + SkMulDiv255Round(dst, 255 - alpha); 18} 19 20static void test_srcover_hack(skiatest::Reporter* reporter) { 21 /* Here's the idea. Can we ensure that when we blend on top of an opaque 22 dst, that the result always stay's opaque (i.e. exactly 255)? 23 */ 24 25 unsigned i; 26 int opaqueCounter0 = 0; 27 int opaqueCounter1 = 0; 28 int opaqueCounter2 = 0; 29 for (i = 0; i <= 255; i++) { 30 unsigned result0 = test_srcover0(0xFF, i); 31 unsigned result1 = test_srcover1(0xFF, i); 32 unsigned result2 = test_srcover2(0xFF, i); 33 opaqueCounter0 += (result0 == 0xFF); 34 opaqueCounter1 += (result1 == 0xFF); 35 opaqueCounter2 += (result2 == 0xFF); 36 } 37#if 0 38 SkDebugf("---- opaque test: [%d %d %d]\n", 39 opaqueCounter0, opaqueCounter1, opaqueCounter2); 40#endif 41 // we acknowledge that technique0 does not always return opaque 42 REPORTER_ASSERT(reporter, opaqueCounter0 == 256); 43 REPORTER_ASSERT(reporter, opaqueCounter1 == 256); 44 REPORTER_ASSERT(reporter, opaqueCounter2 == 256); 45 46 // Now ensure that we never over/underflow a byte 47 for (i = 0; i <= 255; i++) { 48 for (unsigned dst = 0; dst <= 255; dst++) { 49 unsigned r0 = test_srcover0(dst, i); 50 unsigned r1 = test_srcover1(dst, i); 51 unsigned r2 = test_srcover2(dst, i); 52 unsigned max = SkMax32(dst, i); 53 // ignore the known failure 54 if (dst != 255) { 55 REPORTER_ASSERT(reporter, r0 <= 255 && r0 >= max); 56 } 57 REPORTER_ASSERT(reporter, r1 <= 255 && r1 >= max); 58 REPORTER_ASSERT(reporter, r2 <= 255 && r2 >= max); 59 60#if 0 61 // this shows where r1 (faster) differs from r2 (more exact) 62 if (r1 != r2) { 63 SkDebugf("--- dst=%d i=%d r1=%d r2=%d exact=%g\n", 64 dst, i, r1, r2, i + dst - dst*i/255.0f); 65 } 66#endif 67 } 68 } 69} 70 71#include "TestClassDef.h" 72DEFINE_TESTCLASS("SrcOver", SrcOverTestClass, test_srcover_hack) 73