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
diff --git a/src/core/SkBitmapController.cpp b/src/core/SkBitmapController.cpp
index 61c14dc..5430575 100644
--- a/src/core/SkBitmapController.cpp
+++ b/src/core/SkBitmapController.cpp
@@ -160,8 +160,15 @@
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 @@
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 14e87a3..c037865 100644
--- a/src/core/SkMipMap.cpp
+++ b/src/core/SkMipMap.cpp
@@ -297,7 +297,13 @@
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 b3e958d..bc6d154 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 @@
struct Level {
SkPixmap fPixmap;
- float fScale; // < 1.0
+ SkSize fScale; // < 1.0
};
bool extractLevel(SkScalar scale, Level*) const;