Bug 787089. Rip out mUpdatePluginGeometryForFrame optimization. It's not known to be a significant win, and creates problems when prescontext ancestor chains are broken; the complexity probably isn't worthwhile. Also, soon (or now) we can rework plugin bounds computation to be use the display list built for rendering. r=matspal
authorRobert O'Callahan <robert@ocallahan.org>
Wed, 05 Sep 2012 22:30:10 +1200
changeset 104262 df1a1a1cfaf49840942f554500873c4befe6d071
parent 104261 0b354d6a9c9085f2daef62c0633c6d3826bd8b9b
child 104263 4168b071661e636e1dffb2966457024237ece96a
push id14430
push userrocallahan@mozilla.com
push dateWed, 05 Sep 2012 10:34:16 +0000
treeherdermozilla-inbound@df1a1a1cfaf4 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmatspal
bugs787089
milestone18.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 787089. Rip out mUpdatePluginGeometryForFrame optimization. It's not known to be a significant win, and creates problems when prescontext ancestor chains are broken; the complexity probably isn't worthwhile. Also, soon (or now) we can rework plugin bounds computation to be use the display list built for rendering. r=matspal
layout/base/nsCSSFrameConstructor.cpp
layout/base/nsPresContext.cpp
layout/base/nsPresContext.h
layout/base/nsPresShell.cpp
layout/generic/nsGfxScrollFrame.cpp
layout/generic/nsObjectFrame.cpp
layout/generic/nsSubDocumentFrame.cpp
--- a/layout/base/nsCSSFrameConstructor.cpp
+++ b/layout/base/nsCSSFrameConstructor.cpp
@@ -8173,20 +8173,19 @@ nsCSSFrameConstructor::ProcessRestyledFr
   }
 
   EndUpdate();
 
   if (didInvalidate && !didReflow) {
     // RepaintFrame changes can indicate changes in opacity etc which
     // can require plugin clipping to change. If we requested a reflow,
     // we don't need to do this since the reflow will do it for us.
-    nsIFrame* rootFrame = GetRootFrame();
     nsRootPresContext* rootPC = presContext->GetRootPresContext();
     if (rootPC) {
-      rootPC->RequestUpdatePluginGeometry(rootFrame);
+      rootPC->RequestUpdatePluginGeometry();
     }
   }
 
   // cleanup references and verify the style tree.  Note that the latter needs
   // to happen once we've processed the whole list, since until then the tree
   // is not in fact in a consistent state.
   index = count;
   while (0 <= --index) {
--- a/layout/base/nsPresContext.cpp
+++ b/layout/base/nsPresContext.cpp
@@ -2338,17 +2338,16 @@ nsPresContext::IsRootContentDocument()
 
   nsIFrame* f = view->GetFrame();
   return (f && f->PresContext()->IsChrome());
 }
 
 nsRootPresContext::nsRootPresContext(nsIDocument* aDocument,
                                      nsPresContextType aType)
   : nsPresContext(aDocument, aType),
-    mUpdatePluginGeometryForFrame(nullptr),
     mDOMGeneration(0),
     mNeedsToUpdatePluginGeometry(false)
 {
   mRegisteredPlugins.Init();
 }
 
 nsRootPresContext::~nsRootPresContext()
 {
@@ -2599,44 +2598,36 @@ nsRootPresContext::UpdatePluginGeometry(
 {
   if (!mNeedsToUpdatePluginGeometry)
     return;
   mNeedsToUpdatePluginGeometry = false;
   // Cancel out mUpdatePluginGeometryTimer so it doesn't do a random
   // update when we don't actually want one.
   CancelUpdatePluginGeometryTimer();
 
-  nsIFrame* f = mUpdatePluginGeometryForFrame;
-  if (f) {
-    mUpdatePluginGeometryForFrame->PresContext()->
-      SetContainsUpdatePluginGeometryFrame(false);
-    mUpdatePluginGeometryForFrame = nullptr;
-  } else {
-    f = FrameManager()->GetRootFrame();
-  }
-
+  nsIFrame* f = FrameManager()->GetRootFrame();
   nsTArray<nsIWidget::Configuration> configurations;
   GetPluginGeometryUpdates(f, &configurations);
   if (configurations.IsEmpty())
     return;
   SortConfigurations(&configurations);
-  nsIWidget* widget = FrameManager()->GetRootFrame()->GetNearestWidget();
+  nsIWidget* widget = f->GetNearestWidget();
   NS_ASSERTION(widget, "Plugins must have a parent window");
   widget->ConfigureChildren(configurations);
   DidApplyPluginGeometryUpdates();
 }
 
 static void
 UpdatePluginGeometryCallback(nsITimer *aTimer, void *aClosure)
 {
   static_cast<nsRootPresContext*>(aClosure)->UpdatePluginGeometry();
 }
 
 void
-nsRootPresContext::RequestUpdatePluginGeometry(nsIFrame* aFrame)
+nsRootPresContext::RequestUpdatePluginGeometry()
 {
   if (mRegisteredPlugins.Count() == 0)
     return;
 
   if (!mNeedsToUpdatePluginGeometry) {
     // We'll update the plugin geometry during the next paint in this
     // presContext (either from nsPresShell::WillPaint or from
     // nsPresShell::DidPaint, depending on the platform) or on the next
@@ -2649,26 +2640,16 @@ nsRootPresContext::RequestUpdatePluginGe
     mUpdatePluginGeometryTimer = do_CreateInstance("@mozilla.org/timer;1");
     if (mUpdatePluginGeometryTimer) {
       mUpdatePluginGeometryTimer->
         InitWithFuncCallback(UpdatePluginGeometryCallback, this,
                              nsRefreshDriver::DefaultInterval() * 2,
                              nsITimer::TYPE_ONE_SHOT);
     }
     mNeedsToUpdatePluginGeometry = true;
-    mUpdatePluginGeometryForFrame = aFrame;
-    mUpdatePluginGeometryForFrame->PresContext()->
-      SetContainsUpdatePluginGeometryFrame(true);
-  } else {
-    if (!mUpdatePluginGeometryForFrame ||
-        aFrame == mUpdatePluginGeometryForFrame)
-      return;
-    mUpdatePluginGeometryForFrame->PresContext()->
-      SetContainsUpdatePluginGeometryFrame(false);
-    mUpdatePluginGeometryForFrame = nullptr;
   }
 }
 
 static PLDHashOperator
 PluginDidSetGeometryEnumerator(nsRefPtrHashKey<nsIContent>* aEntry, void* userArg)
 {
   nsObjectFrame* f = static_cast<nsObjectFrame*>(aEntry->GetKey()->GetPrimaryFrame());
   if (!f) {
@@ -2680,36 +2661,16 @@ PluginDidSetGeometryEnumerator(nsRefPtrH
 }
 
 void
 nsRootPresContext::DidApplyPluginGeometryUpdates()
 {
   mRegisteredPlugins.EnumerateEntries(PluginDidSetGeometryEnumerator, nullptr);
 }
 
-void
-nsRootPresContext::RootForgetUpdatePluginGeometryFrame(nsIFrame* aFrame)
-{
-  if (aFrame == mUpdatePluginGeometryForFrame) {
-    mUpdatePluginGeometryForFrame->PresContext()->
-      SetContainsUpdatePluginGeometryFrame(false);
-    mUpdatePluginGeometryForFrame = nullptr;
-  }
-}
-
-void
-nsRootPresContext::RootForgetUpdatePluginGeometryFrameForPresContext(
-  nsPresContext* aPresContext)
-{
-  if (aPresContext->GetContainsUpdatePluginGeometryFrame()) {
-    aPresContext->SetContainsUpdatePluginGeometryFrame(false);
-    mUpdatePluginGeometryForFrame = nullptr;
-  }
-}
-
 static void
 NotifyDidPaintForSubtreeCallback(nsITimer *aTimer, void *aClosure)
 {
   nsPresContext* presContext = (nsPresContext*)aClosure;
   nsAutoScriptBlocker blockScripts;
   presContext->NotifyDidPaintForSubtree();
 }
 
@@ -2755,13 +2716,9 @@ nsRootPresContext::SizeOfExcludingThis(n
   return nsPresContext::SizeOfExcludingThis(aMallocSizeOf);
 
   // Measurement of the following members may be added later if DMD finds it is
   // worthwhile:
   // - mNotifyDidPaintTimer
   // - mRegisteredPlugins
   // - mWillPaintObservers
   // - mWillPaintFallbackEvent
-  //
-  // The following member are not measured:
-  // - mUpdatePluginGeometryForFrame, because it is non-owning
 }
-
--- a/layout/base/nsPresContext.h
+++ b/layout/base/nsPresContext.h
@@ -882,27 +882,16 @@ public:
    * if you care about which presshell the primary frame is in.
    */
   nsIFrame* GetPrimaryFrameFor(nsIContent* aContent);
 
   void NotifyDestroyingFrame(nsIFrame* aFrame)
   {
     PropertyTable()->DeleteAllFor(aFrame);
   }
-  inline void ForgetUpdatePluginGeometryFrame(nsIFrame* aFrame);
-
-  bool GetContainsUpdatePluginGeometryFrame()
-  {
-    return mContainsUpdatePluginGeometryFrame;
-  }
-
-  void SetContainsUpdatePluginGeometryFrame(bool aValue)
-  {
-    mContainsUpdatePluginGeometryFrame = aValue;
-  }
 
   bool MayHaveFixedBackgroundFrames() { return mMayHaveFixedBackgroundFrames; }
   void SetHasFixedBackgroundFrame() { mMayHaveFixedBackgroundFrames = true; }
 
   virtual size_t SizeOfExcludingThis(nsMallocSizeOfFun aMallocSizeOf) const;
   virtual size_t SizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf) const {
     return aMallocSizeOf(this) + SizeOfExcludingThis(aMallocSizeOf);
   }
@@ -1153,17 +1142,16 @@ protected:
   // the document rather than to change the document's dimensions
   unsigned              mSupressResizeReflow : 1;
 
   unsigned              mIsVisual : 1;
 
   unsigned              mProcessingRestyles : 1;
   unsigned              mProcessingAnimationStyleChange : 1;
 
-  unsigned              mContainsUpdatePluginGeometryFrame : 1;
   unsigned              mFireAfterPaintEvents : 1;
 
   // Cache whether we are chrome or not because it is expensive.  
   // mIsChromeIsCached tells us if mIsChrome is valid or we need to get the
   // value the slow way.
   mutable unsigned      mIsChromeIsCached : 1;
   mutable unsigned      mIsChrome : 1;
 
@@ -1261,31 +1249,17 @@ public:
 
   virtual bool IsRoot() { return true; }
 
   /**
    * Call this after reflow and scrolling to ensure that the geometry
    * of any windowed plugins is updated. aFrame is the root of the
    * frame subtree whose geometry has changed.
    */
-  void RequestUpdatePluginGeometry(nsIFrame* aFrame);
-
-  /**
-   * Call this when a frame is being destroyed and
-   * mContainsUpdatePluginGeometryFrame is set in the frame's prescontext.
-   */
-  void RootForgetUpdatePluginGeometryFrame(nsIFrame* aFrame);
-
-  /**
-   * Call this when a document is going to no longer be valid for plugin updates
-   * (say by going into the bfcache). If mContainsUpdatePluginGeometryFrame is
-   * set in the prescontext then it will be cleared along with
-   * mUpdatePluginGeometryForFrame.
-   */
-  void RootForgetUpdatePluginGeometryFrameForPresContext(nsPresContext* aPresContext);
+  void RequestUpdatePluginGeometry();
 
   /**
    * Increment DOM-modification generation counter to indicate that
    * the DOM has changed in a way that might lead to style changes/
    * reflows/frame creation and destruction.
    */
   void IncrementDOMGeneration() { mDOMGeneration++; }
 
@@ -1338,32 +1312,20 @@ protected:
   nsCOMPtr<nsITimer> mNotifyDidPaintTimer;
   nsCOMPtr<nsITimer> mUpdatePluginGeometryTimer;
   nsTHashtable<nsRefPtrHashKey<nsIContent> > mRegisteredPlugins;
   // if mNeedsToUpdatePluginGeometry is set, then this is the frame to
   // use as the root of the subtree to search for plugin updates, or
   // null to use the root frame of this prescontext
   nsTArray<nsCOMPtr<nsIRunnable> > mWillPaintObservers;
   nsRevocableEventPtr<RunWillPaintObservers> mWillPaintFallbackEvent;
-  nsIFrame* mUpdatePluginGeometryForFrame;
   uint32_t mDOMGeneration;
   bool mNeedsToUpdatePluginGeometry;
 };
 
-inline void
-nsPresContext::ForgetUpdatePluginGeometryFrame(nsIFrame* aFrame)
-{
-  if (mContainsUpdatePluginGeometryFrame) {
-    nsRootPresContext* rootPC = GetRootPresContext();
-    if (rootPC) {
-      rootPC->RootForgetUpdatePluginGeometryFrame(aFrame);
-    }
-  }
-}
-
 #ifdef MOZ_REFLOW_PERF
 
 #define DO_GLOBAL_REFLOW_COUNT(_name) \
   aPresContext->CountReflows((_name), (nsIFrame*)this); 
 #else
 #define DO_GLOBAL_REFLOW_COUNT(_name)
 #endif // MOZ_REFLOW_PERF
 
--- a/layout/base/nsPresShell.cpp
+++ b/layout/base/nsPresShell.cpp
@@ -1966,18 +1966,16 @@ PresShell::SetIgnoreFrameDestruction(boo
   mIgnoreFrameDestruction = aIgnore;
 }
 
 void
 PresShell::NotifyDestroyingFrame(nsIFrame* aFrame)
 {
   NS_TIME_FUNCTION_MIN(1.0);
 
-  mPresContext->ForgetUpdatePluginGeometryFrame(aFrame);
-
   if (!mIgnoreFrameDestruction) {
     mDocument->StyleImageLoader()->DropRequestsForFrame(aFrame);
 
     mFrameConstructor->NotifyDestroyingFrame(aFrame);
 
     for (int32_t idx = mDirtyRoots.Length(); idx; ) {
       --idx;
       if (mDirtyRoots[idx] == aFrame) {
@@ -3595,17 +3593,17 @@ PresShell::UnsuppressAndInvalidate()
     rootFrame->Invalidate(rect);
 
     if (mCaretEnabled && mCaret) {
       mCaret->CheckCaretDrawingState();
     }
 
     nsRootPresContext* rootPC = mPresContext->GetRootPresContext();
     if (rootPC) {
-      rootPC->RequestUpdatePluginGeometry(rootFrame);
+      rootPC->RequestUpdatePluginGeometry();
     }
   }
 
   // now that painting is unsuppressed, focus may be set on the document
   nsPIDOMWindow *win = mDocument->GetWindow();
   if (win)
     win->SetReadyForFocus();
 
@@ -7147,24 +7145,16 @@ PresShell::Freeze()
   }
 
   nsPresContext* presContext = GetPresContext();
   if (presContext &&
       presContext->RefreshDriver()->PresContext() == presContext) {
     presContext->RefreshDriver()->Freeze();
   }
 
-  if (presContext) {
-    nsRootPresContext* rootPresContext = presContext->GetRootPresContext();
-    if (rootPresContext) {
-      rootPresContext->
-        RootForgetUpdatePluginGeometryFrameForPresContext(mPresContext);
-    }
-  }
-
   mFrozen = true;
   if (mDocument) {
     UpdateImageLockingState();
   }
 }
 
 void
 PresShell::FireOrClearDelayedEvents(bool aFireEvents)
@@ -7506,17 +7496,17 @@ PresShell::DoReflow(nsIFrame* target, bo
     // should be suppressed now. We don't want to do extra reflow work
     // before our reflow event happens.
     mSuppressInterruptibleReflows = true;
     MaybeScheduleReflow();
   }
 
   nsRootPresContext* rootPC = mPresContext->GetRootPresContext();
   if (rootPC) {
-    rootPC->RequestUpdatePluginGeometry(target);
+    rootPC->RequestUpdatePluginGeometry();
   }
 
   return !interrupted;
 }
 
 #ifdef DEBUG
 void
 PresShell::DoVerifyReflow()
--- a/layout/generic/nsGfxScrollFrame.cpp
+++ b/layout/generic/nsGfxScrollFrame.cpp
@@ -1928,17 +1928,17 @@ void nsGfxScrollFrameInner::MarkActive()
 
 void nsGfxScrollFrameInner::ScrollVisual(nsPoint aOldScrolledFramePos)
 {
   nsRootPresContext* rootPresContext = mOuter->PresContext()->GetRootPresContext();
   if (!rootPresContext) {
     return;
   }
 
-  rootPresContext->RequestUpdatePluginGeometry(mOuter);
+  rootPresContext->RequestUpdatePluginGeometry();
 
   AdjustViews(mScrolledFrame);
   // We need to call this after fixing up the view positions
   // to be consistent with the frame hierarchy.
   uint32_t flags = nsIFrame::INVALIDATE_REASON_SCROLL_REPAINT;
   bool canScrollWithBlitting = CanScrollWithBlitting(mOuter);
   mOuter->RemoveStateBits(NS_SCROLLFRAME_INVALIDATE_CONTENTS_ON_SCROLL);
   if (IsScrollingActive()) {
--- a/layout/generic/nsObjectFrame.cpp
+++ b/layout/generic/nsObjectFrame.cpp
@@ -745,17 +745,17 @@ nsObjectFrame::RegisterPluginForGeometry
   }
   if (mRootPresContextRegisteredWith && mRootPresContextRegisteredWith != rpc) {
     // Registered to some other root pres context. Unregister, and
     // re-register with our current one...
     UnregisterPluginForGeometryUpdates();
   }
   mRootPresContextRegisteredWith = rpc;
   mRootPresContextRegisteredWith->RegisterPluginForGeometryUpdates(mContent);
-  mRootPresContextRegisteredWith->RequestUpdatePluginGeometry(this);
+  mRootPresContextRegisteredWith->RequestUpdatePluginGeometry();
 }
 
 void
 nsObjectFrame::UnregisterPluginForGeometryUpdates()
 {
   if (!mRootPresContextRegisteredWith) {
     // Not registered...
     return;
--- a/layout/generic/nsSubDocumentFrame.cpp
+++ b/layout/generic/nsSubDocumentFrame.cpp
@@ -759,28 +759,16 @@ BeginSwapDocShellsForViews(nsIView* aSib
 void
 nsSubDocumentFrame::DestroyFrom(nsIFrame* aDestructRoot)
 {
   if (mPostedReflowCallback) {
     PresContext()->PresShell()->CancelReflowCallback(this);
     mPostedReflowCallback = false;
   }
 
-  // Forget about plugin geometry updates in the subdoc's PresContext,
-  // otherwise we can be left with dangling pointers to the "plugin for
-  // geometry update frame" in the root PresContext.
-  nsIFrame* subdocRootFrame = GetSubdocumentRootFrame();
-  if (subdocRootFrame) {
-    nsPresContext* pc = subdocRootFrame->PresContext();
-    nsRootPresContext* rpc = pc ? pc->GetRootPresContext() : nullptr;
-    if (rpc) {
-      rpc->RootForgetUpdatePluginGeometryFrameForPresContext(pc);
-    }
-  }
-
   // Detach the subdocument's views and stash them in the frame loader.
   // We can then reattach them if we're being reframed (for example if
   // the frame has been made position:fixed).
   nsFrameLoader* frameloader = FrameLoader();
   if (frameloader) {
     nsIView* detachedViews = ::BeginSwapDocShellsForViews(mInnerView->GetFirstChild());
     frameloader->SetDetachedSubdocView(detachedViews, mContent->OwnerDoc());