Bug 621228 - Make plugins listening presShell SetActive calls. r=jst
authorOleg Romashin <romaxa@gmail.com>
Thu, 18 Aug 2011 22:08:38 +0200
changeset 76544 c51feb247cc4127b01b62a331bd6f370d85fe638
parent 76543 ec4956f17090631ec826f27e3da5ac6956717083
child 76545 e204fcdf504974372f450422ab851b41af959cfb
push id340
push userclegnitto@mozilla.com
push dateTue, 08 Nov 2011 22:56:33 +0000
treeherdermozilla-beta@f745dc151615 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjst
bugs621228
milestone9.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 621228 - Make plugins listening presShell SetActive calls. r=jst
dom/plugins/base/nsPluginInstanceOwner.cpp
dom/plugins/base/nsPluginInstanceOwner.h
layout/base/nsPresShell.cpp
layout/generic/nsIObjectFrame.h
layout/generic/nsObjectFrame.cpp
layout/generic/nsObjectFrame.h
--- a/dom/plugins/base/nsPluginInstanceOwner.cpp
+++ b/dom/plugins/base/nsPluginInstanceOwner.cpp
@@ -300,16 +300,17 @@ nsPluginInstanceOwner::nsPluginInstanceO
   mInCGPaintLevel = 0;
   mSentInitialTopLevelWindowEvent = PR_FALSE;
   mColorProfile = nsnull;
   mPluginPortChanged = PR_FALSE;
 #endif
   mContentFocused = PR_FALSE;
   mWidgetVisible = PR_TRUE;
   mPluginWindowVisible = PR_FALSE;
+  mPluginDocumentActiveState = PR_TRUE;
   mNumCachedAttrs = 0;
   mNumCachedParams = 0;
   mCachedAttrParamNames = nsnull;
   mCachedAttrParamValues = nsnull;
   mDestroyWidget = PR_FALSE;
 
 #ifdef XP_MACOSX
 #ifndef NP_NO_QUICKDRAW
@@ -3236,17 +3237,17 @@ void nsPluginInstanceOwner::UpdateWindow
   nsIntPoint origin = mObjectFrame->GetWindowOriginInPixels(windowless);
 
   mPluginWindow->x = origin.x;
   mPluginWindow->y = origin.y;
 
   mPluginWindow->clipRect.left = 0;
   mPluginWindow->clipRect.top = 0;
 
-  if (mPluginWindowVisible) {
+  if (mPluginWindowVisible && mPluginDocumentActiveState) {
     mPluginWindow->clipRect.right = mPluginWindow->width;
     mPluginWindow->clipRect.bottom = mPluginWindow->height;
   } else {
     mPluginWindow->clipRect.right = 0;
     mPluginWindow->clipRect.bottom = 0;
   }
 
   if (!aSetWindow)
@@ -3264,16 +3265,22 @@ void nsPluginInstanceOwner::UpdateWindow
 
 void
 nsPluginInstanceOwner::UpdateWindowVisibility(PRBool aVisible)
 {
   mPluginWindowVisible = aVisible;
   UpdateWindowPositionAndClipRect(PR_TRUE);
 }
 
+void
+nsPluginInstanceOwner::UpdateDocumentActiveState(PRBool aIsActive)
+{
+  mPluginDocumentActiveState = aIsActive;
+  UpdateWindowPositionAndClipRect(PR_TRUE);
+}
 #endif // XP_MACOSX
 
 void
 nsPluginInstanceOwner::CallSetWindow()
 {
   if (!mInstance)
     return;
 
--- a/dom/plugins/base/nsPluginInstanceOwner.h
+++ b/dom/plugins/base/nsPluginInstanceOwner.h
@@ -197,16 +197,17 @@ public:
   // FixUpPluginWindow() (i.e. we need to know when FixUpPluginWindow() has
   // been called from nsObjectFrame::PaintPlugin() when we're using the
   // CoreGraphics drawing model).
   void BeginCGPaint();
   void EndCGPaint();
 #else // XP_MACOSX
   void UpdateWindowPositionAndClipRect(PRBool aSetWindow);
   void UpdateWindowVisibility(PRBool aVisible);
+  void UpdateDocumentActiveState(PRBool aIsActive);
 #endif // XP_MACOSX
   void CallSetWindow();
   
   void SetOwner(nsObjectFrame *aOwner)
   {
     mObjectFrame = aOwner;
   }
   nsObjectFrame* GetOwner() {
@@ -338,16 +339,17 @@ private:
 #ifdef XP_MACOSX
   PRPackedBool                mPluginPortChanged;
 #endif
 #ifdef MOZ_X11
   // Used with windowless plugins only, initialized in CreateWidget().
   PRPackedBool                mFlash10Quirks;
 #endif
   PRPackedBool                mPluginWindowVisible;
+  PRPackedBool                mPluginDocumentActiveState;
   
   // If true, destroy the widget on destruction. Used when plugin stop
   // is being delayed to a safer point in time.
   PRPackedBool                mDestroyWidget;
   PRUint16          mNumCachedAttrs;
   PRUint16          mNumCachedParams;
   char              **mCachedAttrParamNames;
   char              **mCachedAttrParamValues;
--- a/layout/base/nsPresShell.cpp
+++ b/layout/base/nsPresShell.cpp
@@ -9406,31 +9406,43 @@ SetExternalResourceIsActive(nsIDocument*
 {
   nsIPresShell* shell = aDocument->GetShell();
   if (shell) {
     shell->SetIsActive(*static_cast<PRBool*>(aClosure));
   }
   return PR_TRUE;
 }
 
+static void
+SetPluginIsActive(nsIContent* aContent, void* aClosure)
+{
+  nsIFrame *frame = aContent->GetPrimaryFrame();
+  nsIObjectFrame *objectFrame = do_QueryFrame(frame);
+  if (objectFrame) {
+    objectFrame->SetIsDocumentActive(*static_cast<PRBool*>(aClosure));
+  }
+}
+
 nsresult
 PresShell::SetIsActive(PRBool aIsActive)
 {
   NS_PRECONDITION(mDocument, "should only be called with a document");
 
   mIsActive = aIsActive;
   nsPresContext* presContext = GetPresContext();
   if (presContext &&
       presContext->RefreshDriver()->PresContext() == presContext) {
     presContext->RefreshDriver()->SetThrottled(!mIsActive);
   }
 
   // Propagate state-change to my resource documents' PresShells
   mDocument->EnumerateExternalResources(SetExternalResourceIsActive,
                                         &aIsActive);
+  mDocument->EnumerateFreezableElements(SetPluginIsActive,
+                                        &aIsActive);
   nsresult rv = UpdateImageLockingState();
 #ifdef ACCESSIBILITY
   if (aIsActive) {
     nsAccessibilityService* accService = AccService();
     if (accService) {
       accService->PresShellActivated(this);
     }
   }
--- a/layout/generic/nsIObjectFrame.h
+++ b/layout/generic/nsIObjectFrame.h
@@ -89,11 +89,18 @@ public:
    * is currently active in this frame.
    */
   virtual void StopPlugin() = 0;
 
   /**
    * Get the native widget for the plugin, if any.
    */
   virtual nsIWidget* GetWidget() = 0;
+
+  /**
+   * Update plugin active state. Frame should update if it is on an active tab
+   * or not and forward that information to the plugin to make it possible to
+   * throttle down plugin instance in non active case.
+   */
+  virtual void SetIsDocumentActive(PRBool aIsActive) = 0;
 };
 
 #endif /* nsIObjectFrame_h___ */
--- a/layout/generic/nsObjectFrame.cpp
+++ b/layout/generic/nsObjectFrame.cpp
@@ -2490,16 +2490,26 @@ nsObjectFrame::GetCursor(const nsPoint& 
   if (!useDOMCursor) {
     return NS_ERROR_FAILURE;
   }
 
   return nsObjectFrameSuper::GetCursor(aPoint, aCursor);
 }
 
 void
+nsObjectFrame::SetIsDocumentActive(PRBool aIsActive)
+{
+#ifndef XP_MACOSX
+  if (mInstanceOwner) {
+    mInstanceOwner->UpdateDocumentActiveState(aIsActive);
+  }
+#endif
+}
+
+void
 nsObjectFrame::NotifyContentObjectWrapper()
 {
   nsCOMPtr<nsIDocument> doc = mContent->GetDocument();
   if (!doc)
     return;
 
   nsIScriptGlobalObject *sgo = doc->GetScriptGlobalObject();
   if (!sgo)
--- a/layout/generic/nsObjectFrame.h
+++ b/layout/generic/nsObjectFrame.h
@@ -123,16 +123,17 @@ public:
 
   virtual void DidSetStyleContext(nsStyleContext* aOldStyleContext);
 
   NS_METHOD GetPluginInstance(nsNPAPIPluginInstance** aPluginInstance);
   virtual nsresult Instantiate(nsIChannel* aChannel, nsIStreamListener** aStreamListener);
   virtual nsresult Instantiate(const char* aMimeType, nsIURI* aURI);
   virtual void TryNotifyContentObjectWrapper();
   virtual void StopPlugin();
+  virtual void SetIsDocumentActive(PRBool aIsActive);
 
   /*
    * Stop a plugin instance. If aDelayedStop is true, the plugin will
    * be stopped at a later point when it's safe to do so (i.e. not
    * while destroying the frame tree). Delayed stopping is only
    * implemented on Win32 for now.
    */
   void StopPluginInternal(PRBool aDelayedStop);