Index: src/core/SkBitmapProcState.cpp |
diff --git a/src/core/SkBitmapProcState.cpp b/src/core/SkBitmapProcState.cpp |
index 166b62c48cf40a2da9829b717db3fbcbadd1993b..ed5e6874795f636486f6a3f916317c2d3f9712ae 100644 |
--- a/src/core/SkBitmapProcState.cpp |
+++ b/src/core/SkBitmapProcState.cpp |
@@ -12,11 +12,17 @@ |
#include "SkShader.h" // for tilemodes |
#include "SkUtilsArm.h" |
#include "SkBitmapScaler.h" |
+#include "SkMatrixUtils.h" |
#include "SkMipMap.h" |
#include "SkPixelRef.h" |
#include "SkScaledImageCache.h" |
#include "SkImageEncoder.h" |
+static int paintfilter_to_subpixelbits(SkPaint::FilterLevel level) { |
+ const int gBits[] = { 0, 4, 4, 4, }; |
+ return gBits[level]; |
+} |
+ |
#if !SK_ARM_NEON_IS_NONE |
// These are defined in src/opts/SkBitmapProcState_arm_neon.cpp |
extern const SkBitmapProcState::SampleProc16 gSkBitmapProcStateSample16_neon[]; |
@@ -374,14 +380,26 @@ SkBitmapProcState::~SkBitmapProcState() { |
SkDELETE(fBitmapFilter); |
} |
+bool SkBitmapProcState::isInverseTrivial() const { |
+ unsigned bits = paintfilter_to_subpixelbits((SkPaint::FilterLevel)fFilterLevel); |
+ return SkTreatAsSprite(fInvMatrix, fBitmap->width(), fBitmap->height(), bits); |
+} |
+ |
bool SkBitmapProcState::chooseProcs(const SkMatrix& inv, const SkPaint& paint) { |
SkASSERT(fOrigBitmap.width() && fOrigBitmap.height()); |
+ SkASSERT(NULL == fScaledCacheID); |
- fBitmap = NULL; |
fInvMatrix = inv; |
fFilterLevel = paint.getFilterLevel(); |
+ fBitmap = &fOrigBitmap; |
- SkASSERT(NULL == fScaledCacheID); |
+ bool trivialMX = this->isInverseTrivial(); |
+ if (trivialMX) { |
+ fFilterLevel = SkPaint::kNone_FilterLevel; |
+ } |
+ |
+ // Reset to null for possiblyScaleImage() |
+ fBitmap = NULL; |
// possiblyScaleImage will look to see if it can rescale the image as a |
// preprocess; either by scaling up to the target size, or by selecting |
@@ -406,11 +424,15 @@ bool SkBitmapProcState::chooseProcs(const SkMatrix& inv, const SkPaint& paint) { |
fFilterLevel = SkPaint::kLow_FilterLevel; |
} |
- bool trivialMatrix = (fInvMatrix.getType() & ~SkMatrix::kTranslate_Mask) == 0; |
+ trivialMX = this->isInverseTrivial(); |
+ if (trivialMX) { |
+ fFilterLevel = SkPaint::kNone_FilterLevel; |
+ } |
+ |
bool clampClamp = SkShader::kClamp_TileMode == fTileModeX && |
SkShader::kClamp_TileMode == fTileModeY; |
- if (!(clampClamp || trivialMatrix)) { |
+ if (!(clampClamp || trivialMX)) { |
fInvMatrix.postIDiv(fOrigBitmap.width(), fOrigBitmap.height()); |
} |
@@ -422,7 +444,8 @@ bool SkBitmapProcState::chooseProcs(const SkMatrix& inv, const SkPaint& paint) { |
// This code will only execute if the matrix has some scale component; |
// if it's already pure translate then we won't do this inversion. |
- if (matrix_only_scale_translate(fInvMatrix)) { |
+// if (matrix_only_scale_translate(fInvMatrix)) { |
+ if (trivialMX) { |
SkMatrix forward; |
if (fInvMatrix.invert(&forward)) { |
if (clampClamp ? just_trans_clamp(forward, *fBitmap) |
@@ -434,6 +457,10 @@ bool SkBitmapProcState::chooseProcs(const SkMatrix& inv, const SkPaint& paint) { |
} |
} |
+ if (trivialMX && (fInvMatrix.getType() & ~SkMatrix::kTranslate_Mask)) { |
+// SkDebugf("sfsd\n"); |
+ } |
+ |
fInvProc = fInvMatrix.getMapXYProc(); |
fInvType = fInvMatrix.getType(); |
fInvSx = SkScalarToFixed(fInvMatrix.getScaleX()); |
@@ -448,11 +475,6 @@ bool SkBitmapProcState::chooseProcs(const SkMatrix& inv, const SkPaint& paint) { |
fSampleProc32 = NULL; |
fSampleProc16 = NULL; |
- // recompute the triviality of the matrix here because we may have |
- // changed it! |
- |
- trivialMatrix = (fInvMatrix.getType() & ~SkMatrix::kTranslate_Mask) == 0; |
- |
if (SkPaint::kHigh_FilterLevel == fFilterLevel) { |
// If this is still set, that means we wanted HQ sampling |
// but couldn't do it as a preprocess. Let's try to install |
@@ -470,20 +492,10 @@ bool SkBitmapProcState::chooseProcs(const SkMatrix& inv, const SkPaint& paint) { |
} |
} |
- if (SkPaint::kLow_FilterLevel == fFilterLevel) { |
- // Only try bilerp if the matrix is "interesting" and |
- // the image has a suitable size. |
- |
- if (fInvType <= SkMatrix::kTranslate_Mask || |
- !valid_for_filtering(fBitmap->width() | fBitmap->height())) { |
- fFilterLevel = SkPaint::kNone_FilterLevel; |
- } |
- } |
- |
// At this point, we know exactly what kind of sampling the per-scanline |
// shader will perform. |
- fMatrixProc = this->chooseMatrixProc(trivialMatrix); |
+ fMatrixProc = this->chooseMatrixProc(trivialMX); |
// TODO(dominikg): SkASSERT(fMatrixProc) instead? chooseMatrixProc never returns NULL. |
if (NULL == fMatrixProc) { |
return false; |