Bug 1410906 - Store ThemeGeometry for display item instead of frame r=mattwoodrow
authorMiko Mynttinen <mikokm@gmail.com>
Mon, 23 Oct 2017 18:07:36 +0200
changeset 387814 aa02fa00af6f2d7495a6c9193ce812ce622b0393
parent 387813 09f25b91132eb1f2391f2dabe1569cbd31a7c655
child 387815 d29dc7075531df37a0901ec07b80f83cfae507c1
push id96497
push userarchaeopteryx@coole-files.de
push dateTue, 24 Oct 2017 09:57:53 +0000
treeherdermozilla-inbound@7de3cc48b5b1 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmattwoodrow
bugs1410906
milestone58.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 1410906 - Store ThemeGeometry for display item instead of frame r=mattwoodrow MozReview-Commit-ID: 6x7GRRTEVja
layout/painting/nsDisplayList.cpp
layout/painting/nsDisplayList.h
layout/xul/tree/nsTreeBodyFrame.cpp
--- a/layout/painting/nsDisplayList.cpp
+++ b/layout/painting/nsDisplayList.cpp
@@ -3215,25 +3215,25 @@ nsDisplaySolidColorRegion::CreateWebRend
                       !BackfaceIsHidden(),
                       wr::ToColorF(ToDeviceColor(mColor)));
   }
 
   return true;
 }
 
 static void
-RegisterThemeGeometry(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
-                      nsITheme::ThemeGeometryType aType)
+RegisterThemeGeometry(nsDisplayListBuilder* aBuilder, nsDisplayItem* aItem,
+                      nsIFrame* aFrame, nsITheme::ThemeGeometryType aType)
 {
   if (aBuilder->IsInChromeDocumentOrPopup() && !aBuilder->IsInTransform()) {
     nsIFrame* displayRoot = nsLayoutUtils::GetDisplayRootFrame(aFrame);
     nsPoint offset = aBuilder->IsInSubdocument() ? aBuilder->ToReferenceFrame(aFrame)
                                                  : aFrame->GetOffsetTo(displayRoot);
     nsRect borderBox = nsRect(offset, aFrame->GetSize());
-    aBuilder->RegisterThemeGeometry(aType, aFrame,
+    aBuilder->RegisterThemeGeometry(aType, aItem,
       LayoutDeviceIntRect::FromUnknownRect(
         borderBox.ToNearestPixels(
           aFrame->PresContext()->AppUnitsPerDevPixel())));
   }
 }
 
 // Return the bounds of the viewport relative to |aFrame|'s reference frame.
 // Returns Nothing() if transforming into |aFrame|'s coordinate space fails.
@@ -4179,17 +4179,17 @@ nsDisplayThemedBackground::nsDisplayThem
   mAppearance = disp->mAppearance;
   mFrame->IsThemed(disp, &mThemeTransparency);
 
   // Perform necessary RegisterThemeGeometry
   nsITheme* theme = mFrame->PresContext()->GetTheme();
   nsITheme::ThemeGeometryType type =
     theme->ThemeGeometryTypeForWidget(mFrame, disp->mAppearance);
   if (type != nsITheme::eThemeGeometryTypeUnknown) {
-    RegisterThemeGeometry(aBuilder, aFrame, type);
+    RegisterThemeGeometry(aBuilder, this, aFrame, type);
   }
 
   if (disp->mAppearance == NS_THEME_WIN_BORDERLESS_GLASS ||
       disp->mAppearance == NS_THEME_WIN_GLASS) {
     aBuilder->SetGlassDisplayItem(this);
   }
 
   mBounds = GetBoundsInternal();
--- a/layout/painting/nsDisplayList.h
+++ b/layout/painting/nsDisplayList.h
@@ -869,35 +869,37 @@ public:
    * at the given rectangle within the currently built display list.
    * For certain appearance values (currently only NS_THEME_TOOLBAR and
    * NS_THEME_WINDOW_TITLEBAR) this gets called during every display list
    * construction, for every themed widget of the right type within the
    * display list, except for themed widgets which are transformed or have
    * effects applied to them (e.g. CSS opacity or filters).
    *
    * @param aWidgetType the -moz-appearance value for the themed widget
+   * @param aItem the item associated with the theme geometry
    * @param aRect the device-pixel rect relative to the widget's displayRoot
    * for the themed widget
    */
-  void RegisterThemeGeometry(uint8_t aWidgetType, nsIFrame* aFrame,
-                             const mozilla::LayoutDeviceIntRect& aRect) {
-    if (mIsPaintingToWindow) {
-      nsTArray<ThemeGeometry>* geometries =
-        mThemeGeometries.LookupOrAdd(aFrame);
-
-      geometries->AppendElement(ThemeGeometry(aWidgetType, aRect));
+  void RegisterThemeGeometry(uint8_t aWidgetType, nsDisplayItem* aItem,
+                             const mozilla::LayoutDeviceIntRect& aRect)
+  {
+    if (!mIsPaintingToWindow) {
+      return;
     }
-  }
-
-  /**
-   * Removes theme geometries associated with the given frame.
-   */
-  void UnregisterThemeGeometry(nsIFrame* aFrame)
-  {
-    mThemeGeometries.Remove(aFrame);
+
+    nsTArray<ThemeGeometry>* geometries = mThemeGeometries.LookupOrAdd(aItem);
+    geometries->AppendElement(ThemeGeometry(aWidgetType, aRect));
+  }
+
+  /**
+   * Removes theme geometries associated with the given display item |aItem|.
+   */
+  void UnregisterThemeGeometry(nsDisplayItem* aItem)
+  {
+    mThemeGeometries.Remove(aItem);
   }
 
   /**
    * Adjusts mWindowDraggingRegion to take into account aFrame. If aFrame's
    * -moz-window-dragging value is |drag|, its border box is added to the
    * collected dragging region; if the value is |no-drag|, the border box is
    * subtracted from the region; if the value is |default|, that frame does
    * not influence the window dragging region.
@@ -1698,17 +1700,17 @@ private:
   nsIFrame*                      mIgnoreScrollFrame;
   nsDisplayLayerEventRegions*    mLayerEventRegions;
 
   nsPresArena mPool;
 
   nsCOMPtr<nsISelection>         mBoundingSelection;
   AutoTArray<PresShellState,8> mPresShellStates;
   AutoTArray<nsIFrame*,400>    mFramesMarkedForDisplay;
-  nsClassHashtable<nsPtrHashKey<nsIFrame>, nsTArray<ThemeGeometry>> mThemeGeometries;
+  nsClassHashtable<nsPtrHashKey<nsDisplayItem>, nsTArray<ThemeGeometry>> mThemeGeometries;
   nsDisplayTableItem*            mCurrentTableItem;
   DisplayListClipState           mClipState;
   const ActiveScrolledRoot*      mCurrentActiveScrolledRoot;
   const ActiveScrolledRoot*      mCurrentContainerASR;
   // mCurrentFrame is the frame that we're currently calling (or about to call)
   // BuildDisplayList on.
   const nsIFrame*                mCurrentFrame;
   // The reference frame for mCurrentFrame.
@@ -3853,17 +3855,17 @@ protected:
 class nsDisplayThemedBackground : public nsDisplayItem {
 public:
   nsDisplayThemedBackground(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
                             const nsRect& aBackgroundRect);
   virtual ~nsDisplayThemedBackground();
 
   void Destroy(nsDisplayListBuilder* aBuilder) override
   {
-    aBuilder->UnregisterThemeGeometry(mFrame);
+    aBuilder->UnregisterThemeGeometry(this);
     nsDisplayItem::Destroy(aBuilder);
   }
 
   virtual void HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect,
                        HitTestState* aState, nsTArray<nsIFrame*> *aOutFrames) override;
   virtual nsRegion GetOpaqueRegion(nsDisplayListBuilder* aBuilder,
                                    bool* aSnap) const override;
   virtual mozilla::Maybe<nscolor> IsUniform(nsDisplayListBuilder* aBuilder) const override;
--- a/layout/xul/tree/nsTreeBodyFrame.cpp
+++ b/layout/xul/tree/nsTreeBodyFrame.cpp
@@ -2785,17 +2785,17 @@ public:
 
   nsDisplayItemGeometry* AllocateGeometry(nsDisplayListBuilder* aBuilder) override
   {
     return new nsDisplayItemGenericImageGeometry(this, aBuilder);
   }
 
   void Destroy(nsDisplayListBuilder* aBuilder) override
   {
-    aBuilder->UnregisterThemeGeometry(mFrame);
+    aBuilder->UnregisterThemeGeometry(this);
     nsDisplayItem::Destroy(aBuilder);
   }
 
   void ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder,
                                  const nsDisplayItemGeometry* aGeometry,
                                  nsRegion *aInvalidRegion) const override
   {
     auto geometry =
@@ -2844,16 +2844,19 @@ nsTreeBodyFrame::BuildDisplayList(nsDisp
   // Handles painting our background, border, and outline.
   nsLeafBoxFrame::BuildDisplayList(aBuilder, aLists);
 
   // Bail out now if there's no view or we can't run script because the
   // document is a zombie
   if (!mView || !GetContent ()->GetComposedDoc()->GetWindow())
     return;
 
+  nsDisplayItem* item = new (aBuilder) nsDisplayTreeBody(aBuilder, this);
+  aLists.Content()->AppendToTop(item);
+
 #ifdef XP_MACOSX
   nsIContent* baseElement = GetBaseElement();
   nsIFrame* treeFrame =
     baseElement ? baseElement->GetPrimaryFrame() : nullptr;
   nsCOMPtr<nsITreeSelection> selection;
   mView->GetSelection(getter_AddRefs(selection));
   nsITheme* theme = PresContext()->GetTheme();
   // On Mac, we support native theming of selected rows. On 10.10 and higher,
@@ -2879,30 +2882,27 @@ nsTreeBodyFrame::BuildDisplayList(nsDisp
         if (appearance) {
           if (theme->ThemeSupportsWidget(PresContext(), this, appearance)) {
             nsITheme::ThemeGeometryType type =
               theme->ThemeGeometryTypeForWidget(this, appearance);
             if (type != nsITheme::eThemeGeometryTypeUnknown) {
               nsRect rowRect(mInnerBox.x, mInnerBox.y + mRowHeight *
                              (i - FirstVisibleRow()), mInnerBox.width,
                              mRowHeight);
-              aBuilder->RegisterThemeGeometry(type, this,
+              aBuilder->RegisterThemeGeometry(type, item,
                 LayoutDeviceIntRect::FromUnknownRect(
                   (rowRect + aBuilder->ToReferenceFrame(this)).ToNearestPixels(
                     PresContext()->AppUnitsPerDevPixel())));
             }
           }
         }
       }
     }
   }
 #endif
-
-  aLists.Content()->AppendNewToTop(new (aBuilder)
-    nsDisplayTreeBody(aBuilder, this));
 }
 
 DrawResult
 nsTreeBodyFrame::PaintTreeBody(gfxContext& aRenderingContext,
                                const nsRect& aDirtyRect, nsPoint aPt,
                                nsDisplayListBuilder* aBuilder)
 {
   // Update our available height and our page count.