From 921d7ac75206740e69fc6bc9893971249a909fe1 Mon Sep 17 00:00:00 2001 From: fmalita Date: Fri, 22 Jan 2016 11:45:39 -0800 Subject: [PATCH] Anisotropic mipmap fixes 1) when selecting a level scale, use max(scaleX, scaleY) instead of current sqrt(scaleX * scaleY) 2) track and apply non-uniform fixup scales R=reed@google.com GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&issue=1617183004 Review URL: https://codereview.chromium.org/1617183004 --- src/core/SkBitmapController.cpp | 15 +++++++++++---- src/core/SkMipMap.cpp | 8 +++++++- src/core/SkMipMap.h | 3 ++- 3 files changed, 20 insertions(+), 6 deletions(-) diff --git a/src/core/SkBitmapController.cpp b/src/core/SkBitmapController.cpp index 61c14dc7b8..5430575515 100644 --- a/src/core/SkBitmapController.cpp +++ b/src/core/SkBitmapController.cpp @@ -160,8 +160,15 @@ bool SkDefaultBitmapControllerState::processMediumRequest(const SkBitmapProvider if (!fInvMatrix.decomposeScale(&invScaleSize, nullptr)) { return false; } + +#ifdef SK_SUPPORT_LEGACY_ANISOTROPIC_MIPMAPS SkScalar invScale = SkScalarSqrt(invScaleSize.width() * invScaleSize.height()); - +#else + // Use the largest (non-inverse) scale, to ensure anisotropic consistency. + SkASSERT(invScaleSize.width() >= 0 && invScaleSize.height() >= 0); + const SkScalar invScale = SkTMin(invScaleSize.width(), invScaleSize.height()); +#endif + if (invScale > SK_Scalar1) { fCurrMip.reset(SkMipMapCache::FindAndRef(provider.makeCacheDesc())); if (nullptr == fCurrMip.get()) { @@ -182,9 +189,9 @@ bool SkDefaultBitmapControllerState::processMediumRequest(const SkBitmapProvider SkScalar levelScale = SkScalarInvert(invScale); SkMipMap::Level level; if (fCurrMip->extractLevel(levelScale, &level)) { - SkScalar invScaleFixup = level.fScale; - fInvMatrix.postScale(invScaleFixup, invScaleFixup); - + const SkSize& invScaleFixup = level.fScale; + fInvMatrix.postScale(invScaleFixup.width(), invScaleFixup.height()); + // todo: if we could wrap the fCurrMip in a pixelref, then we could just install // that here, and not need to explicitly track it ourselves. return fResultBitmap.installPixels(level.fPixmap); diff --git a/src/core/SkMipMap.cpp b/src/core/SkMipMap.cpp index 14e87a33a3..c037865fd4 100644 --- a/src/core/SkMipMap.cpp +++ b/src/core/SkMipMap.cpp @@ -297,7 +297,13 @@ SkMipMap* SkMipMap::Build(const SkPixmap& src, SkDiscardableFactoryProc fact) { rowBytes = SkToU32(SkColorTypeMinRowBytes(ct, width)); levels[i].fPixmap = SkPixmap(SkImageInfo::Make(width, height, ct, at), addr, rowBytes); - levels[i].fScale = (float)width / src.width(); +#ifdef SK_SUPPORT_LEGACY_ANISOTROPIC_MIPMAPS + levels[i].fScale = SkSize::Make(SkIntToScalar(width) / src.width(), + SkIntToScalar(width) / src.width()); +#else + levels[i].fScale = SkSize::Make(SkIntToScalar(width) / src.width(), + SkIntToScalar(height) / src.height()); +#endif const SkPixmap& dstPM = levels[i].fPixmap; const void* srcBasePtr = srcPM.addr(); diff --git a/src/core/SkMipMap.h b/src/core/SkMipMap.h index b3e958d63c..bc6d154939 100644 --- a/src/core/SkMipMap.h +++ b/src/core/SkMipMap.h @@ -11,6 +11,7 @@ #include "SkCachedData.h" #include "SkPixmap.h" #include "SkScalar.h" +#include "SkSize.h" class SkBitmap; class SkDiscardableMemory; @@ -24,7 +25,7 @@ public: struct Level { SkPixmap fPixmap; - float fScale; // < 1.0 + SkSize fScale; // < 1.0 }; bool extractLevel(SkScalar scale, Level*) const;