forked from mirrors/gecko-dev
Bug 1809061 - Simplify background painting. r=tnikkel,layout-reviewers
The issue here is that DealWithWindowsAppearanceHacks doesn't run unless we're actually painting a background because we look at `mDefaultAppearance` and nsIFrame only checks `HasAppearance`. However this code can be simplified a bit, now that we cleaned up background propagation in bug 1665476. Enter in AppendBackgroundItemsToTop unconditionally, and clean up a bit while at it. Differential Revision: https://phabricator.services.mozilla.com/D166352
This commit is contained in:
parent
f4948f24dd
commit
673df6949e
3 changed files with 65 additions and 105 deletions
|
|
@ -2621,8 +2621,7 @@ auto nsIFrame::ComputeShouldPaintBackground() const -> ShouldPaintBackground {
|
|||
|
||||
bool nsIFrame::DisplayBackgroundUnconditional(nsDisplayListBuilder* aBuilder,
|
||||
const nsDisplayListSet& aLists) {
|
||||
const bool hitTesting = aBuilder->IsForEventDelivery();
|
||||
if (hitTesting && !aBuilder->HitTestIsForVisibility()) {
|
||||
if (aBuilder->IsForEventDelivery() && !aBuilder->HitTestIsForVisibility()) {
|
||||
// For hit-testing, we generally just need a light-weight data structure
|
||||
// like nsDisplayEventReceiver. But if the hit-testing is for visibility,
|
||||
// then we need to know the opaque region in order to determine whether to
|
||||
|
|
@ -2632,21 +2631,11 @@ bool nsIFrame::DisplayBackgroundUnconditional(nsDisplayListBuilder* aBuilder,
|
|||
return false;
|
||||
}
|
||||
|
||||
AppendedBackgroundType result = AppendedBackgroundType::None;
|
||||
// Here we don't try to detect background propagation, canvas frame does its
|
||||
// own thing.
|
||||
if (hitTesting || !StyleBackground()->IsTransparent(this) ||
|
||||
StyleDisplay()->HasAppearance() ||
|
||||
// We do forcibly create a display item for background color animations
|
||||
// even if the current background-color is transparent so that we can
|
||||
// run the animations on the compositor.
|
||||
EffectCompositor::HasAnimationsForCompositor(
|
||||
this, DisplayItemType::TYPE_BACKGROUND_COLOR)) {
|
||||
result = nsDisplayBackgroundImage::AppendBackgroundItemsToTop(
|
||||
aBuilder, this,
|
||||
GetRectRelativeToSelf() + aBuilder->ToReferenceFrame(this),
|
||||
aLists.BorderBackground());
|
||||
}
|
||||
const AppendedBackgroundType result =
|
||||
nsDisplayBackgroundImage::AppendBackgroundItemsToTop(
|
||||
aBuilder, this,
|
||||
GetRectRelativeToSelf() + aBuilder->ToReferenceFrame(this),
|
||||
aLists.BorderBackground());
|
||||
|
||||
if (result == AppendedBackgroundType::None) {
|
||||
aBuilder->BuildCompositorHitTestInfoIfNeeded(this,
|
||||
|
|
|
|||
|
|
@ -2955,28 +2955,6 @@ nsDisplayBackgroundImage::~nsDisplayBackgroundImage() {
|
|||
}
|
||||
}
|
||||
|
||||
static nsIFrame* GetBackgroundComputedStyleFrame(nsIFrame* aFrame) {
|
||||
nsIFrame* f = nsCSSRendering::FindBackgroundFrame(aFrame);
|
||||
if (!f) {
|
||||
// We don't want to bail out if moz-appearance is set on a root
|
||||
// node. If it has a parent content node, bail because it's not
|
||||
// a root, other wise keep going in order to let the theme stuff
|
||||
// draw the background. The canvas really should be drawing the
|
||||
// bg, but there's no way to hook that up via css.
|
||||
if (!aFrame->StyleDisplay()->HasAppearance()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsIContent* content = aFrame->GetContent();
|
||||
if (!content || content->GetParent()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
f = aFrame;
|
||||
}
|
||||
return f;
|
||||
}
|
||||
|
||||
static void SetBackgroundClipRegion(
|
||||
DisplayListClipState::AutoSaveRestore& aClipState, nsIFrame* aFrame,
|
||||
const nsStyleImageLayers::Layer& aLayer, const nsRect& aBackgroundRect,
|
||||
|
|
@ -3072,7 +3050,7 @@ static nsDisplayBackgroundImage* CreateBackgroundImage(
|
|||
|
||||
static nsDisplayThemedBackground* CreateThemedBackground(
|
||||
nsDisplayListBuilder* aBuilder, nsIFrame* aFrame, nsIFrame* aSecondaryFrame,
|
||||
nsRect& aBgRect) {
|
||||
const nsRect& aBgRect) {
|
||||
if (aSecondaryFrame) {
|
||||
const uint16_t index = static_cast<uint16_t>(GetTableTypeFromFrame(aFrame));
|
||||
return MakeDisplayItemWithIndex<nsDisplayTableThemedBackground>(
|
||||
|
|
@ -3131,36 +3109,39 @@ AppendedBackgroundType nsDisplayBackgroundImage::AppendBackgroundItemsToTop(
|
|||
nsIFrame* aSecondaryReferenceFrame,
|
||||
Maybe<nsDisplayListBuilder::AutoBuildingDisplayList>*
|
||||
aAutoBuildingDisplayList) {
|
||||
const ComputedStyle* bgSC = nullptr;
|
||||
const nsStyleBackground* bg = nullptr;
|
||||
nsRect bgRect = aBackgroundRect;
|
||||
nsRect bgOriginRect = bgRect;
|
||||
if (!aBackgroundOriginRect.IsEmpty()) {
|
||||
bgOriginRect = aBackgroundOriginRect;
|
||||
MOZ_ASSERT(!aFrame->IsCanvasFrame(),
|
||||
"We don't expect propagated canvas backgrounds here");
|
||||
#ifdef DEBUG
|
||||
{
|
||||
nsIFrame* bgFrame = nsCSSRendering::FindBackgroundFrame(aFrame);
|
||||
MOZ_ASSERT(
|
||||
!bgFrame || bgFrame == aFrame,
|
||||
"Should only suppress backgrounds, never propagate to another frame");
|
||||
}
|
||||
const bool isThemed = aFrame->IsThemed();
|
||||
#endif
|
||||
|
||||
DealWithWindowsAppearanceHacks(aFrame, aBuilder);
|
||||
|
||||
nsIFrame* dependentFrame = nullptr;
|
||||
if (!isThemed) {
|
||||
if (!bgSC) {
|
||||
dependentFrame = GetBackgroundComputedStyleFrame(aFrame);
|
||||
if (dependentFrame) {
|
||||
bgSC = dependentFrame->Style();
|
||||
if (dependentFrame == aFrame) {
|
||||
dependentFrame = nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (bgSC) {
|
||||
bg = bgSC->StyleBackground();
|
||||
}
|
||||
const bool isThemed = aFrame->IsThemed();
|
||||
|
||||
const ComputedStyle* bgSC = aFrame->Style();
|
||||
const nsStyleBackground* bg = bgSC->StyleBackground();
|
||||
const bool needsBackgroundColor =
|
||||
aBuilder->IsForEventDelivery() ||
|
||||
(EffectCompositor::HasAnimationsForCompositor(
|
||||
aFrame, DisplayItemType::TYPE_BACKGROUND_COLOR) &&
|
||||
!isThemed);
|
||||
if (!needsBackgroundColor && !isThemed && bg->IsTransparent(bgSC)) {
|
||||
return AppendedBackgroundType::None;
|
||||
}
|
||||
|
||||
bool drawBackgroundColor = false;
|
||||
bool drawBackgroundImage = false;
|
||||
nscolor color = NS_RGBA(0, 0, 0, 0);
|
||||
if (bg && !(aFrame->IsCanvasFrame() || aFrame->IsViewportFrame())) {
|
||||
// Don't get background color / images if we propagated our background to the
|
||||
// canvas (that is, if FindBackgroundFrame is null). But don't early return
|
||||
// yet, since we might still need a background-color item for hit-testing.
|
||||
if (!isThemed && nsCSSRendering::FindBackgroundFrame(aFrame)) {
|
||||
color = nsCSSRendering::DetermineBackgroundColor(
|
||||
aFrame->PresContext(), bgSC, aFrame, drawBackgroundImage,
|
||||
drawBackgroundColor);
|
||||
|
|
@ -3171,11 +3152,21 @@ AppendedBackgroundType nsDisplayBackgroundImage::AppendBackgroundItemsToTop(
|
|||
return AppendedBackgroundType::None;
|
||||
}
|
||||
|
||||
const nsStyleBorder* borderStyle = aFrame->StyleBorder();
|
||||
const nsStyleEffects* effectsStyle = aFrame->StyleEffects();
|
||||
bool hasInsetShadow = effectsStyle->HasBoxShadowWithInset(true);
|
||||
bool willPaintBorder = aAllowWillPaintBorderOptimization && !isThemed &&
|
||||
!hasInsetShadow && borderStyle->HasBorder();
|
||||
const nsStyleBorder& border = *aFrame->StyleBorder();
|
||||
const bool willPaintBorder =
|
||||
aAllowWillPaintBorderOptimization && !isThemed &&
|
||||
!aFrame->StyleEffects()->HasBoxShadowWithInset(true) &&
|
||||
border.HasBorder();
|
||||
|
||||
auto EnsureBuildingDisplayList = [&] {
|
||||
if (!aAutoBuildingDisplayList || *aAutoBuildingDisplayList) {
|
||||
return;
|
||||
}
|
||||
nsPoint offset = aBuilder->GetCurrentFrame()->GetOffsetTo(aFrame);
|
||||
aAutoBuildingDisplayList->emplace(aBuilder, aFrame,
|
||||
aBuilder->GetVisibleRect() + offset,
|
||||
aBuilder->GetDirtyRect() + offset);
|
||||
};
|
||||
|
||||
// An auxiliary list is necessary in case we have background blending; if that
|
||||
// is the case, background items need to be wrapped by a blend container to
|
||||
|
|
@ -3185,19 +3176,11 @@ AppendedBackgroundType nsDisplayBackgroundImage::AppendBackgroundItemsToTop(
|
|||
// need to create an item for hit testing and we still need to create an item
|
||||
// for background-color animations.
|
||||
if ((drawBackgroundColor && color != NS_RGBA(0, 0, 0, 0)) ||
|
||||
aBuilder->IsForEventDelivery() ||
|
||||
(EffectCompositor::HasAnimationsForCompositor(
|
||||
aFrame, DisplayItemType::TYPE_BACKGROUND_COLOR) &&
|
||||
!isThemed)) {
|
||||
if (aAutoBuildingDisplayList && !*aAutoBuildingDisplayList) {
|
||||
nsPoint offset = aBuilder->GetCurrentFrame()->GetOffsetTo(aFrame);
|
||||
aAutoBuildingDisplayList->emplace(aBuilder, aFrame,
|
||||
aBuilder->GetVisibleRect() + offset,
|
||||
aBuilder->GetDirtyRect() + offset);
|
||||
}
|
||||
needsBackgroundColor) {
|
||||
EnsureBuildingDisplayList();
|
||||
Maybe<DisplayListClipState::AutoSaveRestore> clipState;
|
||||
nsRect bgColorRect = bgRect;
|
||||
if (bg && !aBuilder->IsForEventDelivery()) {
|
||||
nsRect bgColorRect = aBackgroundRect;
|
||||
if (!isThemed && !aBuilder->IsForEventDelivery()) {
|
||||
// Disable the will-paint-border optimization for background
|
||||
// colors with no border-radius. Enabling it for background colors
|
||||
// doesn't help much (there are no tiling issues) and clipping the
|
||||
|
|
@ -3205,13 +3188,13 @@ AppendedBackgroundType nsDisplayBackgroundImage::AppendBackgroundItemsToTop(
|
|||
// opaque. For nonzero border-radius we still need it because we
|
||||
// want to inset the background if possible to avoid antialiasing
|
||||
// artifacts along the rounded corners.
|
||||
bool useWillPaintBorderOptimization =
|
||||
const bool useWillPaintBorderOptimization =
|
||||
willPaintBorder &&
|
||||
nsLayoutUtils::HasNonZeroCorner(borderStyle->mBorderRadius);
|
||||
nsLayoutUtils::HasNonZeroCorner(border.mBorderRadius);
|
||||
|
||||
nsCSSRendering::ImageLayerClipState clip;
|
||||
nsCSSRendering::GetImageLayerClip(
|
||||
bg->BottomLayer(), aFrame, *aFrame->StyleBorder(), bgRect, bgRect,
|
||||
bg->BottomLayer(), aFrame, border, aBackgroundRect, aBackgroundRect,
|
||||
useWillPaintBorderOptimization,
|
||||
aFrame->PresContext()->AppUnitsPerDevPixel(), &clip);
|
||||
|
||||
|
|
@ -3230,14 +3213,13 @@ AppendedBackgroundType nsDisplayBackgroundImage::AppendBackgroundItemsToTop(
|
|||
drawBackgroundColor ? color : NS_RGBA(0, 0, 0, 0));
|
||||
|
||||
if (bgItem) {
|
||||
bgItem->SetDependentFrame(aBuilder, dependentFrame);
|
||||
bgItemList.AppendToTop(bgItem);
|
||||
}
|
||||
}
|
||||
|
||||
if (isThemed) {
|
||||
nsDisplayThemedBackground* bgItem = CreateThemedBackground(
|
||||
aBuilder, aFrame, aSecondaryReferenceFrame, bgRect);
|
||||
aBuilder, aFrame, aSecondaryReferenceFrame, aBackgroundRect);
|
||||
|
||||
if (bgItem) {
|
||||
bgItem->Init(aBuilder);
|
||||
|
|
@ -3252,7 +3234,7 @@ AppendedBackgroundType nsDisplayBackgroundImage::AppendBackgroundItemsToTop(
|
|||
return AppendedBackgroundType::None;
|
||||
}
|
||||
|
||||
if (!bg || !drawBackgroundImage) {
|
||||
if (!drawBackgroundImage) {
|
||||
if (!bgItemList.IsEmpty()) {
|
||||
aList->AppendToTop(&bgItemList);
|
||||
return AppendedBackgroundType::Background;
|
||||
|
|
@ -3264,6 +3246,8 @@ AppendedBackgroundType nsDisplayBackgroundImage::AppendBackgroundItemsToTop(
|
|||
const ActiveScrolledRoot* asr = aBuilder->CurrentActiveScrolledRoot();
|
||||
|
||||
bool needBlendContainer = false;
|
||||
const nsRect& bgOriginRect =
|
||||
aBackgroundOriginRect.IsEmpty() ? aBackgroundRect : aBackgroundOriginRect;
|
||||
|
||||
// Passing bg == nullptr in this macro will result in one iteration with
|
||||
// i = 0.
|
||||
|
|
@ -3272,12 +3256,7 @@ AppendedBackgroundType nsDisplayBackgroundImage::AppendBackgroundItemsToTop(
|
|||
continue;
|
||||
}
|
||||
|
||||
if (aAutoBuildingDisplayList && !*aAutoBuildingDisplayList) {
|
||||
nsPoint offset = aBuilder->GetCurrentFrame()->GetOffsetTo(aFrame);
|
||||
aAutoBuildingDisplayList->emplace(aBuilder, aFrame,
|
||||
aBuilder->GetVisibleRect() + offset,
|
||||
aBuilder->GetDirtyRect() + offset);
|
||||
}
|
||||
EnsureBuildingDisplayList();
|
||||
|
||||
if (bg->mImage.mLayers[i].mBlendMode != StyleBlend::Normal) {
|
||||
needBlendContainer = true;
|
||||
|
|
@ -3286,7 +3265,7 @@ AppendedBackgroundType nsDisplayBackgroundImage::AppendBackgroundItemsToTop(
|
|||
DisplayListClipState::AutoSaveRestore clipState(aBuilder);
|
||||
if (!aBuilder->IsForEventDelivery()) {
|
||||
const nsStyleImageLayers::Layer& layer = bg->mImage.mLayers[i];
|
||||
SetBackgroundClipRegion(clipState, aFrame, layer, bgRect,
|
||||
SetBackgroundClipRegion(clipState, aFrame, layer, aBackgroundRect,
|
||||
willPaintBorder);
|
||||
}
|
||||
|
||||
|
|
@ -3335,8 +3314,6 @@ AppendedBackgroundType nsDisplayBackgroundImage::AppendBackgroundItemsToTop(
|
|||
aSecondaryReferenceFrame, bgData);
|
||||
}
|
||||
if (bgItem) {
|
||||
bgItem->SetDependentFrame(aBuilder, dependentFrame);
|
||||
|
||||
thisItemList.AppendToTop(
|
||||
nsDisplayFixedPosition::CreateForFixedBackground(
|
||||
aBuilder, aFrame, aSecondaryReferenceFrame, bgItem, i, asr));
|
||||
|
|
@ -3345,7 +3322,6 @@ AppendedBackgroundType nsDisplayBackgroundImage::AppendBackgroundItemsToTop(
|
|||
nsDisplayBackgroundImage* bgItem = CreateBackgroundImage(
|
||||
aBuilder, aFrame, aSecondaryReferenceFrame, bgData);
|
||||
if (bgItem) {
|
||||
bgItem->SetDependentFrame(aBuilder, dependentFrame);
|
||||
thisItemList.AppendToTop(bgItem);
|
||||
}
|
||||
}
|
||||
|
|
@ -7847,8 +7823,8 @@ static void ComputeMaskGeometry(PaintFramesParams& aParams) {
|
|||
nsCSSRendering::ImageLayerClipState clipState;
|
||||
nsCSSRendering::GetImageLayerClip(
|
||||
svgReset->mMask.mLayers[i], frame, *frame->StyleBorder(),
|
||||
userSpaceBorderArea, userSpaceDirtyRect, false, /* aWillPaintBorder */
|
||||
appUnitsPerDevPixel, &clipState);
|
||||
userSpaceBorderArea, userSpaceDirtyRect,
|
||||
/* aWillPaintBorder = */ false, appUnitsPerDevPixel, &clipState);
|
||||
currentMaskSurfaceRect = LayoutDeviceRect::FromUnknownRect(
|
||||
ToRect(clipState.mDirtyRectInDevPx));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1047,14 +1047,9 @@ void nsTableCellFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
|
|||
nsRect bgRect = GetRectRelativeToSelf() + aBuilder->ToReferenceFrame(this);
|
||||
|
||||
// display background if we need to.
|
||||
AppendedBackgroundType result = AppendedBackgroundType::None;
|
||||
if (aBuilder->IsForEventDelivery() ||
|
||||
!StyleBackground()->IsTransparent(this) ||
|
||||
StyleDisplay()->HasAppearance()) {
|
||||
result = nsDisplayBackgroundImage::AppendBackgroundItemsToTop(
|
||||
aBuilder, this, bgRect, aLists.BorderBackground());
|
||||
}
|
||||
|
||||
const AppendedBackgroundType result =
|
||||
nsDisplayBackgroundImage::AppendBackgroundItemsToTop(
|
||||
aBuilder, this, bgRect, aLists.BorderBackground());
|
||||
if (result == AppendedBackgroundType::None) {
|
||||
aBuilder->BuildCompositorHitTestInfoIfNeeded(this,
|
||||
aLists.BorderBackground());
|
||||
|
|
|
|||
Loading…
Reference in a new issue