зеркало из https://github.com/mozilla/pjs.git
Bug 750598. Add some heuristics to catch cases when we can use nearest filtering. r=roc
These may need some tuning to get right, but should be an improvement over just disabling bilinear for backgrounds. It also expectedly regresses tcheckerboard & tcheck2 because we're now using bilinear when we were using nearest before.
This commit is contained in:
Родитель
17949dcad6
Коммит
09426b763a
|
@ -414,6 +414,73 @@ DeviceToImageTransform(gfxContext* aContext,
|
|||
return gfxMatrix(deviceToUser).Multiply(aUserSpaceToImageSpace);
|
||||
}
|
||||
|
||||
/* These heuristics are based on Source/WebCore/platform/graphics/skia/ImageSkia.cpp:computeResamplingMode() */
|
||||
#ifdef MOZ_GFX_OPTIMIZE_MOBILE
|
||||
static gfxPattern::GraphicsFilter ReduceResamplingFilter(gfxPattern::GraphicsFilter aFilter,
|
||||
int aImgWidth, int aImgHeight,
|
||||
float aSourceWidth, float aSourceHeight)
|
||||
{
|
||||
// Images smaller than this in either direction are considered "small" and
|
||||
// are not resampled ever (see below).
|
||||
const int kSmallImageSizeThreshold = 8;
|
||||
|
||||
// The amount an image can be stretched in a single direction before we
|
||||
// say that it is being stretched so much that it must be a line or
|
||||
// background that doesn't need resampling.
|
||||
const float kLargeStretch = 3.0f;
|
||||
|
||||
if (aImgWidth <= kSmallImageSizeThreshold
|
||||
|| aImgHeight <= kSmallImageSizeThreshold) {
|
||||
// Never resample small images. These are often used for borders and
|
||||
// rules (think 1x1 images used to make lines).
|
||||
return gfxPattern::FILTER_NEAREST;
|
||||
}
|
||||
|
||||
if (aImgHeight * kLargeStretch <= aSourceHeight || aImgWidth * kLargeStretch <= aSourceWidth) {
|
||||
// Large image tiling detected.
|
||||
|
||||
// Don't resample if it is being tiled a lot in only one direction.
|
||||
// This is trying to catch cases where somebody has created a border
|
||||
// (which might be large) and then is stretching it to fill some part
|
||||
// of the page.
|
||||
if (fabs(aSourceWidth - aImgWidth)/aImgWidth < 0.5 || fabs(aSourceHeight - aImgHeight)/aImgHeight < 0.5)
|
||||
return gfxPattern::FILTER_NEAREST;
|
||||
|
||||
// The image is growing a lot and in more than one direction. Resampling
|
||||
// is slow and doesn't give us very much when growing a lot.
|
||||
return aFilter;
|
||||
}
|
||||
|
||||
/* Some notes on other heuristics:
|
||||
The Skia backend also uses nearest for backgrounds that are stretched by
|
||||
a large amount. I'm not sure this is common enough for us to worry about
|
||||
now. It also uses nearest for backgrounds/avoids high quality for images
|
||||
that are very slightly scaled. I'm also not sure that very slightly
|
||||
scaled backgrounds are common enough us to worry about.
|
||||
|
||||
We don't currently have much support for doing high quality interpolation.
|
||||
The only place this currently happens is on Quartz and we don't have as
|
||||
much control over it as would be needed. Webkit avoids using high quality
|
||||
resampling during load. It also avoids high quality if the transformation
|
||||
is not just a scale and translation
|
||||
|
||||
WebKit bug #40045 added code to avoid resampling different parts
|
||||
of an image with different methods by using a resampling hint size.
|
||||
It currently looks unused in WebKit but it's something to watch out for.
|
||||
*/
|
||||
|
||||
return aFilter;
|
||||
}
|
||||
#else
|
||||
static gfxPattern::GraphicsFilter ReduceResamplingFilter(gfxPattern::GraphicsFilter aFilter,
|
||||
int aImgWidth, int aImgHeight,
|
||||
int aSourceWidth, int aSourceHeight)
|
||||
{
|
||||
// Just pass the filter through unchanged
|
||||
return aFilter;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* static */ void
|
||||
gfxUtils::DrawPixelSnapped(gfxContext* aContext,
|
||||
gfxDrawable* aDrawable,
|
||||
|
@ -423,7 +490,7 @@ gfxUtils::DrawPixelSnapped(gfxContext* aContext,
|
|||
const gfxRect& aImageRect,
|
||||
const gfxRect& aFill,
|
||||
const gfxImageSurface::gfxImageFormat aFormat,
|
||||
const gfxPattern::GraphicsFilter& aFilter,
|
||||
gfxPattern::GraphicsFilter aFilter,
|
||||
PRUint32 aImageFlags)
|
||||
{
|
||||
SAMPLE_LABEL("gfxUtils", "DrawPixelSnapped");
|
||||
|
@ -441,6 +508,8 @@ gfxUtils::DrawPixelSnapped(gfxContext* aContext,
|
|||
|
||||
nsRefPtr<gfxDrawable> drawable = aDrawable;
|
||||
|
||||
aFilter = ReduceResamplingFilter(aFilter, aImageRect.Width(), aImageRect.Height(), aSourceRect.Width(), aSourceRect.Height());
|
||||
|
||||
// OK now, the hard part left is to account for the subimage sampling
|
||||
// restriction. If all the transforms involved are just integer
|
||||
// translations, then we assume no resampling will occur so there's
|
||||
|
|
|
@ -90,7 +90,7 @@ public:
|
|||
const gfxRect& aImageRect,
|
||||
const gfxRect& aFill,
|
||||
const gfxImageSurface::gfxImageFormat aFormat,
|
||||
const gfxPattern::GraphicsFilter& aFilter,
|
||||
gfxPattern::GraphicsFilter aFilter,
|
||||
PRUint32 aImageFlags = imgIContainer::FLAG_NONE);
|
||||
|
||||
/**
|
||||
|
|
|
@ -117,8 +117,7 @@ fails-if(Android) == viewport-translucent-color-3.html viewport-translucent-colo
|
|||
# the image aren't the issue, because they're being obscured to avoid sampling
|
||||
# algorithm dependencies (at least assuming the sampling algorithm in use
|
||||
# doesn't sample too far astray from the boundaries).
|
||||
# Android uses FILTER_NEAREST which doesn't suffer from this issue.
|
||||
fails-if(!Android) == background-size-zoom-repeat.html background-size-zoom-repeat-ref.html
|
||||
fails == background-size-zoom-repeat.html background-size-zoom-repeat-ref.html
|
||||
|
||||
# -moz-default-background-color and -moz-default-color (bug 591341)
|
||||
== background-moz-default-background-color.html background-moz-default-background-color-ref.html
|
||||
|
|
|
@ -215,11 +215,7 @@ pref("gfx.downloadable_fonts.enabled", true);
|
|||
pref("gfx.downloadable_fonts.fallback_delay", 3000);
|
||||
pref("gfx.downloadable_fonts.sanitize", true);
|
||||
|
||||
#ifdef ANDROID
|
||||
pref("gfx.filter.nearest.force-enabled", true);
|
||||
#else
|
||||
pref("gfx.filter.nearest.force-enabled", false);
|
||||
#endif
|
||||
|
||||
// whether to always search all font cmaps during system font fallback
|
||||
pref("gfx.font_rendering.fallback.always_use_cmaps", false);
|
||||
|
|
Загрузка…
Ссылка в новой задаче