mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 950312 - Part 4: Create active layers for nsDisplayMixBlendMode and nsDisplayBlendContainer if the layer manager supports all contained blend mode. r=roc
This commit is contained in:
parent
f1253774f4
commit
41d4a92470
@ -518,7 +518,6 @@ nsDisplayListBuilder::nsDisplayListBuilder(nsIFrame* aReferenceFrame,
|
|||||||
mIsPaintingToWindow(false),
|
mIsPaintingToWindow(false),
|
||||||
mIsCompositingCheap(false),
|
mIsCompositingCheap(false),
|
||||||
mContainsPluginItem(false),
|
mContainsPluginItem(false),
|
||||||
mContainsBlendMode(false),
|
|
||||||
mAncestorHasTouchEventHandler(false),
|
mAncestorHasTouchEventHandler(false),
|
||||||
mHaveScrollableDisplayPort(false)
|
mHaveScrollableDisplayPort(false)
|
||||||
{
|
{
|
||||||
@ -553,6 +552,13 @@ static void MarkFrameForDisplay(nsIFrame* aFrame, nsIFrame* aStopAtFrame) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void nsDisplayListBuilder::SetContainsBlendMode(uint8_t aBlendMode)
|
||||||
|
{
|
||||||
|
MOZ_ASSERT(aBlendMode != NS_STYLE_BLEND_NORMAL);
|
||||||
|
gfxContext::GraphicsOperator op = nsCSSRendering::GetGFXBlendMode(aBlendMode);
|
||||||
|
mContainedBlendModes += gfx::CompositionOpForOp(op);
|
||||||
|
}
|
||||||
|
|
||||||
void nsDisplayListBuilder::MarkOutOfFlowFrameForDisplay(nsIFrame* aDirtyFrame,
|
void nsDisplayListBuilder::MarkOutOfFlowFrameForDisplay(nsIFrame* aDirtyFrame,
|
||||||
nsIFrame* aFrame,
|
nsIFrame* aFrame,
|
||||||
const nsRect& aDirtyRect)
|
const nsRect& aDirtyRect)
|
||||||
@ -3384,6 +3390,18 @@ nsRegion nsDisplayMixBlendMode::GetOpaqueRegion(nsDisplayListBuilder* aBuilder,
|
|||||||
return nsRegion();
|
return nsRegion();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LayerState
|
||||||
|
nsDisplayMixBlendMode::GetLayerState(nsDisplayListBuilder* aBuilder,
|
||||||
|
LayerManager* aManager,
|
||||||
|
const ContainerLayerParameters& aParameters)
|
||||||
|
{
|
||||||
|
gfxContext::GraphicsOperator op = nsCSSRendering::GetGFXBlendMode(mFrame->StyleDisplay()->mMixBlendMode);
|
||||||
|
if (aManager->SupportsMixBlendMode(gfx::CompositionOpForOp(op))) {
|
||||||
|
return LAYER_ACTIVE;
|
||||||
|
}
|
||||||
|
return LAYER_INACTIVE;
|
||||||
|
}
|
||||||
|
|
||||||
// nsDisplayMixBlendMode uses layers for rendering
|
// nsDisplayMixBlendMode uses layers for rendering
|
||||||
already_AddRefed<Layer>
|
already_AddRefed<Layer>
|
||||||
nsDisplayMixBlendMode::BuildLayer(nsDisplayListBuilder* aBuilder,
|
nsDisplayMixBlendMode::BuildLayer(nsDisplayListBuilder* aBuilder,
|
||||||
@ -3437,8 +3455,19 @@ bool nsDisplayMixBlendMode::TryMerge(nsDisplayListBuilder* aBuilder, nsDisplayIt
|
|||||||
|
|
||||||
nsDisplayBlendContainer::nsDisplayBlendContainer(nsDisplayListBuilder* aBuilder,
|
nsDisplayBlendContainer::nsDisplayBlendContainer(nsDisplayListBuilder* aBuilder,
|
||||||
nsIFrame* aFrame, nsDisplayList* aList,
|
nsIFrame* aFrame, nsDisplayList* aList,
|
||||||
uint32_t aFlags)
|
BlendModeSet& aContainedBlendModes)
|
||||||
: nsDisplayWrapList(aBuilder, aFrame, aList) {
|
: nsDisplayWrapList(aBuilder, aFrame, aList)
|
||||||
|
, mContainedBlendModes(aContainedBlendModes)
|
||||||
|
, mCanBeActive(true)
|
||||||
|
{
|
||||||
|
MOZ_COUNT_CTOR(nsDisplayBlendContainer);
|
||||||
|
}
|
||||||
|
|
||||||
|
nsDisplayBlendContainer::nsDisplayBlendContainer(nsDisplayListBuilder* aBuilder,
|
||||||
|
nsIFrame* aFrame, nsDisplayList* aList)
|
||||||
|
: nsDisplayWrapList(aBuilder, aFrame, aList)
|
||||||
|
, mCanBeActive(false)
|
||||||
|
{
|
||||||
MOZ_COUNT_CTOR(nsDisplayBlendContainer);
|
MOZ_COUNT_CTOR(nsDisplayBlendContainer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -45,6 +45,10 @@ class ImageContainer;
|
|||||||
} //namepsace
|
} //namepsace
|
||||||
} //namepsace
|
} //namepsace
|
||||||
|
|
||||||
|
// A set of blend modes, that never includes OP_OVER (since it's
|
||||||
|
// considered the default, rather than a specific blend mode).
|
||||||
|
typedef mozilla::EnumSet<mozilla::gfx::CompositionOp> BlendModeSet;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* An nsIFrame can have many different visual parts. For example an image frame
|
* An nsIFrame can have many different visual parts. For example an image frame
|
||||||
* can have a background, border, and outline, the image itself, and a
|
* can have a background, border, and outline, the image itself, and a
|
||||||
@ -688,8 +692,14 @@ public:
|
|||||||
* has a blend mode attached. We do this so we can insert a
|
* has a blend mode attached. We do this so we can insert a
|
||||||
* nsDisplayBlendContainer in the parent stacking context.
|
* nsDisplayBlendContainer in the parent stacking context.
|
||||||
*/
|
*/
|
||||||
void SetContainsBlendMode(bool aContainsBlendMode) { mContainsBlendMode = aContainsBlendMode; }
|
void SetContainsBlendMode(uint8_t aBlendMode);
|
||||||
bool ContainsBlendMode() const { return mContainsBlendMode; }
|
void SetContainsBlendModes(const BlendModeSet& aModes) {
|
||||||
|
mContainedBlendModes = aModes;
|
||||||
|
}
|
||||||
|
bool ContainsBlendMode() const { return !mContainedBlendModes.isEmpty(); }
|
||||||
|
BlendModeSet& ContainedBlendModes() {
|
||||||
|
return mContainedBlendModes;
|
||||||
|
}
|
||||||
|
|
||||||
DisplayListClipState& ClipState() { return mClipState; }
|
DisplayListClipState& ClipState() { return mClipState; }
|
||||||
|
|
||||||
@ -731,6 +741,7 @@ private:
|
|||||||
nsTArray<DisplayItemClip*> mDisplayItemClipsToDestroy;
|
nsTArray<DisplayItemClip*> mDisplayItemClipsToDestroy;
|
||||||
Mode mMode;
|
Mode mMode;
|
||||||
ViewID mCurrentScrollParentId;
|
ViewID mCurrentScrollParentId;
|
||||||
|
BlendModeSet mContainedBlendModes;
|
||||||
bool mBuildCaret;
|
bool mBuildCaret;
|
||||||
bool mIgnoreSuppression;
|
bool mIgnoreSuppression;
|
||||||
bool mHadToIgnoreSuppression;
|
bool mHadToIgnoreSuppression;
|
||||||
@ -749,7 +760,6 @@ private:
|
|||||||
bool mIsPaintingToWindow;
|
bool mIsPaintingToWindow;
|
||||||
bool mIsCompositingCheap;
|
bool mIsCompositingCheap;
|
||||||
bool mContainsPluginItem;
|
bool mContainsPluginItem;
|
||||||
bool mContainsBlendMode;
|
|
||||||
bool mAncestorHasTouchEventHandler;
|
bool mAncestorHasTouchEventHandler;
|
||||||
// True when the first async-scrollable scroll frame for which we build a
|
// True when the first async-scrollable scroll frame for which we build a
|
||||||
// display list has a display port. An async-scrollable scroll frame is one
|
// display list has a display port. An async-scrollable scroll frame is one
|
||||||
@ -2730,10 +2740,7 @@ public:
|
|||||||
}
|
}
|
||||||
virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder,
|
virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder,
|
||||||
LayerManager* aManager,
|
LayerManager* aManager,
|
||||||
const ContainerLayerParameters& aParameters) MOZ_OVERRIDE
|
const ContainerLayerParameters& aParameters) MOZ_OVERRIDE;
|
||||||
{
|
|
||||||
return mozilla::LAYER_INACTIVE;
|
|
||||||
}
|
|
||||||
virtual bool ComputeVisibility(nsDisplayListBuilder* aBuilder,
|
virtual bool ComputeVisibility(nsDisplayListBuilder* aBuilder,
|
||||||
nsRegion* aVisibleRegion,
|
nsRegion* aVisibleRegion,
|
||||||
const nsRect& aAllowVisibleRegionExpansion) MOZ_OVERRIDE;
|
const nsRect& aAllowVisibleRegionExpansion) MOZ_OVERRIDE;
|
||||||
@ -2744,7 +2751,10 @@ public:
|
|||||||
class nsDisplayBlendContainer : public nsDisplayWrapList {
|
class nsDisplayBlendContainer : public nsDisplayWrapList {
|
||||||
public:
|
public:
|
||||||
nsDisplayBlendContainer(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
|
nsDisplayBlendContainer(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
|
||||||
nsDisplayList* aList, uint32_t aFlags = 0);
|
nsDisplayList* aList,
|
||||||
|
BlendModeSet& aContainedBlendModes);
|
||||||
|
nsDisplayBlendContainer(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
|
||||||
|
nsDisplayList* aList);
|
||||||
#ifdef NS_BUILD_REFCNT_LOGGING
|
#ifdef NS_BUILD_REFCNT_LOGGING
|
||||||
virtual ~nsDisplayBlendContainer();
|
virtual ~nsDisplayBlendContainer();
|
||||||
#endif
|
#endif
|
||||||
@ -2756,10 +2766,20 @@ public:
|
|||||||
LayerManager* aManager,
|
LayerManager* aManager,
|
||||||
const ContainerLayerParameters& aParameters) MOZ_OVERRIDE
|
const ContainerLayerParameters& aParameters) MOZ_OVERRIDE
|
||||||
{
|
{
|
||||||
|
if (mCanBeActive && aManager->SupportsMixBlendModes(mContainedBlendModes)) {
|
||||||
|
return mozilla::LAYER_ACTIVE;
|
||||||
|
}
|
||||||
return mozilla::LAYER_INACTIVE;
|
return mozilla::LAYER_INACTIVE;
|
||||||
}
|
}
|
||||||
virtual bool TryMerge(nsDisplayListBuilder* aBuilder, nsDisplayItem* aItem) MOZ_OVERRIDE;
|
virtual bool TryMerge(nsDisplayListBuilder* aBuilder, nsDisplayItem* aItem) MOZ_OVERRIDE;
|
||||||
NS_DISPLAY_DECL_NAME("BlendContainer", TYPE_BLEND_CONTAINER)
|
NS_DISPLAY_DECL_NAME("BlendContainer", TYPE_BLEND_CONTAINER)
|
||||||
|
|
||||||
|
private:
|
||||||
|
// The set of all blend modes used by nsDisplayMixBlendMode descendents of this container.
|
||||||
|
BlendModeSet mContainedBlendModes;
|
||||||
|
// If this is true, then we should make the layer active if all contained blend
|
||||||
|
// modes can be supported by the current layer manager.
|
||||||
|
bool mCanBeActive;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1868,15 +1868,15 @@ WrapPreserve3DList(nsIFrame* aFrame, nsDisplayListBuilder* aBuilder, nsDisplayLi
|
|||||||
class AutoSaveRestoreBlendMode
|
class AutoSaveRestoreBlendMode
|
||||||
{
|
{
|
||||||
nsDisplayListBuilder& mBuilder;
|
nsDisplayListBuilder& mBuilder;
|
||||||
bool AutoResetContainsBlendMode;
|
EnumSet<gfx::CompositionOp> mSavedBlendModes;
|
||||||
public:
|
public:
|
||||||
AutoSaveRestoreBlendMode(nsDisplayListBuilder& aBuilder)
|
AutoSaveRestoreBlendMode(nsDisplayListBuilder& aBuilder)
|
||||||
: mBuilder(aBuilder),
|
: mBuilder(aBuilder)
|
||||||
AutoResetContainsBlendMode(aBuilder.ContainsBlendMode()) {
|
, mSavedBlendModes(aBuilder.ContainedBlendModes())
|
||||||
}
|
{ }
|
||||||
|
|
||||||
~AutoSaveRestoreBlendMode() {
|
~AutoSaveRestoreBlendMode() {
|
||||||
mBuilder.SetContainsBlendMode(AutoResetContainsBlendMode);
|
mBuilder.SetContainsBlendModes(mSavedBlendModes);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1929,7 +1929,7 @@ nsIFrame::BuildDisplayListForStackingContext(nsDisplayListBuilder* aBuilder,
|
|||||||
// a nsDisplayBlendContainer. Set the blend mode back when the routine exits
|
// a nsDisplayBlendContainer. Set the blend mode back when the routine exits
|
||||||
// so we keep track if the parent stacking context needs a container too.
|
// so we keep track if the parent stacking context needs a container too.
|
||||||
AutoSaveRestoreBlendMode autoRestoreBlendMode(*aBuilder);
|
AutoSaveRestoreBlendMode autoRestoreBlendMode(*aBuilder);
|
||||||
aBuilder->SetContainsBlendMode(false);
|
aBuilder->SetContainsBlendModes(BlendModeSet());
|
||||||
|
|
||||||
if (isTransformed) {
|
if (isTransformed) {
|
||||||
const nsRect overflow = GetVisualOverflowRectRelativeToSelf();
|
const nsRect overflow = GetVisualOverflowRectRelativeToSelf();
|
||||||
@ -2129,7 +2129,7 @@ nsIFrame::BuildDisplayListForStackingContext(nsDisplayListBuilder* aBuilder,
|
|||||||
|
|
||||||
if (aBuilder->ContainsBlendMode()) {
|
if (aBuilder->ContainsBlendMode()) {
|
||||||
resultList.AppendNewToTop(
|
resultList.AppendNewToTop(
|
||||||
new (aBuilder) nsDisplayBlendContainer(aBuilder, this, &resultList));
|
new (aBuilder) nsDisplayBlendContainer(aBuilder, this, &resultList, aBuilder->ContainedBlendModes()));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If there's blending, wrap up the list in a blend-mode item. Note
|
/* If there's blending, wrap up the list in a blend-mode item. Note
|
||||||
@ -2343,7 +2343,7 @@ nsIFrame::BuildDisplayListForChild(nsDisplayListBuilder* aBuilder,
|
|||||||
nsDisplayList extraPositionedDescendants;
|
nsDisplayList extraPositionedDescendants;
|
||||||
if (isStackingContext) {
|
if (isStackingContext) {
|
||||||
if (disp->mMixBlendMode != NS_STYLE_BLEND_NORMAL) {
|
if (disp->mMixBlendMode != NS_STYLE_BLEND_NORMAL) {
|
||||||
aBuilder->SetContainsBlendMode(true);
|
aBuilder->SetContainsBlendMode(disp->mMixBlendMode);
|
||||||
}
|
}
|
||||||
// True stacking context.
|
// True stacking context.
|
||||||
// For stacking contexts, BuildDisplayListForStackingContext handles
|
// For stacking contexts, BuildDisplayListForStackingContext handles
|
||||||
|
@ -162,6 +162,10 @@ class EnumSet
|
|||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool isEmpty() const {
|
||||||
|
return mBitField == 0;
|
||||||
|
}
|
||||||
|
|
||||||
uint32_t serialize() const {
|
uint32_t serialize() const {
|
||||||
return mBitField;
|
return mBitField;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user