mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1132371. Allow opacity items that only contain one item that paints (and others that don't) to flatten away as well. r=mattwoodrow
The optimization that allows opacity items that only contain one item (which can fold the opacity into it's own drawing) to flatten away will never apply when we have layer event region items. This is because opacity generates a stacking context and we always push a new layer event regions item for a stacking context. So if we want to keep this optimization we need to extend to to at least two items. Layer event regions items have empty bounds, which allows the non-overlapping test to pass for layer event region items. Although it will work with any non-overlapping items.
This commit is contained in:
parent
19e6db2719
commit
d5358ff2dc
@ -2960,15 +2960,21 @@ nsDisplayThemedBackground::GetBoundsInternal() {
|
||||
return r + ToReferenceFrame();
|
||||
}
|
||||
|
||||
bool
|
||||
void
|
||||
nsDisplayBackgroundColor::ApplyOpacity(nsDisplayListBuilder* aBuilder,
|
||||
float aOpacity,
|
||||
const DisplayItemClip* aClip)
|
||||
{
|
||||
NS_ASSERTION(CanApplyOpacity(), "ApplyOpacity should be allowed");
|
||||
mColor.a = mColor.a * aOpacity;
|
||||
if (aClip) {
|
||||
IntersectClip(aBuilder, *aClip);
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
nsDisplayBackgroundColor::CanApplyOpacity() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -3822,15 +3828,21 @@ nsDisplayOpacity::NeedsActiveLayer(nsDisplayListBuilder* aBuilder)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
void
|
||||
nsDisplayOpacity::ApplyOpacity(nsDisplayListBuilder* aBuilder,
|
||||
float aOpacity,
|
||||
const DisplayItemClip* aClip)
|
||||
{
|
||||
NS_ASSERTION(CanApplyOpacity(), "ApplyOpacity should be allowed");
|
||||
mOpacity = mOpacity * aOpacity;
|
||||
if (aClip) {
|
||||
IntersectClip(aBuilder, *aClip);
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
nsDisplayOpacity::CanApplyOpacity() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -3841,14 +3853,41 @@ nsDisplayOpacity::ShouldFlattenAway(nsDisplayListBuilder* aBuilder)
|
||||
return false;
|
||||
|
||||
nsDisplayItem* child = mList.GetBottom();
|
||||
// Only try folding our opacity down if we have a single
|
||||
// child. We could potentially do this also if we had multiple
|
||||
// children as long as they don't overlap.
|
||||
if (!child || child->GetAbove()) {
|
||||
// Only try folding our opacity down if we have at most three children
|
||||
// that don't overlap and can all apply the opacity to themselves.
|
||||
if (!child) {
|
||||
return false;
|
||||
}
|
||||
struct {
|
||||
nsDisplayItem* item;
|
||||
nsRect bounds;
|
||||
} children[3];
|
||||
bool snap;
|
||||
uint32_t numChildren = 0;
|
||||
for (; numChildren < ArrayLength(children) && child; numChildren++, child = child->GetAbove()) {
|
||||
if (!child->CanApplyOpacity()) {
|
||||
return false;
|
||||
}
|
||||
children[numChildren].item = child;
|
||||
children[numChildren].bounds = child->GetBounds(aBuilder, &snap);
|
||||
}
|
||||
if (child) {
|
||||
// we have a fourth (or more) child
|
||||
return false;
|
||||
}
|
||||
|
||||
return child->ApplyOpacity(aBuilder, mOpacity, mClip);
|
||||
for (uint32_t i = 0; i < numChildren; i++) {
|
||||
for (uint32_t j = i+1; j < numChildren; j++) {
|
||||
if (children[i].bounds.Intersects(children[j].bounds)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < numChildren; i++) {
|
||||
children[i].item->ApplyOpacity(aBuilder, mOpacity, mClip);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
nsDisplayItem::LayerState
|
||||
|
@ -1367,12 +1367,19 @@ public:
|
||||
virtual const nsRect& GetVisibleRectForChildren() const { return mVisibleRect; }
|
||||
|
||||
/**
|
||||
* Stores the given opacity value to be applied when drawing. Returns
|
||||
* false if this isn't supported for this display item.
|
||||
* Stores the given opacity value to be applied when drawing. It is an error to
|
||||
* call this if CanApplyOpacity returned false.
|
||||
*/
|
||||
virtual bool ApplyOpacity(nsDisplayListBuilder* aBuilder,
|
||||
virtual void ApplyOpacity(nsDisplayListBuilder* aBuilder,
|
||||
float aOpacity,
|
||||
const DisplayItemClip* aClip) {
|
||||
NS_ASSERTION(CanApplyOpacity(), "ApplyOpacity not supported on this type");
|
||||
}
|
||||
/**
|
||||
* Returns true if this display item would return true from ApplyOpacity without
|
||||
* actually applying the opacity. Otherwise returns false.
|
||||
*/
|
||||
virtual bool CanApplyOpacity() const {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -2377,9 +2384,10 @@ public:
|
||||
virtual void HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect,
|
||||
HitTestState* aState, nsTArray<nsIFrame*> *aOutFrames) MOZ_OVERRIDE;
|
||||
|
||||
virtual bool ApplyOpacity(nsDisplayListBuilder* aBuilder,
|
||||
virtual void ApplyOpacity(nsDisplayListBuilder* aBuilder,
|
||||
float aOpacity,
|
||||
const DisplayItemClip* aClip) MOZ_OVERRIDE;
|
||||
virtual bool CanApplyOpacity() const MOZ_OVERRIDE;
|
||||
|
||||
virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) MOZ_OVERRIDE
|
||||
{
|
||||
@ -2486,14 +2494,18 @@ public:
|
||||
const nsDisplayItemGeometry* aGeometry,
|
||||
nsRegion* aInvalidRegion) MOZ_OVERRIDE;
|
||||
|
||||
virtual bool ApplyOpacity(nsDisplayListBuilder* aBuilder,
|
||||
virtual void ApplyOpacity(nsDisplayListBuilder* aBuilder,
|
||||
float aOpacity,
|
||||
const DisplayItemClip* aClip) MOZ_OVERRIDE
|
||||
{
|
||||
NS_ASSERTION(CanApplyOpacity(), "ApplyOpacity should be allowed");
|
||||
mOpacity = aOpacity;
|
||||
if (aClip) {
|
||||
IntersectClip(aBuilder, *aClip);
|
||||
}
|
||||
}
|
||||
virtual bool CanApplyOpacity() const MOZ_OVERRIDE
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -2636,6 +2648,17 @@ public:
|
||||
return mHitRegion.GetBounds().Union(mMaybeHitRegion.GetBounds());
|
||||
}
|
||||
|
||||
virtual void ApplyOpacity(nsDisplayListBuilder* aBuilder,
|
||||
float aOpacity,
|
||||
const DisplayItemClip* aClip) MOZ_OVERRIDE
|
||||
{
|
||||
NS_ASSERTION(CanApplyOpacity(), "ApplyOpacity should be allowed");
|
||||
}
|
||||
virtual bool CanApplyOpacity() const MOZ_OVERRIDE
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
NS_DISPLAY_DECL_NAME("LayerEventRegions", TYPE_LAYER_EVENT_REGIONS)
|
||||
|
||||
// Indicate that aFrame's border-box contributes to the event regions for
|
||||
@ -2865,9 +2888,10 @@ public:
|
||||
{
|
||||
// We don't need to compute an invalidation region since we have LayerTreeInvalidation
|
||||
}
|
||||
virtual bool ApplyOpacity(nsDisplayListBuilder* aBuilder,
|
||||
virtual void ApplyOpacity(nsDisplayListBuilder* aBuilder,
|
||||
float aOpacity,
|
||||
const DisplayItemClip* aClip) MOZ_OVERRIDE;
|
||||
virtual bool CanApplyOpacity() const MOZ_OVERRIDE;
|
||||
virtual bool ShouldFlattenAway(nsDisplayListBuilder* aBuilder) MOZ_OVERRIDE;
|
||||
bool NeedsActiveLayer(nsDisplayListBuilder* aBuilder);
|
||||
NS_DISPLAY_DECL_NAME("Opacity", TYPE_OPACITY)
|
||||
|
@ -4,7 +4,7 @@
|
||||
<style>
|
||||
#image {
|
||||
position:fixed;
|
||||
opacity:0.5;
|
||||
opacity:0.50196078431;
|
||||
left:0;
|
||||
top:0;
|
||||
width:100%;
|
||||
|
@ -7,7 +7,7 @@
|
||||
height:0;
|
||||
}
|
||||
#d2 {
|
||||
opacity:0.5;
|
||||
opacity:0.50196078431;
|
||||
}
|
||||
#d3 {
|
||||
position:absolute;
|
||||
|
@ -7,7 +7,7 @@
|
||||
height:0;
|
||||
}
|
||||
#d2 {
|
||||
opacity:0.5;
|
||||
opacity:0.50196078431;
|
||||
}
|
||||
#image {
|
||||
position:fixed;
|
||||
|
Loading…
Reference in New Issue
Block a user