Bug 1387325 - Part2. Add WR support for nsDisplayXULImage. r=mattwoodrow
☠☠ backed out by 41c7be71c64f ☠ ☠
authorEthan Lin <ethlin@mozilla.com>
Thu, 17 Aug 2017 14:47:25 +0800
changeset 429214 d25d3c15d149a2c18b7ae1caf71d6bd949d2f400
parent 429213 9cbb90abba0df7b0bf242e4f6466e3cbb9a354db
child 429215 cae034ec1d40a07972cdfddf41f7328998544a1c
push id7761
push userjlund@mozilla.com
push dateFri, 15 Sep 2017 00:19:52 +0000
treeherdermozilla-beta@c38455951db4 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmattwoodrow
bugs1387325
milestone57.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 1387325 - Part2. Add WR support for nsDisplayXULImage. r=mattwoodrow MozReview-Commit-ID: 9DncgchiS44
layout/xul/moz.build
layout/xul/nsImageBoxFrame.cpp
layout/xul/nsImageBoxFrame.h
--- a/layout/xul/moz.build
+++ b/layout/xul/moz.build
@@ -89,16 +89,18 @@ if CONFIG['MOZ_XUL']:
         'nsXULPopupManager.cpp',
         'PopupBoxObject.cpp',
         'ScrollBoxObject.cpp',
     ]
 
 if CONFIG['MOZ_XUL']:
     DIRS += ['tree', 'grid']
 
+include('/ipc/chromium/chromium-config.mozbuild')
+
 FINAL_LIBRARY = 'xul'
 LOCAL_INCLUDES += [
     '../base',
     '../generic',
     '../painting',
     '../style',
     '/dom/base',
     '/dom/xul',
--- a/layout/xul/nsImageBoxFrame.cpp
+++ b/layout/xul/nsImageBoxFrame.cpp
@@ -47,16 +47,17 @@
 
 #include "nsContentUtils.h"
 
 #include "mozilla/BasicEvents.h"
 #include "mozilla/EventDispatcher.h"
 #include "mozilla/Maybe.h"
 #include "SVGImageContext.h"
 #include "Units.h"
+#include "mozilla/layers/WebRenderLayerManager.h"
 
 #define ONLOAD_CALLED_TOO_EARLY 1
 
 using namespace mozilla;
 using namespace mozilla::gfx;
 using namespace mozilla::image;
 using namespace mozilla::layers;
 
@@ -405,16 +406,64 @@ nsImageBoxFrame::PaintImage(gfxContext& 
            PresContext(), imgCon,
            nsLayoutUtils::GetSamplingFilterForFrame(this),
            dest, dirty,
            svgContext, aFlags,
            anchorPoint.ptrOr(nullptr),
            hasSubRect ? &mSubRect : nullptr);
 }
 
+DrawResult
+nsImageBoxFrame::CreateWebRenderCommands(mozilla::wr::DisplayListBuilder& aBuilder,
+                                         const StackingContextHelper& aSc,
+                                         mozilla::layers::WebRenderLayerManager* aManager,
+                                         nsDisplayItem* aItem,
+                                         nsPoint aPt,
+                                         uint32_t aFlags)
+{
+  DrawResult result;
+  Maybe<nsPoint> anchorPoint;
+  nsRect dest;
+  nsCOMPtr<imgIContainer> imgCon = GetImageContainerForPainting(aPt, result,
+                                                                anchorPoint,
+                                                                dest);
+  if (!imgCon) {
+    return result;
+  }
+
+  uint32_t containerFlags = imgIContainer::FLAG_NONE;
+  if (aFlags & nsImageRenderer::FLAG_SYNC_DECODE_IMAGES) {
+    containerFlags |= imgIContainer::FLAG_SYNC_DECODE;
+  }
+  RefPtr<layers::ImageContainer> container =
+    imgCon->GetImageContainer(aManager, containerFlags);
+  if (!container) {
+    NS_WARNING("Failed to get image container");
+    return DrawResult::NOT_READY;
+  }
+
+  gfx::IntSize size;
+  Maybe<wr::ImageKey> key = aManager->CreateImageKey(aItem, container, aBuilder, aSc, size);
+  if (key.isNothing()) {
+    return DrawResult::BAD_IMAGE;
+  }
+  const int32_t appUnitsPerDevPixel = PresContext()->AppUnitsPerDevPixel();
+  LayoutDeviceRect fillRect = LayoutDeviceRect::FromAppUnits(dest,
+                                                             appUnitsPerDevPixel);
+  wr::LayoutRect fill = aSc.ToRelativeLayoutRect(fillRect);
+
+  LayoutDeviceSize gapSize(0, 0);
+  SamplingFilter sampleFilter = nsLayoutUtils::GetSamplingFilterForFrame(aItem->Frame());
+  aBuilder.PushImage(fill, fill,
+                     wr::ToLayoutSize(fillRect.Size()), wr::ToLayoutSize(gapSize),
+                     wr::ToImageRendering(sampleFilter), key.value());
+
+  return DrawResult::SUCCESS;
+}
+
 nsRect
 nsImageBoxFrame::GetDestRect(const nsPoint& aOffset, Maybe<nsPoint>& aAnchorPoint)
 {
   nsCOMPtr<imgIContainer> imgCon;
   mImageRequest->GetImage(getter_AddRefs(imgCon));
   MOZ_ASSERT(imgCon);
 
   nsRect clientRect;
@@ -469,16 +518,65 @@ void nsDisplayXULImage::Paint(nsDisplayL
     flags |= imgIContainer::FLAG_HIGH_QUALITY_SCALING;
 
   DrawResult result = static_cast<nsImageBoxFrame*>(mFrame)->
     PaintImage(*aCtx, mVisibleRect, ToReferenceFrame(), flags);
 
   nsDisplayItemGenericImageGeometry::UpdateDrawResult(this, result);
 }
 
+LayerState
+nsDisplayXULImage::GetLayerState(nsDisplayListBuilder* aBuilder,
+                                 LayerManager* aManager,
+                                 const ContainerLayerParameters& aParameters)
+{
+  if (ShouldUseAdvancedLayer(aManager, gfxPrefs::LayersAllowImageLayers) &&
+      CanOptimizeToImageLayer(aManager, aBuilder)) {
+    return LAYER_ACTIVE;
+  }
+  return LAYER_NONE;
+}
+
+already_AddRefed<Layer>
+nsDisplayXULImage::BuildLayer(nsDisplayListBuilder* aBuilder,
+                           LayerManager* aManager,
+                           const ContainerLayerParameters& aContainerParameters)
+{
+  return BuildDisplayItemLayer(aBuilder, aManager, aContainerParameters);
+}
+
+bool
+nsDisplayXULImage::CreateWebRenderCommands(mozilla::wr::DisplayListBuilder& aBuilder,
+                                           const StackingContextHelper& aSc,
+                                           nsTArray<WebRenderParentCommand>& aParentCommands,
+                                           mozilla::layers::WebRenderLayerManager* aManager,
+                                           nsDisplayListBuilder* aDisplayListBuilder)
+{
+  if (aManager->IsLayersFreeTransaction()) {
+    ContainerLayerParameters parameter;
+    if (GetLayerState(aDisplayListBuilder, aManager, parameter) != LAYER_ACTIVE) {
+      return false;
+    }
+  }
+
+  uint32_t flags = imgIContainer::FLAG_SYNC_DECODE_IF_FAST;
+  if (aDisplayListBuilder->ShouldSyncDecodeImages()) {
+    flags |= imgIContainer::FLAG_SYNC_DECODE;
+  }
+  if (aDisplayListBuilder->IsPaintingToWindow()) {
+    flags |= imgIContainer::FLAG_HIGH_QUALITY_SCALING;
+  }
+
+  DrawResult result = static_cast<nsImageBoxFrame*>(mFrame)->
+    CreateWebRenderCommands(aBuilder, aSc, aManager, this, ToReferenceFrame(), flags);
+
+  nsDisplayItemGenericImageGeometry::UpdateDrawResult(this, result);
+  return true;
+}
+
 nsDisplayItemGeometry*
 nsDisplayXULImage::AllocateGeometry(nsDisplayListBuilder* aBuilder)
 {
   return new nsDisplayItemGenericImageGeometry(this, aBuilder);
 }
 
 void
 nsDisplayXULImage::ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder,
--- a/layout/xul/nsImageBoxFrame.h
+++ b/layout/xul/nsImageBoxFrame.h
@@ -94,16 +94,23 @@ public:
                                                                DrawResult& aDrawResult,
                                                                Maybe<nsPoint>& aAnchorPoint,
                                                                nsRect& aDest);
 
   DrawResult PaintImage(gfxContext& aRenderingContext,
                         const nsRect& aDirtyRect,
                         nsPoint aPt, uint32_t aFlags);
 
+  DrawResult CreateWebRenderCommands(mozilla::wr::DisplayListBuilder& aBuilder,
+                                     const mozilla::layers::StackingContextHelper& aSc,
+                                     mozilla::layers::WebRenderLayerManager* aManager,
+                                     nsDisplayItem* aItem,
+                                     nsPoint aPt,
+                                     uint32_t aFlags);
+
   bool CanOptimizeToImageLayer();
 
   nsRect GetDestRect(const nsPoint& aOffset, Maybe<nsPoint>& aAnchorPoint);
 
 protected:
   explicit nsImageBoxFrame(nsStyleContext* aContext);
 
   virtual void GetImageSize();
@@ -158,12 +165,27 @@ public:
   virtual nsDisplayItemGeometry* AllocateGeometry(nsDisplayListBuilder* aBuilder) override;
   virtual void ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder,
                                          const nsDisplayItemGeometry* aGeometry,
                                          nsRegion* aInvalidRegion) override;
   // Doesn't handle HitTest because nsLeafBoxFrame already creates an
   // event receiver for us
   virtual void Paint(nsDisplayListBuilder* aBuilder,
                      gfxContext* 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 bool CreateWebRenderCommands(mozilla::wr::DisplayListBuilder& aBuilder,
+                                       const StackingContextHelper& aSc,
+                                       nsTArray<WebRenderParentCommand>& aParentCommands,
+                                       mozilla::layers::WebRenderLayerManager* aManager,
+                                       nsDisplayListBuilder* aDisplayListBuilder) override;
+
   NS_DISPLAY_DECL_NAME("XULImage", TYPE_XUL_IMAGE)
 };
 
 #endif /* nsImageBoxFrame_h___ */