Backed out 6 changesets (bug 1442190) for failing reftest text-overflow/anonymous-block.html, at least on OS X on a CLOSED TREE

Backed out changeset db65cdb10a34 (bug 1442190)
Backed out changeset 1ca2a0266f20 (bug 1442190)
Backed out changeset c992deef1ec5 (bug 1442190)
Backed out changeset 9503cb9d5fc1 (bug 1442190)
Backed out changeset 8018f83c161b (bug 1442190)
Backed out changeset 7f82627c75fa (bug 1442190)
This commit is contained in:
Andreea Pavel 2018-04-11 17:04:36 +03:00
Родитель 5c103c6c50
Коммит 4e68a27bb1
7 изменённых файлов: 179 добавлений и 615 удалений

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

@ -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