Index: src/core/SkBitmapProcShader.cpp |
diff --git a/src/core/SkBitmapProcShader.cpp b/src/core/SkBitmapProcShader.cpp |
index bb161192763f8b15e50e93692490b22f621da16a..9a94676d6e313c19bcd08961582e66fe33702532 100644 |
--- a/src/core/SkBitmapProcShader.cpp |
+++ b/src/core/SkBitmapProcShader.cpp |
@@ -354,22 +354,36 @@ void SkBitmapProcShader::toString(SkString* str) const { |
#include "effects/GrSimpleTextureEffect.h" |
#include "SkGr.h" |
+// Note that this will return -1 if either matrix is perspective. |
+static SkScalar get_combined_min_stretch(const SkMatrix& viewMatrix, const SkMatrix& localMatrix) { |
+ if (localMatrix.isIdentity()) { |
+ return viewMatrix.getMinStretch(); |
reed1
2013/12/16 21:31:52
since we detect identity inside setConcat (for bot
|
+ } else { |
+ SkMatrix combined; |
+ combined.setConcat(viewMatrix, localMatrix); |
+ return combined.getMinStretch(); |
+ } |
+} |
+ |
GrEffectRef* SkBitmapProcShader::asNewEffect(GrContext* context, const SkPaint& paint) const { |
SkMatrix matrix; |
matrix.setIDiv(fRawBitmap.width(), fRawBitmap.height()); |
- SkMatrix inverse; |
- if (!this->getLocalMatrix().invert(&inverse)) { |
+ SkMatrix lmInverse; |
+ if (!this->getLocalMatrix().invert(&lmInverse)) { |
return NULL; |
} |
- matrix.preConcat(inverse); |
+ matrix.preConcat(lmInverse); |
SkShader::TileMode tm[] = { |
(TileMode)fState.fTileModeX, |
(TileMode)fState.fTileModeY, |
}; |
- // Must set wrap and filter on the sampler before requesting a texture. |
+ // Must set wrap and filter on the sampler before requesting a texture. In two places below |
+ // we check the matrix scale factors to determine how to interpret the filter quality setting. |
+ // This completely ignores the complexity of the drawVertices case where explicit local coords |
+ // are provided by the caller. |
SkPaint::FilterLevel paintFilterLevel = paint.getFilterLevel(); |
GrTextureParams::FilterMode textureFilterMode; |
switch(paintFilterLevel) { |
@@ -380,21 +394,23 @@ GrEffectRef* SkBitmapProcShader::asNewEffect(GrContext* context, const SkPaint& |
textureFilterMode = GrTextureParams::kBilerp_FilterMode; |
break; |
case SkPaint::kMedium_FilterLevel: |
- textureFilterMode = GrTextureParams::kMipMap_FilterMode; |
+ if (get_combined_min_stretch(context->getMatrix(), this->getLocalMatrix()) < |
robertphillips
2013/12/16 20:41:12
Wouldn't the real test be if the tri-lerp factor w
bsalomon
2013/12/16 20:47:49
Do you mean allow some small amount of down-scalin
|
+ SK_Scalar1) { |
+ textureFilterMode = GrTextureParams::kMipMap_FilterMode; |
+ } else { |
+ // Don't trigger MIP level generation unnecessarily. |
+ textureFilterMode = GrTextureParams::kBilerp_FilterMode; |
+ } |
break; |
case SkPaint::kHigh_FilterLevel: |
- // Minification can look bad with the bicubic effect. This is an overly aggressive |
- // check for MIP fallbacks. It doesn't consider the fact that minification in the local |
- // matrix could be offset by the view matrix and vice versa. We also don't know whether |
- // the draw has explicit local coords (e.g. drawVertices) where the scale factor is |
- // unknown and varies. |
- if (context->getMatrix().getMinStretch() >= SK_Scalar1 && |
- this->getLocalMatrix().getMaxStretch() <= SK_Scalar1) { |
- // fall back to no filtering here; we will install another |
- // shader that will do the HQ filtering. |
+ // Minification can look bad with bicubic filtering. |
+ if (get_combined_min_stretch(context->getMatrix(), this->getLocalMatrix()) >= |
+ SK_Scalar1) { |
+ // fall back to no filtering here; we will install another shader that will do the |
+ // HQ filtering. |
textureFilterMode = GrTextureParams::kNone_FilterMode; |
} else { |
- // Fall back to mip-mapping. |
+ // Fall back to MIP-mapping. |
paintFilterLevel = SkPaint::kMedium_FilterLevel; |
textureFilterMode = GrTextureParams::kMipMap_FilterMode; |
} |