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
This commit is contained in:
parent
0209e95cc2
commit
d73c169637
@ -41,3 +41,20 @@ matrixconvolution
|
||||
|
||||
# Added as part of https://codereview.chromium.org/466363009/
|
||||
fontcache
|
||||
|
||||
#humper: https://codereview.chromium.org/470233002/
|
||||
downsamplebitmap_checkerboard_high_512_256
|
||||
downsamplebitmap_image_high_mandrill_512.png
|
||||
downsamplebitmap_text_high_72.00pt
|
||||
filterbitmap_checkerboard_192_192
|
||||
filterbitmap_checkerboard_32_2
|
||||
filterbitmap_checkerboard_32_32
|
||||
filterbitmap_checkerboard_32_8
|
||||
filterbitmap_checkerboard_4_4
|
||||
filterbitmap_image_mandrill_128.png
|
||||
filterbitmap_image_mandrill_16.png
|
||||
filterbitmap_image_mandrill_256.png
|
||||
filterbitmap_image_mandrill_32.png
|
||||
filterbitmap_image_mandrill_64.png
|
||||
filterbitmap_text_3.00pt
|
||||
filterbitmap_text_7.00pt
|
||||
|
@ -41,10 +41,7 @@ public:
|
||||
|
||||
protected:
|
||||
virtual uint32_t onGetFlags() const SK_OVERRIDE {
|
||||
if (SkPaint::kHigh_FilterLevel != fFilterLevel) {
|
||||
return kSkipTiled_Flag;
|
||||
}
|
||||
return 0;
|
||||
return kSkipTiled_Flag;
|
||||
}
|
||||
|
||||
virtual SkString onShortName() SK_OVERRIDE {
|
||||
|
@ -13,6 +13,7 @@
|
||||
# If these become 'permanent', they should be moved into skia_common.gypi
|
||||
#
|
||||
'skia_for_chromium_defines': [
|
||||
'SK_IGNORE_PROPER_FRACTIONAL_SCALING',
|
||||
'SK_SUPPORT_LEGACY_PICTURE_CLONE',
|
||||
'SK_SUPPORT_LEGACY_GETDEVICE',
|
||||
'SK_IGNORE_ETC1_SUPPORT',
|
||||
|
@ -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());
|
||||
}
|
||||
|
||||
|
@ -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&);
|
||||
|
@ -17,7 +17,9 @@ static bool is_in_scaled_image_cache(const SkBitmap& orig,
|
||||
SkScalar xScale,
|
||||
SkScalar yScale) {
|
||||
SkBitmap scaled;
|
||||
return SkBitmapCache::Find(orig, SkScalarInvert(xScale), SkScalarInvert(yScale), &scaled);
|
||||
float roundedImageWidth = SkScalarRoundToScalar(orig.width() * xScale);
|
||||
float roundedImageHeight = SkScalarRoundToScalar(orig.height() * xScale);
|
||||
return SkBitmapCache::Find(orig, roundedImageWidth, roundedImageHeight, &scaled);
|
||||
}
|
||||
|
||||
// Draw a scaled bitmap, then return true iff it has been cached.
|
||||
|
Loading…
Reference in New Issue
Block a user