aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/core
diff options
context:
space:
mode:
authorGravatar humper <humper@google.com>2014-08-28 14:27:42 -0700
committerGravatar Commit bot <commit-bot@chromium.org>2014-08-28 14:27:42 -0700
commitd73c169637f1ab0b96bae43269da7216bb93a7e1 (patch)
tree673a5affaf7d1db167e8f759b10b16bf3ecf9d35 /src/core
parent0209e95cc2625a445c1cb6c4213d2182e5c832d7 (diff)
Second attempt to land the integral image scaling change.
Scale all images to the nearest rounded integer, and if there's still any scaling factor left over, pass it on to the subsequent bilerp code. Should avoid artifacts when tiling scaled images. Original CL received an LGTM from reed; new version disabled tiling in the downsamplebitmap GM; I verified that this fixes the issue we were seeing there on non-neon androids. BUG=skia:2888 R=reed@android.com TBR=reed Author: humper@google.com Review URL: https://codereview.chromium.org/514383003
Diffstat (limited to 'src/core')
-rw-r--r--src/core/SkBitmapProcState.cpp46
-rw-r--r--src/core/SkBitmapProcState.h1
2 files changed, 34 insertions, 13 deletions
diff --git a/src/core/SkBitmapProcState.cpp b/src/core/SkBitmapProcState.cpp
index 52a2ecf25c..a269170422 100644
--- a/src/core/SkBitmapProcState.cpp
+++ b/src/core/SkBitmapProcState.cpp
@@ -129,21 +129,34 @@ static inline bool cache_size_okay(const SkBitmap& bm, const SkMatrix& invMat) {
bool SkBitmapProcState::possiblyScaleImage() {
SkASSERT(NULL == fBitmap);
+ fAdjustedMatrix = false;
+
if (fFilterLevel <= SkPaint::kLow_FilterLevel) {
return false;
}
// Check to see if the transformation matrix is simple, and if we're
// doing high quality scaling. If so, do the bitmap scale here and
- // remove the scaling component from the matrix.
+ // remove the (non-fractional) scaling component from the matrix.
+
+ SkScalar invScaleX = fInvMatrix.getScaleX();
+ SkScalar invScaleY = fInvMatrix.getScaleY();
+
+ float trueDestWidth = fOrigBitmap.width() / invScaleX;
+ float trueDestHeight = fOrigBitmap.height() / invScaleY;
+
+#ifndef SK_IGNORE_PROPER_FRACTIONAL_SCALING
+ float roundedDestWidth = SkScalarRoundToScalar(trueDestWidth);
+ float roundedDestHeight = SkScalarRoundToScalar(trueDestHeight);
+#else
+ float roundedDestWidth = trueDestWidth;
+ float roundedDestHeight = trueDestHeight;
+#endif
if (SkPaint::kHigh_FilterLevel == fFilterLevel &&
fInvMatrix.getType() <= (SkMatrix::kScale_Mask | SkMatrix::kTranslate_Mask) &&
kN32_SkColorType == fOrigBitmap.colorType() &&
cache_size_okay(fOrigBitmap, fInvMatrix)) {
- SkScalar invScaleX = fInvMatrix.getScaleX();
- SkScalar invScaleY = fInvMatrix.getScaleY();
-
if (SkScalarNearlyEqual(invScaleX,1.0f) &&
SkScalarNearlyEqual(invScaleY,1.0f)) {
// short-circuit identity scaling; the output is supposed to
@@ -160,17 +173,14 @@ bool SkBitmapProcState::possiblyScaleImage() {
return false;
}
- if (!SkBitmapCache::Find(fOrigBitmap, invScaleX, invScaleY, &fScaledBitmap)) {
- float dest_width = fOrigBitmap.width() / invScaleX;
- float dest_height = fOrigBitmap.height() / invScaleY;
-
+ if (!SkBitmapCache::Find(fOrigBitmap, roundedDestWidth, roundedDestHeight, &fScaledBitmap)) {
// All the criteria are met; let's make a new bitmap.
if (!SkBitmapScaler::Resize(&fScaledBitmap,
fOrigBitmap,
SkBitmapScaler::RESIZE_BEST,
- dest_width,
- dest_height,
+ roundedDestWidth,
+ roundedDestHeight,
SkResourceCache::GetAllocator())) {
// we failed to create fScaledBitmap, so just return and let
// the scanline proc handle it.
@@ -179,7 +189,7 @@ bool SkBitmapProcState::possiblyScaleImage() {
}
SkASSERT(NULL != fScaledBitmap.getPixels());
- SkBitmapCache::Add(fOrigBitmap, invScaleX, invScaleY, fScaledBitmap);
+ SkBitmapCache::Add(fOrigBitmap, roundedDestWidth, roundedDestHeight, fScaledBitmap);
}
SkASSERT(NULL != fScaledBitmap.getPixels());
@@ -189,9 +199,19 @@ bool SkBitmapProcState::possiblyScaleImage() {
fInvMatrix.setTranslate(fInvMatrix.getTranslateX() / fInvMatrix.getScaleX(),
fInvMatrix.getTranslateY() / fInvMatrix.getScaleY());
+#ifndef SK_IGNORE_PROPER_FRACTIONAL_SCALING
+ // reintroduce any fractional scaling missed by our integral scale done above.
+
+ float fractionalScaleX = roundedDestWidth/trueDestWidth;
+ float fractionalScaleY = roundedDestHeight/trueDestHeight;
+
+ fInvMatrix.postScale(fractionalScaleX, fractionalScaleY);
+#endif
+ fAdjustedMatrix = true;
+
// Set our filter level to low -- the only post-filtering this
// image might require is some interpolation if the translation
- // is fractional.
+ // is fractional or if there's any remaining scaling to be done.
fFilterLevel = SkPaint::kLow_FilterLevel;
return true;
}
@@ -347,7 +367,7 @@ bool SkBitmapProcState::chooseProcs(const SkMatrix& inv, const SkPaint& paint) {
bool clampClamp = SkShader::kClamp_TileMode == fTileModeX &&
SkShader::kClamp_TileMode == fTileModeY;
- if (!(clampClamp || trivialMatrix)) {
+ if (!(fAdjustedMatrix || clampClamp || trivialMatrix)) {
fInvMatrix.postIDiv(fOrigBitmap.width(), fOrigBitmap.height());
}
diff --git a/src/core/SkBitmapProcState.h b/src/core/SkBitmapProcState.h
index 289e308eed..ac4f1a4710 100644
--- a/src/core/SkBitmapProcState.h
+++ b/src/core/SkBitmapProcState.h
@@ -141,6 +141,7 @@ private:
SkBitmap fScaledBitmap; // chooseProcs
SkAutoTUnref<const SkMipMap> fCurrMip;
+ bool fAdjustedMatrix; // set by possiblyScaleImage
MatrixProc chooseMatrixProc(bool trivial_matrix);
bool chooseProcs(const SkMatrix& inv, const SkPaint&);