Bug 1263829 - Part 2: Don't apply opacity in PaintFramesWithEffects if we created an nsDisplayOpacity. r=jwatt

This commit is contained in:
Matt Woodrow 2016-06-08 17:12:35 +12:00
Родитель 2cdd2a5840
Коммит 565f5ee9a1
5 изменённых файлов: 24 добавлений и 10 удалений

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

@ -6572,9 +6572,11 @@ nsCharClipDisplayItem::ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder,
}
nsDisplaySVGEffects::nsDisplaySVGEffects(nsDisplayListBuilder* aBuilder,
nsIFrame* aFrame, nsDisplayList* aList)
: nsDisplayWrapList(aBuilder, aFrame, aList),
mEffectsBounds(aFrame->GetVisualOverflowRectRelativeToSelf())
nsIFrame* aFrame, nsDisplayList* aList,
bool aOpacityItemCreated)
: nsDisplayWrapList(aBuilder, aFrame, aList)
, mEffectsBounds(aFrame->GetVisualOverflowRectRelativeToSelf())
, mOpacityItemCreated(aOpacityItemCreated)
{
MOZ_COUNT_CTOR(nsDisplaySVGEffects);
}
@ -6638,7 +6640,7 @@ nsDisplaySVGEffects::PaintAsLayer(nsDisplayListBuilder* aBuilder,
nsSVGIntegrationUtils::PaintFramesParams params(*aCtx->ThebesContext(),
mFrame, mVisibleRect,
borderArea, aBuilder,
aManager);
aManager, mOpacityItemCreated);
nsSVGIntegrationUtils::PaintFramesWithEffects(params);
}

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

@ -3788,7 +3788,7 @@ private:
class nsDisplaySVGEffects : public nsDisplayWrapList {
public:
nsDisplaySVGEffects(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
nsDisplayList* aList);
nsDisplayList* aList, bool aOpacityItemCreated);
#ifdef NS_BUILD_REFCNT_LOGGING
virtual ~nsDisplaySVGEffects();
#endif
@ -3842,6 +3842,9 @@ public:
private:
// relative to mFrame
nsRect mEffectsBounds;
// True if the caller also created an nsDisplayOpacity item, and we should tell
// PaintFramesWithEffects that it doesn't need to handle opacity itself.
bool mOpacityItemCreated;
};
/* A display item that applies a transformation to all of its descendant

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

@ -2285,7 +2285,11 @@ nsIFrame::BuildDisplayListForStackingContext(nsDisplayListBuilder* aBuilder,
aBuilder->EnterSVGEffectsContents(&hoistedScrollInfoItemsStorage);
}
bool useOpacity = HasVisualOpacity() && !nsSVGUtils::CanOptimizeOpacity(this) && !usingSVGEffects;
// We build an opacity item if it's not going to be drawn by SVG content, or SVG effects.
// SVG effects won't handle the opacity if we want an active layer (for async animations),
// see nsSVGIntegrationsUtils::PaintFramesWithEffects.
bool useOpacity = HasVisualOpacity() && !nsSVGUtils::CanOptimizeOpacity(this) &&
(!usingSVGEffects || nsDisplayOpacity::NeedsActiveLayer(aBuilder, this));
bool useBlendMode = effects->mMixBlendMode != NS_STYLE_BLEND_NORMAL;
bool useStickyPosition = disp->mPosition == NS_STYLE_POSITION_STICKY &&
IsScrollFrameActive(aBuilder,
@ -2456,7 +2460,7 @@ nsIFrame::BuildDisplayListForStackingContext(nsDisplayListBuilder* aBuilder,
buildingDisplayList.SetDirtyRect(dirtyRectOutsideSVGEffects);
/* List now emptied, so add the new list to the top. */
resultList.AppendNewToTop(
new (aBuilder) nsDisplaySVGEffects(aBuilder, this, &resultList));
new (aBuilder) nsDisplaySVGEffects(aBuilder, this, &resultList, useOpacity));
// Also add the hoisted scroll info items. We need those for APZ scrolling
// because nsDisplaySVGEffects items can't build active layers.
aBuilder->ExitSVGEffectsContents();

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

@ -564,9 +564,12 @@ nsSVGIntegrationUtils::PaintFramesWithEffects(const PaintFramesParams& aParams)
return;
}
if (opacity != 1.0f &&
hasSVGLayout && nsSVGUtils::CanOptimizeOpacity(frame)) {
(nsSVGUtils::CanOptimizeOpacity(frame) ||
aParams.callerPaintsOpacity)) {
opacity = 1.0f;
}
MOZ_ASSERT(!nsSVGUtils::CanOptimizeOpacity(frame) || !aParams.callerPaintsOpacity,
"How can we be optimizing the opacity into the svg as well as having the caller paint it?");
/* Properties are added lazily and may have been removed by a restyle,
so make sure all applicable ones are set again. */

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

@ -130,14 +130,16 @@ public:
const nsRect& borderArea;
nsDisplayListBuilder* builder;
mozilla::layers::LayerManager* layerManager;
bool callerPaintsOpacity;
explicit PaintFramesParams(gfxContext& aCtx, nsIFrame* aFrame,
const nsRect& aDirtyRect,
const nsRect& aBorderArea,
nsDisplayListBuilder* aBuilder,
mozilla::layers::LayerManager* aLayerManager)
mozilla::layers::LayerManager* aLayerManager,
bool aCallerPaintsOpacity)
: ctx(aCtx), frame(aFrame), dirtyRect(aDirtyRect),
borderArea(aBorderArea), builder(aBuilder),
layerManager(aLayerManager)
layerManager(aLayerManager), callerPaintsOpacity(aCallerPaintsOpacity)
{ }
};