Bug 1686654 - Ensure SwitchItem is called at the start of each blob group. r=jrmuizel
authorNicolas Silva <nsilva@mozilla.com>
Wed, 23 Feb 2022 13:43:38 +0000
changeset 608501 2233117f11933cd23145f0bd4cf995df5faf32b0
parent 608500 f069118981556cfad69be5f1bb8f5632581e2082
child 608502 9ea981dec8e0f339eb1c0204da47ad066f442a38
push id158351
push usernsilva@mozilla.com
push dateWed, 23 Feb 2022 13:46:00 +0000
treeherderautoland@2233117f1193 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjrmuizel
bugs1686654
milestone99.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 1686654 - Ensure SwitchItem is called at the start of each blob group. r=jrmuizel It was previously only called where we create a stacking context helper: before entering the grouping code and before pushing an active item into the wr display list, and not between the active items and the next blob group. This caused the leaf clip rect of the active item to leak into the next blob group. Differential Revision: https://phabricator.services.mozilla.com/D136906
gfx/layers/wr/WebRenderCommandBuilder.cpp
--- a/gfx/layers/wr/WebRenderCommandBuilder.cpp
+++ b/gfx/layers/wr/WebRenderCommandBuilder.cpp
@@ -211,17 +211,18 @@ struct Grouper {
                           RenderRootStateManager* aRootManager,
                           wr::IpcResourceUpdateQueue& aResources);
 
   // Builds groups of display items split based on 'layer activity'
   void ConstructGroups(nsDisplayListBuilder* aDisplayListBuilder,
                        WebRenderCommandBuilder* aCommandBuilder,
                        wr::DisplayListBuilder& aBuilder,
                        wr::IpcResourceUpdateQueue& aResources, DIGroup* aGroup,
-                       nsDisplayList* aList, const StackingContextHelper& aSc);
+                       nsDisplayList* aList, nsDisplayItem* aWrappingItem,
+                       const StackingContextHelper& aSc);
   // Builds a group of display items without promoting anything to active.
   bool ConstructGroupInsideInactive(WebRenderCommandBuilder* aCommandBuilder,
                                     wr::DisplayListBuilder& aBuilder,
                                     wr::IpcResourceUpdateQueue& aResources,
                                     DIGroup* aGroup, nsDisplayList* aList,
                                     const StackingContextHelper& aSc);
   // Helper method for processing a single inactive item
   bool ConstructItemInsideInactive(WebRenderCommandBuilder* aCommandBuilder,
@@ -1179,32 +1180,37 @@ static bool IsItemProbablyActive(
 
 // This does a pass over the display lists and will join the display items
 // into groups as well as paint them
 void Grouper::ConstructGroups(nsDisplayListBuilder* aDisplayListBuilder,
                               WebRenderCommandBuilder* aCommandBuilder,
                               wr::DisplayListBuilder& aBuilder,
                               wr::IpcResourceUpdateQueue& aResources,
                               DIGroup* aGroup, nsDisplayList* aList,
+                              nsDisplayItem* aWrappingItem,
                               const StackingContextHelper& aSc) {
   RenderRootStateManager* manager =
       aCommandBuilder->mManager->GetRenderRootStateManager();
 
   nsDisplayList::iterator startOfCurrentGroup = aList->end();
   DIGroup* currentGroup = aGroup;
 
   // We need to track whether we have active siblings for mixed blend mode.
   bool encounteredActiveItem = false;
+  bool isFirstGroup = true;
 
   for (auto it = aList->begin(); it != aList->end(); ++it) {
     nsDisplayItem* item = *it;
     MOZ_ASSERT(item);
 
     if (startOfCurrentGroup == aList->end()) {
       startOfCurrentGroup = it;
+      if (!isFirstGroup) {
+        mClipManager.SwitchItem(aDisplayListBuilder, aWrappingItem);
+      }
     }
 
     if (IsItemProbablyActive(item, aBuilder, aResources, aSc, manager,
                              mDisplayListBuilder, encounteredActiveItem)) {
       encounteredActiveItem = true;
       // We're going to be starting a new group.
       RefPtr<WebRenderGroupData> groupData =
           aCommandBuilder->CreateOrRecycleWebRenderUserData<WebRenderGroupData>(
@@ -1270,16 +1276,17 @@ void Grouper::ConstructGroups(nsDisplayL
             aBuilder, aResources, aSc, manager, mDisplayListBuilder);
         MOZ_RELEASE_ASSERT(
             createdWRCommands,
             "active transforms should always succeed at creating "
             "WebRender commands");
         sIndent--;
       }
 
+	  isFirstGroup = false;
       startOfCurrentGroup = aList->end();
       currentGroup = &groupData->mFollowingGroup;
     } else {  // inactive item
       ConstructItemInsideInactive(aCommandBuilder, aBuilder, aResources,
                                   currentGroup, item, aSc);
     }
   }
 
@@ -1536,17 +1543,17 @@ void WebRenderCommandBuilder::DoGrouping
   group.mAppUnitsPerDevPixel = appUnitsPerDevPixel;
   group.mClippedImageBounds = layerBounds;
 
   g.mTransform = Matrix::Scaling(scale.width, scale.height)
                      .PostTranslate(residualOffset.x, residualOffset.y);
   group.mScale = scale;
   group.mScrollId = scrollId;
   g.ConstructGroups(aDisplayListBuilder, this, aBuilder, aResources, &group,
-                    aList, aSc);
+                    aList, aWrappingItem, aSc);
   mClipManager.EndList(aSc);
 }
 
 WebRenderCommandBuilder::WebRenderCommandBuilder(
     WebRenderLayerManager* aManager)
     : mManager(aManager),
       mLastAsr(nullptr),
       mBuilderDumpIndex(0),