diff options
author | reed@google.com <reed@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2013-07-24 14:31:33 +0000 |
---|---|---|
committer | reed@google.com <reed@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2013-07-24 14:31:33 +0000 |
commit | d94697c21ae479df4190a1afbf08d85ce244a4ef (patch) | |
tree | 3a8170934ed3aa549e0d9a2a3f8eb22f2c9640e7 /src/core/SkBitmapProcState.cpp | |
parent | 58c856a54a75e703aa3c82a0cd4e1affd9bd8ffc (diff) |
add mipmaps to scaledimagecache
BUG=
Review URL: https://codereview.chromium.org/19789016
git-svn-id: http://skia.googlecode.com/svn/trunk@10305 2bbb7eff-a529-9590-31e7-b0007b416f81
Diffstat (limited to 'src/core/SkBitmapProcState.cpp')
-rw-r--r-- | src/core/SkBitmapProcState.cpp | 46 |
1 files changed, 33 insertions, 13 deletions
diff --git a/src/core/SkBitmapProcState.cpp b/src/core/SkBitmapProcState.cpp index 37c5026797..3a059d3876 100644 --- a/src/core/SkBitmapProcState.cpp +++ b/src/core/SkBitmapProcState.cpp @@ -12,6 +12,7 @@ #include "SkShader.h" // for tilemodes #include "SkUtilsArm.h" #include "SkBitmapScaler.h" +#include "SkMipMap.h" #include "SkScaledImageCache.h" #if !SK_ARM_NEON_IS_NONE @@ -92,7 +93,7 @@ static bool valid_for_filtering(unsigned dimension) { return (dimension & ~0x3FFF) == 0; } -static bool effective_matrix_scale_sqrd(const SkMatrix& mat) { +static SkScalar effective_matrix_scale_sqrd(const SkMatrix& mat) { SkPoint v1, v2; v1.fX = mat.getScaleX(); @@ -225,24 +226,43 @@ void SkBitmapProcState::possiblyScaleImage() { * a scale > 1 to indicate down scaling by the CTM. */ if (scaleSqd > SK_Scalar1) { - if (!fOrigBitmap.hasMipMap()) { - fOrigBitmap.buildMipMap(); - // build may fail, so we need to check again + const SkMipMap* mip = NULL; + + SkASSERT(NULL == fScaledCacheID); + fScaledCacheID = SkScaledImageCache::FindAndLockMip(fOrigBitmap, &mip); + if (!fScaledCacheID) { + SkASSERT(NULL == mip); + mip = SkMipMap::Build(fOrigBitmap); + if (mip) { + fScaledCacheID = SkScaledImageCache::AddAndLockMip(fOrigBitmap, + mip); + mip->unref(); // the cache took a ref + SkASSERT(fScaledCacheID); + } + } else { + SkASSERT(mip); } - if (fOrigBitmap.hasMipMap()) { - int shift = fOrigBitmap.extractMipLevel(&fScaledBitmap, - SkScalarToFixed(fInvMatrix.getScaleX()), - SkScalarToFixed(fInvMatrix.getSkewY())); - if (shift > 0) { - SkScalar scale = SkFixedToScalar(SK_Fixed1 >> shift); - fInvMatrix.postScale(scale, scale); + + if (mip) { + SkScalar levelScale = SkScalarInvert(SkScalarSqrt(scaleSqd)); + SkMipMap::Level level; + if (mip->extractLevel(levelScale, &level)) { + SkScalar invScaleFixup = level.fScale; + fInvMatrix.postScale(invScaleFixup, invScaleFixup); + + fScaledBitmap.setConfig(fOrigBitmap.config(), + level.fWidth, level.fHeight, + level.fRowBytes); + fScaledBitmap.setPixels(level.fPixels); fBitmap = &fScaledBitmap; } } } - // Now that we've built the mipmaps (if applicable), we set the filter-level - // bilinear interpolation. + /* + * At this point, we may or may not have built a mipmap. Regardless, we + * now fall back on Low so will bilerp whatever fBitmap now points at. + */ fFilterLevel = SkPaint::kLow_FilterLevel; } |