diff --git a/src/core/SkBitmapProcState.cpp b/src/core/SkBitmapProcState.cpp index 3c3f3a54b7..c4b29392f1 100644 --- a/src/core/SkBitmapProcState.cpp +++ b/src/core/SkBitmapProcState.cpp @@ -586,24 +586,36 @@ static void DoNothing_shaderproc(const void*, int x, int y, } bool SkBitmapProcState::setupForTranslate() { +#ifdef SK_SUPPORT_LEGACY_SAMPLER_BIAS SkPoint pt; fInvProc(fInvMatrix, SK_ScalarHalf, SK_ScalarHalf, &pt); + const SkScalar too_big = SkIntToScalar(1 << 30); + if (SkScalarAbs(pt.fX) > too_big || SkScalarAbs(pt.fY) > too_big) { + return false; + } + + fFilterOneX = SkScalarFloorToInt(pt.fX); + fFilterOneY = SkScalarFloorToInt(pt.fY); +#else + SkBitmapProcStateAutoMapper mapper(*this, 0, 0); + /* * if the translate is larger than our ints, we can get random results, or * worse, we might get 0x80000000, which wreaks havoc on us, since we can't * negate it. */ - const SkScalar too_big = SkIntToScalar(1 << 30); - if (SkScalarAbs(pt.fX) > too_big || SkScalarAbs(pt.fY) > too_big) { + if (mapper.isOverflow()) { return false; } // Since we know we're not filtered, we re-purpose these fields allow // us to go from device -> src coordinates w/ just an integer add, // rather than running through the inverse-matrix - fFilterOneX = SkScalarFloorToInt(pt.fX); - fFilterOneY = SkScalarFloorToInt(pt.fY); + fFilterOneX = SkFractionalIntToInt(mapper.x()); + fFilterOneY = SkFractionalIntToInt(mapper.y()); +#endif + return true; } diff --git a/src/core/SkBitmapProcState.h b/src/core/SkBitmapProcState.h index 3f1d699cf2..5e680befd2 100644 --- a/src/core/SkBitmapProcState.h +++ b/src/core/SkBitmapProcState.h @@ -206,13 +206,27 @@ public: const SkFixed biasY = (s.fInvMatrix.getScaleY() > 0); fX = SkScalarToFractionalInt(pt.x()) - SkFixedToFractionalInt(biasX); fY = SkScalarToFractionalInt(pt.y()) - SkFixedToFractionalInt(biasY); + + /* + * (see SkBitmapProcState::setupForTranslate, which is the only user of this flag) + * + * if the translate is larger than our ints, we can get random results, or + * worse, we might get 0x80000000, which wreaks havoc on us, since we can't + * negate it. + */ + const SkScalar too_big = SkIntToScalar(1 << 30); + fOverflow = SkScalarAbs(pt.x() - SkFixedToScalar(biasX)) > too_big + || SkScalarAbs(pt.y() - SkFixedToScalar(biasY)) > too_big; } SkFractionalInt x() const { return fX; } SkFractionalInt y() const { return fY; } + bool isOverflow() const { return fOverflow; } + private: SkFractionalInt fX, fY; + bool fOverflow; }; #endif