Bug 1395501 - Part2. Use stacking context's scale value to compute the correct paint rect. r=jrmuizel draft
authorEthan Lin <ethlin@mozilla.com>
Thu, 07 Sep 2017 16:41:35 +0800
changeset 671812 d8930cd5438b5358bdf9e819edbb8c903cb5773e
parent 671811 7c60ef61650bb7e234a9016dd6269b961da72e19
child 671813 3138d734c389e9a97d1921ecf859e1b958e1512a
push id82050
push userbmo:ethlin@mozilla.com
push dateThu, 28 Sep 2017 10:05:31 +0000
reviewersjrmuizel
bugs1395501
milestone58.0a1
Bug 1395501 - Part2. Use stacking context's scale value to compute the correct paint rect. r=jrmuizel MozReview-Commit-ID: AaAhTza5TP4
gfx/layers/wr/WebRenderLayerManager.cpp
gfx/layers/wr/WebRenderLayerManager.h
--- a/gfx/layers/wr/WebRenderLayerManager.cpp
+++ b/gfx/layers/wr/WebRenderLayerManager.cpp
@@ -467,25 +467,27 @@ WebRenderLayerManager::PushImage(nsDispl
 
 static void
 PaintItemByDrawTarget(nsDisplayItem* aItem,
                       DrawTarget* aDT,
                       const LayerRect& aImageRect,
                       const LayerPoint& aOffset,
                       nsDisplayListBuilder* aDisplayListBuilder,
                       RefPtr<BasicLayerManager>& aManager,
-                      WebRenderLayerManager* aWrManager)
+                      WebRenderLayerManager* aWrManager,
+                      const gfx::Size& aScale)
 {
   MOZ_ASSERT(aDT);
 
   aDT->ClearRect(aImageRect.ToUnknownRect());
   RefPtr<gfxContext> context = gfxContext::CreateOrNull(aDT);
   MOZ_ASSERT(context);
 
-  context->SetMatrix(gfxMatrix::Translation(-aOffset.x, -aOffset.y));
+  context->SetMatrix(context->CurrentMatrix().PreScale(aScale.width, aScale.height).PreTranslate(-aOffset.x, -aOffset.y));
+
   switch (aItem->GetType()) {
   case DisplayItemType::TYPE_MASK:
     static_cast<nsDisplayMask*>(aItem)->PaintMask(aDisplayListBuilder, context);
     break;
   case DisplayItemType::TYPE_FILTER:
     {
       if (aManager == nullptr) {
         aManager = new BasicLayerManager(BasicLayerManager::BLM_INACTIVE);
@@ -543,19 +545,19 @@ PaintItemByDrawTarget(nsDisplayItem* aIt
     aDT->FillRect(Rect(0, 0, aImageRect.Width(), aImageRect.Height()), ColorPattern(Color(r, g, b, 0.5)));
   }
 }
 
 already_AddRefed<WebRenderFallbackData>
 WebRenderLayerManager::GenerateFallbackData(nsDisplayItem* aItem,
                                             wr::DisplayListBuilder& aBuilder,
                                             wr::IpcResourceUpdateQueue& aResources,
+                                            const StackingContextHelper& aSc,
                                             nsDisplayListBuilder* aDisplayListBuilder,
-                                            LayerRect& aImageRect,
-                                            LayerPoint& aOffset)
+                                            LayerRect& aImageRect)
 {
   RefPtr<WebRenderFallbackData> fallbackData = CreateOrRecycleWebRenderUserData<WebRenderFallbackData>(aItem);
 
   bool snap;
   nsRect itemBounds = aItem->GetBounds(aDisplayListBuilder, &snap);
   nsRect clippedBounds = itemBounds;
 
   const DisplayItemClip& clip = aItem->GetClip();
@@ -572,28 +574,28 @@ WebRenderLayerManager::GenerateFallbackD
   nsRegion visibleRegion(clippedBounds);
   aItem->ComputeVisibility(aDisplayListBuilder, &visibleRegion);
 
   const int32_t appUnitsPerDevPixel = aItem->Frame()->PresContext()->AppUnitsPerDevPixel();
   LayerRect bounds = ViewAs<LayerPixel>(
       LayoutDeviceRect::FromAppUnits(clippedBounds, appUnitsPerDevPixel),
       PixelCastJustification::WebRenderHasUnitResolution);
 
-  LayerIntSize imageSize = RoundedToInt(bounds.Size());
-  aImageRect = LayerRect(LayerPoint(0, 0), LayerSize(imageSize));
-  if (imageSize.width == 0 || imageSize.height == 0) {
+  gfx::Size scale = aSc.GetInheritedScale();
+  LayerIntSize paintSize = RoundedToInt(LayerSize(bounds.width * scale.width, bounds.height * scale.height));
+  if (paintSize.width == 0 || paintSize.height == 0) {
     return nullptr;
   }
 
-  aOffset = RoundedToInt(bounds.TopLeft());
-
   bool needPaint = true;
+  LayerIntPoint offset = RoundedToInt(bounds.TopLeft());
+  aImageRect = LayerRect(offset, LayerSize(RoundedToInt(bounds.Size())));
+  LayerRect paintRect = LayerRect(LayerPoint(0, 0), LayerSize(paintSize));
   nsAutoPtr<nsDisplayItemGeometry> geometry = fallbackData->GetGeometry();
 
-
   // nsDisplayFilter is rendered via BasicLayerManager which means the invalidate
   // region is unknown until we traverse the displaylist contained by it.
   if (geometry && !fallbackData->IsInvalid() &&
       aItem->GetType() != DisplayItemType::TYPE_FILTER) {
     nsRect invalid;
     nsRegion invalidRegion;
 
     if (aItem->IsInvalid(invalid)) {
@@ -619,41 +621,41 @@ WebRenderLayerManager::GenerateFallbackD
                                                       gfx::SurfaceFormat::A8 : gfx::SurfaceFormat::B8G8R8A8;
     if (gfxPrefs::WebRenderBlobImages()) {
       bool snapped;
       bool isOpaque = aItem->GetOpaqueRegion(aDisplayListBuilder, &snapped).Contains(clippedBounds);
 
       RefPtr<gfx::DrawEventRecorderMemory> recorder = MakeAndAddRef<gfx::DrawEventRecorderMemory>();
       RefPtr<gfx::DrawTarget> dummyDt =
         gfx::Factory::CreateDrawTarget(gfx::BackendType::SKIA, gfx::IntSize(1, 1), format);
-      RefPtr<gfx::DrawTarget> dt = gfx::Factory::CreateRecordingDrawTarget(recorder, dummyDt, imageSize.ToUnknownSize());
-      PaintItemByDrawTarget(aItem, dt, aImageRect, aOffset, aDisplayListBuilder,
-                            fallbackData->mBasicLayerManager, this);
+      RefPtr<gfx::DrawTarget> dt = gfx::Factory::CreateRecordingDrawTarget(recorder, dummyDt, paintSize.ToUnknownSize());
+      PaintItemByDrawTarget(aItem, dt, paintRect, offset, aDisplayListBuilder,
+                            fallbackData->mBasicLayerManager, this, scale);
       recorder->Finish();
 
       Range<uint8_t> bytes((uint8_t*)recorder->mOutputStream.mData, recorder->mOutputStream.mLength);
       wr::ImageKey key = WrBridge()->GetNextImageKey();
-      wr::ImageDescriptor descriptor(imageSize.ToUnknownSize(), 0, dt->GetFormat(), isOpaque);
+      wr::ImageDescriptor descriptor(paintSize.ToUnknownSize(), 0, dt->GetFormat(), isOpaque);
       aResources.AddBlobImage(key, descriptor, bytes);
       fallbackData->SetKey(key);
     } else {
       fallbackData->CreateImageClientIfNeeded();
       RefPtr<ImageClient> imageClient = fallbackData->GetImageClient();
       RefPtr<ImageContainer> imageContainer = LayerManager::CreateImageContainer();
 
       {
-        UpdateImageHelper helper(imageContainer, imageClient, imageSize.ToUnknownSize(), format);
+        UpdateImageHelper helper(imageContainer, imageClient, paintSize.ToUnknownSize(), format);
         {
           RefPtr<gfx::DrawTarget> dt = helper.GetDrawTarget();
           if (!dt) {
             return nullptr;
           }
-          PaintItemByDrawTarget(aItem, dt, aImageRect, aOffset,
+          PaintItemByDrawTarget(aItem, dt, paintRect, offset,
                                 aDisplayListBuilder,
-                                fallbackData->mBasicLayerManager, this);
+                                fallbackData->mBasicLayerManager, this, scale);
         }
         if (!helper.UpdateImage()) {
           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
@@ -680,20 +682,19 @@ Maybe<wr::WrImageMask>
 WebRenderLayerManager::BuildWrMaskImage(nsDisplayItem* aItem,
                                         wr::DisplayListBuilder& aBuilder,
                                         wr::IpcResourceUpdateQueue& aResources,
                                         const StackingContextHelper& aSc,
                                         nsDisplayListBuilder* aDisplayListBuilder,
                                         const LayerRect& aBounds)
 {
   LayerRect imageRect;
-  LayerPoint offset;
   RefPtr<WebRenderFallbackData> fallbackData = GenerateFallbackData(aItem, aBuilder, aResources,
-                                                                    aDisplayListBuilder,
-                                                                    imageRect, offset);
+                                                                    aSc, aDisplayListBuilder,
+                                                                    imageRect);
   if (!fallbackData) {
     return Nothing();
   }
 
   wr::WrImageMask imageMask;
   imageMask.image = fallbackData->GetKey().value();
   imageMask.rect = aSc.ToRelativeLayoutRect(aBounds);
   imageMask.repeat = false;
@@ -703,25 +704,24 @@ WebRenderLayerManager::BuildWrMaskImage(
 bool
 WebRenderLayerManager::PushItemAsImage(nsDisplayItem* aItem,
                                        wr::DisplayListBuilder& aBuilder,
                                        wr::IpcResourceUpdateQueue& aResources,
                                        const StackingContextHelper& aSc,
                                        nsDisplayListBuilder* aDisplayListBuilder)
 {
   LayerRect imageRect;
-  LayerPoint offset;
   RefPtr<WebRenderFallbackData> fallbackData = GenerateFallbackData(aItem, aBuilder, aResources,
-                                                                    aDisplayListBuilder,
-                                                                    imageRect, offset);
+                                                                    aSc, aDisplayListBuilder,
+                                                                    imageRect);
   if (!fallbackData) {
     return false;
   }
 
-  wr::LayoutRect dest = aSc.ToRelativeLayoutRect(imageRect + offset);
+  wr::LayoutRect dest = aSc.ToRelativeLayoutRect(imageRect);
   SamplingFilter sampleFilter = nsLayoutUtils::GetSamplingFilterForFrame(aItem->Frame());
   aBuilder.PushImage(dest,
                      dest,
                      !aItem->BackfaceIsHidden(),
                      wr::ToImageRendering(sampleFilter),
                      fallbackData->GetKey().value());
   return true;
 }
--- a/gfx/layers/wr/WebRenderLayerManager.h
+++ b/gfx/layers/wr/WebRenderLayerManager.h
@@ -75,19 +75,19 @@ public:
                  mozilla::wr::IpcResourceUpdateQueue& aResources,
                  const StackingContextHelper& aSc,
                  const LayerRect& aRect);
 
   already_AddRefed<WebRenderFallbackData>
   GenerateFallbackData(nsDisplayItem* aItem,
                        wr::DisplayListBuilder& aBuilder,
                        wr::IpcResourceUpdateQueue& aResourceUpdates,
+                       const StackingContextHelper& aSc,
                        nsDisplayListBuilder* aDisplayListBuilder,
-                       LayerRect& aImageRect,
-                       LayerPoint& aOffset);
+                       LayerRect& aImageRect);
 
   Maybe<wr::WrImageMask> BuildWrMaskImage(nsDisplayItem* aItem,
                                           wr::DisplayListBuilder& aBuilder,
                                           wr::IpcResourceUpdateQueue& aResources,
                                           const StackingContextHelper& aSc,
                                           nsDisplayListBuilder* aDisplayListBuilder,
                                           const LayerRect& aBounds);
   bool PushItemAsImage(nsDisplayItem* aItem,