diff options
author | Yuqian Li <liyuqian@google.com> | 2016-11-18 10:18:15 -0500 |
---|---|---|
committer | Skia Commit-Bot <skia-commit-bot@chromium.org> | 2016-11-18 17:16:49 +0000 |
commit | ce1d293880da7d37da984090ed40320e0e3a6ca7 (patch) | |
tree | 1d2e20af99f05e0fc4fbd4251137dfb4642bb1cf /src/core/SkFDot6.h | |
parent | 83cd50b8afb0769154321ad39866f699c2c28e1e (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.h | 37 |
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 |