Bug 747274 - Add a pref (default to true on Android) to forcible use nearest pixel filtering for background drawing. r=jrmuizel,ajuma a=blassey
--- a/layout/base/nsLayoutUtils.cpp
+++ b/layout/base/nsLayoutUtils.cpp
@@ -163,16 +163,30 @@ nsLayoutUtils::Are3DTransformsEnabled()
s3DTransformPrefCached = true;
mozilla::Preferences::AddBoolVarCache(&s3DTransformsEnabled,
"layout.3d-transforms.enabled");
}
return s3DTransformsEnabled;
}
+bool
+nsLayoutUtils::UseBackgroundNearestFiltering()
+{
+ static bool sUseBackgroundNearestFilteringEnabled;
+ static bool sUseBackgroundNearestFilteringPrefInitialised = false;
+
+ if (!sUseBackgroundNearestFilteringPrefInitialised) {
+ sUseBackgroundNearestFilteringPrefInitialised = true;
+ sUseBackgroundNearestFilteringEnabled = mozilla::Preferences::GetBool("gfx.filter.nearest.force-enabled", false);
+ }
+
+ return sUseBackgroundNearestFilteringEnabled;
+}
+
void
nsLayoutUtils::UnionChildOverflow(nsIFrame* aFrame,
nsOverflowAreas& aOverflowAreas)
{
// Iterate over all children except pop-ups.
const nsIFrame::ChildListIDs skip(nsIFrame::kPopupList |
nsIFrame::kSelectPopupList);
for (nsIFrame::ChildListIterator childLists(aFrame);
@@ -3729,16 +3743,21 @@ nsLayoutUtils::DrawBackgroundImage(nsRen
GraphicsFilter aGraphicsFilter,
const nsRect& aDest,
const nsRect& aFill,
const nsPoint& aAnchor,
const nsRect& aDirty,
PRUint32 aImageFlags)
{
SAMPLE_LABEL("layout", "nsLayoutUtils::DrawBackgroundImage");
+
+ if (UseBackgroundNearestFiltering()) {
+ aGraphicsFilter = gfxPattern::FILTER_NEAREST;
+ }
+
return DrawImageInternal(aRenderingContext, aImage, aGraphicsFilter,
aDest, aFill, aAnchor, aDirty,
aImageSize, aImageFlags);
}
/* static */ nsresult
nsLayoutUtils::DrawImage(nsRenderingContext* aRenderingContext,
imgIContainer* aImage,
--- a/layout/base/nsLayoutUtils.h
+++ b/layout/base/nsLayoutUtils.h
@@ -1492,16 +1492,22 @@ public:
bool clear);
/**
* Checks if CSS 3D transforms are currently enabled.
*/
static bool Are3DTransformsEnabled();
/**
+ * Checks if we should forcibly use nearest pixel filtering for the
+ * background.
+ */
+ static bool UseBackgroundNearestFiltering();
+
+ /**
* Unions the overflow areas of all non-popup children of aFrame with
* aOverflowAreas.
*/
static void UnionChildOverflow(nsIFrame* aFrame,
nsOverflowAreas& aOverflowAreas);
/**
* Return whether this is a frame whose width is used when computing
--- a/layout/reftests/backgrounds/reftest.list
+++ b/layout/reftests/backgrounds/reftest.list
@@ -112,17 +112,18 @@ fails-if(Android) == viewport-translucen
== background-size-monster-px.html background-size-monster-ref.html
== background-size-monster-rem.html background-size-monster-ref.html
# There seems to be a pixel-snapping problem here, where the repeated background
# image isn't being snapped at its boundaries. Note that the boundaries within
# 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).
-fails == background-size-zoom-repeat.html background-size-zoom-repeat-ref.html
+# 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
# -moz-default-background-color and -moz-default-color (bug 591341)
== background-moz-default-background-color.html background-moz-default-background-color-ref.html
== fixed-bg-with-transform-outside-viewport-1.html fixed-bg-with-transform-outside-viewport-ref.html
HTTP == root-background-1.html root-background-ref.html
HTTP != root-background-1.html about:blank
--- a/layout/reftests/backgrounds/vector/reftest.list
+++ b/layout/reftests/backgrounds/vector/reftest.list
@@ -81,18 +81,19 @@ include empty/reftest.list
== tall--contain--percent-width-nonpercent-height.html ref-tall-lime256x384-aqua256x384.html
== tall--contain--percent-width-nonpercent-height-viewbox.html ref-tall-lime48x384-aqua48x384.html
== tall--contain--percent-width-omitted-height.html ref-tall-lime256x384-aqua256x384.html
== tall--contain--percent-width-omitted-height-viewbox.html ref-tall-lime48x384-aqua48x384.html
== tall--contain--percent-width-percent-height.html ref-tall-lime256x384-aqua256x384.html
== tall--contain--percent-width-percent-height-viewbox.html ref-tall-lime48x384-aqua48x384.html
# We smear the background image when scaling it in these two tests...
-fails == tall--cover--nonpercent-width-nonpercent-height.html ref-tall-lime256x512-aqua256x256.html
-fails == tall--cover--nonpercent-width-nonpercent-height-viewbox.html ref-tall-lime256x512-aqua256x256.html
+# Android uses FILTER_NEAREST for background images so the smear doesn't occur
+fails-if(!Android) == tall--cover--nonpercent-width-nonpercent-height.html ref-tall-lime256x512-aqua256x256.html
+fails-if(!Android) == tall--cover--nonpercent-width-nonpercent-height-viewbox.html ref-tall-lime256x512-aqua256x256.html
# ...but we don't in identical tests with image-rendering: -moz-crisp-edges.
== tall--cover--nonpercent-width-nonpercent-height--crisp.html ref-tall-lime256x512-aqua256x256.html
== tall--cover--nonpercent-width-nonpercent-height-viewbox--crisp.html ref-tall-lime256x512-aqua256x256.html
== tall--cover--nonpercent-width-omitted-height.html ref-tall-lime256x384-aqua256x384.html
== tall--cover--nonpercent-width-omitted-height-viewbox.html ref-tall-lime256x768.html
== tall--cover--nonpercent-width-percent-height.html ref-tall-lime256x384-aqua256x384.html
--- a/modules/libpref/src/init/all.js
+++ b/modules/libpref/src/init/all.js
@@ -207,16 +207,22 @@ pref("gfx.color_management.mode", 2);
pref("gfx.color_management.display_profile", "");
pref("gfx.color_management.rendering_intent", 0);
pref("gfx.color_management.enablev4", false);
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);
#ifdef MOZ_GRAPHITE
pref("gfx.font_rendering.graphite.enabled", false);
#endif
// see gfx/thebes/gfxUnicodeProperties.h for definitions of script bits