| 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;
|
|
|