fix asserts in SkMulDiv255Round, and add test
authorreed@google.com <reed@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>
Mon, 22 Apr 2013 20:21:56 +0000 (20:21 +0000)
committerreed@google.com <reed@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>
Mon, 22 Apr 2013 20:21:56 +0000 (20:21 +0000)
Review URL: https://codereview.chromium.org/13934010

git-svn-id: http://skia.googlecode.com/svn/trunk@8813 2bbb7eff-a529-9590-31e7-b0007b416f81

include/core/SkMath.h
tests/MathTest.cpp

index 314311f6550122cf6f1fd8416e46ef07447e8a5e..cee325719790490b6696ea67a681e6f7b3e7c74c 100644 (file)
@@ -139,7 +139,7 @@ static inline bool SkIsPow2(int value) {
  *  Return a*b/((1 << shift) - 1), rounding any fractional bits.
  *  Only valid if a and b are unsigned and <= 32767 and shift is > 0 and <= 8
  */
-static inline unsigned SkMul16ShiftRound(unsigned a, unsigned b, int shift) {
+static inline unsigned SkMul16ShiftRound(U16CPU a, U16CPU b, int shift) {
     SkASSERT(a <= 32767);
     SkASSERT(b <= 32767);
     SkASSERT(shift > 0 && shift <= 8);
@@ -148,12 +148,12 @@ static inline unsigned SkMul16ShiftRound(unsigned a, unsigned b, int shift) {
 }
 
 /**
- *  Return a*b/255, rounding any fractional bits. Only valid if both
- *  a and b are 0..255
+ *  Return a*b/255, rounding any fractional bits.
+ *  Only valid if a and b are unsigned and <= 32767.
  */
-static inline U8CPU SkMulDiv255Round(U8CPU a, U8CPU b) {
-    SkASSERT((uint8_t)a == a);
-    SkASSERT((uint8_t)b == b);
+static inline U8CPU SkMulDiv255Round(U16CPU a, U16CPU b) {
+    SkASSERT(a <= 32767);
+    SkASSERT(b <= 32767);
     unsigned prod = SkMulS16(a, b) + 128;
     return (prod + (prod >> 8)) >> 8;
 }
index 105a3e4bdf8a35fd049ca7e58253eea4310579fb..372b41c7938218b311d7f6976bc047bb7ecb5384 100644 (file)
@@ -48,6 +48,32 @@ static void test_floor(skiatest::Reporter* reporter) {
 
 ///////////////////////////////////////////////////////////////////////////////
 
+// test that SkMul16ShiftRound and SkMulDiv255Round return the same result
+static void test_muldivround(skiatest::Reporter* reporter) {
+#if 0
+    // this "complete" test is too slow, so we test a random sampling of it
+
+    for (int a = 0; a <= 32767; ++a) {
+        for (int b = 0; b <= 32767; ++b) {
+            unsigned prod0 = SkMul16ShiftRound(a, b, 8);
+            unsigned prod1 = SkMulDiv255Round(a, b);
+            SkASSERT(prod0 == prod1);
+        }
+    }
+#endif
+
+    SkRandom rand;
+    for (int i = 0; i < 10000; ++i) {
+        unsigned a = rand.nextU() & 0x7FFF;
+        unsigned b = rand.nextU() & 0x7FFF;
+
+        unsigned prod0 = SkMul16ShiftRound(a, b, 8);
+        unsigned prod1 = SkMulDiv255Round(a, b);
+
+        REPORTER_ASSERT(reporter, prod0 == prod1);
+    }
+}
+
 static float float_blend(int src, int dst, float unit) {
     return dst + (src - dst) * unit;
 }
@@ -595,6 +621,8 @@ static void TestMath(skiatest::Reporter* reporter) {
 
     // disable for now
     if (false) test_blend31();  // avoid bit rot, suppress warning
+
+    test_muldivround(reporter);
 }
 
 #include "TestClassDef.h"