Bug 1384839 - Part1. Extract the generation of fallback data from PushItemAsImage into a helper function to reuse it for mask painting. r=kats draft
authorEthan Lin <ethlin@mozilla.com>
Fri, 28 Jul 2017 11:30:05 +0800
changeset 618771 06d5984e92e8115805fa70827d97c8b5191713cf
parent 618757 44121dbcac6a9d3ff18ed087a09b3205e5a04db1
child 618772 89e4e0996d73bfba536b439ea16a350adf3f92cc
push id71449
push userbmo:ethlin@mozilla.com
push dateTue, 01 Aug 2017 02:58:22 +0000
reviewerskats
bugs1384839
milestone56.0a1
Bug 1384839 - Part1. Extract the generation of fallback data from PushItemAsImage into a helper function to reuse it for mask painting. r=kats MozReview-Commit-ID: FUP6bZyfalQ
gfx/layers/wr/WebRenderLayerManager.cpp
gfx/layers/wr/WebRenderLayerManager.h
--- a/gfx/layers/wr/WebRenderLayerManager.cpp
+++ b/gfx/layers/wr/WebRenderLayerManager.cpp
@@ -381,21 +381,22 @@ PaintItemByDrawTarget(nsDisplayItem* aIt
     aDT->SetTransform(Matrix());
     float r = float(rand()) / RAND_MAX;
     float g = float(rand()) / RAND_MAX;
     float b = float(rand()) / RAND_MAX;
     aDT->FillRect(Rect(0, 0, aImageRect.width, aImageRect.height), ColorPattern(Color(r, g, b, 0.5)));
   }
 }
 
-bool
-WebRenderLayerManager::PushItemAsImage(nsDisplayItem* aItem,
-                                       wr::DisplayListBuilder& aBuilder,
-                                       const StackingContextHelper& aSc,
-                                       nsDisplayListBuilder* aDisplayListBuilder)
+already_AddRefed<WebRenderFallbackData>
+WebRenderLayerManager::GenerateFallbackData(nsDisplayItem* aItem,
+                                            wr::DisplayListBuilder& aBuilder,
+                                            nsDisplayListBuilder* aDisplayListBuilder,
+                                            LayerRect& aImageRect,
+                                            LayerPoint& aOffset)
 {
   RefPtr<WebRenderFallbackData> fallbackData = CreateOrRecycleWebRenderUserData<WebRenderFallbackData>(aItem);
 
   bool snap;
   nsRect itemBounds = aItem->GetBounds(aDisplayListBuilder, &snap);
   nsRect clippedBounds = itemBounds;
 
   const DisplayItemClip& clip = aItem->GetClip();
@@ -404,24 +405,23 @@ WebRenderLayerManager::PushItemAsImage(n
   }
 
   const int32_t appUnitsPerDevPixel = aItem->Frame()->PresContext()->AppUnitsPerDevPixel();
   LayerRect bounds = ViewAs<LayerPixel>(
       LayoutDeviceRect::FromAppUnits(clippedBounds, appUnitsPerDevPixel),
       PixelCastJustification::WebRenderHasUnitResolution);
 
   LayerIntSize imageSize = RoundedToInt(bounds.Size());
-  LayerRect imageRect;
-  imageRect.SizeTo(LayerSize(imageSize));
+  aImageRect = LayerRect(LayerPoint(0, 0), LayerSize(imageSize));
   if (imageSize.width == 0 || imageSize.height == 0) {
-    return true;
+    return nullptr;
   }
 
   nsPoint shift = clippedBounds.TopLeft() - itemBounds.TopLeft();
-  LayerPoint offset = ViewAs<LayerPixel>(
+  aOffset = ViewAs<LayerPixel>(
       LayoutDevicePoint::FromAppUnits(aItem->ToReferenceFrame() + shift, appUnitsPerDevPixel),
       PixelCastJustification::WebRenderHasUnitResolution);
 
   nsRegion invalidRegion;
   nsAutoPtr<nsDisplayItemGeometry> geometry = fallbackData->GetGeometry();
 
   if (geometry) {
     nsRect invalid;
@@ -443,57 +443,74 @@ WebRenderLayerManager::PushItemAsImage(n
   }
 
   if (!geometry || !invalidRegion.IsEmpty() || fallbackData->IsInvalid()) {
     if (gfxPrefs::WebRenderBlobImages()) {
       RefPtr<gfx::DrawEventRecorderMemory> recorder = MakeAndAddRef<gfx::DrawEventRecorderMemory>();
       RefPtr<gfx::DrawTarget> dummyDt =
         gfx::Factory::CreateDrawTarget(gfx::BackendType::SKIA, gfx::IntSize(1, 1), gfx::SurfaceFormat::B8G8R8X8);
       RefPtr<gfx::DrawTarget> dt = gfx::Factory::CreateRecordingDrawTarget(recorder, dummyDt, imageSize.ToUnknownSize());
-      PaintItemByDrawTarget(aItem, dt, imageRect, offset, aDisplayListBuilder);
+      PaintItemByDrawTarget(aItem, dt, aImageRect, aOffset, aDisplayListBuilder);
       recorder->Finish();
 
       wr::ByteBuffer bytes(recorder->mOutputStream.mLength, (uint8_t*)recorder->mOutputStream.mData);
       wr::ImageKey key = WrBridge()->GetNextImageKey();
       WrBridge()->SendAddBlobImage(key, imageSize.ToUnknownSize(), imageSize.width * 4, dt->GetFormat(), bytes);
       fallbackData->SetKey(key);
     } else {
       fallbackData->CreateImageClientIfNeeded();
       RefPtr<ImageClient> imageClient = fallbackData->GetImageClient();
       RefPtr<ImageContainer> imageContainer = LayerManager::CreateImageContainer();
 
       {
         UpdateImageHelper helper(imageContainer, imageClient, imageSize.ToUnknownSize());
         {
           RefPtr<gfx::DrawTarget> dt = helper.GetDrawTarget();
-          PaintItemByDrawTarget(aItem, dt, imageRect, offset, aDisplayListBuilder);
+          PaintItemByDrawTarget(aItem, dt, aImageRect, aOffset, aDisplayListBuilder);
         }
         if (!helper.UpdateImage()) {
-          return false;
+          return nullptr;
         }
       }
 
       // Force update the key in fallback data since we repaint the image in this path.
       // If not force update, fallbackData may reuse the original key because it
       // doesn't know UpdateImageHelper already updated the image container.
       if (!fallbackData->UpdateImageKey(imageContainer, true)) {
-        return false;
+        return nullptr;
       }
     }
 
     geometry = aItem->AllocateGeometry(aDisplayListBuilder);
     fallbackData->SetInvalid(false);
   }
 
   // Update current bounds to fallback data
   fallbackData->SetGeometry(Move(geometry));
   fallbackData->SetBounds(clippedBounds);
 
   MOZ_ASSERT(fallbackData->GetKey());
 
+  return fallbackData.forget();
+}
+
+bool
+WebRenderLayerManager::PushItemAsImage(nsDisplayItem* aItem,
+                                       wr::DisplayListBuilder& aBuilder,
+                                       const StackingContextHelper& aSc,
+                                       nsDisplayListBuilder* aDisplayListBuilder)
+{
+  LayerRect imageRect;
+  LayerPoint offset;
+  RefPtr<WebRenderFallbackData> fallbackData = GenerateFallbackData(aItem, aBuilder, aDisplayListBuilder,
+                                                                    imageRect, offset);
+  if (!fallbackData) {
+    return false;
+  }
+
   wr::LayoutRect dest = aSc.ToRelativeLayoutRect(imageRect + offset);
   aBuilder.PushImage(dest,
                      dest,
                      wr::ImageRendering::Auto,
                      fallbackData->GetKey().value());
   return true;
 }
 
--- a/gfx/layers/wr/WebRenderLayerManager.h
+++ b/gfx/layers/wr/WebRenderLayerManager.h
@@ -65,16 +65,21 @@ public:
                                      mozilla::wr::DisplayListBuilder& aBuilder,
                                      const StackingContextHelper& aSc,
                                      gfx::IntSize& aSize);
   bool PushImage(nsDisplayItem* aItem,
                  ImageContainer* aContainer,
                  mozilla::wr::DisplayListBuilder& aBuilder,
                  const StackingContextHelper& aSc,
                  const LayerRect& aRect);
+  already_AddRefed<WebRenderFallbackData> GenerateFallbackData(nsDisplayItem* aItem,
+                                                               wr::DisplayListBuilder& aBuilder,
+                                                               nsDisplayListBuilder* aDisplayListBuilder,
+                                                               LayerRect& aImageRect,
+                                                               LayerPoint& aOffset);
   bool PushItemAsImage(nsDisplayItem* aItem,
                        wr::DisplayListBuilder& aBuilder,
                        const StackingContextHelper& aSc,
                        nsDisplayListBuilder* aDisplayListBuilder);
   void CreateWebRenderCommandsFromDisplayList(nsDisplayList* aDisplayList,
                                               nsDisplayListBuilder* aDisplayListBuilder,
                                               const StackingContextHelper& aSc,
                                               wr::DisplayListBuilder& aBuilder);