--- a/layout/forms/nsButtonFrameRenderer.cpp
+++ b/layout/forms/nsButtonFrameRenderer.cpp
@@ -325,18 +325,18 @@ nsDisplayButtonBorder::GetLayerState(nsD
mBorderIsEmpty = false;
Maybe<nsCSSBorderRenderer> br =
nsCSSRendering::CreateBorderRenderer(mFrame->PresContext(),
nullptr,
mFrame,
nsRect(),
nsRect(offset, mFrame->GetSize()),
mFrame->StyleContext(),
- mFrame->GetSkipSides(),
- &mBorderIsEmpty);
+ &mBorderIsEmpty,
+ mFrame->GetSkipSides());
if (!br) {
if (mBorderIsEmpty) {
return LAYER_ACTIVE;
}
return LAYER_NONE;
}
if (!br->CanCreateWebRenderCommands()) {
@@ -515,18 +515,23 @@ nsDisplayButtonForeground::GetLayerState
{
Maybe<nsCSSBorderRenderer> br;
if (ShouldUseAdvancedLayer(aManager, gfxPrefs::LayersAllowButtonForegroundLayers)) {
nsPresContext *presContext = mFrame->PresContext();
const nsStyleDisplay *disp = mFrame->StyleDisplay();
if (!mFrame->IsThemed(disp) ||
!presContext->GetTheme()->ThemeDrawsFocusForWidget(disp->mAppearance)) {
+ bool borderIsEmpty = false;
nsRect r = nsRect(ToReferenceFrame(), mFrame->GetSize());
- br = mBFR->CreateInnerFocusBorderRenderer(aBuilder, presContext, nullptr, mVisibleRect, r);
+ br = mBFR->CreateInnerFocusBorderRenderer(aBuilder, presContext, nullptr,
+ mVisibleRect, r, &borderIsEmpty);
+ if (borderIsEmpty) {
+ return LAYER_ACTIVE;
+ }
}
}
if (!br || !br->CanCreateWebRenderCommands()) {
return LAYER_NONE;
}
mBorderRenderer = br;
@@ -549,16 +554,21 @@ nsDisplayButtonForeground::CreateWebRend
mozilla::layers::WebRenderLayerManager* aManager,
nsDisplayListBuilder* aDisplayListBuilder)
{
ContainerLayerParameters parameter;
if (GetLayerState(aDisplayListBuilder, aManager, parameter) != LAYER_ACTIVE) {
return false;
}
+ // empty border, nothing to do
+ if (!mBorderRenderer) {
+ return true;
+ }
+
mBorderRenderer->CreateWebRenderCommands(this, aBuilder, aResources, aSc);
return true;
}
nsresult
nsButtonFrameRenderer::DisplayButton(nsDisplayListBuilder* aBuilder,
nsDisplayList* aBackground,
nsDisplayList* aForeground)
@@ -629,29 +639,31 @@ nsButtonFrameRenderer::PaintInnerFocusBo
}
Maybe<nsCSSBorderRenderer>
nsButtonFrameRenderer::CreateInnerFocusBorderRenderer(
nsDisplayListBuilder* aBuilder,
nsPresContext* aPresContext,
gfxContext* aRenderingContext,
const nsRect& aDirtyRect,
- const nsRect& aRect)
+ const nsRect& aRect,
+ bool* aBorderIsEmpty)
{
if (mInnerFocusStyle) {
nsRect rect;
GetButtonInnerFocusRect(aRect, rect);
gfx::DrawTarget* dt = aRenderingContext ? aRenderingContext->GetDrawTarget() : nullptr;
return nsCSSRendering::CreateBorderRenderer(aPresContext,
dt,
mFrame,
aDirtyRect,
rect,
- mInnerFocusStyle);
+ mInnerFocusStyle,
+ aBorderIsEmpty);
}
return Nothing();
}
DrawResult
nsButtonFrameRenderer::PaintBorder(
nsDisplayListBuilder* aBuilder,
--- a/layout/forms/nsButtonFrameRenderer.h
+++ b/layout/forms/nsButtonFrameRenderer.h
@@ -44,17 +44,18 @@ public:
gfxContext& aRenderingContext,
const nsRect& aDirtyRect,
const nsRect& aRect);
mozilla::Maybe<nsCSSBorderRenderer> CreateInnerFocusBorderRenderer(nsDisplayListBuilder* aBuilder,
nsPresContext* aPresContext,
gfxContext* aRenderingContext,
const nsRect& aDirtyRect,
- const nsRect& aRect);
+ const nsRect& aRect,
+ bool* aBorderIsEmpty);
DrawResult PaintBorder(nsDisplayListBuilder* aBuilder,
nsPresContext* aPresContext,
gfxContext& aRenderingContext,
const nsRect& aDirtyRect,
const nsRect& aRect);
void SetFrame(nsFrame* aFrame, nsPresContext* aPresContext);
--- a/layout/generic/nsColumnSetFrame.cpp
+++ b/layout/generic/nsColumnSetFrame.cpp
@@ -279,22 +279,26 @@ nsColumnSetFrame::CreateBorderRenderers(
ForEachColumn([&]
(const nsRect& aLineRect)
{
// Assert that we're not drawing a border-image here; if we were, we
// couldn't ignore the DrawResult that PaintBorderWithStyleBorder returns.
MOZ_ASSERT(border.mBorderImageSource.GetType() == eStyleImageType_Null);
gfx::DrawTarget* dt = aCtx ? aCtx->GetDrawTarget() : nullptr;
+ bool borderIsEmpty = false;
Maybe<nsCSSBorderRenderer> br =
nsCSSRendering::CreateBorderRendererWithStyleBorder(presContext, dt,
this, aDirtyRect,
aLineRect, border,
- StyleContext(), skipSides);
+ StyleContext(),
+ &borderIsEmpty,
+ skipSides);
if (br.isSome()) {
+ MOZ_ASSERT(!borderIsEmpty);
aBorderRenderers.AppendElement(br.value());
}
}, aPt);
}
static nscoord
GetAvailableContentISize(const ReflowInput& aReflowInput)
{
--- a/layout/mathml/nsMathMLmtableFrame.cpp
+++ b/layout/mathml/nsMathMLmtableFrame.cpp
@@ -326,16 +326,25 @@ public:
bounds,
styleBorder,
mFrame->StyleContext(),
flags,
mFrame->GetSkipSides());
nsDisplayItemGenericImageGeometry::UpdateDrawResult(this, result);
}
+
+ bool CreateWebRenderCommands(mozilla::wr::DisplayListBuilder& aBuilder,
+ mozilla::wr::IpcResourceUpdateQueue& aResources,
+ const StackingContextHelper& aSc,
+ mozilla::layers::WebRenderLayerManager* aManager,
+ nsDisplayListBuilder* aDisplayListBuilder) override
+ {
+ return false;
+ }
};
#ifdef DEBUG
#define DEBUG_VERIFY_THAT_FRAME_IS(_frame, _expected) \
MOZ_ASSERT(mozilla::StyleDisplay::_expected == _frame->StyleDisplay()->mDisplay, \
"internal error");
#else
#define DEBUG_VERIFY_THAT_FRAME_IS(_frame, _expected)
--- a/layout/painting/nsCSSRendering.cpp
+++ b/layout/painting/nsCSSRendering.cpp
@@ -662,65 +662,70 @@ nsCSSRendering::PaintBorder(nsPresContex
Maybe<nsCSSBorderRenderer>
nsCSSRendering::CreateBorderRenderer(nsPresContext* aPresContext,
DrawTarget* aDrawTarget,
nsIFrame* aForFrame,
const nsRect& aDirtyRect,
const nsRect& aBorderArea,
nsStyleContext* aStyleContext,
- Sides aSkipSides,
- bool* aOutBorderIsEmpty)
+ bool* aOutBorderIsEmpty,
+ Sides aSkipSides)
{
nsStyleContext *styleIfVisited = aStyleContext->GetStyleIfVisited();
const nsStyleBorder *styleBorder = aStyleContext->StyleBorder();
// Don't check RelevantLinkVisited here, since we want to take the
// same amount of time whether or not it's true.
if (!styleIfVisited) {
return CreateBorderRendererWithStyleBorder(aPresContext, aDrawTarget,
aForFrame, aDirtyRect,
aBorderArea, *styleBorder,
- aStyleContext, aSkipSides,
- aOutBorderIsEmpty);
+ aStyleContext, aOutBorderIsEmpty,
+ aSkipSides);
}
nsStyleBorder newStyleBorder(*styleBorder);
NS_FOR_CSS_SIDES(side) {
nscolor color = aStyleContext->
GetVisitedDependentColor(nsStyleBorder::BorderColorFieldFor(side));
newStyleBorder.mBorderColor[side] = StyleComplexColor::FromColor(color);
}
return CreateBorderRendererWithStyleBorder(aPresContext, aDrawTarget,
aForFrame, aDirtyRect, aBorderArea,
newStyleBorder, aStyleContext,
- aSkipSides, aOutBorderIsEmpty);
+ aOutBorderIsEmpty, aSkipSides);
}
bool
nsCSSRendering::CreateWebRenderCommandsForBorder(nsDisplayItem* aItem,
nsIFrame* aForFrame,
const nsRect& aBorderArea,
mozilla::wr::DisplayListBuilder& aBuilder,
mozilla::wr::IpcResourceUpdateQueue& aResources,
const mozilla::layers::StackingContextHelper& aSc,
mozilla::layers::WebRenderLayerManager* aManager,
nsDisplayListBuilder* aDisplayListBuilder)
{
// First try to draw a normal border
{
+ bool borderIsEmpty = false;
Maybe<nsCSSBorderRenderer> br =
nsCSSRendering::CreateBorderRenderer(aForFrame->PresContext(),
nullptr,
aForFrame,
nsRect(),
aBorderArea,
aForFrame->StyleContext(),
+ &borderIsEmpty,
aForFrame->GetSkipSides());
+ if (borderIsEmpty) {
+ return true;
+ }
if (br) {
if (!br->CanCreateWebRenderCommands()) {
return false;
}
br->CreateWebRenderCommands(aItem, aBuilder, aResources, aSc);
return true;
}
@@ -979,18 +984,18 @@ nsCSSRendering::PaintBorderWithStyleBord
Maybe<nsCSSBorderRenderer>
nsCSSRendering::CreateBorderRendererWithStyleBorder(nsPresContext* aPresContext,
DrawTarget* aDrawTarget,
nsIFrame* aForFrame,
const nsRect& aDirtyRect,
const nsRect& aBorderArea,
const nsStyleBorder& aStyleBorder,
nsStyleContext* aStyleContext,
- Sides aSkipSides,
- bool* aOutBorderIsEmpty)
+ bool* aOutBorderIsEmpty,
+ Sides aSkipSides)
{
const nsStyleDisplay* displayData = aStyleContext->StyleDisplay();
if (displayData->mAppearance) {
nsITheme *theme = aPresContext->GetTheme();
if (theme &&
theme->ThemeSupportsWidget(aPresContext, aForFrame,
displayData->mAppearance)) {
return Nothing();
--- a/layout/painting/nsCSSRendering.h
+++ b/layout/painting/nsCSSRendering.h
@@ -188,29 +188,29 @@ struct nsCSSRendering {
static mozilla::Maybe<nsCSSBorderRenderer>
CreateBorderRenderer(nsPresContext* aPresContext,
DrawTarget* aDrawTarget,
nsIFrame* aForFrame,
const nsRect& aDirtyRect,
const nsRect& aBorderArea,
nsStyleContext* aStyleContext,
- Sides aSkipSides = Sides(),
- bool* aOutBorderIsEmpty = nullptr);
+ bool* aOutBorderIsEmpty,
+ Sides aSkipSides = Sides());
static mozilla::Maybe<nsCSSBorderRenderer>
CreateBorderRendererWithStyleBorder(nsPresContext* aPresContext,
DrawTarget* aDrawTarget,
nsIFrame* aForFrame,
const nsRect& aDirtyRect,
const nsRect& aBorderArea,
const nsStyleBorder& aBorderStyle,
nsStyleContext* aStyleContext,
- Sides aSkipSides = Sides(),
- bool* aOutBorderIsEmpty = nullptr);
+ bool* aOutBorderIsEmpty,
+ Sides aSkipSides = Sides());
static mozilla::Maybe<nsCSSBorderRenderer>
CreateBorderRendererForOutline(nsPresContext* aPresContext,
gfxContext* aRenderingContext,
nsIFrame* aForFrame,
const nsRect& aDirtyRect,
const nsRect& aBorderArea,
nsStyleContext* aStyleContext);
--- a/layout/painting/nsDisplayList.cpp
+++ b/layout/painting/nsDisplayList.cpp
@@ -5101,16 +5101,17 @@ nsDisplayCaret::BuildLayer(nsDisplayList
LayerManager* aManager,
const ContainerLayerParameters& aContainerParameters)
{
return BuildDisplayItemLayer(aBuilder, aManager, aContainerParameters);
}
nsDisplayBorder::nsDisplayBorder(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame)
: nsDisplayItem(aBuilder, aFrame)
+ , mBorderIsEmpty(false)
{
MOZ_COUNT_CTOR(nsDisplayBorder);
mBounds = CalculateBounds(*mFrame->StyleBorder()).GetBounds();
}
bool
nsDisplayBorder::IsInvisibleInRect(const nsRect& aRect) const
@@ -5165,37 +5166,34 @@ LayerState
nsDisplayBorder::GetLayerState(nsDisplayListBuilder* aBuilder,
LayerManager* aManager,
const ContainerLayerParameters& aParameters)
{
if (!ShouldUseAdvancedLayer(aManager, gfxPrefs::LayersAllowBorderLayers)) {
return LAYER_NONE;
}
+ mBorderIsEmpty = false;
nsPoint offset = ToReferenceFrame();
Maybe<nsCSSBorderRenderer> br =
nsCSSRendering::CreateBorderRenderer(mFrame->PresContext(),
nullptr,
mFrame,
nsRect(),
nsRect(offset, mFrame->GetSize()),
mFrame->StyleContext(),
+ &mBorderIsEmpty,
mFrame->GetSkipSides());
- const nsStyleBorder *styleBorder = mFrame->StyleContext()->StyleBorder();
- const nsStyleImage* image = &styleBorder->mBorderImageSource;
mBorderRenderer = Nothing();
mBorderImageRenderer = Nothing();
- if ((!image ||
- image->GetType() != eStyleImageType_Image ||
- image->GetType() != eStyleImageType_Gradient) && !br) {
- return LAYER_NONE;
- }
-
if (!br) {
+ if (mBorderIsEmpty) {
+ return LAYER_ACTIVE;
+ }
return LAYER_NONE;
}
bool hasCompositeColors;
if (!br->AllBordersSolid(&hasCompositeColors) || hasCompositeColors) {
return LAYER_NONE;
}
@@ -5229,16 +5227,20 @@ nsDisplayBorder::GetLayerState(nsDisplay
return LAYER_ACTIVE;
}
already_AddRefed<Layer>
nsDisplayBorder::BuildLayer(nsDisplayListBuilder* aBuilder,
LayerManager* aManager,
const ContainerLayerParameters& aContainerParameters)
{
+ if (mBorderIsEmpty) {
+ return nullptr;
+ }
+
if (ShouldUseAdvancedLayer(aManager, gfxPrefs::LayersAllowBorderLayers)) {
return BuildDisplayItemLayer(aBuilder, aManager, aContainerParameters);
} else {
RefPtr<BorderLayer> layer = static_cast<BorderLayer*>
(aManager->GetLayerBuilder()->GetLeafLayerFor(aBuilder, this));
if (!layer) {
layer = aManager->CreateBorderLayer();
if (!layer)
--- a/layout/painting/nsDisplayList.h
+++ b/layout/painting/nsDisplayList.h
@@ -3427,16 +3427,17 @@ protected:
mozilla::Array<mozilla::LayerSize, 4> mCorners;
mozilla::Array<uint8_t, 4> mBorderStyles;
mozilla::LayerRect mRect;
mozilla::Maybe<nsCSSBorderRenderer> mBorderRenderer;
mozilla::Maybe<nsCSSBorderImageRenderer> mBorderImageRenderer;
nsRect mBounds;
+ bool mBorderIsEmpty;
};
/**
* A simple display item that just renders a solid color across the
* specified bounds. For canvas frames (in the CSS sense) we split off the
* drawing of the background color into this class (from nsDisplayBackground
* via nsDisplayCanvasBackground). This is done so that we can always draw a
* background color to avoid ugly flashes of white when we can't draw a full