зеркало из https://github.com/mozilla/gecko-dev.git
Backed out 6 changesets (bug 1442190) for reftest failures on /anonymous-block.html on a CLOSED TREE
Backed out changeset e8dc919d0f42 (bug 1442190) Backed out changeset e406251cf5ea (bug 1442190) Backed out changeset ce317da6a8fc (bug 1442190) Backed out changeset cebcdd61afcb (bug 1442190) Backed out changeset 7a1185d616dc (bug 1442190) Backed out changeset f8c99ac6bf0d (bug 1442190)
This commit is contained in:
Родитель
4c83c733c3
Коммит
b57bd05828
|
@ -55,7 +55,6 @@
|
|||
|
||||
#include <algorithm>
|
||||
#include <functional>
|
||||
#include <list>
|
||||
|
||||
using namespace mozilla::layers;
|
||||
using namespace mozilla::gfx;
|
||||
|
@ -119,99 +118,6 @@ static inline MaskLayerImageCache* GetMaskLayerImageCache()
|
|||
return gMaskLayerImageCache;
|
||||
}
|
||||
|
||||
struct DisplayItemEntry {
|
||||
DisplayItemEntry(nsDisplayItem* aItem,
|
||||
DisplayItemEntryType aType)
|
||||
: mItem(aItem)
|
||||
, mType(aType)
|
||||
{}
|
||||
|
||||
nsDisplayItem* mItem;
|
||||
DisplayItemEntryType mType;
|
||||
};
|
||||
|
||||
class FLBDisplayItemIterator : protected FlattenedDisplayItemIterator
|
||||
{
|
||||
public:
|
||||
FLBDisplayItemIterator(nsDisplayListBuilder* aBuilder,
|
||||
nsDisplayList* aList,
|
||||
ContainerState* aState)
|
||||
: FlattenedDisplayItemIterator(aBuilder, aList, false)
|
||||
, mState(aState)
|
||||
{
|
||||
MOZ_ASSERT(mState);
|
||||
ResolveFlattening();
|
||||
}
|
||||
|
||||
DisplayItemEntry GetNextEntry()
|
||||
{
|
||||
if (!mMarkers.empty()) {
|
||||
DisplayItemEntry entry = mMarkers.front();
|
||||
mMarkers.pop_front();
|
||||
return entry;
|
||||
}
|
||||
|
||||
nsDisplayItem* next = GetNext();
|
||||
return DisplayItemEntry { next, DisplayItemEntryType::ITEM };
|
||||
}
|
||||
|
||||
nsDisplayItem* GetNext()
|
||||
{
|
||||
// This function is only supposed to be called if there are no markers set.
|
||||
// Breaking this invariant can potentially break effect flattening and/or
|
||||
// display item merging.
|
||||
MOZ_ASSERT(mMarkers.empty());
|
||||
|
||||
return FlattenedDisplayItemIterator::GetNext();
|
||||
}
|
||||
|
||||
bool HasNext() const
|
||||
{
|
||||
return FlattenedDisplayItemIterator::HasNext() || !mMarkers.empty();
|
||||
}
|
||||
|
||||
nsDisplayItem* PeekNext()
|
||||
{
|
||||
return mNext;
|
||||
}
|
||||
|
||||
private:
|
||||
bool ShouldFlattenNextItem() const override;
|
||||
|
||||
void StartNested(nsDisplayItem* aItem) override
|
||||
{
|
||||
if (aItem->GetType() == DisplayItemType::TYPE_OPACITY) {
|
||||
nsDisplayOpacity* opacity = static_cast<nsDisplayOpacity*> (aItem);
|
||||
|
||||
if (opacity->OpacityAppliedToChildren()) {
|
||||
// If the opacity was already applied to children, there is no need to
|
||||
// emit opacity markers.
|
||||
return;
|
||||
}
|
||||
|
||||
mMarkers.emplace_back(aItem, DisplayItemEntryType::PUSH_OPACITY);
|
||||
mActiveMarkers.AppendElement(aItem);
|
||||
}
|
||||
}
|
||||
|
||||
void EndNested(nsDisplayItem* aItem) override
|
||||
{
|
||||
if (mActiveMarkers.IsEmpty() || mActiveMarkers.LastElement() != aItem) {
|
||||
// Do not emit an end marker if this item did not emit a start marker.
|
||||
return;
|
||||
}
|
||||
|
||||
if (aItem->GetType() == DisplayItemType::TYPE_OPACITY) {
|
||||
mMarkers.emplace_back(aItem, DisplayItemEntryType::POP_OPACITY);
|
||||
mActiveMarkers.RemoveLastElement();
|
||||
}
|
||||
}
|
||||
|
||||
std::list<DisplayItemEntry> mMarkers;
|
||||
AutoTArray<nsDisplayItem*, 4> mActiveMarkers;
|
||||
ContainerState* mState;
|
||||
};
|
||||
|
||||
DisplayItemData::DisplayItemData(LayerManagerData* aParent, uint32_t aKey,
|
||||
Layer* aLayer, nsIFrame* aFrame)
|
||||
|
||||
|
@ -575,8 +481,7 @@ public:
|
|||
const nsIntRect& aVisibleRect,
|
||||
const DisplayItemClip& aClip,
|
||||
LayerState aLayerState,
|
||||
nsDisplayList *aList,
|
||||
DisplayItemEntryType aType);
|
||||
nsDisplayList *aList);
|
||||
AnimatedGeometryRoot* GetAnimatedGeometryRoot() { return mAnimatedGeometryRoot; }
|
||||
|
||||
/**
|
||||
|
@ -772,11 +677,7 @@ public:
|
|||
* These items get added by Accumulate().
|
||||
*/
|
||||
nsTArray<AssignedDisplayItem> mAssignedDisplayItems;
|
||||
/**
|
||||
* Tracks the active opacity markers by holding the indices to PUSH_OPACITY
|
||||
* items in |mAssignedDisplayItems|.
|
||||
*/
|
||||
nsTArray<size_t> mOpacityIndices;
|
||||
|
||||
};
|
||||
|
||||
struct NewLayerEntry {
|
||||
|
@ -1312,7 +1213,6 @@ public:
|
|||
|
||||
protected:
|
||||
friend class PaintedLayerData;
|
||||
friend class FLBDisplayItemIterator;
|
||||
|
||||
LayerManager::PaintedLayerCreationHint
|
||||
GetLayerCreationHint(AnimatedGeometryRoot* aAnimatedGeometryRoot);
|
||||
|
@ -1576,43 +1476,6 @@ protected:
|
|||
nsRect mLastDisplayPortRect;
|
||||
};
|
||||
|
||||
bool
|
||||
FLBDisplayItemIterator::ShouldFlattenNextItem() const
|
||||
{
|
||||
if (!mNext) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!mNext->ShouldFlattenAway(mBuilder)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (mNext->GetType() == DisplayItemType::TYPE_OPACITY) {
|
||||
nsDisplayOpacity* opacity = static_cast<nsDisplayOpacity*>(mNext);
|
||||
|
||||
if (opacity->OpacityAppliedToChildren()) {
|
||||
// This is the previous opacity flattening path, where the opacity has
|
||||
// been applied to children.
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!mState->mManager->IsWidgetLayerManager()) {
|
||||
// Do not flatten opacity inside an inactive layer tree.
|
||||
return false;
|
||||
}
|
||||
|
||||
LayerState layerState = mNext->GetLayerState(mState->mBuilder,
|
||||
mState->mManager,
|
||||
mState->mParameters);
|
||||
|
||||
// Do not flatten opacity if child display items require an active layer.
|
||||
return (layerState == LayerState::LAYER_NONE ||
|
||||
layerState == LayerState::LAYER_INACTIVE);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
class PaintedDisplayItemLayerUserData : public LayerUserData
|
||||
{
|
||||
public:
|
||||
|
@ -1624,8 +1487,7 @@ public:
|
|||
mAnimatedGeometryRootPosition(0, 0),
|
||||
mLastItemCount(0),
|
||||
mContainerLayerFrame(nullptr),
|
||||
mHasExplicitLastPaintOffset(false)
|
||||
{}
|
||||
mHasExplicitLastPaintOffset(false) {}
|
||||
|
||||
NS_INLINE_DECL_REFCOUNTING(PaintedDisplayItemLayerUserData);
|
||||
|
||||
|
@ -2736,13 +2598,6 @@ ContainerState::FindOpaqueBackgroundColorInLayer(const PaintedLayerData* aData,
|
|||
appUnitRect.ScaleInverseRoundOut(mParameters.mXScale, mParameters.mYScale);
|
||||
|
||||
for (auto& assignedItem : Reversed(aData->mAssignedDisplayItems)) {
|
||||
if (assignedItem.mType != DisplayItemEntryType::ITEM ||
|
||||
assignedItem.mHasOpacity) {
|
||||
// |assignedItem| is either an effect marker, or within a flatten opacity
|
||||
// group. In both cases, there is no opaque area.
|
||||
continue;
|
||||
}
|
||||
|
||||
nsDisplayItem* item = assignedItem.mItem;
|
||||
bool snap;
|
||||
nsRect bounds = item->GetBounds(mBuilder, &snap);
|
||||
|
@ -3312,8 +3167,6 @@ void ContainerState::FinishPaintedLayerData(PaintedLayerData& aData, FindOpaqueB
|
|||
{
|
||||
PaintedLayerData* data = &aData;
|
||||
|
||||
MOZ_ASSERT(data->mOpacityIndices.IsEmpty());
|
||||
|
||||
if (!data->mLayer) {
|
||||
// No layer was recycled, so we create a new one.
|
||||
RefPtr<PaintedLayer> paintedLayer = CreatePaintedLayer(data);
|
||||
|
@ -3382,11 +3235,6 @@ void ContainerState::FinishPaintedLayerData(PaintedLayerData& aData, FindOpaqueB
|
|||
MOZ_ASSERT(item.mItem->GetType() != DisplayItemType::TYPE_LAYER_EVENT_REGIONS);
|
||||
MOZ_ASSERT(item.mItem->GetType() != DisplayItemType::TYPE_COMPOSITOR_HITTEST_INFO);
|
||||
|
||||
if (item.mType == DisplayItemEntryType::POP_OPACITY) {
|
||||
// Do not invalidate for end markers.
|
||||
continue;
|
||||
}
|
||||
|
||||
InvalidateForLayerChange(item.mItem, data->mLayer, item.mDisplayItemData);
|
||||
mLayerBuilder->AddPaintedDisplayItem(data, item, *this, layer);
|
||||
item.mDisplayItemData = nullptr;
|
||||
|
@ -3594,68 +3442,32 @@ IsItemAreaInWindowOpaqueRegion(nsDisplayListBuilder* aBuilder,
|
|||
|
||||
void
|
||||
PaintedLayerData::Accumulate(ContainerState* aState,
|
||||
nsDisplayItem* aItem,
|
||||
const nsIntRect& aVisibleRect,
|
||||
const DisplayItemClip& aClip,
|
||||
LayerState aLayerState,
|
||||
nsDisplayList* aList,
|
||||
DisplayItemEntryType aType)
|
||||
nsDisplayItem* aItem,
|
||||
const nsIntRect& aVisibleRect,
|
||||
const DisplayItemClip& aClip,
|
||||
LayerState aLayerState,
|
||||
nsDisplayList* aList)
|
||||
{
|
||||
FLB_LOG_PAINTED_LAYER_DECISION(this, "Accumulating dp=%s(%p), f=%p against pld=%p\n", aItem->Name(), aItem, aItem->Frame(), this);
|
||||
|
||||
const bool hasOpacity = mOpacityIndices.Length() > 0;
|
||||
|
||||
if (aType == DisplayItemEntryType::POP_OPACITY) {
|
||||
MOZ_ASSERT(!mOpacityIndices.IsEmpty());
|
||||
mOpacityIndices.RemoveLastElement();
|
||||
|
||||
AssignedDisplayItem item(aItem, aClip, aLayerState,
|
||||
nullptr, aType, hasOpacity);
|
||||
mAssignedDisplayItems.AppendElement(Move(item));
|
||||
return;
|
||||
}
|
||||
|
||||
if (aState->mBuilder->NeedToForceTransparentSurfaceForItem(aItem)) {
|
||||
mForceTransparentSurface = true;
|
||||
}
|
||||
|
||||
nsRect componentAlphaBounds;
|
||||
if (aState->mParameters.mDisableSubpixelAntialiasingInDescendants) {
|
||||
// Disable component alpha.
|
||||
// Note that the transform (if any) on the PaintedLayer is always an integer
|
||||
// translation so we don't have to factor that in here.
|
||||
// Note that the transform (if any) on the PaintedLayer is always an integer translation so
|
||||
// we don't have to factor that in here.
|
||||
aItem->DisableComponentAlpha();
|
||||
} else {
|
||||
componentAlphaBounds = aItem->GetComponentAlphaBounds(aState->mBuilder);
|
||||
|
||||
if (!componentAlphaBounds.IsEmpty()) {
|
||||
// This display item needs background copy when pushing opacity group.
|
||||
for (size_t i : mOpacityIndices) {
|
||||
AssignedDisplayItem& item = mAssignedDisplayItems[i];
|
||||
MOZ_ASSERT(item.mType == DisplayItemEntryType::PUSH_OPACITY ||
|
||||
item.mType == DisplayItemEntryType::PUSH_OPACITY_WITH_BG);
|
||||
item.mType = DisplayItemEntryType::PUSH_OPACITY_WITH_BG;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool clipMatches = mItemClip == aClip;
|
||||
mItemClip = aClip;
|
||||
|
||||
DisplayItemData* currentData =
|
||||
aItem->HasMergedFrames() ? nullptr : aItem->GetDisplayItemData();
|
||||
|
||||
DisplayItemData* oldData =
|
||||
aState->mLayerBuilder->GetOldLayerForFrame(aItem->Frame(),
|
||||
aItem->GetPerFrameKey(),
|
||||
currentData);
|
||||
AssignedDisplayItem item(aItem, aClip, aLayerState,
|
||||
oldData, aType, hasOpacity);
|
||||
mAssignedDisplayItems.AppendElement(Move(item));
|
||||
|
||||
if (aType == DisplayItemEntryType::PUSH_OPACITY) {
|
||||
mOpacityIndices.AppendElement(mAssignedDisplayItems.Length() - 1);
|
||||
}
|
||||
aState->mLayerBuilder->GetOldLayerForFrame(aItem->Frame(),
|
||||
aItem->GetPerFrameKey(),
|
||||
aItem->HasMergedFrames() ? nullptr : aItem->GetDisplayItemData());
|
||||
mAssignedDisplayItems.AppendElement(AssignedDisplayItem(aItem, aClip, aLayerState, oldData));
|
||||
|
||||
if (aItem->MustPaintOnContentSide()) {
|
||||
mShouldPaintOnContentSide = true;
|
||||
|
@ -3674,15 +3486,10 @@ PaintedLayerData::Accumulate(ContainerState* aState,
|
|||
return;
|
||||
}
|
||||
|
||||
nsIntRegion opaquePixels;
|
||||
|
||||
// Active opacity means no opaque pixels.
|
||||
if (!hasOpacity) {
|
||||
opaquePixels = aState->ComputeOpaqueRect(aItem, mAnimatedGeometryRoot, mASR,
|
||||
aClip, aList, &mHideAllLayersBelow,
|
||||
&mOpaqueForAnimatedGeometryRootParent);
|
||||
opaquePixels.AndWith(aVisibleRect);
|
||||
}
|
||||
nsIntRegion opaquePixels = aState->ComputeOpaqueRect(aItem,
|
||||
mAnimatedGeometryRoot, mASR, aClip, aList,
|
||||
&mHideAllLayersBelow, &mOpaqueForAnimatedGeometryRootParent);
|
||||
opaquePixels.AndWith(aVisibleRect);
|
||||
|
||||
/* Mark as available for conversion to image layer if this is a nsDisplayImage and
|
||||
* it's the only thing visible in this layer.
|
||||
|
@ -3699,10 +3506,7 @@ PaintedLayerData::Accumulate(ContainerState* aState,
|
|||
|
||||
bool isFirstVisibleItem = mVisibleRegion.IsEmpty();
|
||||
|
||||
Maybe<nscolor> uniformColor;
|
||||
if (!hasOpacity) {
|
||||
uniformColor = aItem->IsUniform(aState->mBuilder);
|
||||
}
|
||||
Maybe<nscolor> uniformColor = aItem->IsUniform(aState->mBuilder);
|
||||
|
||||
// Some display items have to exist (so they can set forceTransparentSurface
|
||||
// below) but don't draw anything. They'll return true for isUniform but
|
||||
|
@ -3760,17 +3564,18 @@ PaintedLayerData::Accumulate(ContainerState* aState,
|
|||
}
|
||||
}
|
||||
|
||||
if (!aState->mParameters.mDisableSubpixelAntialiasingInDescendants &&
|
||||
!componentAlphaBounds.IsEmpty()) {
|
||||
nsIntRect componentAlphaRect =
|
||||
aState->ScaleToOutsidePixels(componentAlphaBounds, false).Intersect(aVisibleRect);
|
||||
|
||||
if (!mOpaqueRegion.Contains(componentAlphaRect)) {
|
||||
if (IsItemAreaInWindowOpaqueRegion(aState->mBuilder, aItem,
|
||||
componentAlphaBounds.Intersect(aItem->GetVisibleRect()))) {
|
||||
mNeedComponentAlpha = true;
|
||||
} else {
|
||||
aItem->DisableComponentAlpha();
|
||||
if (!aState->mParameters.mDisableSubpixelAntialiasingInDescendants) {
|
||||
nsRect componentAlpha = aItem->GetComponentAlphaBounds(aState->mBuilder);
|
||||
if (!componentAlpha.IsEmpty()) {
|
||||
nsIntRect componentAlphaRect =
|
||||
aState->ScaleToOutsidePixels(componentAlpha, false).Intersect(aVisibleRect);
|
||||
if (!mOpaqueRegion.Contains(componentAlphaRect)) {
|
||||
if (IsItemAreaInWindowOpaqueRegion(aState->mBuilder, aItem,
|
||||
componentAlpha.Intersect(aItem->GetVisibleRect()))) {
|
||||
mNeedComponentAlpha = true;
|
||||
} else {
|
||||
aItem->DisableComponentAlpha();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3780,7 +3585,8 @@ PaintedLayerData::Accumulate(ContainerState* aState,
|
|||
// not support subpixel positioning of text that animated transforms can
|
||||
// generate. bug 633097
|
||||
if (aState->mParameters.mInActiveTransformedSubtree &&
|
||||
(mNeedComponentAlpha || !componentAlphaBounds.IsEmpty())) {
|
||||
(mNeedComponentAlpha ||
|
||||
!aItem->GetComponentAlphaBounds(aState->mBuilder).IsEmpty())) {
|
||||
mDisableFlattening = true;
|
||||
}
|
||||
}
|
||||
|
@ -4277,20 +4083,11 @@ ContainerState::ProcessDisplayItems(nsDisplayList* aList)
|
|||
|
||||
AnimatedGeometryRoot* lastAnimatedGeometryRoot = nullptr;
|
||||
nsPoint lastTopLeft;
|
||||
|
||||
// Tracks the PaintedLayerData that the item will be accumulated in, if it is
|
||||
// non-null. Currently only used with PUSH_OPACITY and POP_OPACITY markers.
|
||||
PaintedLayerData* selectedPLD = nullptr;
|
||||
|
||||
FLBDisplayItemIterator iter(mBuilder, aList, this);
|
||||
while (iter.HasNext()) {
|
||||
DisplayItemEntry e = iter.GetNextEntry();
|
||||
nsDisplayItem* i = e.mItem;
|
||||
DisplayItemEntryType marker = e.mType;
|
||||
|
||||
|
||||
FlattenedDisplayItemIterator iter(mBuilder, aList);
|
||||
while (nsDisplayItem* i = iter.GetNext()) {
|
||||
nsDisplayItem* item = i;
|
||||
MOZ_ASSERT(item);
|
||||
|
||||
DisplayItemType itemType = item->GetType();
|
||||
|
||||
// If the item is a event regions item, but is empty (has no regions in it)
|
||||
|
@ -4322,23 +4119,20 @@ ContainerState::ProcessDisplayItems(nsDisplayList* aList)
|
|||
// Only allow either LayerEventRegions or CompositorHitTestInfo items.
|
||||
MOZ_ASSERT(!(hadLayerEventRegions && hadCompositorHitTestInfo));
|
||||
|
||||
|
||||
// Peek ahead to the next item and see if it can be merged with the current
|
||||
// item. We create a list of consecutive items that can be merged together.
|
||||
AutoTArray<nsDisplayItem*, 1> mergedItems;
|
||||
|
||||
if (marker == DisplayItemEntryType::ITEM) {
|
||||
mergedItems.AppendElement(item);
|
||||
|
||||
while (nsDisplayItem* peek = iter.PeekNext()) {
|
||||
if (!item->CanMerge(peek)) {
|
||||
break;
|
||||
}
|
||||
|
||||
mergedItems.AppendElement(peek);
|
||||
|
||||
// Move the iterator forward since we will merge this item.
|
||||
i = iter.GetNext();
|
||||
mergedItems.AppendElement(item);
|
||||
while (nsDisplayItem* peek = iter.PeekNext()) {
|
||||
if (!item->CanMerge(peek)) {
|
||||
break;
|
||||
}
|
||||
|
||||
mergedItems.AppendElement(peek);
|
||||
|
||||
// Move the iterator forward since we will merge this item.
|
||||
i = iter.GetNext();
|
||||
}
|
||||
|
||||
if (mergedItems.Length() > 1) {
|
||||
|
@ -4364,14 +4158,10 @@ ContainerState::ProcessDisplayItems(nsDisplayList* aList)
|
|||
continue;
|
||||
}
|
||||
|
||||
LayerState layerState = LAYER_NONE;
|
||||
|
||||
if (marker == DisplayItemEntryType::ITEM) {
|
||||
layerState = item->GetLayerState(mBuilder, mManager, mParameters);
|
||||
|
||||
if (layerState == LAYER_INACTIVE && nsDisplayItem::ForceActiveLayers()) {
|
||||
layerState = LAYER_ACTIVE;
|
||||
}
|
||||
LayerState layerState = item->GetLayerState(mBuilder, mManager, mParameters);
|
||||
if (layerState == LAYER_INACTIVE &&
|
||||
nsDisplayItem::ForceActiveLayers()) {
|
||||
layerState = LAYER_ACTIVE;
|
||||
}
|
||||
|
||||
bool forceInactive = false;
|
||||
|
@ -4474,11 +4264,6 @@ ContainerState::ProcessDisplayItems(nsDisplayList* aList)
|
|||
|
||||
layerCount++;
|
||||
|
||||
// Currently we do not support flattening effects within nested inactive
|
||||
// layer trees.
|
||||
MOZ_ASSERT(selectedPLD == nullptr);
|
||||
MOZ_ASSERT(marker == DisplayItemEntryType::ITEM);
|
||||
|
||||
// LAYER_ACTIVE_EMPTY means the layer is created just for its metadata.
|
||||
// We should never see an empty layer with any visible content!
|
||||
NS_ASSERTION(layerState != LAYER_ACTIVE_EMPTY ||
|
||||
|
@ -4798,21 +4583,14 @@ ContainerState::ProcessDisplayItems(nsDisplayList* aList)
|
|||
const bool backfaceHidden = item->In3DContextAndBackfaceIsHidden();
|
||||
const nsIFrame* referenceFrame = item->ReferenceFrame();
|
||||
|
||||
PaintedLayerData* paintedLayerData = selectedPLD;
|
||||
|
||||
if (!selectedPLD) {
|
||||
MOZ_ASSERT(marker != DisplayItemEntryType::POP_OPACITY);
|
||||
|
||||
paintedLayerData =
|
||||
mPaintedLayerDataTree.FindPaintedLayerFor(animatedGeometryRoot, itemASR, layerClipChain,
|
||||
itemVisibleRect, backfaceHidden,
|
||||
[&](PaintedLayerData* aData) {
|
||||
NewPaintedLayerData(aData, animatedGeometryRoot, itemASR,
|
||||
layerClipChain, scrollMetadataASR, topLeft,
|
||||
referenceFrame, backfaceHidden);
|
||||
PaintedLayerData* paintedLayerData =
|
||||
mPaintedLayerDataTree.FindPaintedLayerFor(animatedGeometryRoot, itemASR, layerClipChain,
|
||||
itemVisibleRect, backfaceHidden,
|
||||
[&](PaintedLayerData* aData) {
|
||||
NewPaintedLayerData(aData, animatedGeometryRoot, itemASR,
|
||||
layerClipChain, scrollMetadataASR, topLeft,
|
||||
referenceFrame, backfaceHidden);
|
||||
});
|
||||
}
|
||||
MOZ_ASSERT(paintedLayerData);
|
||||
|
||||
if (itemType == DisplayItemType::TYPE_LAYER_EVENT_REGIONS) {
|
||||
nsDisplayLayerEventRegions* eventRegions =
|
||||
|
@ -4823,8 +4601,7 @@ ContainerState::ProcessDisplayItems(nsDisplayList* aList)
|
|||
static_cast<nsDisplayCompositorHitTestInfo*>(item);
|
||||
paintedLayerData->AccumulateHitTestInfo(this, hitTestInfo);
|
||||
} else {
|
||||
paintedLayerData->Accumulate(this, item, itemVisibleRect, itemClip,
|
||||
layerState, aList, marker);
|
||||
paintedLayerData->Accumulate(this, item, itemVisibleRect, itemClip, layerState, aList);
|
||||
|
||||
if (!paintedLayerData->mLayer) {
|
||||
// Try to recycle the old layer of this display item.
|
||||
|
@ -4843,18 +4620,6 @@ ContainerState::ProcessDisplayItems(nsDisplayList* aList)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (marker == DisplayItemEntryType::PUSH_OPACITY) {
|
||||
selectedPLD = paintedLayerData;
|
||||
}
|
||||
|
||||
if (marker == DisplayItemEntryType::POP_OPACITY ) {
|
||||
MOZ_ASSERT(selectedPLD);
|
||||
|
||||
if (selectedPLD->mOpacityIndices.IsEmpty()) {
|
||||
selectedPLD = nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nsDisplayList* childItems = item->GetSameCoordinateSystemChildren();
|
||||
|
@ -4862,8 +4627,6 @@ ContainerState::ProcessDisplayItems(nsDisplayList* aList)
|
|||
aList->SetNeedsTransparentSurface();
|
||||
}
|
||||
}
|
||||
|
||||
MOZ_ASSERT(selectedPLD == nullptr);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -5196,17 +4959,13 @@ FrameLayerBuilder::StoreDataForFrame(nsIFrame* aFrame,
|
|||
AssignedDisplayItem::AssignedDisplayItem(nsDisplayItem* aItem,
|
||||
const DisplayItemClip& aClip,
|
||||
LayerState aLayerState,
|
||||
DisplayItemData* aData,
|
||||
DisplayItemEntryType aType,
|
||||
const bool aHasOpacity)
|
||||
DisplayItemData* aData)
|
||||
: mItem(aItem)
|
||||
, mClip(aClip)
|
||||
, mLayerState(aLayerState)
|
||||
, mDisplayItemData(aData)
|
||||
, mReused(aItem->IsReused())
|
||||
, mMerged(aItem->HasMergedFrames())
|
||||
, mType(aType)
|
||||
, mHasOpacity(aHasOpacity)
|
||||
{}
|
||||
|
||||
AssignedDisplayItem::~AssignedDisplayItem()
|
||||
|
@ -6147,16 +5906,6 @@ FrameLayerBuilder::RecomputeVisibilityForItems(nsTArray<AssignedDisplayItem>& aI
|
|||
if (!cdi->mItem) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (cdi->mType == DisplayItemEntryType::POP_OPACITY ||
|
||||
(cdi->mType == DisplayItemEntryType::ITEM && cdi->mHasOpacity)) {
|
||||
// The visibility calculations are skipped when the item is an effect end
|
||||
// marker, or when the display item is within a flattened opacity group.
|
||||
// This is because RecomputeVisibility has already been called for the
|
||||
// group item, and all the children.
|
||||
continue;
|
||||
}
|
||||
|
||||
const DisplayItemClip& clip = cdi->mItem->GetClip();
|
||||
|
||||
NS_ASSERTION(AppUnitsPerDevPixel(cdi->mItem) == aAppUnitsPerDevPixel,
|
||||
|
@ -6191,70 +5940,6 @@ FrameLayerBuilder::RecomputeVisibilityForItems(nsTArray<AssignedDisplayItem>& aI
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the clip chain and starts a new opacity group.
|
||||
*/
|
||||
static void
|
||||
PushOpacity(gfxContext* aContext,
|
||||
const nsRect& aPaintRect,
|
||||
AssignedDisplayItem& aItem,
|
||||
const int32_t aAUPDP)
|
||||
{
|
||||
MOZ_ASSERT(aItem.mType == DisplayItemEntryType::PUSH_OPACITY ||
|
||||
aItem.mType == DisplayItemEntryType::PUSH_OPACITY_WITH_BG);
|
||||
MOZ_ASSERT(aItem.mItem->GetType() == DisplayItemType::TYPE_OPACITY);
|
||||
|
||||
aContext->Save();
|
||||
|
||||
DisplayItemClip clip;
|
||||
clip.SetTo(aPaintRect);
|
||||
clip.IntersectWith(aItem.mItem->GetClip());
|
||||
clip.ApplyTo(aContext, aAUPDP);
|
||||
|
||||
nsDisplayOpacity* opacityItem = static_cast<nsDisplayOpacity*>(aItem.mItem);
|
||||
const float opacity = opacityItem->GetOpacity();
|
||||
|
||||
if (aItem.mType == DisplayItemEntryType::PUSH_OPACITY_WITH_BG) {
|
||||
aContext->PushGroupAndCopyBackground(gfxContentType::COLOR_ALPHA, opacity);
|
||||
} else {
|
||||
aContext->PushGroupForBlendBack(gfxContentType::COLOR_ALPHA, opacity);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tracks item clips per opacity nesting level.
|
||||
*/
|
||||
struct ClipTracker {
|
||||
explicit ClipTracker(gfxContext* aContext)
|
||||
: mContext(aContext)
|
||||
{}
|
||||
|
||||
bool HasClip(int aOpacityNesting) const
|
||||
{
|
||||
return !mClips.IsEmpty() &&
|
||||
mClips.LastElement() == aOpacityNesting;
|
||||
}
|
||||
|
||||
void PopClipIfNeeded(int aOpacityNesting)
|
||||
{
|
||||
if (!HasClip(aOpacityNesting)) {
|
||||
return;
|
||||
}
|
||||
|
||||
mContext->Restore();
|
||||
mClips.RemoveLastElement();
|
||||
};
|
||||
|
||||
void SaveClip(int aOpacityNesting)
|
||||
{
|
||||
mContext->Save();
|
||||
mClips.AppendElement(aOpacityNesting);
|
||||
};
|
||||
|
||||
AutoTArray<int, 2> mClips;
|
||||
gfxContext* mContext;
|
||||
};
|
||||
|
||||
void
|
||||
FrameLayerBuilder::PaintItems(nsTArray<AssignedDisplayItem>& aItems,
|
||||
const nsIntRect& aRect,
|
||||
|
@ -6272,102 +5957,73 @@ FrameLayerBuilder::PaintItems(nsTArray<AssignedDisplayItem>& aItems,
|
|||
NSIntPixelsToAppUnits(aOffset.y, appUnitsPerDevPixel));
|
||||
boundRect.ScaleInverseRoundOut(aXScale, aYScale);
|
||||
|
||||
DisplayItemClip currentClip, tmpClip;
|
||||
|
||||
int opacityNesting = 0;
|
||||
ClipTracker clipTracker(aContext);
|
||||
DisplayItemClip currentClip;
|
||||
bool currentClipIsSetInContext = false;
|
||||
DisplayItemClip tmpClip;
|
||||
|
||||
for (uint32_t i = 0; i < aItems.Length(); ++i) {
|
||||
AssignedDisplayItem& cdi = aItems[i];
|
||||
nsDisplayItem* item = cdi.mItem;
|
||||
|
||||
if (!item) {
|
||||
MOZ_ASSERT(cdi.mType == DisplayItemEntryType::ITEM);
|
||||
AssignedDisplayItem* cdi = &aItems[i];
|
||||
if (!cdi->mItem) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const nsRect& visibleRect = item->GetVisibleRect();
|
||||
|
||||
nsRect paintRect = visibleRect.Intersect(boundRect);
|
||||
if (paintRect.IsEmpty()) {
|
||||
nsRect paintRect = cdi->mItem->GetVisibleRect().Intersect(boundRect);
|
||||
if (paintRect.IsEmpty())
|
||||
continue;
|
||||
}
|
||||
|
||||
#ifdef MOZ_DUMP_PAINTING
|
||||
AUTO_PROFILER_LABEL_DYNAMIC_CSTR("FrameLayerBuilder::PaintItems", GRAPHICS,
|
||||
item->Name());
|
||||
cdi->mItem->Name());
|
||||
#else
|
||||
AUTO_PROFILER_LABEL("FrameLayerBuilder::PaintItems", GRAPHICS);
|
||||
#endif
|
||||
|
||||
MOZ_ASSERT((opacityNesting == 0 && !cdi.mHasOpacity) ||
|
||||
(opacityNesting > 0 && cdi.mHasOpacity));
|
||||
|
||||
if (cdi.mType == DisplayItemEntryType::PUSH_OPACITY ||
|
||||
cdi.mType == DisplayItemEntryType::PUSH_OPACITY_WITH_BG) {
|
||||
clipTracker.PopClipIfNeeded(opacityNesting);
|
||||
PushOpacity(aContext, paintRect, cdi, appUnitsPerDevPixel);
|
||||
opacityNesting++;
|
||||
}
|
||||
|
||||
if (cdi.mType == DisplayItemEntryType::POP_OPACITY) {
|
||||
MOZ_ASSERT(item->GetType() == DisplayItemType::TYPE_OPACITY);
|
||||
MOZ_ASSERT(opacityNesting > 0);
|
||||
|
||||
clipTracker.PopClipIfNeeded(opacityNesting);
|
||||
aContext->PopGroupAndBlend();
|
||||
aContext->Restore();
|
||||
opacityNesting--;
|
||||
}
|
||||
|
||||
if (cdi.mType != DisplayItemEntryType::ITEM) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// If the new desired clip state is different from the current state,
|
||||
// update the clip.
|
||||
const DisplayItemClip* clip = &item->GetClip();
|
||||
const DisplayItemClip* clip = &cdi->mItem->GetClip();
|
||||
if (clip->GetRoundedRectCount() > 0 &&
|
||||
!clip->IsRectClippedByRoundedCorner(visibleRect)) {
|
||||
!clip->IsRectClippedByRoundedCorner(cdi->mItem->GetVisibleRect())) {
|
||||
tmpClip = *clip;
|
||||
tmpClip.RemoveRoundedCorners();
|
||||
clip = &tmpClip;
|
||||
}
|
||||
if (clipTracker.HasClip(opacityNesting) != clip->HasClip() ||
|
||||
if (currentClipIsSetInContext != clip->HasClip() ||
|
||||
(clip->HasClip() && *clip != currentClip)) {
|
||||
clipTracker.PopClipIfNeeded(opacityNesting);
|
||||
|
||||
if (clip->HasClip()) {
|
||||
if (currentClipIsSetInContext) {
|
||||
aContext->Restore();
|
||||
}
|
||||
currentClipIsSetInContext = clip->HasClip();
|
||||
if (currentClipIsSetInContext) {
|
||||
currentClip = *clip;
|
||||
clipTracker.SaveClip(opacityNesting);
|
||||
currentClip.ApplyTo(aContext, appUnitsPerDevPixel);
|
||||
aContext->Save();
|
||||
currentClip.ApplyTo(aContext, aPresContext->AppUnitsPerDevPixel());
|
||||
aContext->NewPath();
|
||||
}
|
||||
}
|
||||
|
||||
if (cdi.mInactiveLayerManager) {
|
||||
if (cdi->mInactiveLayerManager) {
|
||||
bool saved = aDrawTarget.GetPermitSubpixelAA();
|
||||
PaintInactiveLayer(aBuilder, cdi.mInactiveLayerManager,
|
||||
item, aContext, aContext);
|
||||
PaintInactiveLayer(aBuilder, cdi->mInactiveLayerManager, cdi->mItem, aContext, aContext);
|
||||
aDrawTarget.SetPermitSubpixelAA(saved);
|
||||
} else {
|
||||
nsIFrame* frame = item->Frame();
|
||||
nsIFrame* frame = cdi->mItem->Frame();
|
||||
if (aBuilder->IsPaintingToWindow()) {
|
||||
frame->AddStateBits(NS_FRAME_PAINTED_THEBES);
|
||||
}
|
||||
#ifdef MOZ_DUMP_PAINTING
|
||||
if (gfxEnv::DumpPaintItems()) {
|
||||
DebugPaintItem(aDrawTarget, aPresContext, item, aBuilder);
|
||||
DebugPaintItem(aDrawTarget, aPresContext, cdi->mItem, aBuilder);
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
item->Paint(aBuilder, aContext);
|
||||
cdi->mItem->Paint(aBuilder, aContext);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
clipTracker.PopClipIfNeeded(opacityNesting);
|
||||
MOZ_ASSERT(opacityNesting == 0);
|
||||
if (currentClipIsSetInContext) {
|
||||
aContext->Restore();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -45,13 +45,6 @@ class PaintedLayerData;
|
|||
class ContainerState;
|
||||
class PaintedDisplayItemLayerUserData;
|
||||
|
||||
enum class DisplayItemEntryType {
|
||||
ITEM,
|
||||
PUSH_OPACITY,
|
||||
PUSH_OPACITY_WITH_BG,
|
||||
POP_OPACITY
|
||||
};
|
||||
|
||||
/**
|
||||
* Retained data storage:
|
||||
*
|
||||
|
@ -222,9 +215,7 @@ struct AssignedDisplayItem
|
|||
AssignedDisplayItem(nsDisplayItem* aItem,
|
||||
const DisplayItemClip& aClip,
|
||||
LayerState aLayerState,
|
||||
DisplayItemData* aData,
|
||||
DisplayItemEntryType aType,
|
||||
const bool aHasOpacity);
|
||||
DisplayItemData* aData);
|
||||
~AssignedDisplayItem();
|
||||
|
||||
nsDisplayItem* mItem;
|
||||
|
@ -241,9 +232,6 @@ struct AssignedDisplayItem
|
|||
|
||||
bool mReused;
|
||||
bool mMerged;
|
||||
|
||||
DisplayItemEntryType mType;
|
||||
bool mHasOpacity;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -6409,7 +6409,6 @@ 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;
|
||||
|
@ -6545,8 +6544,27 @@ CollectItemsWithOpacity(nsDisplayList* aList,
|
|||
}
|
||||
|
||||
bool
|
||||
nsDisplayOpacity::ApplyOpacityToChildren(nsDisplayListBuilder* aBuilder)
|
||||
nsDisplayOpacity::ShouldFlattenAway(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;
|
||||
|
@ -6583,41 +6601,9 @@ nsDisplayOpacity::ApplyOpacityToChildren(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 true if we successfully applied opacity to child items, or if
|
||||
// WebRender is not in use. In the latter case, the opacity gets flattened and
|
||||
// applied during layer building.
|
||||
return ApplyOpacityToChildren(aBuilder) || !gfxVars::UseWebRender();
|
||||
}
|
||||
|
||||
nsDisplayItem::LayerState
|
||||
nsDisplayOpacity::GetLayerState(nsDisplayListBuilder* aBuilder,
|
||||
LayerManager* aManager,
|
||||
|
@ -6654,20 +6640,6 @@ nsDisplayOpacity::ComputeVisibility(nsDisplayListBuilder* aBuilder,
|
|||
nsDisplayWrapList::ComputeVisibility(aBuilder, &visibleUnderChildren);
|
||||
}
|
||||
|
||||
void
|
||||
nsDisplayOpacity::ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder,
|
||||
const nsDisplayItemGeometry* aGeometry,
|
||||
nsRegion* aInvalidRegion) const
|
||||
{
|
||||
const nsDisplayOpacityGeometry* geometry =
|
||||
static_cast<const nsDisplayOpacityGeometry*>(aGeometry);
|
||||
|
||||
bool snap;
|
||||
if (mOpacity != geometry->mOpacity) {
|
||||
aInvalidRegion->Or(GetBounds(aBuilder, &snap), geometry->mBounds);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsDisplayOpacity::WriteDebugInfo(std::stringstream& aStream)
|
||||
{
|
||||
|
|
|
@ -3203,92 +3203,6 @@ private:
|
|||
bool mForceTransparentSurface;
|
||||
};
|
||||
|
||||
class FlattenedDisplayItemIterator
|
||||
{
|
||||
public:
|
||||
FlattenedDisplayItemIterator(nsDisplayListBuilder* aBuilder,
|
||||
nsDisplayList* aList,
|
||||
const bool aResolveFlattening = true)
|
||||
: mBuilder(aBuilder)
|
||||
, mNext(aList->GetBottom())
|
||||
{
|
||||
if (aResolveFlattening) {
|
||||
// This is done conditionally in case subclass overrides
|
||||
// ShouldFlattenNextItem().
|
||||
ResolveFlattening();
|
||||
}
|
||||
}
|
||||
|
||||
virtual ~FlattenedDisplayItemIterator()
|
||||
{
|
||||
MOZ_ASSERT(!HasNext());
|
||||
}
|
||||
|
||||
nsDisplayItem* GetNext()
|
||||
{
|
||||
nsDisplayItem* next = mNext;
|
||||
|
||||
// Advance mNext to the following item
|
||||
if (next) {
|
||||
mNext = mNext->GetAbove();
|
||||
ResolveFlattening();
|
||||
}
|
||||
return next;
|
||||
}
|
||||
|
||||
bool HasNext() const
|
||||
{
|
||||
return mNext || !mStack.IsEmpty();
|
||||
}
|
||||
|
||||
nsDisplayItem* PeekNext()
|
||||
{
|
||||
return mNext;
|
||||
}
|
||||
|
||||
protected:
|
||||
bool AtEndOfNestedList() const
|
||||
{
|
||||
return !mNext && mStack.Length() > 0;
|
||||
}
|
||||
|
||||
virtual bool ShouldFlattenNextItem() const
|
||||
{
|
||||
return mNext && mNext->ShouldFlattenAway(mBuilder);
|
||||
}
|
||||
|
||||
void ResolveFlattening()
|
||||
{
|
||||
// Handle the case where we reach the end of a nested list, or the current
|
||||
// item should start a new nested list. Repeat this until we find an actual
|
||||
// item, or the very end of the outer list.
|
||||
while (AtEndOfNestedList() || ShouldFlattenNextItem()) {
|
||||
if (AtEndOfNestedList()) {
|
||||
// Pop the last item off the stack.
|
||||
mNext = mStack.LastElement();
|
||||
EndNested(mNext);
|
||||
mStack.RemoveElementAt(mStack.Length() - 1);
|
||||
// We stored the item that was flattened, so advance to the next.
|
||||
mNext = mNext->GetAbove();
|
||||
} else {
|
||||
// This item wants to be flattened. Store the current item on the stack,
|
||||
// and use the first item in the child list instead.
|
||||
mStack.AppendElement(mNext);
|
||||
StartNested(mNext);
|
||||
nsDisplayList* childItems = mNext->GetSameCoordinateSystemChildren();
|
||||
mNext = childItems->GetBottom();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
virtual void EndNested(nsDisplayItem* aItem) {}
|
||||
virtual void StartNested(nsDisplayItem* aItem) {}
|
||||
|
||||
nsDisplayListBuilder* mBuilder;
|
||||
nsDisplayItem* mNext;
|
||||
AutoTArray<nsDisplayItem*, 10> mStack;
|
||||
};
|
||||
|
||||
/**
|
||||
* This is passed as a parameter to nsIFrame::BuildDisplayList. That method
|
||||
* will put any generated items onto the appropriate list given here. It's
|
||||
|
@ -5246,18 +5160,12 @@ public:
|
|||
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
|
||||
|
@ -5266,7 +5174,6 @@ public:
|
|||
{
|
||||
nsDisplayItem::RestoreState();
|
||||
mOpacity = mState.mOpacity;
|
||||
mOpacityAppliedToChildren = false;
|
||||
}
|
||||
|
||||
virtual nsDisplayWrapList* Clone(nsDisplayListBuilder* aBuilder) const override
|
||||
|
@ -5294,15 +5201,12 @@ public:
|
|||
return HasSameTypeAndClip(aItem) && HasSameContent(aItem);
|
||||
}
|
||||
|
||||
virtual nsDisplayItemGeometry* AllocateGeometry(nsDisplayListBuilder* aBuilder) override
|
||||
{
|
||||
return new nsDisplayOpacityGeometry(this, aBuilder, mOpacity);
|
||||
}
|
||||
|
||||
virtual void ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder,
|
||||
const nsDisplayItemGeometry* aGeometry,
|
||||
nsRegion* aInvalidRegion) const override;
|
||||
|
||||
nsRegion* aInvalidRegion) const override
|
||||
{
|
||||
// We don't need to compute an invalidation region since we have LayerTreeInvalidation
|
||||
}
|
||||
virtual bool IsInvalid(nsRect& aRect) const override
|
||||
{
|
||||
if (mForEventsAndPluginsOnly) {
|
||||
|
@ -5315,12 +5219,6 @@ public:
|
|||
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;
|
||||
|
@ -5336,11 +5234,8 @@ public:
|
|||
float GetOpacity() { return mOpacity; }
|
||||
|
||||
private:
|
||||
bool ApplyOpacityToChildren(nsDisplayListBuilder* aBuilder);
|
||||
|
||||
float mOpacity;
|
||||
bool mForEventsAndPluginsOnly;
|
||||
bool mOpacityAppliedToChildren;
|
||||
|
||||
struct {
|
||||
float mOpacity;
|
||||
|
@ -6876,6 +6771,72 @@ public:
|
|||
mutable mozilla::Maybe<bool> mIsFrameSelected;
|
||||
};
|
||||
|
||||
class FlattenedDisplayItemIterator
|
||||
{
|
||||
public:
|
||||
FlattenedDisplayItemIterator(nsDisplayListBuilder* aBuilder,
|
||||
nsDisplayList* aList)
|
||||
: mBuilder(aBuilder)
|
||||
, mNext(aList->GetBottom())
|
||||
{
|
||||
ResolveFlattening();
|
||||
}
|
||||
|
||||
nsDisplayItem* GetNext()
|
||||
{
|
||||
nsDisplayItem* next = mNext;
|
||||
|
||||
// Advance mNext to the following item
|
||||
if (next) {
|
||||
mNext = mNext->GetAbove();
|
||||
ResolveFlattening();
|
||||
}
|
||||
return next;
|
||||
}
|
||||
|
||||
nsDisplayItem* PeekNext()
|
||||
{
|
||||
return mNext;
|
||||
}
|
||||
|
||||
private:
|
||||
bool AtEndOfNestedList()
|
||||
{
|
||||
return !mNext && mStack.Length() > 0;
|
||||
}
|
||||
|
||||
bool ShouldFlattenNextItem()
|
||||
{
|
||||
return mNext && mNext->ShouldFlattenAway(mBuilder);
|
||||
}
|
||||
|
||||
void ResolveFlattening()
|
||||
{
|
||||
// Handle the case where we reach the end of a nested list, or the current
|
||||
// item should start a new nested list. Repeat this until we find an actual
|
||||
// item, or the very end of the outer list.
|
||||
while (AtEndOfNestedList() || ShouldFlattenNextItem()) {
|
||||
if (AtEndOfNestedList()) {
|
||||
// Pop the last item off the stack.
|
||||
mNext = mStack.PopLastElement();
|
||||
// We stored the item that was flattened, so advance to the next.
|
||||
mNext = mNext->GetAbove();
|
||||
} else {
|
||||
// This item wants to be flattened. Store the current item on the stack,
|
||||
// and use the first item in the child list instead.
|
||||
mStack.AppendElement(mNext);
|
||||
nsDisplayList* childItems = mNext->GetSameCoordinateSystemChildren();
|
||||
mNext = childItems->GetBottom();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
nsDisplayListBuilder* mBuilder;
|
||||
nsDisplayItem* mNext;
|
||||
AutoTArray<nsDisplayItem*, 10> mStack;
|
||||
};
|
||||
|
||||
/**
|
||||
* A display item that for webrender to handle SVG
|
||||
*/
|
||||
|
|
|
@ -353,17 +353,4 @@ public:
|
|||
nsPoint mFrameOffsetToViewport;
|
||||
};
|
||||
|
||||
class nsDisplayOpacityGeometry : public nsDisplayItemGenericGeometry
|
||||
{
|
||||
public:
|
||||
nsDisplayOpacityGeometry(nsDisplayItem* aItem,
|
||||
nsDisplayListBuilder* aBuilder,
|
||||
float aOpacity)
|
||||
: nsDisplayItemGenericGeometry(aItem, aBuilder)
|
||||
, mOpacity(aOpacity)
|
||||
{}
|
||||
|
||||
float mOpacity;
|
||||
};
|
||||
|
||||
#endif /*NSDISPLAYLISTINVALIDATION_H_*/
|
||||
|
|
|
@ -1682,7 +1682,7 @@ HTTP == 652991-3.html 652991-3-ref.html
|
|||
HTTP == 652991-4.html 652991-4-ref.html
|
||||
fuzzy-if(skiaContent,1,5) == 653930-1.html 653930-1-ref.html
|
||||
== 654057-1.html 654057-1-ref.html
|
||||
fuzzy-if(skiaContent,1,65536) == 654950-1.html 654950-1-ref.html # Quartz alpha blending doesn't match GL alpha blending
|
||||
fuzzy-if(skiaContent,1,4500) == 654950-1.html 654950-1-ref.html # Quartz alpha blending doesn't match GL alpha blending
|
||||
== 655549-1.html 655549-1-ref.html
|
||||
== 655836-1.html 655836-1-ref.html
|
||||
!= 656875.html about:blank
|
||||
|
|
|
@ -16,7 +16,7 @@ fails == grid-whitespace-handling-1b.xhtml grid-whitespace-handling-1-ref.xhtml
|
|||
== grid-track-sizing-001.html grid-track-sizing-001-ref.html
|
||||
== grid-track-sizing-002.html grid-track-sizing-002-ref.html
|
||||
== grid-abspos-items-001.html grid-abspos-items-001-ref.html
|
||||
fuzzy(180,3) == grid-abspos-items-002.html grid-abspos-items-002-ref.html # flattening differences
|
||||
== grid-abspos-items-002.html grid-abspos-items-002-ref.html
|
||||
== grid-abspos-items-003.html grid-abspos-items-003-ref.html
|
||||
== grid-abspos-items-004.html grid-abspos-items-004-ref.html
|
||||
== grid-abspos-items-005.html grid-abspos-items-005-ref.html
|
||||
|
|
|
@ -5,7 +5,7 @@ fuzzy-if(Android,16,244) == marker-basic.html marker-basic-ref.html # Bug 11282
|
|||
skip-if(Android) == bidi-simple.html bidi-simple-ref.html # Fails on Android due to anti-aliasing
|
||||
skip-if(!gtkWidget) fuzzy-if(gtkWidget,2,289) == bidi-simple-scrolled.html bidi-simple-scrolled-ref.html # Fails on Windows and OSX due to anti-aliasing
|
||||
fuzzy-if(Android,24,4000) fuzzy-if(cocoaWidget,1,40) fuzzy-if(asyncPan&&!layersGPUAccelerated,149,1836) == scroll-rounding.html scroll-rounding-ref.html # bug 760264
|
||||
fuzzy(2,453) fuzzy-if(skiaContent,16,435) fails-if(gtkWidget) fuzzy-if(webrender&&winWidget,50-50,499-499) == anonymous-block.html anonymous-block-ref.html # gtkWidget:bug 1309103, skia: subpixel aa
|
||||
fuzzy(2,453) fuzzy-if(skiaContent,9,2100) fails-if(gtkWidget) fuzzy-if(webrender&&winWidget,50-50,499-499) == anonymous-block.html anonymous-block-ref.html # gtkWidget:bug 1309103
|
||||
== false-marker-overlap.html false-marker-overlap-ref.html
|
||||
== visibility-hidden.html visibility-hidden-ref.html
|
||||
fuzzy-if(asyncPan&&!layersGPUAccelerated,102,1724) fuzzy-if(gtkWidget,10,8) == block-padding.html block-padding-ref.html
|
||||
|
|
Загрузка…
Ссылка в новой задаче