Bug 1319626 - Part 4: Build BorderLayers if enabled. r?mstange draft
authorMatt Woodrow <mwoodrow@mozilla.com>
Wed, 23 Nov 2016 14:36:14 +1300
changeset 442691 87d7a3c73782f05eba8d70f1c4cfb87d42673633
parent 442690 decd8d5d70febbf5394f21168d7a0ce1d571676c
child 442692 d4458fd841ec667ec1d02aa05f1d05ed85c925c2
push id36782
push usermwoodrow@mozilla.com
push dateWed, 23 Nov 2016 01:39:09 +0000
reviewersmstange
bugs1319626
milestone53.0a1
Bug 1319626 - Part 4: Build BorderLayers if enabled. r?mstange MozReview-Commit-ID: EAjfD8myZwl
gfx/thebes/gfxPrefs.h
layout/painting/nsDisplayList.cpp
layout/painting/nsDisplayList.h
--- a/gfx/thebes/gfxPrefs.h
+++ b/gfx/thebes/gfxPrefs.h
@@ -441,16 +441,17 @@ private:
   DECL_GFX_PREF(Once, "image.mem.surfacecache.size_factor",    ImageMemSurfaceCacheSizeFactor, uint32_t, 64);
   DECL_GFX_PREF(Once, "image.multithreaded_decoding.limit",    ImageMTDecodingLimit, int32_t, -1);
 
   DECL_GFX_PREF(Once, "layers.acceleration.disabled",          LayersAccelerationDisabledDoNotUseDirectly, bool, false);
   DECL_GFX_PREF(Live, "layers.acceleration.draw-fps",          LayersDrawFPS, bool, false);
   DECL_GFX_PREF(Live, "layers.acceleration.draw-fps.print-histogram",  FPSPrintHistogram, bool, false);
   DECL_GFX_PREF(Live, "layers.acceleration.draw-fps.write-to-file", WriteFPSToFile, bool, false);
   DECL_GFX_PREF(Once, "layers.acceleration.force-enabled",     LayersAccelerationForceEnabledDoNotUseDirectly, bool, false);
+  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(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);
--- a/layout/painting/nsDisplayList.cpp
+++ b/layout/painting/nsDisplayList.cpp
@@ -31,16 +31,17 @@
 #include "gfxMatrix.h"
 #include "gfxPrefs.h"
 #include "nsSVGIntegrationUtils.h"
 #include "nsSVGUtils.h"
 #include "nsLayoutUtils.h"
 #include "nsIScrollableFrame.h"
 #include "nsIFrameInlines.h"
 #include "nsThemeConstants.h"
+#include "BorderConsts.h"
 #include "LayerTreeInvalidation.h"
 
 #include "imgIContainer.h"
 #include "BasicLayers.h"
 #include "nsBoxFrame.h"
 #include "nsViewportFrame.h"
 #include "nsSubDocumentFrame.h"
 #include "nsSVGEffects.h"
@@ -4052,16 +4053,90 @@ nsDisplayBorder::ComputeInvalidationRegi
   }
 
   if (aBuilder->ShouldSyncDecodeImages() &&
       geometry->ShouldInvalidateToSyncDecodeImages()) {
     aInvalidRegion->Or(*aInvalidRegion, GetBounds(aBuilder, &snap));
   }
 }
 
+LayerState
+nsDisplayBorder::GetLayerState(nsDisplayListBuilder* aBuilder,
+                               LayerManager* aManager,
+                               const ContainerLayerParameters& aParameters)
+{
+  if (!gfxPrefs::LayersAllowBorderLayers()) {
+    return LAYER_NONE;
+  }
+
+  nsPoint offset = ToReferenceFrame();
+  Maybe<nsCSSBorderRenderer> br =
+    nsCSSRendering::CreateBorderRenderer(mFrame->PresContext(),
+                                         nullptr,
+                                         mFrame,
+                                         nsRect(),
+                                         nsRect(offset, mFrame->GetSize()),
+                                         mFrame->StyleContext(),
+                                         mFrame->GetSkipSides());
+  if (!br) {
+    return LAYER_NONE;
+  }
+
+  bool hasCompositeColors;
+  if (!br->AllBordersSolid(&hasCompositeColors) || hasCompositeColors) {
+    return LAYER_NONE;
+  }
+
+  // We don't support this yet as we don't copy the values to
+  // the layer, and BasicBorderLayer doesn't support it yet.
+  if (!br->mNoBorderRadius) {
+    return LAYER_NONE;
+  }
+
+  // We copy these values correctly to the layer, but BasicBorderLayer
+  // won't render them
+  if (!br->AreBorderSideFinalStylesSame(SIDE_BITS_ALL) ||
+      !br->AllBordersSameWidth()) {
+    return LAYER_NONE;
+  }
+
+  NS_FOR_CSS_SIDES(i) {
+    if (br->mBorderStyles[i] == NS_STYLE_BORDER_STYLE_SOLID) {
+      mColors[i] = ToDeviceColor(br->mBorderColors[i]);
+      mWidths[i] = br->mBorderWidths[i];
+    } else {
+      mWidths[i] = 0;
+    }
+  }
+
+  mRect = ViewAs<LayerPixel>(br->mOuterRect);
+  return LAYER_INACTIVE;
+}
+
+already_AddRefed<Layer>
+nsDisplayBorder::BuildLayer(nsDisplayListBuilder* aBuilder,
+                            LayerManager* aManager,
+                            const ContainerLayerParameters& aContainerParameters)
+{
+  RefPtr<BorderLayer> layer = static_cast<BorderLayer*>
+    (aManager->GetLayerBuilder()->GetLeafLayerFor(aBuilder, this));
+  if (!layer) {
+    layer = aManager->CreateBorderLayer();
+    if (!layer)
+      return nullptr;
+  }
+  layer->SetRect(mRect);
+  layer->SetCorners({ LayerSize(), LayerSize(), LayerSize(), LayerSize() });
+  layer->SetColors(mColors);
+  layer->SetWidths(mWidths);
+  layer->SetBaseTransform(gfx::Matrix4x4::Translation(aContainerParameters.mOffset.x,
+                                                      aContainerParameters.mOffset.y, 0));
+  return layer.forget();
+}
+
 void
 nsDisplayBorder::Paint(nsDisplayListBuilder* aBuilder,
                        nsRenderingContext* aCtx) {
   nsPoint offset = ToReferenceFrame();
 
   PaintBorderFlags flags = aBuilder->ShouldSyncDecodeImages()
                          ? PaintBorderFlags::SYNC_DECODE_IMAGES
                          : PaintBorderFlags();
--- a/layout/painting/nsDisplayList.h
+++ b/layout/painting/nsDisplayList.h
@@ -9,16 +9,17 @@
  * structures that represent things to be painted (ordered in z-order),
  * used during painting and hit testing
  */
 
 #ifndef NSDISPLAYLIST_H_
 #define NSDISPLAYLIST_H_
 
 #include "mozilla/Attributes.h"
+#include "mozilla/Array.h"
 #include "mozilla/DebugOnly.h"
 #include "mozilla/EnumSet.h"
 #include "mozilla/Maybe.h"
 #include "nsCOMPtr.h"
 #include "nsContainerFrame.h"
 #include "nsPoint.h"
 #include "nsRect.h"
 #include "plarena.h"
@@ -2552,28 +2553,39 @@ public:
 #ifdef NS_BUILD_REFCNT_LOGGING
   virtual ~nsDisplayBorder() {
     MOZ_COUNT_DTOR(nsDisplayBorder);
   }
 #endif
 
   virtual bool IsInvisibleInRect(const nsRect& aRect) override;
   virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) 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 Paint(nsDisplayListBuilder* aBuilder, nsRenderingContext* aCtx) override;
   NS_DISPLAY_DECL_NAME("Border", TYPE_BORDER)
   
   virtual nsDisplayItemGeometry* AllocateGeometry(nsDisplayListBuilder* aBuilder) override;
 
   virtual void ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder,
                                          const nsDisplayItemGeometry* aGeometry,
                                          nsRegion* aInvalidRegion) override;
 
 protected:
   nsRect CalculateBounds(const nsStyleBorder& aStyleBorder);
 
+  mozilla::Array<mozilla::gfx::Color, 4> mColors;
+  mozilla::Array<mozilla::LayerCoord, 4> mWidths;
+  mozilla::LayerRect mRect;
+
   nsRect mBounds;
 };
 
 /**
  * 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