Bug 1424177 - Slightly enlarge drawtarget size when fallback. r=kats
authorMorris Tseng <mtseng@mozila.com>
Tue, 16 Jan 2018 17:33:12 +0800
changeset 399376 c4c4ce0c895b129717af8fa9042af6bc50b43740
parent 399375 8aec32412f04950fd53d81e8dc4a15d657f59378
child 399377 e0a2cfd2fc7a5265419ebe3d119130fc88782ff5
push id98942
push usermtseng@mozilla.com
push dateTue, 16 Jan 2018 09:34:08 +0000
treeherdermozilla-inbound@e0a2cfd2fc7a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerskats
bugs1424177
milestone59.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 1424177 - Slightly enlarge drawtarget size when fallback. r=kats MozReview-Commit-ID: Dam5l91Y93Y
gfx/layers/wr/WebRenderCommandBuilder.cpp
--- a/gfx/layers/wr/WebRenderCommandBuilder.cpp
+++ b/gfx/layers/wr/WebRenderCommandBuilder.cpp
@@ -522,19 +522,25 @@ WebRenderCommandBuilder::GenerateFallbac
 
   // XXX not sure if paintSize should be in layer or layoutdevice pixels, it
   // has some sort of scaling applied.
   LayerIntSize paintSize = RoundedToInt(LayerSize(bounds.Width() * scale.width, bounds.Height() * scale.height));
   if (paintSize.width == 0 || paintSize.height == 0) {
     return nullptr;
   }
 
+  // Some display item may draw exceed the paintSize, we need prepare a larger
+  // draw target to contain the result.
+  auto scaledBounds = bounds * LayoutDeviceToLayerScale(1);
+  scaledBounds.Scale(scale.width, scale.height);
+  LayerIntSize dtSize = RoundedToInt(scaledBounds).Size();
+
   bool needPaint = true;
   LayoutDeviceIntPoint offset = RoundedToInt(bounds.TopLeft());
-  aImageRect = LayoutDeviceRect(offset, LayoutDeviceSize(RoundedToInt(bounds.Size())));
+  aImageRect = LayoutDeviceRect(offset, LayoutDeviceSize(RoundedToInt(bounds).Size()));
   LayerRect paintRect = LayerRect(LayerPoint(0, 0), LayerSize(paintSize));
   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 &&
       aItem->GetType() != DisplayItemType::TYPE_SVG_WRAPPER &&
@@ -576,29 +582,29 @@ WebRenderCommandBuilder::GenerateFallbac
           aStream.write((const char*)&count, sizeof(count));
           for (auto unscaled : aUnscaledFonts) {
             wr::FontKey key = mManager->WrBridge()->GetFontKeyForUnscaledFont(unscaled);
             aStream.write((const char*)&key, sizeof(key));
           }
         });
       RefPtr<gfx::DrawTarget> dummyDt =
         gfx::Factory::CreateDrawTarget(gfx::BackendType::SKIA, gfx::IntSize(1, 1), format);
-      RefPtr<gfx::DrawTarget> dt = gfx::Factory::CreateRecordingDrawTarget(recorder, dummyDt, paintSize.ToUnknownSize());
+      RefPtr<gfx::DrawTarget> dt = gfx::Factory::CreateRecordingDrawTarget(recorder, dummyDt, dtSize.ToUnknownSize());
       if (!fallbackData->mBasicLayerManager) {
         fallbackData->mBasicLayerManager = new BasicLayerManager(BasicLayerManager::BLM_INACTIVE);
       }
       bool isInvalidated = PaintItemByDrawTarget(aItem, dt, paintRect, offset, aDisplayListBuilder,
                                                  fallbackData->mBasicLayerManager, scale, highlight);
       recorder->FlushItem(IntRect());
       recorder->Finish();
 
       if (isInvalidated) {
         Range<uint8_t> bytes((uint8_t *)recorder->mOutputStream.mData, recorder->mOutputStream.mLength);
         wr::ImageKey key = mManager->WrBridge()->GetNextImageKey();
-        wr::ImageDescriptor descriptor(paintSize.ToUnknownSize(), 0, dt->GetFormat(), isOpaque);
+        wr::ImageDescriptor descriptor(dtSize.ToUnknownSize(), 0, dt->GetFormat(), isOpaque);
         if (!aResources.AddBlobImage(key, descriptor, bytes)) {
           return nullptr;
         }
         fallbackData->SetKey(key);
       } else {
         // If there is no invalidation region and we don't have a image key,
         // it means we don't need to push image for the item.
         if (!fallbackData->GetKey().isSome()) {
@@ -607,29 +613,29 @@ WebRenderCommandBuilder::GenerateFallbac
       }
     } else {
       fallbackData->CreateImageClientIfNeeded();
       RefPtr<ImageClient> imageClient = fallbackData->GetImageClient();
       RefPtr<ImageContainer> imageContainer = LayerManager::CreateImageContainer();
       bool isInvalidated = false;
 
       {
-        UpdateImageHelper helper(imageContainer, imageClient, paintSize.ToUnknownSize(), format);
+        UpdateImageHelper helper(imageContainer, imageClient, dtSize.ToUnknownSize(), format);
         {
           RefPtr<gfx::DrawTarget> dt = helper.GetDrawTarget();
           if (!dt) {
             return nullptr;
           }
           if (!fallbackData->mBasicLayerManager) {
             fallbackData->mBasicLayerManager = new BasicLayerManager(mManager->GetWidget());
           }
           isInvalidated = PaintItemByDrawTarget(aItem, dt, paintRect, offset,
-                                               aDisplayListBuilder,
-                                               fallbackData->mBasicLayerManager, scale,
-                                               highlight);
+                                                aDisplayListBuilder,
+                                                fallbackData->mBasicLayerManager, scale,
+                                                highlight);
         }
 
         if (isInvalidated) {
           // Update image if there it's invalidated.
           if (!helper.UpdateImage()) {
             return nullptr;
           }
         } else {