aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/core/SkFDot6.h
diff options
context:
space:
mode:
authorGravatar george <george@mozilla.com>2014-08-29 08:47:55 -0700
committerGravatar Commit bot <commit-bot@chromium.org>2014-08-29 08:47:55 -0700
commit2f26528e59908856e36e88aa3be94d84014e9a58 (patch)
treea8d2ad9ccd9a38a26139481d1ff74c4d9bbc24c1 /src/core/SkFDot6.h
parentb75b2c05b999e26343e095eabff646705a0091ae (diff)
Use even rounding for better results when converting from scalar to fdot6
Originally from https://bugzilla.mozilla.org/show_bug.cgi?id=996108, patch by Jeff Muizelaar R=reed@google.com, reed1 BUG=skia: Author: george@mozilla.com Review URL: https://codereview.chromium.org/270263005
Diffstat (limited to 'src/core/SkFDot6.h')
-rw-r--r--src/core/SkFDot6.h22
1 files changed, 22 insertions, 0 deletions
diff --git a/src/core/SkFDot6.h b/src/core/SkFDot6.h
index 5a0ec57f59..3da753da41 100644
--- a/src/core/SkFDot6.h
+++ b/src/core/SkFDot6.h
@@ -15,6 +15,28 @@
typedef int32_t SkFDot6;
+/* This uses the magic number approach suggested here:
+ * http://stereopsis.com/sree/fpu2006.html and used in
+ * _cairo_fixed_from_double. It does banker's rounding
+ * (i.e. round to nearest even)
+ */
+inline SkFDot6 SkScalarRoundToFDot6(SkScalar x, int shift = 0)
+{
+ union {
+ double fDouble;
+ int32_t fBits[2];
+ } tmp;
+ int fractionalBits = 6 + shift;
+ double magic = (1LL << (52 - (fractionalBits))) * 1.5;
+
+ tmp.fDouble = SkScalarToDouble(x) + magic;
+#ifdef SK_CPU_BENDIAN
+ return tmp.fBits[1];
+#else
+ return tmp.fBits[0];
+#endif
+}
+
#define SK_FDot6One (64)
#define SK_FDot6Half (32)