Bug 1549751 - Part 3: Use nsPaintedDisplayItem in WR and FLB r=mattwoodrow
authorMiko Mynttinen <mikokm@gmail.com>
Wed, 08 May 2019 13:50:09 +0000
changeset 531888 b5a3f0b9ce243f5cb610ee849d35637d3402c35b
parent 531887 69a48ceb1ecb6c0857a5a258d653be3b0a7b93b6
child 531889 616fc2abbbec6c4e8d0bcf00ee682745c24674bb
push id11265
push userffxbld-merge
push dateMon, 13 May 2019 10:53:39 +0000
treeherdermozilla-beta@77e0fe8dbdd3 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmattwoodrow
bugs1549751
milestone68.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 1549751 - Part 3: Use nsPaintedDisplayItem in WR and FLB r=mattwoodrow Differential Revision: https://phabricator.services.mozilla.com/D30226
gfx/layers/wr/WebRenderCommandBuilder.cpp
layout/painting/FrameLayerBuilder.cpp
--- a/gfx/layers/wr/WebRenderCommandBuilder.cpp
+++ b/gfx/layers/wr/WebRenderCommandBuilder.cpp
@@ -819,37 +819,40 @@ struct DIGroup {
       }
 
       nsDisplayList* children = item->GetChildren();
       if (children) {
         GP("doing children in EndGroup\n");
         aGrouper->PaintContainerItem(this, item, bounds, children, aContext,
                                      aRecorder);
       } else {
-        // Hit test items don't have anything to paint so skip them. Ideally we
-        // would drop these items earlier...
-        if (dirty &&
+        nsPaintedDisplayItem* paintedItem = item->AsPaintedDisplayItem();
+        if (dirty && paintedItem &&
+            // Hit test items don't have anything to paint so skip them.
+            // Ideally we would drop these items earlier...
             item->GetType() != DisplayItemType::TYPE_COMPOSITOR_HITTEST_INFO) {
           // What should the clip settting strategy be? We can set the full clip
           // everytime. this is probably easiest for now. An alternative would
           // be to put the push and the pop into separate items and let
           // invalidation handle it that way.
-          DisplayItemClip currentClip = item->GetClip();
+          DisplayItemClip currentClip = paintedItem->GetClip();
 
           if (currentClip.HasClip()) {
             aContext->Save();
             currentClip.ApplyTo(aContext, aGrouper->mAppUnitsPerDevPixel);
           }
           aContext->NewPath();
-          GP("painting %s %p-%d\n", item->Name(), item->Frame(),
-             item->GetPerFrameKey());
+          GP("painting %s %p-%d\n", paintedItem->Name(), paintedItem->Frame(),
+             paintedItem->GetPerFrameKey());
           if (aGrouper->mDisplayListBuilder->IsPaintingToWindow()) {
-            item->Frame()->AddStateBits(NS_FRAME_PAINTED_THEBES);
+            paintedItem->Frame()->AddStateBits(NS_FRAME_PAINTED_THEBES);
           }
-          item->Paint(aGrouper->mDisplayListBuilder, aContext);
+
+          paintedItem->Paint(aGrouper->mDisplayListBuilder, aContext);
+
           if (currentClip.HasClip()) {
             aContext->Restore();
           }
         }
         aContext->GetDrawTarget()->FlushItem(bounds);
       }
     }
   }
@@ -966,19 +969,18 @@ void Grouper::PaintContainerItem(DIGroup
                              aRecorder);
       aContext->GetDrawTarget()->PopLayer();
       GP("endGroup %s %p-%d\n", aItem->Name(), aItem->Frame(),
          aItem->GetPerFrameKey());
       aContext->GetDrawTarget()->FlushItem(aItemBounds);
       break;
     }
     case DisplayItemType::TYPE_BLEND_CONTAINER: {
-      aContext->GetDrawTarget()->PushLayer(false, 1.0,
-                                           nullptr, mozilla::gfx::Matrix(),
-                                           aItemBounds);
+      aContext->GetDrawTarget()->PushLayer(false, 1.0, nullptr,
+                                           mozilla::gfx::Matrix(), aItemBounds);
       GP("beginGroup %s %p-%d\n", aItem->Name(), aItem->Frame(),
          aItem->GetPerFrameKey());
       aContext->GetDrawTarget()->FlushItem(aItemBounds);
       aGroup->PaintItemRange(this, aChildren->GetBottom(), nullptr, aContext,
                              aRecorder);
       aContext->GetDrawTarget()->PopLayer();
       GP("endGroup %s %p-%d\n", aItem->Name(), aItem->Frame(),
          aItem->GetPerFrameKey());
@@ -2036,23 +2038,27 @@ static bool PaintItemByDrawTarget(nsDisp
           aItem, aDisplayListBuilder, aManager, context, {1, 1}, [&]() {
             static_cast<nsDisplayFilters*>(aItem)->PaintAsLayer(
                 aDisplayListBuilder, context, aManager);
           });
       break;
     }
 
     default:
+      if (!aItem->AsPaintedDisplayItem()) {
+        break;
+      }
+
       context->SetMatrix(context->CurrentMatrix()
                              .PreScale(aScale.width, aScale.height)
                              .PreTranslate(-aOffset.x, -aOffset.y));
       if (aDisplayListBuilder->IsPaintingToWindow()) {
         aItem->Frame()->AddStateBits(NS_FRAME_PAINTED_THEBES);
       }
-      aItem->Paint(aDisplayListBuilder, context);
+      aItem->AsPaintedDisplayItem()->Paint(aDisplayListBuilder, context);
       isInvalidated = true;
       break;
   }
 
   if (aItem->GetType() != DisplayItemType::TYPE_MASK) {
     // Apply highlight fills, if the appropriate prefs are set.
     // We don't do this for masks because we'd be filling the A8 mask surface,
     // which isn't very useful.
@@ -2233,17 +2239,18 @@ WebRenderCommandBuilder::GenerateFallbac
       if (!fallbackData->mBasicLayerManager) {
         fallbackData->mBasicLayerManager =
             new BasicLayerManager(BasicLayerManager::BLM_INACTIVE);
       }
       bool isInvalidated = PaintItemByDrawTarget(
           aItem, dt, offset, aDisplayListBuilder,
           fallbackData->mBasicLayerManager, scale, highlight);
       if (!isInvalidated) {
-        if (!aItem->GetBuildingRect().IsEqualInterior(fallbackData->mBuildingRect)) {
+        if (!aItem->GetBuildingRect().IsEqualInterior(
+                fallbackData->mBuildingRect)) {
           // The building rect has changed but we didn't see any invalidations.
           // We should still consider this an invalidation.
           isInvalidated = true;
         }
       }
       recorder->FlushItem(IntRect({0, 0}, dtSize.ToUnknownSize()));
       TakeExternalSurfaces(
           recorder, fallbackData->mExternalSurfaces,
--- a/layout/painting/FrameLayerBuilder.cpp
+++ b/layout/painting/FrameLayerBuilder.cpp
@@ -6460,17 +6460,17 @@ gfxSize FrameLayerBuilder::GetPaintedLay
     return ThebesMatrix(transform2d).ScaleFactors(true);
   }
 
   return gfxSize(1.0, 1.0);
 }
 
 #ifdef MOZ_DUMP_PAINTING
 static void DebugPaintItem(DrawTarget& aDrawTarget, nsPresContext* aPresContext,
-                           nsDisplayItem* aItem,
+                           nsPaintedDisplayItem* aItem,
                            nsDisplayListBuilder* aBuilder) {
   bool snap;
   Rect bounds = NSRectToRect(aItem->GetBounds(aBuilder, &snap),
                              aPresContext->AppUnitsPerDevPixel());
 
   const IntSize size = IntSize::Truncate(bounds.width, bounds.height);
   if (size.IsEmpty()) {
     return;
@@ -6985,58 +6985,68 @@ void FrameLayerBuilder::PaintItems(std::
     if (cdi.mType != DisplayItemEntryType::Item) {
 #ifdef DEBUG
       UpdateEffectTracking(opacityLevel, transformLevel, cdi.mType);
 #endif
       // Nothing more to do with effect markers.
       continue;
     }
 
+    const bool paintAsLayer = cdi.mInactiveLayerManager;
+    nsPaintedDisplayItem* paintedItem = item->AsPaintedDisplayItem();
+    MOZ_ASSERT(paintAsLayer || paintedItem,
+               "The display item does not support painting");
+
     const DisplayItemClip* itemClip = GetItemClip(item, temporaryClip);
     bool itemPaintsOwnClip = false;
 
     if (itemClip && !itemClipTracker.HasClip(itemClip)) {
       // The clip has changed. Remove the previous clip.
       itemClipTracker.Restore();
 
       // Check if the item supports painting with clip.
-      itemPaintsOwnClip = item->CanPaintWithClip(*itemClip);
+      itemPaintsOwnClip =
+          paintAsLayer ? false : paintedItem->CanPaintWithClip(*itemClip);
 
       if (!itemPaintsOwnClip) {
         // Item does not support painting with clip, set the clip.
         itemClipTracker.ChangeClipIfNeeded(itemClip);
       }
     }
 
     if (!itemClip) {
       // Item does not need clipping, remove the clip if there is one.
       itemClipTracker.Restore();
     }
 
-    if (cdi.mInactiveLayerManager) {
+    if (paintAsLayer) {
       bool saved = aDrawTarget.GetPermitSubpixelAA();
       PaintInactiveLayer(aBuilder, cdi.mInactiveLayerManager, item, aContext,
                          aContext);
       aDrawTarget.SetPermitSubpixelAA(saved);
-    } else {
-      nsIFrame* frame = item->Frame();
-      if (aBuilder->IsPaintingToWindow()) {
-        frame->AddStateBits(NS_FRAME_PAINTED_THEBES);
-      }
+      continue;
+    }
+
+    nsIFrame* frame = item->Frame();
+    if (aBuilder->IsPaintingToWindow()) {
+      frame->AddStateBits(NS_FRAME_PAINTED_THEBES);
+    }
+
 #ifdef MOZ_DUMP_PAINTING
-      if (gfxEnv::DumpPaintItems()) {
-        DebugPaintItem(aDrawTarget, aPresContext, item, aBuilder);
-      } else
+    if (gfxEnv::DumpPaintItems()) {
+      DebugPaintItem(aDrawTarget, aPresContext, paintedItem, aBuilder);
+      continue;
+    }
 #endif
-          if (itemPaintsOwnClip) {
-        MOZ_ASSERT(itemClip);
-        item->PaintWithClip(aBuilder, aContext, *itemClip);
-      } else {
-        item->Paint(aBuilder, aContext);
-      }
+
+    if (itemPaintsOwnClip) {
+      MOZ_ASSERT(itemClip);
+      paintedItem->PaintWithClip(aBuilder, aContext, *itemClip);
+    } else {
+      paintedItem->Paint(aBuilder, aContext);
     }
   }
 
   itemClipTracker.Restore();
 
   MOZ_ASSERT(opacityLevel == 0);
   MOZ_ASSERT(transformLevel == 0);
   MOZ_ASSERT(emptyEffectLevel == 0);