aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/core/SkFDot6.h
diff options
context:
space:
mode:
authorGravatar Yuqian Li <liyuqian@google.com>2016-11-18 10:18:15 -0500
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2016-11-18 17:16:49 +0000
commitce1d293880da7d37da984090ed40320e0e3a6ca7 (patch)
tree1d2e20af99f05e0fc4fbd4251137dfb4642bb1cf /src/core/SkFDot6.h
parent83cd50b8afb0769154321ad39866f699c2c28e1e (diff)
Add test for QuickFDot6Div
This test will catch our (1 << 10) bug (which should be 1 << 9) BUG=skia: GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=4986 Change-Id: I25b607d1535a647284cee3b304a6f567f389e7f6 Reviewed-on: https://skia-review.googlesource.com/4986 Reviewed-by: Cary Clark <caryclark@google.com> Commit-Queue: Yuqian Li <liyuqian@google.com>
Diffstat (limited to 'src/core/SkFDot6.h')
-rw-r--r--src/core/SkFDot6.h37
1 files changed, 37 insertions, 0 deletions
diff --git a/src/core/SkFDot6.h b/src/core/SkFDot6.h
index 726aa2e46d..b9a5c2a12d 100644
--- a/src/core/SkFDot6.h
+++ b/src/core/SkFDot6.h
@@ -75,4 +75,41 @@ inline SkFixed SkFDot6Div(SkFDot6 a, SkFDot6 b) {
}
}
+#include "SkFDot6Constants.h"
+
+class QuickFDot6Inverse {
+private:
+ static constexpr const SkFDot6* table = gFDot6INVERSE + kInverseTableSize;
+public:
+ inline static SkFixed Lookup(SkFDot6 x) {
+ SkASSERT(SkAbs32(x) < kInverseTableSize);
+ return table[x];
+ }
+};
+
+static inline SkFixed QuickSkFDot6Div(SkFDot6 a, SkFDot6 b) {
+ const int kMinBits = 3; // abs(b) should be at least (1 << kMinBits) for quick division
+ const int kMaxBits = 31; // Number of bits available in signed int
+ // Given abs(b) <= (1 << kMinBits), the inverse of abs(b) is at most 1 << (22 - kMinBits) in
+ // SkFixed format. Hence abs(a) should be less than kMaxAbsA
+ const int kMaxAbsA = 1 << (kMaxBits - (22 - kMinBits));
+ SkFDot6 abs_a = SkAbs32(a);
+ SkFDot6 abs_b = SkAbs32(b);
+ if (abs_b >= (1 << kMinBits) && abs_b < kInverseTableSize && abs_a < kMaxAbsA) {
+ SkASSERT((int64_t)a * QuickFDot6Inverse::Lookup(b) <= SK_MaxS32
+ && (int64_t)a * QuickFDot6Inverse::Lookup(b) >= SK_MinS32);
+ SkFixed ourAnswer = (a * QuickFDot6Inverse::Lookup(b)) >> 6;
+ #ifdef SK_DEBUG
+ SkFixed directAnswer = SkFDot6Div(a, b);
+ SkASSERT(
+ (directAnswer == 0 && ourAnswer == 0) ||
+ SkFixedDiv(SkAbs32(directAnswer - ourAnswer), SkAbs32(directAnswer)) <= 1 << 10
+ );
+ #endif
+ return ourAnswer;
+ } else {
+ return SkFDot6Div(a, b);
+ }
+}
+
#endif