Bug 1021564 - Invalidate filtered frames when they move in certain ways. r=roc

This commit is contained in:
Markus Stange 2014-08-30 18:22:31 +02:00
parent 6d51000320
commit 0619a8c79d
10 changed files with 286 additions and 5 deletions

View File

@ -27,6 +27,7 @@
#include "gfxMatrix.h"
#include "gfxPrefs.h"
#include "nsSVGIntegrationUtils.h"
#include "nsSVGUtils.h"
#include "nsLayoutUtils.h"
#include "nsIScrollableFrame.h"
#include "nsIFrameInlines.h"
@ -5499,6 +5500,40 @@ bool nsDisplaySVGEffects::TryMerge(nsDisplayListBuilder* aBuilder, nsDisplayItem
return true;
}
gfxRect
nsDisplaySVGEffects::BBoxInUserSpace() const
{
return nsSVGUtils::GetBBox(mFrame);
}
gfxPoint
nsDisplaySVGEffects::UserSpaceOffset() const
{
return nsSVGUtils::FrameSpaceInCSSPxToUserSpaceOffset(mFrame);
}
void
nsDisplaySVGEffects::ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder,
const nsDisplayItemGeometry* aGeometry,
nsRegion* aInvalidRegion)
{
const nsDisplaySVGEffectsGeometry* geometry =
static_cast<const nsDisplaySVGEffectsGeometry*>(aGeometry);
bool snap;
nsRect bounds = GetBounds(aBuilder, &snap);
if (geometry->mFrameOffsetToReferenceFrame != ToReferenceFrame() ||
geometry->mUserSpaceOffset != UserSpaceOffset() ||
!geometry->mBBox.IsEqualInterior(BBoxInUserSpace())) {
// Filter and mask output can depend on the location of the frame's user
// space and on the frame's BBox. We need to invalidate if either of these
// change relative to the reference frame.
// Invalidations from our inactive layer manager are not enough to catch
// some of these cases because filters can produce output even if there's
// nothing in the filter input.
aInvalidRegion->Or(bounds, geometry->mBounds);
}
}
#ifdef MOZ_DUMP_PAINTING
void
nsDisplaySVGEffects::PrintEffects(nsACString& aTo)

View File

@ -3150,13 +3150,17 @@ public:
virtual already_AddRefed<Layer> BuildLayer(nsDisplayListBuilder* aBuilder,
LayerManager* aManager,
const ContainerLayerParameters& aContainerParameters) MOZ_OVERRIDE;
gfxRect BBoxInUserSpace() const;
gfxPoint UserSpaceOffset() const;
virtual nsDisplayItemGeometry* AllocateGeometry(nsDisplayListBuilder* aBuilder) MOZ_OVERRIDE
{
return new nsDisplaySVGEffectsGeometry(this, aBuilder);
}
virtual void ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder,
const nsDisplayItemGeometry* aGeometry,
nsRegion* aInvalidRegion) MOZ_OVERRIDE
{
// We don't need to compute an invalidation region since we have LayerTreeInvalidation
}
nsRegion* aInvalidRegion) MOZ_OVERRIDE;
void PaintAsLayer(nsDisplayListBuilder* aBuilder,
nsRenderingContext* aCtx,

View File

@ -94,3 +94,17 @@ nsDisplayBoxShadowOuterGeometry::nsDisplayBoxShadowOuterGeometry(nsDisplayItem*
: nsDisplayItemGenericGeometry(aItem, aBuilder)
, mOpacity(aOpacity)
{}
nsDisplaySVGEffectsGeometry::nsDisplaySVGEffectsGeometry(nsDisplaySVGEffects* aItem, nsDisplayListBuilder* aBuilder)
: nsDisplayItemGeometry(aItem, aBuilder)
, mBBox(aItem->BBoxInUserSpace())
, mUserSpaceOffset(aItem->UserSpaceOffset())
, mFrameOffsetToReferenceFrame(aItem->ToReferenceFrame())
{}
void
nsDisplaySVGEffectsGeometry::MoveBy(const nsPoint& aOffset)
{
mBounds.MoveBy(aOffset);
mFrameOffsetToReferenceFrame += aOffset;
}

View File

@ -9,11 +9,13 @@
#include "mozilla/Attributes.h"
#include "nsRect.h"
#include "nsColor.h"
#include "gfxRect.h"
class nsDisplayItem;
class nsDisplayListBuilder;
class nsDisplayBackgroundImage;
class nsDisplayThemedBackground;
class nsDisplaySVGEffects;
/**
* This stores the geometry of an nsDisplayItem, and the area
@ -141,4 +143,16 @@ public:
nscolor mColor;
};
class nsDisplaySVGEffectsGeometry : public nsDisplayItemGeometry
{
public:
nsDisplaySVGEffectsGeometry(nsDisplaySVGEffects* aItem, nsDisplayListBuilder* aBuilder);
virtual void MoveBy(const nsPoint& aOffset) MOZ_OVERRIDE;
gfxRect mBBox;
gfxPoint mUserSpaceOffset;
nsPoint mFrameOffsetToReferenceFrame;
};
#endif /*NSDISPLAYLISTINVALIDATION_H_*/

View File

@ -0,0 +1,46 @@
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
-->
<!DOCTYPE html>
<html lang="en" class="reftest-wait">
<meta charset="utf-8">
<title>When the filtered element's BBox relative to the page changes, the filtered element needs to be invalidated</title>
<style>
#spacer {
height: 100px;
}
#filtered {
width: 100px;
height: 100px;
background-color: lime;
filter: url(#filter);
}
</style>
<svg height="0">
<defs>
<filter id="filter" filterUnits="objectBoundingBox"
x="0%" y="0%" width="100%" height="100%"
color-interpolation-filters="sRGB">
<feMerge><feMergeNode/></feMerge>
</filter>
</defs>
</svg>
<div id="spacer"></div>
<div id="filtered"></div>
<script>
window.addEventListener("MozReftestInvalidate", function () {
document.getElementById("spacer").style.height = "50px";
document.documentElement.removeAttribute("class");
});
</script>

View File

@ -0,0 +1,45 @@
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
-->
<!DOCTYPE html>
<html lang="en" class="reftest-wait">
<meta charset="utf-8">
<title>When the filtered element's BBox relative to the page changes, the filtered element needs to be invalidated</title>
<style>
#spacer {
height: 100px;
}
#filtered {
width: 100px;
height: 100px;
filter: url(#filter);
}
</style>
<svg height="0">
<defs>
<filter id="filter" filterUnits="objectBoundingBox"
x="0%" y="0%" width="100%" height="100%"
color-interpolation-filters="sRGB">
<feFlood flood-color="lime"/>
</filter>
</defs>
</svg>
<div id="spacer"></div>
<div id="filtered"></div>
<script>
window.addEventListener("MozReftestInvalidate", function () {
document.getElementById("spacer").style.height = "50px";
document.documentElement.removeAttribute("class");
});
</script>

View File

@ -0,0 +1,46 @@
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
-->
<!DOCTYPE html>
<html lang="en" class="reftest-wait">
<meta charset="utf-8">
<title>When the filtered element's BBox relative to the page changes, the filtered element needs to be invalidated</title>
<style>
#spacer {
height: 100px;
}
#filtered {
width: 100px;
height: 100px;
background-color: lime;
filter: url(#filter);
}
</style>
<svg height="0">
<defs>
<filter id="filter" filterUnits="userSpaceOnUse"
x="0" y="0" width="100" height="100"
color-interpolation-filters="sRGB">
<feMerge><feMergeNode/></feMerge>
</filter>
</defs>
</svg>
<div id="spacer"></div>
<div id="filtered"></div>
<script>
window.addEventListener("MozReftestInvalidate", function () {
document.getElementById("spacer").style.height = "50px";
document.documentElement.removeAttribute("class");
});
</script>

View File

@ -0,0 +1,45 @@
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
-->
<!DOCTYPE html>
<html lang="en" class="reftest-wait">
<meta charset="utf-8">
<title>When the filtered element's BBox relative to the page changes, the filtered element needs to be invalidated</title>
<style>
#spacer {
height: 100px;
}
#filtered {
width: 100px;
height: 100px;
filter: url(#filter);
}
</style>
<svg height="0">
<defs>
<filter id="filter" filterUnits="userSpaceOnUse"
x="0" y="0" width="100" height="100"
color-interpolation-filters="sRGB">
<feFlood flood-color="lime"/>
</filter>
</defs>
</svg>
<div id="spacer"></div>
<div id="filtered"></div>
<script>
window.addEventListener("MozReftestInvalidate", function () {
document.getElementById("spacer").style.height = "50px";
document.documentElement.removeAttribute("class");
});
</script>

View File

@ -0,0 +1,28 @@
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
-->
<!DOCTYPE html>
<html lang="en">
<meta charset="utf-8">
<title>When the filtered element's BBox relative to the page changes, the filtered element needs to be invalidated</title>
<style>
#spacer {
height: 50px;
}
#filtered {
width: 100px;
height: 100px;
background-color: lime;
}
</style>
<svg height="0"></svg>
<div id="spacer"></div>
<div id="filtered"></div>

View File

@ -1815,6 +1815,10 @@ pref(layout.css.overflow-clip-box.enabled,true) == 992447.html 992447-ref.html
pref(layout.css.sticky.enabled,true) == 1005405-1.html 1005405-1-ref.html
fuzzy-if(/^Windows\x20NT\x205\.1/.test(http.oscpu),255,1) == 1013054-1.html 1013054-1-ref.html
pref(layout.css.will-change.enabled,true) == 1018522-1.html 1018522-1-ref.html
== 1021564-1.html 1021564-ref.html
== 1021564-2.html 1021564-ref.html
== 1021564-3.html 1021564-ref.html
== 1021564-4.html 1021564-ref.html
pref(browser.display.use_document_fonts,0) == 1022481-1.html 1022481-1-ref.html
== 1022612-1.html 1022612-1-ref.html
== 1024473-1.html 1024473-1-ref.html