зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1295094 - Part 11. Implement nsDisplayFilter. r=mstange
MozReview-Commit-ID: 1V6dxJsejsi --HG-- extra : rebase_source : 713cf1375c950644cda8dafa96b7227d9ebf2c89
This commit is contained in:
Родитель
78ca020a31
Коммит
a16d0ca68b
|
@ -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
|
||||
|
|
Загрузка…
Ссылка в новой задаче