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
This commit is contained in:
fmalita 2016-01-22 11:45:39 -08:00 committed by Commit bot
parent 7f6a1e0786
commit 921d7ac752
3 changed files with 20 additions and 6 deletions

View File

@ -160,8 +160,15 @@ bool SkDefaultBitmapControllerState::processMediumRequest(const SkBitmapProvider
if (!fInvMatrix.decomposeScale(&invScaleSize, nullptr)) { if (!fInvMatrix.decomposeScale(&invScaleSize, nullptr)) {
return false; return false;
} }
#ifdef SK_SUPPORT_LEGACY_ANISOTROPIC_MIPMAPS
SkScalar invScale = SkScalarSqrt(invScaleSize.width() * invScaleSize.height()); 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) { if (invScale > SK_Scalar1) {
fCurrMip.reset(SkMipMapCache::FindAndRef(provider.makeCacheDesc())); fCurrMip.reset(SkMipMapCache::FindAndRef(provider.makeCacheDesc()));
if (nullptr == fCurrMip.get()) { if (nullptr == fCurrMip.get()) {
@ -182,9 +189,9 @@ bool SkDefaultBitmapControllerState::processMediumRequest(const SkBitmapProvider
SkScalar levelScale = SkScalarInvert(invScale); SkScalar levelScale = SkScalarInvert(invScale);
SkMipMap::Level level; SkMipMap::Level level;
if (fCurrMip->extractLevel(levelScale, &level)) { if (fCurrMip->extractLevel(levelScale, &level)) {
SkScalar invScaleFixup = level.fScale; const SkSize& invScaleFixup = level.fScale;
fInvMatrix.postScale(invScaleFixup, invScaleFixup); fInvMatrix.postScale(invScaleFixup.width(), invScaleFixup.height());
// todo: if we could wrap the fCurrMip in a pixelref, then we could just install // 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. // that here, and not need to explicitly track it ourselves.
return fResultBitmap.installPixels(level.fPixmap); return fResultBitmap.installPixels(level.fPixmap);

View File

@ -297,7 +297,13 @@ SkMipMap* SkMipMap::Build(const SkPixmap& src, SkDiscardableFactoryProc fact) {
rowBytes = SkToU32(SkColorTypeMinRowBytes(ct, width)); rowBytes = SkToU32(SkColorTypeMinRowBytes(ct, width));
levels[i].fPixmap = SkPixmap(SkImageInfo::Make(width, height, ct, at), addr, rowBytes); 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 SkPixmap& dstPM = levels[i].fPixmap;
const void* srcBasePtr = srcPM.addr(); const void* srcBasePtr = srcPM.addr();

View File

@ -11,6 +11,7 @@
#include "SkCachedData.h" #include "SkCachedData.h"
#include "SkPixmap.h" #include "SkPixmap.h"
#include "SkScalar.h" #include "SkScalar.h"
#include "SkSize.h"
class SkBitmap; class SkBitmap;
class SkDiscardableMemory; class SkDiscardableMemory;
@ -24,7 +25,7 @@ public:
struct Level { struct Level {
SkPixmap fPixmap; SkPixmap fPixmap;
float fScale; // < 1.0 SkSize fScale; // < 1.0
}; };
bool extractLevel(SkScalar scale, Level*) const; bool extractLevel(SkScalar scale, Level*) const;