Bug 1419917 - Add nsDisplayTableThemedBackground. r=mattwoodrow
authorMorris Tseng <mtseng@mozilla.com>
Fri, 24 Nov 2017 16:19:56 +0800
changeset 394084 2ea21d0761dd5f5a34d6623fece44472381c89e8
parent 394083 88b37f04fdd6887efb4a59c4afae34ebae8fd642
child 394085 b84de8dee9f6a65a263f79b7af6a318cc78afe32
push id56208
push usermtseng@mozilla.com
push dateWed, 29 Nov 2017 07:43:02 +0000
treeherderautoland@2ea21d0761dd [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmattwoodrow
bugs1419917
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 1419917 - Add nsDisplayTableThemedBackground. r=mattwoodrow MozReview-Commit-ID: D86CXjyro4
layout/painting/nsDisplayList.cpp
layout/painting/nsDisplayList.h
--- a/layout/painting/nsDisplayList.cpp
+++ b/layout/painting/nsDisplayList.cpp
@@ -3588,19 +3588,30 @@ nsDisplayBackgroundImage::AppendBackgrou
 
   if (isThemed) {
     nsITheme* theme = presContext->GetTheme();
     if (theme->NeedToClearBackgroundBehindWidget(aFrame, aFrame->StyleDisplay()->mAppearance) &&
         aBuilder->IsInChromeDocumentOrPopup() && !aBuilder->IsInTransform()) {
       bgItemList.AppendNewToTop(
         new (aBuilder) nsDisplayClearBackground(aBuilder, aFrame));
     }
-    nsDisplayThemedBackground* bgItem =
-      new (aBuilder) nsDisplayThemedBackground(aBuilder, aFrame, bgRect);
-    bgItemList.AppendNewToTop(bgItem);
+    if (aSecondaryReferenceFrame) {
+      nsDisplayTableThemedBackground* bgItem =
+        new (aBuilder) nsDisplayTableThemedBackground(aBuilder,
+                                                      aSecondaryReferenceFrame,
+                                                      bgRect,
+                                                      aFrame);
+      bgItem->Init(aBuilder);
+      bgItemList.AppendNewToTop(bgItem);
+    } else {
+      nsDisplayThemedBackground* bgItem =
+        new (aBuilder) nsDisplayThemedBackground(aBuilder, aFrame, bgRect);
+      bgItem->Init(aBuilder);
+      bgItemList.AppendNewToTop(bgItem);
+    }
     aList->AppendToTop(&bgItemList);
     return true;
   }
 
   if (!bg) {
     aList->AppendToTop(&bgItemList);
     return false;
   }
@@ -4229,44 +4240,48 @@ nsDisplayTableBackgroundImage::IsInvalid
 
 nsDisplayThemedBackground::nsDisplayThemedBackground(nsDisplayListBuilder* aBuilder,
                                                      nsIFrame* aFrame,
                                                      const nsRect& aBackgroundRect)
   : nsDisplayItem(aBuilder, aFrame)
   , mBackgroundRect(aBackgroundRect)
 {
   MOZ_COUNT_CTOR(nsDisplayThemedBackground);
-
-  const nsStyleDisplay* disp = mFrame->StyleDisplay();
+}
+
+nsDisplayThemedBackground::~nsDisplayThemedBackground()
+{
+#ifdef NS_BUILD_REFCNT_LOGGING
+  MOZ_COUNT_DTOR(nsDisplayThemedBackground);
+#endif
+}
+
+void
+nsDisplayThemedBackground::Init(nsDisplayListBuilder* aBuilder)
+{
+  const nsStyleDisplay* disp = StyleFrame()->StyleDisplay();
   mAppearance = disp->mAppearance;
-  mFrame->IsThemed(disp, &mThemeTransparency);
+  StyleFrame()->IsThemed(disp, &mThemeTransparency);
 
   // Perform necessary RegisterThemeGeometry
-  nsITheme* theme = mFrame->PresContext()->GetTheme();
+  nsITheme* theme = StyleFrame()->PresContext()->GetTheme();
   nsITheme::ThemeGeometryType type =
-    theme->ThemeGeometryTypeForWidget(mFrame, disp->mAppearance);
+    theme->ThemeGeometryTypeForWidget(StyleFrame(), disp->mAppearance);
   if (type != nsITheme::eThemeGeometryTypeUnknown) {
-    RegisterThemeGeometry(aBuilder, this, aFrame, type);
+    RegisterThemeGeometry(aBuilder, this, StyleFrame(), type);
   }
 
   if (disp->mAppearance == NS_THEME_WIN_BORDERLESS_GLASS ||
       disp->mAppearance == NS_THEME_WIN_GLASS) {
     aBuilder->SetGlassDisplayItem(this);
   }
 
   mBounds = GetBoundsInternal();
 }
 
-nsDisplayThemedBackground::~nsDisplayThemedBackground()
-{
-#ifdef NS_BUILD_REFCNT_LOGGING
-  MOZ_COUNT_DTOR(nsDisplayThemedBackground);
-#endif
-}
-
 void
 nsDisplayThemedBackground::WriteDebugInfo(std::stringstream& aStream)
 {
   aStream << " (themed, appearance:" << (int)mAppearance << ")";
 }
 
 void
 nsDisplayThemedBackground::HitTest(nsDisplayListBuilder* aBuilder,
@@ -4318,36 +4333,36 @@ nsDisplayThemedBackground::Paint(nsDispl
 
 
 void
 nsDisplayThemedBackground::PaintInternal(nsDisplayListBuilder* aBuilder,
                                          gfxContext* aCtx, const nsRect& aBounds,
                                          nsRect* aClipRect)
 {
   // XXXzw this ignores aClipRect.
-  nsPresContext* presContext = mFrame->PresContext();
+  nsPresContext* presContext = StyleFrame()->PresContext();
   nsITheme *theme = presContext->GetTheme();
   nsRect drawing(mBackgroundRect);
-  theme->GetWidgetOverflow(presContext->DeviceContext(), mFrame, mAppearance,
+  theme->GetWidgetOverflow(presContext->DeviceContext(), StyleFrame(), mAppearance,
                            &drawing);
   drawing.IntersectRect(drawing, aBounds);
-  theme->DrawWidgetBackground(aCtx, mFrame, mAppearance, mBackgroundRect, drawing);
+  theme->DrawWidgetBackground(aCtx, StyleFrame(), mAppearance, mBackgroundRect, drawing);
 }
 
 
 bool
 nsDisplayThemedBackground::CreateWebRenderCommands(mozilla::wr::DisplayListBuilder& aBuilder,
                                                    mozilla::wr::IpcResourceUpdateQueue& aResources,
                                                    const StackingContextHelper& aSc,
                                                    mozilla::layers::WebRenderLayerManager* aManager,
                                                    nsDisplayListBuilder* aDisplayListBuilder)
 {
-  nsITheme *theme = mFrame->PresContext()->GetTheme();
+  nsITheme *theme = StyleFrame()->PresContext()->GetTheme();
   return theme->CreateWebRenderCommandsForWidget(aBuilder, aResources, aSc, aManager,
-                                                 mFrame, mAppearance, mBackgroundRect);
+                                                 StyleFrame(), mAppearance, mBackgroundRect);
 }
 
 bool
 nsDisplayThemedBackground::IsWindowActive() const
 {
   EventStates docState = mFrame->GetContent()->OwnerDoc()->GetDocumentState();
   return !docState.HasState(NS_DOCUMENT_STATE_WINDOW_INACTIVE);
 }
@@ -4367,17 +4382,17 @@ nsDisplayThemedBackground::ComputeInvali
     aInvalidRegion->Or(bounds, geometry->mBounds);
     return;
   }
   if (!bounds.IsEqualInterior(geometry->mBounds)) {
     // Positioning area is unchanged, so invalidate just the change in the
     // painting area.
     aInvalidRegion->Xor(bounds, geometry->mBounds);
   }
-  nsITheme* theme = mFrame->PresContext()->GetTheme();
+  nsITheme* theme = StyleFrame()->PresContext()->GetTheme();
   if (theme->WidgetAppearanceDependsOnWindowFocus(mAppearance) &&
       IsWindowActive() != geometry->mWindowIsActive) {
     aInvalidRegion->Or(*aInvalidRegion, bounds);
   }
 }
 
 nsRect
 nsDisplayThemedBackground::GetBounds(nsDisplayListBuilder* aBuilder,
--- a/layout/painting/nsDisplayList.h
+++ b/layout/painting/nsDisplayList.h
@@ -3877,16 +3877,17 @@ protected:
 /**
  * A display item to paint the native theme background for a frame.
  */
 class nsDisplayThemedBackground : public nsDisplayItem {
 public:
   nsDisplayThemedBackground(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
                             const nsRect& aBackgroundRect);
   virtual ~nsDisplayThemedBackground();
+  void Init(nsDisplayListBuilder* aBuilder);
 
   void Destroy(nsDisplayListBuilder* aBuilder) override
   {
     aBuilder->UnregisterThemeGeometry(this);
     nsDisplayItem::Destroy(aBuilder);
   }
 
   virtual void HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect,
@@ -3939,16 +3940,40 @@ protected:
                      const nsRect& aBounds, nsRect* aClipRect);
 
   nsRect mBackgroundRect;
   nsRect mBounds;
   nsITheme::Transparency mThemeTransparency;
   uint8_t mAppearance;
 };
 
+class nsDisplayTableThemedBackground : public nsDisplayThemedBackground {
+public:
+  nsDisplayTableThemedBackground(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
+                                 const nsRect& aBackgroundRect,
+                                 nsIFrame* aAncestorFrame)
+    : nsDisplayThemedBackground(aBuilder, aFrame, aBackgroundRect)
+    , mAncestorFrame(aAncestorFrame)
+    , mTableType(GetTableTypeFromFrame(aAncestorFrame))
+  { }
+
+  virtual uint32_t GetPerFrameKey() const override {
+    return (static_cast<uint8_t>(mTableType) << TYPE_BITS) |
+           nsDisplayItem::GetPerFrameKey();
+  }
+
+  virtual nsIFrame* FrameForInvalidation() const override { return mAncestorFrame; }
+
+  NS_DISPLAY_DECL_NAME("TableThemedBackground", TYPE_TABLE_BACKGROUND_IMAGE)
+protected:
+  virtual nsIFrame* StyleFrame() const override { return mAncestorFrame; }
+  nsIFrame* mAncestorFrame;
+  TableType mTableType;
+};
+
 class nsDisplayBackgroundColor : public nsDisplayItem
 {
   typedef mozilla::gfx::Color Color;
 
 public:
   nsDisplayBackgroundColor(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
                            const nsRect& aBackgroundRect,
                            const nsStyleBackground* aBackgroundStyle,