Bug 1350182 - Enable button border display items by default. r=ethlin
authorMason Chang <mchang@mozilla.com>
Mon, 27 Mar 2017 13:09:55 -0700
changeset 349780 a6f35285bd1e674553527873614c55e0b7366bdb
parent 349779 04bfc9efd61601638d9a91e777453a3a527dea59
child 349894 a8bb5c8e0e80e87e21ad63997f8881991b5347cf
child 350346 b26e81328f0da2726abca19a90f985ee09642f26
push id31561
push userkwierso@gmail.com
push dateMon, 27 Mar 2017 21:21:48 +0000
treeherdermozilla-central@a6f35285bd1e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersethlin
bugs1350182
milestone55.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1350182 - Enable button border display items by default. r=ethlin
gfx/thebes/gfxPrefs.h
layout/forms/nsButtonFrameRenderer.cpp
layout/painting/nsCSSRendering.cpp
layout/painting/nsCSSRendering.h
layout/painting/nsCSSRenderingBorders.cpp
layout/painting/nsCSSRenderingBorders.h
layout/painting/nsDisplayList.cpp
layout/painting/nsDisplayList.h
modules/libpref/init/all.js
--- a/gfx/thebes/gfxPrefs.h
+++ b/gfx/thebes/gfxPrefs.h
@@ -487,17 +487,17 @@ private:
   DECL_GFX_PREF(Once, "layers.acceleration.force-enabled",     LayersAccelerationForceEnabledDoNotUseDirectly, bool, false);
   DECL_OVERRIDE_PREF(Live, "layers.advanced.border-layers",    LayersAllowBorderLayers, false);
   DECL_OVERRIDE_PREF(Live, "layers.advanced.boxshadow-inset-layers", LayersAllowInsetBoxShadow, gfxPrefs::OverrideBase_WebRender());
   DECL_OVERRIDE_PREF(Live, "layers.advanced.boxshadow-outer-layers", LayersAllowOuterBoxShadow, false);
   DECL_GFX_PREF(Live, "layers.advanced.bullet-layers",         LayersAllowBulletLayers, bool, false);
   DECL_GFX_PREF(Live, "layers.advanced.button-foreground-layers", LayersAllowButtonForegroundLayers, bool, false);
   DECL_GFX_PREF(Live, "layers.advanced.canvas-background-color", LayersAllowCanvasBackgroundColorLayers, bool, false);
   DECL_OVERRIDE_PREF(Live, "layers.advanced.caret-layers",     LayersAllowCaretLayers, gfxPrefs::OverrideBase_WebRender());
-  DECL_GFX_PREF(Live, "layers.advanced.displaybuttonborder-layers", LayersAllowDisplayButtonBorder, bool, false);
+  DECL_OVERRIDE_PREF(Live, "layers.advanced.displaybuttonborder-layers", LayersAllowDisplayButtonBorder, gfxPrefs::OverrideBase_WebRender());
   DECL_GFX_PREF(Live, "layers.advanced.image-layers",          LayersAllowImageLayers, bool, false);
   DECL_OVERRIDE_PREF(Live, "layers.advanced.outline-layers",   LayersAllowOutlineLayers, gfxPrefs::OverrideBase_WebRender());
   DECL_GFX_PREF(Live, "layers.advanced.text-layers",           LayersAllowTextLayers, bool, false);
   DECL_GFX_PREF(Once, "layers.amd-switchable-gfx.enabled",     LayersAMDSwitchableGfxEnabled, bool, false);
   DECL_GFX_PREF(Once, "layers.async-pan-zoom.enabled",         AsyncPanZoomEnabledDoNotUseDirectly, bool, true);
   DECL_GFX_PREF(Once, "layers.async-pan-zoom.separate-event-thread", AsyncPanZoomSeparateEventThread, bool, false);
   DECL_GFX_PREF(Live, "layers.bench.enabled",                  LayersBenchEnabled, bool, false);
   DECL_GFX_PREF(Once, "layers.bufferrotation.enabled",         BufferRotationEnabled, bool, true);
--- a/layout/forms/nsButtonFrameRenderer.cpp
+++ b/layout/forms/nsButtonFrameRenderer.cpp
@@ -141,30 +141,60 @@ public:
                                              LayerManager* aManager,
                                              const ContainerLayerParameters& aContainerParameters) override;
   virtual void CreateWebRenderCommands(mozilla::wr::DisplayListBuilder& aBuilder,
                                        nsTArray<WebRenderParentCommand>& aParentCommands,
                                        WebRenderDisplayItemLayer* aLayer) override;
   NS_DISPLAY_DECL_NAME("ButtonBorderBackground", TYPE_BUTTON_BORDER_BACKGROUND)
 private:
   nsButtonFrameRenderer* mBFR;
+  Maybe<nsCSSBorderRenderer> mBorderRenderer;
 };
 
 nsDisplayItemGeometry*
 nsDisplayButtonBorder::AllocateGeometry(nsDisplayListBuilder* aBuilder)
 {
   return new nsDisplayItemGenericImageGeometry(this, aBuilder);
 }
 
 LayerState
 nsDisplayButtonBorder::GetLayerState(nsDisplayListBuilder* aBuilder,
                                      LayerManager* aManager,
                                      const ContainerLayerParameters& aParameters)
 {
   if (gfxPrefs::LayersAllowDisplayButtonBorder()) {
+    // TODO: Figure out what to do with sync decode images
+    if (aBuilder->ShouldSyncDecodeImages()) {
+      return LAYER_NONE;
+    }
+
+    nsPoint offset = ToReferenceFrame();
+    if (!nsDisplayBoxShadowInner::CanCreateWebRenderCommands(aBuilder,
+                                                             mFrame,
+                                                             offset)) {
+      return LAYER_NONE;
+    }
+
+    Maybe<nsCSSBorderRenderer> br =
+    nsCSSRendering::CreateBorderRenderer(mFrame->PresContext(),
+                                         nullptr,
+                                         mFrame,
+                                         nsRect(),
+                                         nsRect(offset, mFrame->GetSize()),
+                                         mFrame->StyleContext(),
+                                         mFrame->GetSkipSides());
+    if (!br) {
+      return LAYER_NONE;
+    }
+
+    if (!br->CanCreateWebRenderCommands()) {
+      return LAYER_NONE;
+    }
+
+    mBorderRenderer = br;
     return LAYER_ACTIVE;
   }
 
   return LAYER_NONE;
 }
 
 already_AddRefed<Layer>
 nsDisplayButtonBorder::BuildLayer(nsDisplayListBuilder* aBuilder,
@@ -174,49 +204,25 @@ nsDisplayButtonBorder::BuildLayer(nsDisp
   return BuildDisplayItemLayer(aBuilder, aManager, aContainerParameters);
 }
 
 void
 nsDisplayButtonBorder::CreateWebRenderCommands(mozilla::wr::DisplayListBuilder& aBuilder,
                                                nsTArray<WebRenderParentCommand>& aCommands,
                                                WebRenderDisplayItemLayer* aLayer)
 {
+  MOZ_ASSERT(mBorderRenderer);
   // This is really a combination of paint box shadow inner +
   // paint border.
   nsRect buttonRect = nsRect(ToReferenceFrame(), mFrame->GetSize());
-  //nsRect dirtyRect = mVisibleRect;
-
-  // TODO: Figure out what to do with sync decode images
-  /*
-  PaintBorderFlags borderFlags = aBuilder->ShouldSyncDecodeImages()
-                               ? PaintBorderFlags::SYNC_DECODE_IMAGES
-                               : PaintBorderFlags();
-                               */
-
   nsDisplayBoxShadowInner::CreateInsetBoxShadowWebRenderCommands(aBuilder,
                                                                  aLayer,
                                                                  mFrame,
                                                                  buttonRect);
-
-  nsPoint offset = ToReferenceFrame();
-  Maybe<nsCSSBorderRenderer> br =
-    nsCSSRendering::CreateBorderRenderer(mFrame->PresContext(),
-                                         nullptr,
-                                         mFrame,
-                                         nsRect(),
-                                         nsRect(offset, mFrame->GetSize()),
-                                         mFrame->StyleContext(),
-                                         mFrame->GetSkipSides());
-
-  if (!br) {
-    NS_WARNING("Could not create border renderer during nsDisplayButtonBorder");
-    return;
-  }
-
-  br->CreateWebRenderCommands(aBuilder, aLayer);
+  mBorderRenderer->CreateWebRenderCommands(aBuilder, aLayer);
 }
 
 void
 nsDisplayButtonBorder::ComputeInvalidationRegion(
   nsDisplayListBuilder* aBuilder,
   const nsDisplayItemGeometry* aGeometry,
   nsRegion *aInvalidRegion)
 {
--- a/layout/painting/nsCSSRendering.cpp
+++ b/layout/painting/nsCSSRendering.cpp
@@ -1691,17 +1691,17 @@ nsCSSRendering::GetBoxShadowInnerPadding
 
   nsRect paddingRect = frameRect;
   nsMargin border = aFrame->GetUsedBorder();
   paddingRect.Deflate(border);
   return paddingRect;
 }
 
 bool
-nsCSSRendering::CanPaintBoxShadowInner(nsIFrame* aFrame)
+nsCSSRendering::ShouldPaintBoxShadowInner(nsIFrame* aFrame)
 {
   nsCSSShadowArray* shadows = aFrame->StyleEffects()->mBoxShadow;
   if (!shadows)
     return false;
 
   if (aFrame->IsThemed() && aFrame->GetContent() &&
       !nsContentUtils::IsChromeDoc(aFrame->GetContent()->GetUncomposedDoc())) {
     // There's no way of getting hold of a shape corresponding to a
@@ -1750,17 +1750,17 @@ nsCSSRendering::GetShadowInnerRadii(nsIF
 }
 
 void
 nsCSSRendering::PaintBoxShadowInner(nsPresContext* aPresContext,
                                     nsRenderingContext& aRenderingContext,
                                     nsIFrame* aForFrame,
                                     const nsRect& aFrameArea)
 {
-  if (!CanPaintBoxShadowInner(aForFrame)) {
+  if (!ShouldPaintBoxShadowInner(aForFrame)) {
     return;
   }
 
   nsCSSShadowArray* shadows = aForFrame->StyleEffects()->mBoxShadow;
   NS_ASSERTION(aForFrame->GetType() == nsGkAtoms::fieldSetFrame ||
                aFrameArea.Size() == aForFrame->GetSize(), "unexpected size");
 
   nsRect paddingRect = GetBoxShadowInnerPaddingRect(aForFrame, aFrameArea);
--- a/layout/painting/nsCSSRendering.h
+++ b/layout/painting/nsCSSRendering.h
@@ -111,17 +111,17 @@ struct nsCSSRendering {
    */
   static void Shutdown();
   
   static bool GetShadowInnerRadii(nsIFrame* aFrame,
                                   const nsRect& aFrameArea,
                                   RectCornerRadii& aOutInnerRadii);
   static nsRect GetBoxShadowInnerPaddingRect(nsIFrame* aFrame,
                                              const nsRect& aFrameArea);
-  static bool CanPaintBoxShadowInner(nsIFrame* aFrame);
+  static bool ShouldPaintBoxShadowInner(nsIFrame* aFrame);
   static void PaintBoxShadowInner(nsPresContext* aPresContext,
                                   nsRenderingContext& aRenderingContext,
                                   nsIFrame* aForFrame,
                                   const nsRect& aFrameArea);
 
   static bool GetBorderRadii(const nsRect& aFrameRect,
                              const nsRect& aBorderRect,
                              nsIFrame* aFrame,
--- a/layout/painting/nsCSSRenderingBorders.cpp
+++ b/layout/painting/nsCSSRenderingBorders.cpp
@@ -3527,17 +3527,17 @@ nsCSSBorderRenderer::DrawBorders()
       mDrawTarget->PopClip();
 
       PrintAsStringNewline("---------------- (*)");
     }
   }
 }
 
 bool
-nsCSSBorderRenderer::CanCreateWebrenderCommands()
+nsCSSBorderRenderer::CanCreateWebRenderCommands()
 {
   NS_FOR_CSS_SIDES(i) {
     if (mCompositeColors[i] != nullptr) {
       return false;
     }
 
     if (mBorderStyles[i] == NS_STYLE_BORDER_STYLE_DOUBLE ||
         mBorderStyles[i] == NS_STYLE_BORDER_STYLE_DOTTED ||
--- a/layout/painting/nsCSSRenderingBorders.h
+++ b/layout/painting/nsCSSRenderingBorders.h
@@ -100,17 +100,17 @@ public:
                       RectCornerRadii& aBorderRadii,
                       const nscolor* aBorderColors,
                       nsBorderColors* const* aCompositeColors,
                       nscolor aBackgroundColor);
 
   // draw the entire border
   void DrawBorders();
 
-  bool CanCreateWebrenderCommands();
+  bool CanCreateWebRenderCommands();
   void CreateWebRenderCommands(mozilla::wr::DisplayListBuilder& aBuilder,
                                mozilla::layers::WebRenderDisplayItemLayer* aLayer,
                                Rect aClipRect = Rect(0, 0, 0, 0));
 
   // utility function used for background painting as well as borders
   static void ComputeInnerRadii(const RectCornerRadii& aRadii,
                                 const Float* aBorderSizes,
                                 RectCornerRadii* aInnerRadiiRet);
--- a/layout/painting/nsDisplayList.cpp
+++ b/layout/painting/nsDisplayList.cpp
@@ -4545,17 +4545,17 @@ nsDisplayBorder::GetLayerState(nsDisplay
   mBorderImageRenderer = Nothing();
   if ((!image || image->GetType() != eStyleImageType_Image) && !br) {
     return LAYER_NONE;
   }
 
   LayersBackend backend = aManager->GetBackendType();
   if (backend == layers::LayersBackend::LAYERS_WR) {
     if (br) {
-      if (!br->CanCreateWebrenderCommands()) {
+      if (!br->CanCreateWebRenderCommands()) {
         return LAYER_NONE;
       }
       mBorderRenderer = br;
     } else {
       if (styleBorder->mBorderImageRepeatH == NS_STYLE_BORDER_IMAGE_REPEAT_ROUND ||
           styleBorder->mBorderImageRepeatH == NS_STYLE_BORDER_IMAGE_REPEAT_SPACE ||
           styleBorder->mBorderImageRepeatV == NS_STYLE_BORDER_IMAGE_REPEAT_ROUND ||
           styleBorder->mBorderImageRepeatV == NS_STYLE_BORDER_IMAGE_REPEAT_SPACE) {
@@ -5112,45 +5112,57 @@ nsDisplayBoxShadowInner::Paint(nsDisplay
   for (uint32_t i = 0; i < rects.Length(); ++i) {
     gfx->Save();
     gfx->Clip(NSRectToSnappedRect(rects[i], appUnitsPerDevPixel, *drawTarget));
     nsCSSRendering::PaintBoxShadowInner(presContext, *aCtx, mFrame, borderRect);
     gfx->Restore();
   }
 }
 
+bool
+nsDisplayBoxShadowInner::CanCreateWebRenderCommands(nsDisplayListBuilder* aBuilder,
+                                                    nsIFrame* aFrame,
+                                                    nsPoint aReferenceOffset)
+{
+  nsRect borderRect = nsRect(aReferenceOffset, aFrame->GetSize());
+  RectCornerRadii innerRadii;
+  bool hasBorderRadius =
+      nsCSSRendering::GetShadowInnerRadii(aFrame, borderRect, innerRadii);
+  if (hasBorderRadius) {
+    return false;
+  }
+
+  nsCSSShadowArray *shadows = aFrame->StyleEffects()->mBoxShadow;
+  if (!shadows) {
+    // Means we don't have to paint anything
+    return true;
+  }
+
+  for (uint32_t i = shadows->Length(); i > 0; --i) {
+    nsCSSShadowItem *shadowItem = shadows->ShadowAt(i - 1);
+    if (!shadowItem->mInset) {
+      continue;
+    }
+
+    if (shadowItem->mXOffset <= 0 || shadowItem->mYOffset <= 0) {
+      // Need to wait for WR to support clip out.
+      return false;
+    }
+  }
+
+  return true;
+}
+
 LayerState
 nsDisplayBoxShadowInner::GetLayerState(nsDisplayListBuilder* aBuilder,
                                        LayerManager* aManager,
                                        const ContainerLayerParameters& aParameters)
 {
-  if (gfxPrefs::LayersAllowInsetBoxShadow()) {
-    nsPoint offset = ToReferenceFrame();
-    nsRect borderRect = nsRect(offset, mFrame->GetSize());
-    RectCornerRadii innerRadii;
-    bool hasBorderRadius = nsCSSRendering::GetShadowInnerRadii(mFrame,
-                                                               borderRect,
-                                                               innerRadii);
-    if (hasBorderRadius) {
-      return LAYER_NONE;
-    }
-
-    nsCSSShadowArray* shadows = mFrame->StyleEffects()->mBoxShadow;
-    for (uint32_t i = shadows->Length(); i > 0; --i) {
-      nsCSSShadowItem* shadowItem = shadows->ShadowAt(i - 1);
-      if (!shadowItem->mInset) {
-        continue;
-      }
-
-      if (shadowItem->mXOffset <= 0 || shadowItem->mYOffset <= 0) {
-        // Need to wait for WR to support clip out.
-        return LAYER_NONE;
-      }
-    }
-
+  if (gfxPrefs::LayersAllowInsetBoxShadow() &&
+      CanCreateWebRenderCommands(aBuilder, mFrame, ToReferenceFrame())) {
     return LAYER_ACTIVE;
   }
 
   return LAYER_NONE;
 }
 
 already_AddRefed<Layer>
 nsDisplayBoxShadowInner::BuildLayer(nsDisplayListBuilder* aBuilder,
@@ -5161,17 +5173,17 @@ nsDisplayBoxShadowInner::BuildLayer(nsDi
 }
 
 /* static */ void
 nsDisplayBoxShadowInner::CreateInsetBoxShadowWebRenderCommands(mozilla::wr::DisplayListBuilder& aBuilder,
                                                                WebRenderDisplayItemLayer* aLayer,
                                                                nsIFrame* aFrame,
                                                                const nsRect aBorderRect)
 {
-  if (!nsCSSRendering::CanPaintBoxShadowInner(aFrame)) {
+  if (!nsCSSRendering::ShouldPaintBoxShadowInner(aFrame)) {
     return;
   }
 
   int32_t appUnitsPerDevPixel = aFrame->PresContext()->AppUnitsPerDevPixel();
 
   AutoTArray<nsRect,10> rects;
   nsRegion visible = aLayer->GetVisibleRegion().ToAppUnits(appUnitsPerDevPixel);
   ComputeDisjointRectangles(visible, &rects);
--- a/layout/painting/nsDisplayList.h
+++ b/layout/painting/nsDisplayList.h
@@ -3458,16 +3458,19 @@ public:
     if (!geometry->mPaddingRect.IsEqualInterior(GetPaddingRect())) {
       // nsDisplayBoxShadowInner is based around the padding rect, but it can
       // touch pixels outside of this. We should invalidate the entire bounds.
       bool snap;
       aInvalidRegion->Or(geometry->mBounds, GetBounds(aBuilder, &snap));
     }
   }
 
+  static bool CanCreateWebRenderCommands(nsDisplayListBuilder* aBuilder,
+                                         nsIFrame* aFrame,
+                                         nsPoint aReferencePoint);
   static void CreateInsetBoxShadowWebRenderCommands(mozilla::wr::DisplayListBuilder& aBuilder,
                                                     WebRenderDisplayItemLayer* aLayer,
                                                     nsIFrame* aFrame,
                                                     const nsRect aBorderRect);
   virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder,
                                    LayerManager* aManager,
                                    const ContainerLayerParameters& aParameters) override;
   virtual already_AddRefed<Layer> BuildLayer(nsDisplayListBuilder* aBuilder,
--- a/modules/libpref/init/all.js
+++ b/modules/libpref/init/all.js
@@ -5667,9 +5667,10 @@ pref("fuzzing.enabled", false);
 // to a value of 2, and the conditional-pref code in gfxPrefs.h will convert
 // it to a boolean as appropriate. In particular, do NOT add ifdefs here to
 // turn these on and off, instead use the conditional-pref code in gfxPrefs.h
 // to do that.
 pref("layers.advanced.border-layers", 2);
 pref("layers.advanced.boxshadow-inset-layers", 2);
 pref("layers.advanced.boxshadow-outer-layers", 2);
 pref("layers.advanced.caret-layers", 2);
+pref("layers.advanced.displaybuttonborder-layers", 2);
 pref("layers.advanced.outline-layers", 2);