aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/core/SkBitmapProcState.cpp
diff options
context:
space:
mode:
authorGravatar reed@google.com <reed@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2013-07-24 14:31:33 +0000
committerGravatar reed@google.com <reed@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2013-07-24 14:31:33 +0000
commitd94697c21ae479df4190a1afbf08d85ce244a4ef (patch)
tree3a8170934ed3aa549e0d9a2a3f8eb22f2c9640e7 /src/core/SkBitmapProcState.cpp
parent58c856a54a75e703aa3c82a0cd4e1affd9bd8ffc (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.cpp46
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;
}