Bug 1344622 - Part2. Add webrender support for nsDisplayButtonForeground. r=mattwoodrow
authorEthan Lin <ethlin@mozilla.com>
Thu, 09 Mar 2017 16:58:39 +0800
changeset 397761 5a5fdbdd7892e11ed3a287c174a2f10f70d43998
parent 397760 4c6b9024e6ec0a0e1f03dd7f3e8e0460dcf45f43
child 397762 75c18055512b267b173a5a12bfbec9b71367c674
push id1490
push usermtabara@mozilla.com
push dateMon, 31 Jul 2017 14:08:16 +0000
treeherdermozilla-release@70e32e6bf15e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmattwoodrow
bugs1344622
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 1344622 - Part2. Add webrender support for nsDisplayButtonForeground. r=mattwoodrow
gfx/thebes/gfxPrefs.h
layout/forms/nsButtonFrameRenderer.cpp
layout/forms/nsButtonFrameRenderer.h
layout/painting/nsCSSRenderingBorders.h
--- a/gfx/thebes/gfxPrefs.h
+++ b/gfx/thebes/gfxPrefs.h
@@ -461,16 +461,17 @@ private:
   DECL_GFX_PREF(Live, "layers.advanced.border-layers",         LayersAllowBorderLayers, bool, false);
   DECL_GFX_PREF(Live, "layers.advanced.text-layers",           LayersAllowTextLayers, bool, false);
   DECL_GFX_PREF(Live, "layers.advanced.bullet-layers",         LayersAllowBulletLayers, bool, false);
   DECL_GFX_PREF(Live, "layers.advanced.caret-layers",          LayersAllowCaretLayers, bool, false);
   DECL_GFX_PREF(Live, "layers.advanced.boxshadow-outer-layers", LayersAllowOuterBoxShadow, bool, false);
   DECL_GFX_PREF(Live, "layers.advanced.boxshadow-inset-layers", LayersAllowInsetBoxShadow, bool, false);
   DECL_GFX_PREF(Live, "layers.advanced.outline-layers",        LayersAllowOutlineLayers, bool, false);
   DECL_GFX_PREF(Live, "layers.advanced.displaybuttonborder-layers", LayersAllowDisplayButtonBorder, bool, false);
+  DECL_GFX_PREF(Live, "layers.advanced.button-foreground-layers", LayersAllowButtonForegroundLayers, bool, false);
   DECL_GFX_PREF(Once, "layers.allow-d3d9-fallback",            LayersAllowD3D9Fallback, 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);
   DECL_GFX_PREF(Live, "layers.child-process-shutdown",         ChildProcessShutdown, bool, true);
 #ifdef MOZ_GFX_OPTIMIZE_MOBILE
--- a/layout/forms/nsButtonFrameRenderer.cpp
+++ b/layout/forms/nsButtonFrameRenderer.cpp
@@ -304,19 +304,29 @@ public:
 #endif  
 
   nsDisplayItemGeometry* AllocateGeometry(nsDisplayListBuilder* aBuilder) override;
   void ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder,
                                  const nsDisplayItemGeometry* aGeometry,
                                  nsRegion *aInvalidRegion) override;
   virtual void Paint(nsDisplayListBuilder* aBuilder,
                      nsRenderingContext* aCtx) override;
+  virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder,
+                                   LayerManager* aManager,
+                                   const ContainerLayerParameters& aParameters) override;
+  virtual already_AddRefed<Layer> BuildLayer(nsDisplayListBuilder* aBuilder,
+                                             LayerManager* aManager,
+                                             const ContainerLayerParameters& aContainerParameters) override;
+   virtual void CreateWebRenderCommands(wr::DisplayListBuilder& aBuilder,
+                                        nsTArray<WebRenderParentCommand>& aParentCommands,
+                                        WebRenderDisplayItemLayer* aLayer) override;
   NS_DISPLAY_DECL_NAME("ButtonForeground", TYPE_BUTTON_FOREGROUND)
 private:
   nsButtonFrameRenderer* mBFR;
+  Maybe<nsCSSBorderRenderer> mBorderRenderer;
 };
 
 nsDisplayItemGeometry*
 nsDisplayButtonForeground::AllocateGeometry(nsDisplayListBuilder* aBuilder)
 {
   return new nsDisplayItemGenericImageGeometry(this, aBuilder);
 }
 
@@ -350,16 +360,59 @@ void nsDisplayButtonForeground::Paint(ns
     // Draw the -moz-focus-inner border
     DrawResult result =
       mBFR->PaintInnerFocusBorder(aBuilder, presContext, *aCtx, mVisibleRect, r);
 
     nsDisplayItemGenericImageGeometry::UpdateDrawResult(this, result);
   }
 }
 
+LayerState
+nsDisplayButtonForeground::GetLayerState(nsDisplayListBuilder* aBuilder,
+                                         LayerManager* aManager,
+                                         const ContainerLayerParameters& aParameters)
+{
+  Maybe<nsCSSBorderRenderer> br;
+
+  if (gfxPrefs::LayersAllowButtonForegroundLayers()) {
+    nsPresContext *presContext = mFrame->PresContext();
+    const nsStyleDisplay *disp = mFrame->StyleDisplay();
+    if (!mFrame->IsThemed(disp) ||
+        !presContext->GetTheme()->ThemeDrawsFocusForWidget(disp->mAppearance)) {
+      nsRect r = nsRect(ToReferenceFrame(), mFrame->GetSize());
+      br = mBFR->CreateInnerFocusBorderRenderer(aBuilder, presContext, nullptr, mVisibleRect, r);
+    }
+  }
+
+  if (!br) {
+    return LAYER_NONE;
+  }
+
+  mBorderRenderer = br;
+
+  return LAYER_ACTIVE;
+}
+
+already_AddRefed<mozilla::layers::Layer>
+nsDisplayButtonForeground::BuildLayer(nsDisplayListBuilder* aBuilder,
+                                      LayerManager* aManager,
+                                      const ContainerLayerParameters& aContainerParameters)
+{
+  return BuildDisplayItemLayer(aBuilder, aManager, aContainerParameters);
+}
+
+void
+nsDisplayButtonForeground::CreateWebRenderCommands(wr::DisplayListBuilder& aBuilder,
+                                                   nsTArray<WebRenderParentCommand>& aParentCommands,
+                                                   mozilla::layers::WebRenderDisplayItemLayer* aLayer)
+{
+  MOZ_ASSERT(mBorderRenderer.isSome());
+  mBorderRenderer->CreateWebRenderCommands(aBuilder, aLayer);
+}
+
 nsresult
 nsButtonFrameRenderer::DisplayButton(nsDisplayListBuilder* aBuilder,
                                      nsDisplayList* aBackground,
                                      nsDisplayList* aForeground)
 {
   if (mFrame->StyleEffects()->mBoxShadow) {
     aBackground->AppendNewToTop(new (aBuilder)
       nsDisplayButtonBoxShadowOuter(aBuilder, this));
@@ -420,16 +473,40 @@ nsButtonFrameRenderer::PaintInnerFocusBo
     result &=
       nsCSSRendering::PaintBorder(aPresContext, aRenderingContext, mFrame,
                                   aDirtyRect, rect, mInnerFocusStyle, flags);
   }
 
   return result;
 }
 
+Maybe<nsCSSBorderRenderer>
+nsButtonFrameRenderer::CreateInnerFocusBorderRenderer(
+  nsDisplayListBuilder* aBuilder,
+  nsPresContext* aPresContext,
+  nsRenderingContext* aRenderingContext,
+  const nsRect& aDirtyRect,
+  const nsRect& aRect)
+{
+  if (mInnerFocusStyle) {
+    nsRect rect;
+    GetButtonInnerFocusRect(aRect, rect);
+
+    gfx::DrawTarget* dt = aRenderingContext ? aRenderingContext->GetDrawTarget() : nullptr;
+    return nsCSSRendering::CreateBorderRenderer(aPresContext,
+                                                dt,
+                                                mFrame,
+                                                aDirtyRect,
+                                                rect,
+                                                mInnerFocusStyle);
+  }
+
+  return Nothing();
+}
+
 DrawResult
 nsButtonFrameRenderer::PaintBorder(
   nsDisplayListBuilder* aBuilder,
   nsPresContext* aPresContext,
   nsRenderingContext& aRenderingContext,
   const nsRect& aDirtyRect,
   const nsRect& aRect)
 {
--- a/layout/forms/nsButtonFrameRenderer.h
+++ b/layout/forms/nsButtonFrameRenderer.h
@@ -3,16 +3,17 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef nsButtonFrameRenderer_h___
 #define nsButtonFrameRenderer_h___
 
 #include "imgIContainer.h"
 #include "nsMargin.h"
+#include "nsCSSRenderingBorders.h"
 
 class nsIFrame;
 class nsFrame;
 class nsDisplayList;
 class nsDisplayListBuilder;
 class nsPresContext;
 class nsRenderingContext;
 struct nsRect;
@@ -38,16 +39,22 @@ public:
 
 
   DrawResult PaintInnerFocusBorder(nsDisplayListBuilder* aBuilder,
                                    nsPresContext* aPresContext,
                                    nsRenderingContext& aRenderingContext,
                                    const nsRect& aDirtyRect,
                                    const nsRect& aRect);
 
+  mozilla::Maybe<nsCSSBorderRenderer> CreateInnerFocusBorderRenderer(nsDisplayListBuilder* aBuilder,
+                                                                     nsPresContext* aPresContext,
+                                                                     nsRenderingContext* aRenderingContext,
+                                                                     const nsRect& aDirtyRect,
+                                                                     const nsRect& aRect);
+
   DrawResult PaintBorder(nsDisplayListBuilder* aBuilder,
                          nsPresContext* aPresContext,
                          nsRenderingContext& aRenderingContext,
                          const nsRect& aDirtyRect,
                          const nsRect& aRect);
 
   void SetFrame(nsFrame* aFrame, nsPresContext* aPresContext);
  
--- a/layout/painting/nsCSSRenderingBorders.h
+++ b/layout/painting/nsCSSRenderingBorders.h
@@ -79,16 +79,17 @@ class nsCSSBorderRenderer final
   typedef mozilla::gfx::Point Point;
   typedef mozilla::gfx::Rect Rect;
   typedef mozilla::gfx::RectCornerRadii RectCornerRadii;
   typedef mozilla::gfx::StrokeOptions StrokeOptions;
 
   friend class nsDisplayBorder;
   friend class nsDisplayOutline;
   friend class nsDisplayButtonBorder;
+  friend class nsDisplayButtonForeground;
 
 public:
 
   nsCSSBorderRenderer(nsPresContext* aPresContext,
                       const nsIDocument* aDocument,
                       DrawTarget* aDrawTarget,
                       const Rect& aDirtyRect,
                       Rect& aOuterRect,