diff options
author | reed@google.com <reed@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2013-01-03 15:22:40 +0000 |
---|---|---|
committer | reed@google.com <reed@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2013-01-03 15:22:40 +0000 |
commit | ae57358447bac678e3fc458fa2857a349a6a7081 (patch) | |
tree | 3d583ee5f60faa53de876703cef47f7e8d088ed8 | |
parent | 9c81bd5540119b61756239a540216b108c11b6c5 (diff) |
use SkTreatAsSprite in SkDraw (with guard for chrome if needed)
git-svn-id: http://skia.googlecode.com/svn/trunk@6994 2bbb7eff-a529-9590-31e7-b0007b416f81
-rw-r--r-- | src/core/SkDraw.cpp | 5 | ||||
-rw-r--r-- | src/core/SkMatrix.cpp | 20 | ||||
-rw-r--r-- | src/core/SkMatrixUtils.h | 15 | ||||
-rw-r--r-- | tests/DrawBitmapRectTest.cpp | 51 |
4 files changed, 57 insertions, 34 deletions
diff --git a/src/core/SkDraw.cpp b/src/core/SkDraw.cpp index 281c69c017..0700353cfb 100644 --- a/src/core/SkDraw.cpp +++ b/src/core/SkDraw.cpp @@ -28,6 +28,7 @@ #include "SkAutoKern.h" #include "SkBitmapProcShader.h" #include "SkDrawProcs.h" +#include "SkMatrixUtils.h" //#define TRACE_BITMAP_DRAWS @@ -1113,6 +1114,7 @@ void SkDraw::drawPath(const SkPath& origSrcPath, const SkPaint& origPaint, go ahead and treat it as if it were, so that subsequent code can go fast. */ static bool just_translate(const SkMatrix& matrix, const SkBitmap& bitmap) { +#ifdef SK_IGNORE_TREAT_AS_SPRITE SkMatrix::TypeMask mask = matrix.getType(); if (mask & (SkMatrix::kAffine_Mask | SkMatrix::kPerspective_Mask)) { @@ -1129,6 +1131,9 @@ static bool just_translate(const SkMatrix& matrix, const SkBitmap& bitmap) { } // if we got here, we're either kTranslate_Mask or identity return true; +#else + return SkTreatAsSpriteFilter(matrix, bitmap.width(), bitmap.height()); +#endif } void SkDraw::drawBitmapAsMask(const SkBitmap& bitmap, diff --git a/src/core/SkMatrix.cpp b/src/core/SkMatrix.cpp index 15d295cc27..1eabc78fba 100644 --- a/src/core/SkMatrix.cpp +++ b/src/core/SkMatrix.cpp @@ -1807,8 +1807,9 @@ void SkMatrix::toDumpString(SkString* str) const { #include "SkMatrixUtils.h" -bool SkTreatAsSprite(const SkMatrix& mat, const SkRect& src, +bool SkTreatAsSprite(const SkMatrix& mat, int width, int height, unsigned subpixelBits) { + // quick reject on affine or perspective if (mat.getType() & ~(SkMatrix::kScale_Mask | SkMatrix::kTranslate_Mask)) { return false; } @@ -1824,16 +1825,18 @@ bool SkTreatAsSprite(const SkMatrix& mat, const SkRect& src, } SkRect dst; - SkIRect isrc, idst; - - mat.mapRect(&dst, src); - + SkIRect isrc = { 0, 0, width, height }; + { - SkRect tmp = src; - tmp.offset(mat.getTranslateX(), mat.getTranslateY()); - tmp.round(&isrc); + SkRect src; + src.set(isrc); + mat.mapRect(&dst, src); } + // just apply the translate to isrc + isrc.offset(SkScalarRoundToInt(mat.getTranslateX()), + SkScalarRoundToInt(mat.getTranslateY())); + if (subpixelBits) { isrc.fLeft <<= subpixelBits; isrc.fTop <<= subpixelBits; @@ -1847,6 +1850,7 @@ bool SkTreatAsSprite(const SkMatrix& mat, const SkRect& src, dst.fBottom *= scale; } + SkIRect idst; dst.round(&idst); return isrc == idst; } diff --git a/src/core/SkMatrixUtils.h b/src/core/SkMatrixUtils.h index 04c0892776..2074267b7d 100644 --- a/src/core/SkMatrixUtils.h +++ b/src/core/SkMatrixUtils.h @@ -17,16 +17,27 @@ #define kSkSubPixelBitsForBilerp 4 /** - * Given a matrix and a src-rect, return true if the computed dst-rect would + * Given a matrix and width/height, return true if the computed dst-rect would * align such that there is a 1-to-1 coorspondence between src and dst pixels. * This can be called by drawing code to see if drawBitmap can be turned into * drawSprite (which is faster). * + * The src-rect is defined to be { 0, 0, width, height } + * * The "closeness" test is based on the subpixelBits parameter. Pass 0 for * round-to-nearest behavior (e.g. nearest neighbor sampling). Pass the number * of subpixel-bits to simulate filtering. */ -bool SkTreatAsSprite(const SkMatrix&, const SkRect& src, unsigned subpixelBits); +bool SkTreatAsSprite(const SkMatrix&, int width, int height, + unsigned subpixelBits); +/** + * Calls SkTreatAsSprite() with default subpixelBits value to match Skia's + * filter-bitmap implementation (i.e. kSkSubPixelBitsForBilerp). + */ +static inline bool SkTreatAsSpriteFilter(const SkMatrix& matrix, + int width, int height) { + return SkTreatAsSprite(matrix, width, height, kSkSubPixelBitsForBilerp); +} #endif diff --git a/tests/DrawBitmapRectTest.cpp b/tests/DrawBitmapRectTest.cpp index df5f2f5a41..a56396cc20 100644 --- a/tests/DrawBitmapRectTest.cpp +++ b/tests/DrawBitmapRectTest.cpp @@ -29,25 +29,28 @@ static void rand_matrix(SkMatrix* mat, SkRandom& rand, unsigned mask) { } } -static void rand_rect(SkRect* r, SkRandom& rand) { - r->set(rand.nextSScalar1() * 1000, rand.nextSScalar1() * 1000, - rand.nextSScalar1() * 1000, rand.nextSScalar1() * 1000); - r->sort(); +static void rand_size(SkISize* size, SkRandom& rand) { + size->set(rand.nextU() & 0xFFFF, rand.nextU() & 0xFFFF); +} + +static bool treat_as_sprite(const SkMatrix& mat, const SkISize& size, + unsigned bits) { + return SkTreatAsSprite(mat, size.width(), size.height(), bits); } static void test_treatAsSprite(skiatest::Reporter* reporter) { const unsigned bilerBits = kSkSubPixelBitsForBilerp; SkMatrix mat; - SkRect r; + SkISize size; SkRandom rand; // assert: translate-only no-filter can always be treated as sprite for (int i = 0; i < 1000; ++i) { rand_matrix(&mat, rand, SkMatrix::kTranslate_Mask); for (int j = 0; j < 1000; ++j) { - rand_rect(&r, rand); - REPORTER_ASSERT(reporter, SkTreatAsSprite(mat, r, 0)); + rand_size(&size, rand); + REPORTER_ASSERT(reporter, treat_as_sprite(mat, size, 0)); } } @@ -55,43 +58,43 @@ static void test_treatAsSprite(skiatest::Reporter* reporter) { for (int i = 0; i < 1000; ++i) { rand_matrix(&mat, rand, SkMatrix::kAffine_Mask | SkMatrix::kPerspective_Mask); for (int j = 0; j < 1000; ++j) { - rand_rect(&r, rand); - REPORTER_ASSERT(reporter, !SkTreatAsSprite(mat, r, 0)); - REPORTER_ASSERT(reporter, !SkTreatAsSprite(mat, r, bilerBits)); + rand_size(&size, rand); + REPORTER_ASSERT(reporter, !treat_as_sprite(mat, size, 0)); + REPORTER_ASSERT(reporter, !treat_as_sprite(mat, size, bilerBits)); } } - r.set(10, 10, 500, 600); + size.set(500, 600); const SkScalar tooMuchSubpixel = SkFloatToScalar(100.1f); mat.setTranslate(tooMuchSubpixel, 0); - REPORTER_ASSERT(reporter, !SkTreatAsSprite(mat, r, bilerBits)); + REPORTER_ASSERT(reporter, !treat_as_sprite(mat, size, bilerBits)); mat.setTranslate(0, tooMuchSubpixel); - REPORTER_ASSERT(reporter, !SkTreatAsSprite(mat, r, bilerBits)); + REPORTER_ASSERT(reporter, !treat_as_sprite(mat, size, bilerBits)); const SkScalar tinySubPixel = SkFloatToScalar(100.02f); mat.setTranslate(tinySubPixel, 0); - REPORTER_ASSERT(reporter, SkTreatAsSprite(mat, r, bilerBits)); + REPORTER_ASSERT(reporter, treat_as_sprite(mat, size, bilerBits)); mat.setTranslate(0, tinySubPixel); - REPORTER_ASSERT(reporter, SkTreatAsSprite(mat, r, bilerBits)); + REPORTER_ASSERT(reporter, treat_as_sprite(mat, size, bilerBits)); const SkScalar twoThirds = SK_Scalar1 * 2 / 3; - const SkScalar bigScale = SkScalarDiv(r.width() + twoThirds, r.width()); + const SkScalar bigScale = SkScalarDiv(size.width() + twoThirds, size.width()); mat.setScale(bigScale, bigScale); - REPORTER_ASSERT(reporter, !SkTreatAsSprite(mat, r, false)); - REPORTER_ASSERT(reporter, !SkTreatAsSprite(mat, r, bilerBits)); + REPORTER_ASSERT(reporter, !treat_as_sprite(mat, size, false)); + REPORTER_ASSERT(reporter, !treat_as_sprite(mat, size, bilerBits)); const SkScalar oneThird = SK_Scalar1 / 3; - const SkScalar smallScale = SkScalarDiv(r.width() + oneThird, r.width()); + const SkScalar smallScale = SkScalarDiv(size.width() + oneThird, size.width()); mat.setScale(smallScale, smallScale); - REPORTER_ASSERT(reporter, SkTreatAsSprite(mat, r, false)); - REPORTER_ASSERT(reporter, !SkTreatAsSprite(mat, r, bilerBits)); + REPORTER_ASSERT(reporter, treat_as_sprite(mat, size, false)); + REPORTER_ASSERT(reporter, !treat_as_sprite(mat, size, bilerBits)); const SkScalar oneFortyth = SK_Scalar1 / 40; - const SkScalar tinyScale = SkScalarDiv(r.width() + oneFortyth, r.width()); + const SkScalar tinyScale = SkScalarDiv(size.width() + oneFortyth, size.width()); mat.setScale(tinyScale, tinyScale); - REPORTER_ASSERT(reporter, SkTreatAsSprite(mat, r, false)); - REPORTER_ASSERT(reporter, SkTreatAsSprite(mat, r, bilerBits)); + REPORTER_ASSERT(reporter, treat_as_sprite(mat, size, false)); + REPORTER_ASSERT(reporter, treat_as_sprite(mat, size, bilerBits)); } static void assert_ifDrawnTo(skiatest::Reporter* reporter, |