Chromium Code Reviews| 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; |
| } |