Bug 1526972 - P1: Compress bool state into bit flags. r=miko

Also move to first cache-line (64-bytes) of nsDisplayItem to improve D-cache hit
when accessing mFrame, mItemFlags, etc.

Differential Revision: https://phabricator.services.mozilla.com/D26134

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Dan Glastonbury 2019-04-15 00:23:07 +00:00
Родитель 86cd66683b
Коммит a9319e3ae3
9 изменённых файлов: 111 добавлений и 75 удалений

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

@ -218,7 +218,7 @@ static void PaintTextShadowCallback(gfxContext* aCtx, nsPoint aShadowOffset,
void nsDisplayTextOverflowMarker::Paint(nsDisplayListBuilder* aBuilder,
gfxContext* aCtx) {
DrawTargetAutoDisableSubpixelAntialiasing disable(aCtx->GetDrawTarget(),
mDisableSubpixelAA);
IsSubpixelAADisabled());
nscolor foregroundColor =
nsLayoutUtils::GetColor(mFrame, &nsStyleText::mWebkitTextFillColor);

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

@ -646,7 +646,7 @@ void nsDisplayBullet::Paint(nsDisplayListBuilder* aBuilder, gfxContext* aCtx) {
}
ImgDrawResult result = static_cast<nsBulletFrame*>(mFrame)->PaintBullet(
*aCtx, ToReferenceFrame(), GetPaintRect(), flags, mDisableSubpixelAA);
*aCtx, ToReferenceFrame(), GetPaintRect(), flags, IsSubpixelAADisabled());
nsDisplayBulletGeometry::UpdateDrawResult(this, result);
}

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

@ -457,7 +457,7 @@ class nsDisplayHeaderFooter final : public nsDisplayItem {
MOZ_ASSERT(pageFrame, "We should have an nsPageFrame");
#endif
static_cast<nsPageFrame*>(mFrame)->PaintHeaderFooter(
*aCtx, ToReferenceFrame(), mDisableSubpixelAA);
*aCtx, ToReferenceFrame(), IsSubpixelAADisabled());
}
NS_DISPLAY_DECL_NAME("HeaderFooter", TYPE_HEADER_FOOTER)

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

@ -141,8 +141,7 @@ bool RetainedDisplayListBuilder::PreProcessDisplayList(
MOZ_RELEASE_ASSERT(aList->mOldItems.IsEmpty());
while (nsDisplayItem* item = aList->RemoveBottom()) {
#ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED
item->mMergedItem = false;
item->mPreProcessedItem = true;
item->SetMergedPreProcessed(false, true);
#endif
if (item->HasDeletedFrame() || !item->CanBeReused()) {
@ -496,12 +495,11 @@ class MergeState {
for (nsDisplayItem* i : *items) {
if (i->Frame() == aItem->Frame() &&
i->GetPerFrameKey() == aItem->GetPerFrameKey()) {
MOZ_DIAGNOSTIC_ASSERT(!i->mMergedItem);
MOZ_DIAGNOSTIC_ASSERT(!i->IsMergedItem());
}
}
aItem->mMergedItem = true;
aItem->mPreProcessedItem = false;
aItem->SetMergedPreProcessed(true, false);
#endif
mMergedItems.AppendToTop(aItem);

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

@ -135,7 +135,7 @@ void AssertUniqueItem(nsDisplayItem* aItem) {
for (nsDisplayItem* i : *items) {
if (i != aItem && !i->HasDeletedFrame() && i->Frame() == aItem->Frame() &&
i->GetPerFrameKey() == aItem->GetPerFrameKey()) {
if (i->mPreProcessedItem) {
if (i->IsPreProcessedItem()) {
continue;
}
MOZ_DIAGNOSTIC_ASSERT(false, "Duplicate display item!");
@ -3171,18 +3171,9 @@ nsDisplayItem::nsDisplayItem(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame)
nsDisplayItem::nsDisplayItem(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
const ActiveScrolledRoot* aActiveScrolledRoot)
: mFrame(aFrame),
mItemFlags(),
mActiveScrolledRoot(aActiveScrolledRoot),
mAnimatedGeometryRoot(nullptr),
mForceNotVisible(aBuilder->IsBuildingInvisibleItems()),
mDisableSubpixelAA(false),
mReusedItem(false),
mPaintRectValid(false),
mCanBeReused(true)
#ifdef MOZ_DUMP_PAINTING
,
mPainted(false)
#endif
{
mAnimatedGeometryRoot(nullptr) {
MOZ_COUNT_CTOR(nsDisplayItem);
if (aBuilder->IsRetainingDisplayList()) {
mFrame->AddDisplayItem(this);
@ -3208,9 +3199,12 @@ nsDisplayItem::nsDisplayItem(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
SetBuildingRect(visible);
const nsStyleDisplay* disp = mFrame->StyleDisplay();
mBackfaceIsHidden = mFrame->BackfaceIsHidden(disp);
mCombines3DTransformWithAncestors =
mFrame->Combines3DTransformWithAncestors(disp);
if (mFrame->BackfaceIsHidden(disp)) {
mItemFlags += ItemFlag::BackfaceHidden;
}
if (mFrame->Combines3DTransformWithAncestors(disp)) {
mItemFlags += ItemFlag::Combines3DTransformWithAncestors;
}
}
/* static */
@ -3236,7 +3230,7 @@ bool nsDisplayItem::ComputeVisibility(nsDisplayListBuilder* aBuilder,
bool nsDisplayItem::RecomputeVisibility(nsDisplayListBuilder* aBuilder,
nsRegion* aVisibleRegion) {
if (mForceNotVisible && !GetSameCoordinateSystemChildren()) {
if (ForceNotVisible() && !GetSameCoordinateSystemChildren()) {
// mForceNotVisible wants to ensure that this display item doesn't render
// anything itself. If this item has contents, then we obviously want to
// render those, so we don't need this check in that case.
@ -8944,7 +8938,7 @@ void nsDisplayText::Paint(nsDisplayListBuilder* aBuilder, gfxContext* aCtx) {
AUTO_PROFILER_LABEL("nsDisplayText::Paint", GRAPHICS);
DrawTargetAutoDisableSubpixelAntialiasing disable(aCtx->GetDrawTarget(),
mDisableSubpixelAA);
IsSubpixelAADisabled());
RenderToContext(aCtx, aBuilder);
}

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

@ -2183,7 +2183,7 @@ class nsDisplayItem : public nsDisplayItemLink {
virtual void RestoreState() {
mClipChain = mState.mClipChain;
mClip = mState.mClip;
mDisableSubpixelAA = false;
mItemFlags -= ItemFlag::DisableSubpixelAA;
}
virtual void RemoveFrame(nsIFrame* aFrame) {
@ -2215,6 +2215,7 @@ class nsDisplayItem : public nsDisplayItemLink {
*/
nsDisplayItem(nsDisplayListBuilder* aBuilder, const nsDisplayItem& aOther)
: mFrame(aOther.mFrame),
mItemFlags(),
mClipChain(aOther.mClipChain),
mClip(aOther.mClip),
mActiveScrolledRoot(aOther.mActiveScrolledRoot),
@ -2222,21 +2223,21 @@ class nsDisplayItem : public nsDisplayItemLink {
mAnimatedGeometryRoot(aOther.mAnimatedGeometryRoot),
mToReferenceFrame(aOther.mToReferenceFrame),
mBuildingRect(aOther.mBuildingRect),
mPaintRect(aOther.mPaintRect),
mForceNotVisible(aOther.mForceNotVisible),
mDisableSubpixelAA(aOther.mDisableSubpixelAA),
mReusedItem(false),
mBackfaceIsHidden(aOther.mBackfaceIsHidden),
mCombines3DTransformWithAncestors(
aOther.mCombines3DTransformWithAncestors),
mPaintRectValid(false),
mCanBeReused(true)
#ifdef MOZ_DUMP_PAINTING
,
mPainted(false)
#endif
{
mPaintRect(aOther.mPaintRect) {
MOZ_COUNT_CTOR(nsDisplayItem);
// TODO: It might be better to remove the flags that aren't copied.
if (aOther.ForceNotVisible()) {
mItemFlags += ItemFlag::ForceNotVisible;
}
if (aOther.IsSubpixelAADisabled()) {
mItemFlags += ItemFlag::DisableSubpixelAA;
}
if (mFrame->In3DContextAndBackfaceIsHidden()) {
mItemFlags += ItemFlag::BackfaceHidden;
}
if (aOther.Combines3DTransformWithAncestors()) {
mItemFlags += ItemFlag::Combines3DTransformWithAncestors;
}
}
struct HitTestState {
@ -2544,12 +2545,12 @@ class nsDisplayItem : public nsDisplayItemLink {
* Mark this display item as being painted via
* FrameLayerBuilder::DrawPaintedLayer.
*/
bool Painted() const { return mPainted; }
bool Painted() const { return mItemFlags.contains(ItemFlag::Painted); }
/**
* Check if this display item has been painted.
*/
void SetPainted() { mPainted = true; }
void SetPainted() { mItemFlags += ItemFlag::Painted; }
#endif
/**
@ -2732,14 +2733,16 @@ class nsDisplayItem : public nsDisplayItemLink {
return;
}
mPaintRect = mBuildingRect = aBuildingRect;
mPaintRectValid = false;
mItemFlags -= ItemFlag::PaintRectValid;
}
void SetPaintRect(const nsRect& aPaintRect) {
mPaintRect = aPaintRect;
mPaintRectValid = true;
mItemFlags += ItemFlag::PaintRectValid;
}
bool HasPaintRect() const {
return mItemFlags.contains(ItemFlag::PaintRectValid);
}
bool HasPaintRect() const { return mPaintRectValid; }
/**
* Returns the building rect for the children, relative to their
@ -2765,7 +2768,9 @@ class nsDisplayItem : public nsDisplayItemLink {
*/
virtual bool CanApplyOpacity() const { return false; }
bool ForceNotVisible() const { return mForceNotVisible; }
bool ForceNotVisible() const {
return mItemFlags.contains(ItemFlag::ForceNotVisible);
}
/**
* For debugging and stuff
@ -2831,9 +2836,11 @@ class nsDisplayItem : public nsDisplayItemLink {
* Disable usage of component alpha. Currently only relevant for items that
* have text.
*/
void DisableComponentAlpha() { mDisableSubpixelAA = true; }
void DisableComponentAlpha() { mItemFlags += ItemFlag::DisableSubpixelAA; }
bool IsSubpixelAADisabled() const { return mDisableSubpixelAA; }
bool IsSubpixelAADisabled() const {
return mItemFlags.contains(ItemFlag::DisableSubpixelAA);
}
/**
* Check if we can add async animations to the layer for this display item.
@ -2869,14 +2876,17 @@ class nsDisplayItem : public nsDisplayItemLink {
void FuseClipChainUpTo(nsDisplayListBuilder* aBuilder,
const ActiveScrolledRoot* aASR);
bool BackfaceIsHidden() const { return mBackfaceIsHidden; }
bool BackfaceIsHidden() const {
return mItemFlags.contains(ItemFlag::BackfaceHidden);
}
bool Combines3DTransformWithAncestors() const {
return mCombines3DTransformWithAncestors;
return mItemFlags.contains(ItemFlag::Combines3DTransformWithAncestors);
}
bool In3DContextAndBackfaceIsHidden() const {
return mBackfaceIsHidden && mCombines3DTransformWithAncestors;
return mItemFlags.contains(ItemFlag::BackfaceHidden) &&
mItemFlags.contains(ItemFlag::Combines3DTransformWithAncestors);
}
bool HasDifferentFrame(const nsDisplayItem* aOther) const {
@ -2892,14 +2902,22 @@ class nsDisplayItem : public nsDisplayItemLink {
return mFrame->GetContent() == aOther->Frame()->GetContent();
}
bool IsReused() const { return mReusedItem; }
bool IsReused() const { return mItemFlags.contains(ItemFlag::ReusedItem); }
void SetReused(bool aReused) {
if (aReused) {
mItemFlags += ItemFlag::ReusedItem;
} else {
mItemFlags -= ItemFlag::ReusedItem;
}
}
void SetReused(bool aReused) { mReusedItem = aReused; }
bool CanBeReused() const { return mCanBeReused; }
bool CanBeReused() const {
return !mItemFlags.contains(ItemFlag::CantBeReused);
}
void SetCantBeReused() { mItemFlags += ItemFlag::CantBeReused; }
void DiscardIfOldItem() {
if (mOldList) {
mCanBeReused = false;
SetCantBeReused();
}
}
virtual void NotifyUsed(nsDisplayListBuilder* aBuilder) {}
@ -2975,7 +2993,26 @@ class nsDisplayItem : public nsDisplayItemLink {
bool ShouldUseAdvancedLayer(LayerManager* aManager, PrefFunc aFunc) const;
bool CanUseAdvancedLayer(LayerManager* aManager) const;
enum class ItemFlag {
ForceNotVisible,
DisableSubpixelAA,
CantBeReused,
ReusedItem,
BackfaceHidden,
Combines3DTransformWithAncestors,
PaintRectValid,
#ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED
MergedItem,
PreProcessedItem,
#endif
#ifdef MOZ_DUMP_PAINTING
// True if this frame has been painted.
Painted,
#endif
};
nsIFrame* mFrame;
mozilla::EnumSet<ItemFlag, uint16_t> mItemFlags;
RefPtr<const DisplayItemClipChain> mClipChain;
const DisplayItemClip* mClip;
RefPtr<const ActiveScrolledRoot> mActiveScrolledRoot;
@ -3009,26 +3046,31 @@ class nsDisplayItem : public nsDisplayItemLink {
#ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED
public:
bool IsMergedItem() const {
return mItemFlags.contains(ItemFlag::MergedItem);
}
bool IsPreProcessedItem() const {
return mItemFlags.contains(ItemFlag::PreProcessedItem);
}
void SetMergedPreProcessed(bool aMerged, bool aPreProcessed) {
if (aMerged) {
mItemFlags += ItemFlag::MergedItem;
} else {
mItemFlags -= ItemFlag::MergedItem;
}
if (aPreProcessed) {
mItemFlags += ItemFlag::PreProcessedItem;
} else {
mItemFlags -= ItemFlag::PreProcessedItem;
}
}
uint32_t mOldListKey = 0;
uint32_t mOldNestingDepth = 0;
bool mMergedItem = false;
bool mPreProcessedItem = false;
protected:
#endif
bool mForceNotVisible;
bool mDisableSubpixelAA;
bool mReusedItem;
bool mBackfaceIsHidden;
bool mCombines3DTransformWithAncestors;
bool mPaintRectValid;
bool mCanBeReused;
#ifdef MOZ_DUMP_PAINTING
// True if this frame has been painted.
bool mPainted;
#endif
};
/**
@ -4161,7 +4203,9 @@ class nsDisplaySolidColor : public nsDisplaySolidColorBase {
NS_ASSERTION(NS_GET_A(aColor) > 0,
"Don't create invisible nsDisplaySolidColors!");
MOZ_COUNT_CTOR(nsDisplaySolidColor);
mCanBeReused = aCanBeReused;
if (!aCanBeReused) {
SetCantBeReused();
}
}
#ifdef NS_BUILD_REFCNT_LOGGING

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

@ -2861,7 +2861,7 @@ void nsDisplaySVGText::HitTest(nsDisplayListBuilder* aBuilder,
void nsDisplaySVGText::Paint(nsDisplayListBuilder* aBuilder, gfxContext* aCtx) {
DrawTargetAutoDisableSubpixelAntialiasing disable(aCtx->GetDrawTarget(),
mDisableSubpixelAA);
IsSubpixelAADisabled());
uint32_t appUnitsPerDevPixel = mFrame->PresContext()->AppUnitsPerDevPixel();

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

@ -278,7 +278,7 @@ static void PaintTextShadowCallback(gfxContext* aCtx, nsPoint aShadowOffset,
void nsDisplayXULTextBox::Paint(nsDisplayListBuilder* aBuilder,
gfxContext* aCtx) {
DrawTargetAutoDisableSubpixelAntialiasing disable(aCtx->GetDrawTarget(),
mDisableSubpixelAA);
IsSubpixelAADisabled());
// Paint the text shadow before doing any foreground stuff
nsRect drawRect =

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

@ -2498,7 +2498,7 @@ class nsDisplayTreeBody final : public nsDisplayItem {
gfxContext* aCtx) override {
MOZ_ASSERT(aBuilder);
DrawTargetAutoDisableSubpixelAntialiasing disable(aCtx->GetDrawTarget(),
mDisableSubpixelAA);
IsSubpixelAADisabled());
ImgDrawResult result = static_cast<nsTreeBodyFrame*>(mFrame)->PaintTreeBody(
*aCtx, GetPaintRect(), ToReferenceFrame(), aBuilder);