Anisotropic mipmap fixes
authorfmalita <fmalita@chromium.org>
Fri, 22 Jan 2016 19:45:39 +0000 (11:45 -0800)
committerCommit bot <commit-bot@chromium.org>
Fri, 22 Jan 2016 19:45:39 +0000 (11:45 -0800)
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
src/core/SkMipMap.cpp
src/core/SkMipMap.h

index 61c14dc..5430575 100644 (file)
@@ -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);
index 14e87a3..c037865 100644 (file)
@@ -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();
index b3e958d..bc6d154 100644 (file)
@@ -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;