aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/core/SkBitmapProcState_matrixProcs.cpp
diff options
context:
space:
mode:
authorGravatar reed@google.com <reed@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2012-05-03 20:14:26 +0000
committerGravatar reed@google.com <reed@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2012-05-03 20:14:26 +0000
commit99c114e0ac732ba01705e24d12f5e4dd7e144abd (patch)
treed60428959061d6b86b8bfd13fcec141cceb053ff /src/core/SkBitmapProcState_matrixProcs.cpp
parent7265e725555098637498db2f397623d7991ceb4b (diff)
We were numerically overflowing our 16bit coordinates that we communicate
between these two procs. The fixes was in two parts: 1. Just don't draw bitmaps larger than 64K-1 in width or height, since we can't represent those coordinates in our transport format (yet). 2. Perform an unsigned shift during the calculation, so we don't get sign-extension bleed when packing the two values (X,Y) into our 32bit slot. Review URL: https://codereview.appspot.com/6173046 git-svn-id: http://skia.googlecode.com/svn/trunk@3836 2bbb7eff-a529-9590-31e7-b0007b416f81
Diffstat (limited to 'src/core/SkBitmapProcState_matrixProcs.cpp')
-rw-r--r--src/core/SkBitmapProcState_matrixProcs.cpp19
1 files changed, 13 insertions, 6 deletions
diff --git a/src/core/SkBitmapProcState_matrixProcs.cpp b/src/core/SkBitmapProcState_matrixProcs.cpp
index 15e7bebbe7..a8a2821524 100644
--- a/src/core/SkBitmapProcState_matrixProcs.cpp
+++ b/src/core/SkBitmapProcState_matrixProcs.cpp
@@ -9,6 +9,13 @@
#include "SkShader.h"
#include "SkUtils.h"
+// Helper to ensure that when we shift down, we do it w/o sign-extension
+// so the caller doesn't have to manually mask off the top 16 bits
+//
+static unsigned SK_USHIFT16(unsigned x) {
+ return x >> 16;
+}
+
/* returns 0...(n-1) given any x (positive or negative).
As an example, if n (which is always positive) is 5...
@@ -32,8 +39,8 @@ void decal_nofilter_scale(uint32_t dst[], SkFixed fx, SkFixed dx, int count);
void decal_filter_scale(uint32_t dst[], SkFixed fx, SkFixed dx, int count);
#define MAKENAME(suffix) ClampX_ClampY ## suffix
-#define TILEX_PROCF(fx, max) SkClampMax((fx) >> 16, max)
-#define TILEY_PROCF(fy, max) SkClampMax((fy) >> 16, max)
+#define TILEX_PROCF(fx, max) SkClampMax(SK_USHIFT16(fx), max)
+#define TILEY_PROCF(fy, max) SkClampMax(SK_USHIFT16(fy), max)
#define TILEX_LOW_BITS(fx, max) (((fx) >> 12) & 0xF)
#define TILEY_LOW_BITS(fy, max) (((fy) >> 12) & 0xF)
#define CHECK_FOR_DECAL
@@ -44,8 +51,8 @@ void decal_filter_scale(uint32_t dst[], SkFixed fx, SkFixed dx, int count);
#endif
#define MAKENAME(suffix) RepeatX_RepeatY ## suffix
-#define TILEX_PROCF(fx, max) (((fx) & 0xFFFF) * ((max) + 1) >> 16)
-#define TILEY_PROCF(fy, max) (((fy) & 0xFFFF) * ((max) + 1) >> 16)
+#define TILEX_PROCF(fx, max) SK_USHIFT16(((fx) & 0xFFFF) * ((max) + 1))
+#define TILEY_PROCF(fy, max) SK_USHIFT16(((fy) & 0xFFFF) * ((max) + 1))
#define TILEX_LOW_BITS(fx, max) ((((fx) & 0xFFFF) * ((max) + 1) >> 12) & 0xF)
#define TILEY_LOW_BITS(fy, max) ((((fy) & 0xFFFF) * ((max) + 1) >> 12) & 0xF)
#if defined(__ARM_HAVE_NEON)
@@ -63,8 +70,8 @@ void decal_filter_scale(uint32_t dst[], SkFixed fx, SkFixed dx, int count);
#define PREAMBLE_PARAM_Y , SkBitmapProcState::FixedTileProc tileProcY, SkBitmapProcState::FixedTileLowBitsProc tileLowBitsProcY
#define PREAMBLE_ARG_X , tileProcX, tileLowBitsProcX
#define PREAMBLE_ARG_Y , tileProcY, tileLowBitsProcY
-#define TILEX_PROCF(fx, max) (tileProcX(fx) * ((max) + 1) >> 16)
-#define TILEY_PROCF(fy, max) (tileProcY(fy) * ((max) + 1) >> 16)
+#define TILEX_PROCF(fx, max) SK_USHIFT16(tileProcX(fx) * ((max) + 1))
+#define TILEY_PROCF(fy, max) SK_USHIFT16(tileProcY(fy) * ((max) + 1))
#define TILEX_LOW_BITS(fx, max) tileLowBitsProcX(fx, (max) + 1)
#define TILEY_LOW_BITS(fy, max) tileLowBitsProcY(fy, (max) + 1)
#include "SkBitmapProcState_matrix.h"