Bug 775965 - Make nsRootPresContext::mRegisteredPlugins a refptr hash table to the content object rather than weak refs to frames. r=roc
authorChris Pearce <cpearce@mozilla.com>
Tue, 14 Aug 2012 16:06:42 +1200
changeset 105728 42af0a2ee337af48ea4554dc312f4895358e63a3
parent 105727 7fe1c2d3d1f41e90160ea520d45eafb9bcf90523
child 105729 0cfcc4e860c52a5dc328a34613cbfafd15f9fc51
push id1989
push userakeybl@mozilla.com
push dateTue, 28 Aug 2012 00:20:43 +0000
treeherdermozilla-aurora@a8e95ae10ea7 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersroc
bugs775965
milestone17.0a1
Bug 775965 - Make nsRootPresContext::mRegisteredPlugins a refptr hash table to the content object rather than weak refs to frames. r=roc
layout/base/nsPresContext.cpp
layout/base/nsPresContext.h
layout/generic/nsObjectFrame.cpp
--- a/layout/base/nsPresContext.cpp
+++ b/layout/base/nsPresContext.cpp
@@ -2356,41 +2356,45 @@ nsRootPresContext::~nsRootPresContext()
 {
   NS_ASSERTION(mRegisteredPlugins.Count() == 0,
                "All plugins should have been unregistered");
   CancelDidPaintTimer();
   CancelUpdatePluginGeometryTimer();
 }
 
 void
-nsRootPresContext::RegisterPluginForGeometryUpdates(nsObjectFrame* aPlugin)
+nsRootPresContext::RegisterPluginForGeometryUpdates(nsIContent* aPlugin)
 {
   mRegisteredPlugins.PutEntry(aPlugin);
 }
 
 void
-nsRootPresContext::UnregisterPluginForGeometryUpdates(nsObjectFrame* aPlugin)
+nsRootPresContext::UnregisterPluginForGeometryUpdates(nsIContent* aPlugin)
 {
   mRegisteredPlugins.RemoveEntry(aPlugin);
 }
 
 struct PluginGeometryClosure {
   nsIFrame* mRootFrame;
   PRInt32   mRootAPD;
   nsIFrame* mChangedSubtree;
   nsRect    mChangedRect;
   nsTHashtable<nsPtrHashKey<nsObjectFrame> > mAffectedPlugins;
   nsRect    mAffectedPluginBounds;
   nsTArray<nsIWidget::Configuration>* mOutputConfigurations;
 };
 static PLDHashOperator
-PluginBoundsEnumerator(nsPtrHashKey<nsObjectFrame>* aEntry, void* userArg)
+PluginBoundsEnumerator(nsRefPtrHashKey<nsIContent>* aEntry, void* userArg)
 {
   PluginGeometryClosure* closure = static_cast<PluginGeometryClosure*>(userArg);
-  nsObjectFrame* f = aEntry->GetKey();
+  nsObjectFrame* f = static_cast<nsObjectFrame*>(aEntry->GetKey()->GetPrimaryFrame());
+  if (!f) {
+    NS_WARNING("Null frame in PluginBoundsEnumerator");
+    return PL_DHASH_NEXT;
+  }
   nsRect fBounds = f->GetContentRect() +
       f->GetParent()->GetOffsetToCrossDoc(closure->mRootFrame);
   PRInt32 APD = f->PresContext()->AppUnitsPerDevPixel();
   fBounds = fBounds.ConvertAppUnitsRoundOut(APD, closure->mRootAPD);
   // We're identifying the plugins that may have been affected by changes
   // to the frame subtree rooted at aChangedRoot. Any plugin that overlaps
   // the overflow area of aChangedRoot could have its clip region affected
   // because it might be covered (or uncovered) by changes to the subtree.
@@ -2661,19 +2665,23 @@ nsRootPresContext::RequestUpdatePluginGe
       return;
     mUpdatePluginGeometryForFrame->PresContext()->
       SetContainsUpdatePluginGeometryFrame(false);
     mUpdatePluginGeometryForFrame = nullptr;
   }
 }
 
 static PLDHashOperator
-PluginDidSetGeometryEnumerator(nsPtrHashKey<nsObjectFrame>* aEntry, void* userArg)
+PluginDidSetGeometryEnumerator(nsRefPtrHashKey<nsIContent>* aEntry, void* userArg)
 {
-  nsObjectFrame* f = aEntry->GetKey();
+  nsObjectFrame* f = static_cast<nsObjectFrame*>(aEntry->GetKey()->GetPrimaryFrame());
+  if (!f) {
+    NS_WARNING("Null frame in PluginDidSetGeometryEnumerator");
+    return PL_DHASH_NEXT;
+  }
   f->DidSetWidgetGeometry();
   return PL_DHASH_NEXT;
 }
 
 void
 nsRootPresContext::DidApplyPluginGeometryUpdates()
 {
   mRegisteredPlugins.EnumerateEntries(PluginDidSetGeometryEnumerator, nullptr);
--- a/layout/base/nsPresContext.h
+++ b/layout/base/nsPresContext.h
@@ -1222,23 +1222,23 @@ public:
   }
 
   /**
    * Registers a plugin to receive geometry updates (position and clip
    * region) so it can update its widget.
    * Callers must call UnregisterPluginForGeometryUpdates before
    * the aPlugin frame is destroyed.
    */
-  void RegisterPluginForGeometryUpdates(nsObjectFrame* aPlugin);
+  void RegisterPluginForGeometryUpdates(nsIContent* aPlugin);
   /**
    * Stops a plugin receiving geometry updates (position and clip
    * region). If the plugin was not already registered, this does
    * nothing.
    */
-  void UnregisterPluginForGeometryUpdates(nsObjectFrame* aPlugin);
+  void UnregisterPluginForGeometryUpdates(nsIContent* aPlugin);
 
   /**
    * Iterate through all plugins that are registered for geometry updates
    * and update their position and clip region to match the current frame
    * tree.
    */
   void UpdatePluginGeometry();
 
@@ -1332,17 +1332,17 @@ protected:
     if (mUpdatePluginGeometryTimer) {
       mUpdatePluginGeometryTimer->Cancel();
       mUpdatePluginGeometryTimer = nullptr;
     }
   }
 
   nsCOMPtr<nsITimer> mNotifyDidPaintTimer;
   nsCOMPtr<nsITimer> mUpdatePluginGeometryTimer;
-  nsTHashtable<nsPtrHashKey<nsObjectFrame> > mRegisteredPlugins;
+  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;
   PRUint32 mDOMGeneration;
   bool mNeedsToUpdatePluginGeometry;
--- a/layout/generic/nsObjectFrame.cpp
+++ b/layout/generic/nsObjectFrame.cpp
@@ -425,17 +425,17 @@ nsObjectFrame::PrepForDrawing(nsIWidget 
     // On Mac, we need to invalidate ourselves since even windowed
     // plugins are painted through Thebes and we need to ensure
     // the Thebes layer containing the plugin is updated.
     if (parentWidget == GetNearestWidget()) {
       Invalidate(GetContentRectRelativeToSelf());
     }
 #endif
 
-    rpc->RegisterPluginForGeometryUpdates(this);
+    rpc->RegisterPluginForGeometryUpdates(mContent);
     rpc->RequestUpdatePluginGeometry(this);
 
     // Here we set the background color for this widget because some plugins will use 
     // the child window background color when painting. If it's not set, it may default to gray
     // Sometimes, a frame doesn't have a background color or is transparent. In this
     // case, walk up the frame tree until we do find a frame with a background color
     for (nsIFrame* frame = this; frame; frame = frame->GetParent()) {
       nscolor bgcolor =
@@ -445,17 +445,17 @@ nsObjectFrame::PrepForDrawing(nsIWidget 
         break;
       }
     }
   } else {
     // Changing to windowless mode changes the NPWindow geometry.
     FixupWindow(GetContentRectRelativeToSelf().Size());
 
 #ifndef XP_MACOSX
-    rpc->RegisterPluginForGeometryUpdates(this);
+    rpc->RegisterPluginForGeometryUpdates(mContent);
     rpc->RequestUpdatePluginGeometry(this);
 #endif
   }
 
   if (!IsHidden()) {
     viewMan->SetViewVisibility(view, nsViewVisibility_kShow);
   }
 
@@ -740,33 +740,33 @@ nsObjectFrame::SetInstanceOwner(nsPlugin
   mInstanceOwner = aOwner;
   if (!mInstanceOwner) {
     nsRootPresContext* rpc = PresContext()->GetRootPresContext();
     if (rpc) {
       if (mWidget) {
         if (mInnerView) {
           mInnerView->DetachWidgetEventHandler(mWidget);
 
-          rpc->UnregisterPluginForGeometryUpdates(this);
+          rpc->UnregisterPluginForGeometryUpdates(mContent);
           // Make sure the plugin is hidden in case an update of plugin geometry
           // hasn't happened since this plugin became hidden.
           nsIWidget* parent = mWidget->GetParent();
           if (parent) {
             nsTArray<nsIWidget::Configuration> configurations;
             this->GetEmptyClipConfiguration(&configurations);
             parent->ConfigureChildren(configurations);
 
             mWidget->Show(false);
             mWidget->Enable(false);
             mWidget->SetParent(nullptr);
           }
         }
       } else {
 #ifndef XP_MACOSX
-        rpc->UnregisterPluginForGeometryUpdates(this);
+        rpc->UnregisterPluginForGeometryUpdates(mContent);
 #endif
       }
     }
   }
 }
 
 bool
 nsObjectFrame::IsFocusable(PRInt32 *aTabIndex, bool aWithMouse)
@@ -2216,17 +2216,17 @@ nsObjectFrame::BeginSwapDocShells(nsICon
   if (!obj)
     return;
 
   nsObjectFrame* objectFrame = static_cast<nsObjectFrame*>(obj);
   NS_ASSERTION(!objectFrame->mWidget || objectFrame->mWidget->GetParent(),
                "Plugin windows must not be toplevel");
   nsRootPresContext* rootPC = objectFrame->PresContext()->GetRootPresContext();
   NS_ASSERTION(rootPC, "unable to unregister the plugin frame");
-  rootPC->UnregisterPluginForGeometryUpdates(objectFrame);
+  rootPC->UnregisterPluginForGeometryUpdates(aContent);
 }
 
 /*static*/ void
 nsObjectFrame::EndSwapDocShells(nsIContent* aContent, void*)
 {
   NS_PRECONDITION(aContent, "");
 
   // This function is called from a document content enumerator so we need
@@ -2242,17 +2242,17 @@ nsObjectFrame::EndSwapDocShells(nsIConte
   if (widget) {
     // Reparent the widget.
     nsIWidget* parent =
       rootPC->PresShell()->GetRootFrame()->GetNearestWidget();
     widget->SetParent(parent);
     objectFrame->CallSetWindow();
 
     // Register for geometry updates and make a request.
-    rootPC->RegisterPluginForGeometryUpdates(objectFrame);
+    rootPC->RegisterPluginForGeometryUpdates(aContent);
     rootPC->RequestUpdatePluginGeometry(objectFrame);
   }
 }
 
 nsIFrame*
 NS_NewObjectFrame(nsIPresShell* aPresShell, nsStyleContext* aContext)
 {
   return new (aPresShell) nsObjectFrame(aContext);