Skip to content

Commit

Permalink
Bug 1442190 - Part 3: Add functionality to know whether nsDisplayOpac…
Browse files Browse the repository at this point in the history
…ity::ShouldFlattenAway() applied opacity to children r=mattwoodrow

MozReview-Commit-ID: Bns788u5wmM
  • Loading branch information
mikokm committed Mar 21, 2018
1 parent c0408f6 commit 1e4cbce
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 21 deletions.
51 changes: 31 additions & 20 deletions layout/painting/nsDisplayList.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6409,6 +6409,7 @@ nsDisplayOpacity::nsDisplayOpacity(nsDisplayListBuilder* aBuilder,
: nsDisplayWrapList(aBuilder, aFrame, aList, aActiveScrolledRoot, true)
, mOpacity(aFrame->StyleEffects()->mOpacity)
, mForEventsAndPluginsOnly(aForEventsAndPluginsOnly)
, mOpacityAppliedToChildren(false)
{
MOZ_COUNT_CTOR(nsDisplayOpacity);
mState.mOpacity = mOpacity;
Expand Down Expand Up @@ -6544,27 +6545,8 @@ CollectItemsWithOpacity(nsDisplayList* aList,
}

bool
nsDisplayOpacity::ShouldFlattenAway(nsDisplayListBuilder* aBuilder)
nsDisplayOpacity::ApplyOpacityToChildren(nsDisplayListBuilder* aBuilder)
{
if (mFrame->GetPrevContinuation() ||
mFrame->GetNextContinuation()) {
// If we've been split, then we might need to merge, so
// don't flatten us away.
return false;
}

if (NeedsActiveLayer(aBuilder, mFrame) || mOpacity == 0.0) {
// If our opacity is zero then we'll discard all descendant display items
// except for layer event regions, so there's no point in doing this
// optimization (and if we do do it, then invalidations of those descendants
// might trigger repainting).
return false;
}

if (mList.IsEmpty()) {
return false;
}

// Only try folding our opacity down if we have at most kMaxChildCount
// children that don't overlap and can all apply the opacity to themselves.
static const size_t kMaxChildCount = 3;
Expand Down Expand Up @@ -6601,9 +6583,38 @@ nsDisplayOpacity::ShouldFlattenAway(nsDisplayListBuilder* aBuilder)
children[i].item->ApplyOpacity(aBuilder, mOpacity, mClipChain);
}

mOpacityAppliedToChildren = true;
return true;
}

bool
nsDisplayOpacity::ShouldFlattenAway(nsDisplayListBuilder* aBuilder)
{
// ShouldFlattenAway() should be called only once during painting.
MOZ_ASSERT(!mOpacityAppliedToChildren);

if (mFrame->GetPrevContinuation() ||
mFrame->GetNextContinuation()) {
// If we've been split, then we might need to merge, so
// don't flatten us away.
return false;
}

if (NeedsActiveLayer(aBuilder, mFrame) || mOpacity == 0.0) {
// If our opacity is zero then we'll discard all descendant display items
// except for layer event regions, so there's no point in doing this
// optimization (and if we do do it, then invalidations of those descendants
// might trigger repainting).
return false;
}

if (mList.IsEmpty()) {
return false;
}

return ApplyOpacityToChildren(aBuilder);
}

nsDisplayItem::LayerState
nsDisplayOpacity::GetLayerState(nsDisplayListBuilder* aBuilder,
LayerManager* aManager,
Expand Down
18 changes: 17 additions & 1 deletion layout/painting/nsDisplayList.h
Original file line number Diff line number Diff line change
Expand Up @@ -5250,12 +5250,18 @@ class nsDisplayOpacity : public nsDisplayWrapList {
nsDisplayList* aList,
const ActiveScrolledRoot* aActiveScrolledRoot,
bool aForEventsAndPluginsOnly);

nsDisplayOpacity(nsDisplayListBuilder* aBuilder,
const nsDisplayOpacity& aOther)
: nsDisplayWrapList(aBuilder, aOther)
, mOpacity(aOther.mOpacity)
, mForEventsAndPluginsOnly(aOther.mForEventsAndPluginsOnly)
{}
, mOpacityAppliedToChildren(false)
{
// We should not try to merge flattened opacities.
MOZ_ASSERT(!aOther.mOpacityAppliedToChildren);
}

#ifdef NS_BUILD_REFCNT_LOGGING
virtual ~nsDisplayOpacity();
#endif
Expand All @@ -5264,6 +5270,7 @@ class nsDisplayOpacity : public nsDisplayWrapList {
{
nsDisplayItem::RestoreState();
mOpacity = mState.mOpacity;
mOpacityAppliedToChildren = false;
}

virtual nsDisplayWrapList* Clone(nsDisplayListBuilder* aBuilder) const override
Expand Down Expand Up @@ -5312,6 +5319,12 @@ class nsDisplayOpacity : public nsDisplayWrapList {
const DisplayItemClipChain* aClip) override;
virtual bool CanApplyOpacity() const override;
virtual bool ShouldFlattenAway(nsDisplayListBuilder* aBuilder) override;

/**
* Returns true if ShouldFlattenAway() applied opacity to children.
*/
bool OpacityAppliedToChildren() const { return mOpacityAppliedToChildren; }

static bool NeedsActiveLayer(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame);
NS_DISPLAY_DECL_NAME("Opacity", TYPE_OPACITY)
virtual void WriteDebugInfo(std::stringstream& aStream) override;
Expand All @@ -5327,8 +5340,11 @@ class nsDisplayOpacity : public nsDisplayWrapList {
float GetOpacity() { return mOpacity; }

private:
bool ApplyOpacityToChildren(nsDisplayListBuilder* aBuilder);

float mOpacity;
bool mForEventsAndPluginsOnly;
bool mOpacityAppliedToChildren;

struct {
float mOpacity;
Expand Down

0 comments on commit 1e4cbce

Please sign in to comment.