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