aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar reed@google.com <reed@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2013-01-03 15:22:40 +0000
committerGravatar reed@google.com <reed@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2013-01-03 15:22:40 +0000
commitae57358447bac678e3fc458fa2857a349a6a7081 (patch)
tree3d583ee5f60faa53de876703cef47f7e8d088ed8
parent9c81bd5540119b61756239a540216b108c11b6c5 (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.cpp5
-rw-r--r--src/core/SkMatrix.cpp20
-rw-r--r--src/core/SkMatrixUtils.h15
-rw-r--r--tests/DrawBitmapRectTest.cpp51
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,