Bug 1295094 - Part 11. Implement nsDisplayFilter. r=mstange

MozReview-Commit-ID: 1V6dxJsejsi

--HG--
extra : rebase_source : 713cf1375c950644cda8dafa96b7227d9ebf2c89
This commit is contained in:
cku 2016-08-16 15:23:33 +08:00
Родитель 78ca020a31
Коммит a16d0ca68b
4 изменённых файлов: 185 добавлений и 19 удалений

Просмотреть файл

@ -52,6 +52,7 @@ DECLARE_DISPLAY_ITEM_TYPE(SELECTION_OVERLAY)
DECLARE_DISPLAY_ITEM_TYPE(SOLID_COLOR)
DECLARE_DISPLAY_ITEM_TYPE(SUBDOCUMENT)
DECLARE_DISPLAY_ITEM_TYPE(MASK)
DECLARE_DISPLAY_ITEM_TYPE(FILTER)
DECLARE_DISPLAY_ITEM_TYPE(SVG_GLYPHS)
DECLARE_DISPLAY_ITEM_TYPE(SVG_OUTER_SVG)
DECLARE_DISPLAY_ITEM_TYPE(SVG_PATH_GEOMETRY)

Просмотреть файл

@ -6677,22 +6677,6 @@ nsDisplaySVGEffects::HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect
}
}
bool nsDisplaySVGEffects::ComputeVisibility(nsDisplayListBuilder* aBuilder,
nsRegion* aVisibleRegion) {
nsPoint offset = ToReferenceFrame();
nsRect dirtyRect =
nsSVGIntegrationUtils::GetRequiredSourceForInvalidArea(mFrame,
mVisibleRect - offset) +
offset;
// Our children may be made translucent or arbitrarily deformed so we should
// not allow them to subtract area from aVisibleRegion.
nsRegion childrenVisible(dirtyRect);
nsRect r = dirtyRect.Intersect(mList.GetBounds(aBuilder));
mList.ComputeVisibilityForSublist(aBuilder, &childrenVisible, r);
return true;
}
gfxRect
nsDisplaySVGEffects::BBoxInUserSpace() const
{
@ -6826,6 +6810,16 @@ nsDisplayMask::GetLayerState(nsDisplayListBuilder* aBuilder,
return LAYER_SVG_EFFECTS;
}
bool nsDisplayMask::ComputeVisibility(nsDisplayListBuilder* aBuilder,
nsRegion* aVisibleRegion) {
// Our children may be made translucent or arbitrarily deformed so we should
// not allow them to subtract area from aVisibleRegion.
nsRegion childrenVisible(mVisibleRect);
nsRect r = mVisibleRect.Intersect(mList.GetBounds(aBuilder));
mList.ComputeVisibilityForSublist(aBuilder, &childrenVisible, r);
return true;
}
void
nsDisplayMask::PaintAsLayer(nsDisplayListBuilder* aBuilder,
nsRenderingContext* aCtx,
@ -6885,3 +6879,140 @@ nsDisplayMask::PrintEffects(nsACString& aTo)
}
#endif
nsDisplayFilter::nsDisplayFilter(nsDisplayListBuilder* aBuilder,
nsIFrame* aFrame, nsDisplayList* aList,
bool aOpacityItemCreated)
: nsDisplaySVGEffects(aBuilder, aFrame, aList, aOpacityItemCreated)
{
MOZ_COUNT_CTOR(nsDisplayFilter);
}
#ifdef NS_BUILD_REFCNT_LOGGING
nsDisplayFilter::~nsDisplayFilter()
{
MOZ_COUNT_DTOR(nsDisplayFilter);
}
#endif
already_AddRefed<Layer>
nsDisplayFilter::BuildLayer(nsDisplayListBuilder* aBuilder,
LayerManager* aManager,
const ContainerLayerParameters& aContainerParameters)
{
if (!ValidateSVGFrame()) {
return nullptr;
}
if (mFrame->StyleEffects()->mOpacity == 0.0f && !mOpacityItemCreated) {
return nullptr;
}
nsIFrame* firstFrame =
nsLayoutUtils::FirstContinuationOrIBSplitSibling(mFrame);
nsSVGEffects::EffectProperties effectProperties =
nsSVGEffects::GetEffectProperties(firstFrame);
ContainerLayerParameters newContainerParameters = aContainerParameters;
if (effectProperties.HasValidFilter()) {
newContainerParameters.mDisableSubpixelAntialiasingInDescendants = true;
}
RefPtr<ContainerLayer> container = aManager->GetLayerBuilder()->
BuildContainerLayerFor(aBuilder, aManager, mFrame, this, &mList,
newContainerParameters, nullptr);
return container.forget();
}
bool nsDisplayFilter::TryMerge(nsDisplayItem* aItem)
{
if (aItem->GetType() != TYPE_FILTER) {
return false;
}
// items for the same content element should be merged into a single
// compositing group.
// aItem->Frame() returns non-null because it's nsDisplayFilter
if (aItem->Frame()->GetContent() != mFrame->GetContent()) {
return false;
}
if (aItem->GetClip() != GetClip()) {
return false;
}
if (aItem->ScrollClip() != ScrollClip()) {
return false;
}
nsDisplayFilter* other = static_cast<nsDisplayFilter*>(aItem);
MergeFromTrackingMergedFrames(other);
mEffectsBounds.UnionRect(mEffectsBounds,
other->mEffectsBounds + other->mFrame->GetOffsetTo(mFrame));
return true;
}
LayerState
nsDisplayFilter::GetLayerState(nsDisplayListBuilder* aBuilder,
LayerManager* aManager,
const ContainerLayerParameters& aParameters)
{
return LAYER_SVG_EFFECTS;
}
bool nsDisplayFilter::ComputeVisibility(nsDisplayListBuilder* aBuilder,
nsRegion* aVisibleRegion) {
nsPoint offset = ToReferenceFrame();
nsRect dirtyRect =
nsSVGIntegrationUtils::GetRequiredSourceForInvalidArea(mFrame,
mVisibleRect - offset) +
offset;
// Our children may be made translucent or arbitrarily deformed so we should
// not allow them to subtract area from aVisibleRegion.
nsRegion childrenVisible(dirtyRect);
nsRect r = dirtyRect.Intersect(mList.GetBounds(aBuilder));
mList.ComputeVisibilityForSublist(aBuilder, &childrenVisible, r);
return true;
}
void
nsDisplayFilter::PaintAsLayer(nsDisplayListBuilder* aBuilder,
nsRenderingContext* aCtx,
LayerManager* aManager)
{
nsRect borderArea = nsRect(ToReferenceFrame(), mFrame->GetSize());
nsSVGIntegrationUtils::PaintFramesParams params(*aCtx->ThebesContext(),
mFrame, mVisibleRect,
borderArea, aBuilder,
aManager, mOpacityItemCreated);
image::DrawResult result =
nsSVGIntegrationUtils::PaintFilter(params);
nsDisplaySVGEffectsGeometry::UpdateDrawResult(this, result);
}
#ifdef MOZ_DUMP_PAINTING
void
nsDisplayFilter::PrintEffects(nsACString& aTo)
{
nsIFrame* firstFrame =
nsLayoutUtils::FirstContinuationOrIBSplitSibling(mFrame);
nsSVGEffects::EffectProperties effectProperties =
nsSVGEffects::GetEffectProperties(firstFrame);
bool first = true;
aTo += " effects=(";
if (mFrame->StyleEffects()->mOpacity != 1.0f) {
first = false;
aTo += nsPrintfCString("opacity(%f)", mFrame->StyleEffects()->mOpacity);
}
if (effectProperties.HasValidFilter()) {
if (!first) {
aTo += ", ";
}
aTo += "filter";
first = false;
}
aTo += ")";
}
#endif

Просмотреть файл

@ -3801,8 +3801,6 @@ public:
return mEffectsBounds + ToReferenceFrame();
}
virtual bool ComputeVisibility(nsDisplayListBuilder* aBuilder,
nsRegion* aVisibleRegion) override;
virtual bool ShouldFlattenAway(nsDisplayListBuilder* aBuilder) override {
return false;
}
@ -3817,7 +3815,6 @@ public:
virtual void ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder,
const nsDisplayItemGeometry* aGeometry,
nsRegion* aInvalidRegion) override;
protected:
bool ValidateSVGFrame();
@ -3850,6 +3847,37 @@ public:
LayerManager* aManager,
const ContainerLayerParameters& aParameters) override;
virtual bool ComputeVisibility(nsDisplayListBuilder* aBuilder,
nsRegion* aVisibleRegion) override;
#ifdef MOZ_DUMP_PAINTING
void PrintEffects(nsACString& aTo);
#endif
void PaintAsLayer(nsDisplayListBuilder* aBuilder,
nsRenderingContext* aCtx,
LayerManager* aManager);
};
class nsDisplayFilter : public nsDisplaySVGEffects {
public:
nsDisplayFilter(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
nsDisplayList* aList, bool aOpacityItemCreated);
#ifdef NS_BUILD_REFCNT_LOGGING
virtual ~nsDisplayFilter();
#endif
NS_DISPLAY_DECL_NAME("Filter", TYPE_FILTER)
virtual bool TryMerge(nsDisplayItem* aItem) override;
virtual already_AddRefed<Layer> BuildLayer(nsDisplayListBuilder* aBuilder,
LayerManager* aManager,
const ContainerLayerParameters& aContainerParameters) override;
virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder,
LayerManager* aManager,
const ContainerLayerParameters& aParameters) override;
virtual bool ComputeVisibility(nsDisplayListBuilder* aBuilder,
nsRegion* aVisibleRegion) override;
#ifdef MOZ_DUMP_PAINTING
void PrintEffects(nsACString& aTo);
#endif

Просмотреть файл

@ -201,6 +201,12 @@ PrintDisplayItemTo(nsDisplayListBuilder* aBuilder, nsDisplayItem* aItem,
(static_cast<nsDisplayMask*>(aItem))->PrintEffects(str);
aStream << str.get();
}
if (aItem->GetType() == nsDisplayItem::TYPE_FILTER) {
nsCString str;
(static_cast<nsDisplayFilter*>(aItem))->PrintEffects(str);
aStream << str.get();
}
#endif
aStream << "\n";
#ifdef MOZ_DUMP_PAINTING