temp draft
authorEthan Lin <ethlin@mozilla.com>
Wed, 01 Nov 2017 16:54:39 +0800
changeset 690028 19ce0c1964b67747a1a152703c2b9a2b51cc6ed6
parent 689820 ee21e5f7f1c1726e0ed2697eb45df54cdceedd36
child 690029 dca2b1221b17514a2f9db8dcff9bbe9f0c11e78e
push id87174
push userbmo:ethlin@mozilla.com
push dateWed, 01 Nov 2017 09:51:20 +0000
milestone58.0a1
temp MozReview-Commit-ID: 9A2jmj4nPcm
layout/forms/nsButtonFrameRenderer.cpp
layout/painting/nsCSSRendering.cpp
layout/painting/nsCSSRendering.h
--- a/layout/forms/nsButtonFrameRenderer.cpp
+++ b/layout/forms/nsButtonFrameRenderer.cpp
@@ -260,17 +260,20 @@ nsDisplayButtonBoxShadowOuter::CreateWeb
   }
   return true;
 }
 
 class nsDisplayButtonBorder : public nsDisplayItem {
 public:
   nsDisplayButtonBorder(nsDisplayListBuilder* aBuilder,
                                   nsButtonFrameRenderer* aRenderer)
-    : nsDisplayItem(aBuilder, aRenderer->GetFrame()), mBFR(aRenderer) {
+    : nsDisplayItem(aBuilder, aRenderer->GetFrame())
+    , mBFR(aRenderer)
+    , mBorderIsEmpty(false)
+  {
     MOZ_COUNT_CTOR(nsDisplayButtonBorder);
   }
 #ifdef NS_BUILD_REFCNT_LOGGING
   virtual ~nsDisplayButtonBorder() {
     MOZ_COUNT_DTOR(nsDisplayButtonBorder);
   }
 #endif
   virtual bool MustPaintOnContentSide() const override { return true; }
@@ -298,16 +301,17 @@ public:
                                        mozilla::wr::IpcResourceUpdateQueue& aResources,
                                        const StackingContextHelper& aSc,
                                        mozilla::layers::WebRenderLayerManager* aManager,
                                        nsDisplayListBuilder* aDisplayListBuilder) override;
   NS_DISPLAY_DECL_NAME("ButtonBorderBackground", TYPE_BUTTON_BORDER_BACKGROUND)
 private:
   nsButtonFrameRenderer* mBFR;
   Maybe<nsCSSBorderRenderer> mBorderRenderer;
+  bool mBorderIsEmpty;
 };
 
 nsDisplayItemGeometry*
 nsDisplayButtonBorder::AllocateGeometry(nsDisplayListBuilder* aBuilder)
 {
   return new nsDisplayItemGenericImageGeometry(this, aBuilder);
 }
 
@@ -324,25 +328,30 @@ nsDisplayButtonBorder::GetLayerState(nsD
 
     nsPoint offset = ToReferenceFrame();
     if (!nsDisplayBoxShadowInner::CanCreateWebRenderCommands(aBuilder,
                                                              mFrame,
                                                              offset)) {
       return LAYER_NONE;
     }
 
+    mBorderIsEmpty = false;
     Maybe<nsCSSBorderRenderer> br =
     nsCSSRendering::CreateBorderRenderer(mFrame->PresContext(),
                                          nullptr,
                                          mFrame,
                                          nsRect(),
                                          nsRect(offset, mFrame->GetSize()),
                                          mFrame->StyleContext(),
-                                         mFrame->GetSkipSides());
+                                         mFrame->GetSkipSides(),
+                                         &mBorderIsEmpty);
     if (!br) {
+      if (mBorderIsEmpty) {
+        return LAYER_ACTIVE;
+      }
       return LAYER_NONE;
     }
 
     if (!br->CanCreateWebRenderCommands()) {
       return LAYER_NONE;
     }
 
     mBorderRenderer = br;
@@ -367,17 +376,21 @@ nsDisplayButtonBorder::CreateWebRenderCo
                                                mozilla::layers::WebRenderLayerManager* aManager,
                                                nsDisplayListBuilder* aDisplayListBuilder)
 {
   ContainerLayerParameters parameter;
   if (GetLayerState(aDisplayListBuilder, aManager, parameter) != LAYER_ACTIVE) {
     return false;
   }
 
-  MOZ_ASSERT(mBorderRenderer);
+  if (!mBorderRenderer) {
+    // empty border, nothing to do
+    MOZ_ASSERT(mBorderIsEmpty);
+    return true;
+  }
 
   // This is really a combination of paint box shadow inner +
   // paint border.
   nsRect buttonRect = nsRect(ToReferenceFrame(), mFrame->GetSize());
   bool snap;
   nsRegion visible = GetBounds(aDisplayListBuilder, &snap);
   nsDisplayBoxShadowInner::CreateInsetBoxShadowWebRenderCommands(aBuilder,
                                                                  aSc,
--- a/layout/painting/nsCSSRendering.cpp
+++ b/layout/painting/nsCSSRendering.cpp
@@ -662,40 +662,42 @@ nsCSSRendering::PaintBorder(nsPresContex
 
 Maybe<nsCSSBorderRenderer>
 nsCSSRendering::CreateBorderRenderer(nsPresContext* aPresContext,
                                      DrawTarget* aDrawTarget,
                                      nsIFrame* aForFrame,
                                      const nsRect& aDirtyRect,
                                      const nsRect& aBorderArea,
                                      nsStyleContext* aStyleContext,
-                                     Sides aSkipSides)
+                                     Sides aSkipSides,
+                                     bool* aOutBorderIsEmpty)
 {
   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);
+                                               aStyleContext, aSkipSides,
+                                               aOutBorderIsEmpty);
   }
 
   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);
+                                             aSkipSides, aOutBorderIsEmpty);
 }
 
 
 bool
 nsCSSRendering::CreateWebRenderCommandsForBorder(nsDisplayItem* aItem,
                                                  nsIFrame* aForFrame,
                                                  const nsRect& aBorderArea,
                                                  mozilla::wr::DisplayListBuilder& aBuilder,
@@ -977,17 +979,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)
+                                                    Sides aSkipSides,
+                                                    bool* aOutBorderIsEmpty)
 {
   const nsStyleDisplay* displayData = aStyleContext->StyleDisplay();
   if (displayData->mAppearance) {
     nsITheme *theme = aPresContext->GetTheme();
     if (theme &&
         theme->ThemeSupportsWidget(aPresContext, aForFrame,
                                    displayData->mAppearance)) {
       return Nothing();
@@ -997,16 +1000,19 @@ nsCSSRendering::CreateBorderRendererWith
   if (aStyleBorder.mBorderImageSource.GetType() != eStyleImageType_Null) {
     return Nothing();
   }
 
   nsMargin border = aStyleBorder.GetComputedBorder();
   if (0 == border.left && 0 == border.right &&
       0 == border.top  && 0 == border.bottom) {
     // Empty border area
+    if (aOutBorderIsEmpty) {
+      *aOutBorderIsEmpty = true;
+    }
     return Nothing();
   }
 
   bool needsClip = false;
   nsCSSBorderRenderer br = ConstructBorderRenderer(aPresContext,
                                                    aStyleContext,
                                                    aDrawTarget,
                                                    aForFrame,
--- a/layout/painting/nsCSSRendering.h
+++ b/layout/painting/nsCSSRendering.h
@@ -188,27 +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());
+                       Sides aSkipSides = Sides(),
+                       bool* aOutBorderIsEmpty = nullptr);
 
   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());
+                                      Sides aSkipSides = Sides(),
+                                      bool* aOutBorderIsEmpty = nullptr);
 
   static mozilla::Maybe<nsCSSBorderRenderer>
   CreateBorderRendererForOutline(nsPresContext* aPresContext,
                                  gfxContext* aRenderingContext,
                                  nsIFrame* aForFrame,
                                  const nsRect& aDirtyRect,
                                  const nsRect& aBorderArea,
                                  nsStyleContext* aStyleContext);