Bug 606285 and Bug 583109 - Send the "visible" notification when painting with async layers, so that when a plugin goes from invisible to visible it starts sending asynchronous paints. Suspend sending surface updates for asynchronous plugins when they are invisible, and set the empty clipRect so that the plugin knows that drawing is suspended per the new API. Assume that plugins are visible again when a Paint or BuildLayer call is received. r-pending=karlt
authorBenjamin Smedberg <benjamin@smedbergs.us>
Fri, 05 Nov 2010 10:40:55 -0400
changeset 57225 6ff3fcbb784501e3dc241e511aeea04ff759a468
parent 57224 24a2e0ac428f81256fc54025a8a9437dafde37b8
child 57226 df0cf7e8e9e6611f0a723c3239625bd5b1e94339
push id16846
push userbsmedberg@mozilla.com
push dateWed, 10 Nov 2010 15:29:47 +0000
treeherdermozilla-central@bdbef533364f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs606285, 583109
milestone2.0b8pre
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 606285 and Bug 583109 - Send the "visible" notification when painting with async layers, so that when a plugin goes from invisible to visible it starts sending asynchronous paints. Suspend sending surface updates for asynchronous plugins when they are invisible, and set the empty clipRect so that the plugin knows that drawing is suspended per the new API. Assume that plugins are visible again when a Paint or BuildLayer call is received. r-pending=karlt
dom/plugins/PPluginInstance.ipdl
dom/plugins/PluginInstanceChild.cpp
dom/plugins/PluginInstanceChild.h
dom/plugins/PluginInstanceParent.cpp
dom/plugins/PluginInstanceParent.h
dom/plugins/PluginLibrary.h
dom/plugins/PluginModuleParent.cpp
dom/plugins/PluginModuleParent.h
layout/generic/nsObjectFrame.cpp
modules/plugin/base/src/PluginPRLibrary.cpp
modules/plugin/base/src/PluginPRLibrary.h
modules/plugin/base/src/nsNPAPIPluginInstance.cpp
--- a/dom/plugins/PPluginInstance.ipdl
+++ b/dom/plugins/PPluginInstance.ipdl
@@ -119,20 +119,16 @@ child:
     returns (int16_t handled);
   // this is only used on windows to forward WM_WINDOWPOSCHANGE
   async WindowPosChanged(NPRemoteEvent event);
 
   // ********************** Async plugins rendering
   // see https://wiki.mozilla.org/Gecko:AsyncPluginPainting
   // **********************
 
-  // Plugin parent notify child that plugin frame
-  // has been painted to the screen
-  async PaintFinished();
-
   // Async version of SetWindow call
   // @param surfaceType - gfxASurface::gfxSurfaceType
   //        plugin child must create offscreen buffer
   //        with type equals to surfaceType
   async AsyncSetWindow(gfxSurfaceType surfaceType, NPRemoteWindow window);
 
   rpc NPP_Destroy()
     returns (NPError rv);
--- a/dom/plugins/PluginInstanceChild.cpp
+++ b/dom/plugins/PluginInstanceChild.cpp
@@ -2157,42 +2157,31 @@ PluginInstanceChild::NPN_NewStream(NPMIM
         return result;
     }
 
     *aStream = &ps->mStream;
     return NPERR_NO_ERROR;
 }
 
 bool
-PluginInstanceChild::RecvPaintFinished(void)
-{
-    if (mPendingForcePaint) {
-        nsIntRect r(0, 0, mWindow.width, mWindow.height);
-        mAccumulatedInvalidRect.UnionRect(r, mAccumulatedInvalidRect);
-        mPendingForcePaint = false;
-    }
-    if (!mAccumulatedInvalidRect.IsEmpty()) {
-        AsyncShowPluginFrame();
-    }
-
-    return true;
-}
-
-bool
 PluginInstanceChild::RecvAsyncSetWindow(const gfxSurfaceType& aSurfaceType,
                                         const NPRemoteWindow& aWindow)
 {
     AssertPluginThread();
 
     mWindow.window = reinterpret_cast<void*>(aWindow.window);
     if (mWindow.width != aWindow.width || mWindow.height != aWindow.height) {
         mCurrentSurface = nsnull;
         mHelperSurface = nsnull;
-        mPendingForcePaint = true;
+        mAccumulatedInvalidRect = nsIntRect(0, 0, aWindow.width, aWindow.height);
     }
+    if (mWindow.clipRect.top != aWindow.clipRect.top ||
+        mWindow.clipRect.left != aWindow.clipRect.left ||
+        mWindow.clipRect.bottom != aWindow.clipRect.bottom ||
+        mWindow.clipRect.right != aWindow.clipRect.right)
 
     mWindow.x = aWindow.x;
     mWindow.y = aWindow.y;
     mWindow.width = aWindow.width;
     mWindow.height = aWindow.height;
     mWindow.clipRect = aWindow.clipRect;
     mWindow.type = aWindow.type;
 
@@ -2205,16 +2194,20 @@ PluginInstanceChild::RecvAsyncSetWindow(
 
 #ifdef XP_WIN
     if (mQuirks & QUIRK_WINLESS_TRACKPOPUP_HOOK)
         CreateWinlessPopupSurrogate();
     if (mQuirks & QUIRK_FLASH_THROTTLE_WMUSER_EVENTS)
         SetupFlashMsgThrottle();
 #endif
 
+    if (!mAccumulatedInvalidRect.IsEmpty()) {
+        AsyncShowPluginFrame();
+    }
+
     return true;
 }
 
 static inline gfxRect
 GfxFromNsRect(const nsIntRect& aRect)
 {
     return gfxRect(aRect.x, aRect.y, aRect.width, aRect.height);
 }
@@ -2425,33 +2418,36 @@ PluginInstanceChild::UpdateWindowAttribu
         needWindowUpdate = true;
     }
 #endif // XP_WIN
 
     if (!needWindowUpdate) {
         return;
     }
 
-    // The clip rect is relative to drawable top-left.
-    nsIntRect clipRect;
 #ifndef XP_WIN
     // On Windows, we translate the device context, in order for the window
     // origin to be correct.
     mWindow.x = mWindow.y = 0;
 #endif
 
-    // Don't ask the plugin to draw outside the drawable. The clip rect
-    // is in plugin coordinates, not window coordinates.
-    // This also ensures that the unsigned clip rectangle offsets won't be -ve.
-    clipRect.SetRect(0, 0, mWindow.width, mWindow.height);
-
-    mWindow.clipRect.left = 0;
-    mWindow.clipRect.top = 0;
-    mWindow.clipRect.right = clipRect.XMost();
-    mWindow.clipRect.bottom = clipRect.YMost();
+    if (IsVisible()) {
+        // The clip rect is relative to drawable top-left.
+        nsIntRect clipRect;
+
+        // Don't ask the plugin to draw outside the drawable. The clip rect
+        // is in plugin coordinates, not window coordinates.
+        // This also ensures that the unsigned clip rectangle offsets won't be -ve.
+        clipRect.SetRect(0, 0, mWindow.width, mWindow.height);
+
+        mWindow.clipRect.left = 0;
+        mWindow.clipRect.top = 0;
+        mWindow.clipRect.right = clipRect.XMost();
+        mWindow.clipRect.bottom = clipRect.YMost();
+    }
 
 #ifdef XP_WIN
     // Windowless plugins on Windows need a WM_WINDOWPOSCHANGED event to update
     // their location... or at least Flash does: Silverlight uses the
     // window.x/y passed to NPP_SetWindow
 
     if (mPluginIface->event) {
         WINDOWPOS winpos = {
@@ -2787,34 +2783,34 @@ PluginInstanceChild::ReadbackDifferenceR
     ctx->Fill();
 
     return true;
 }
 
 void
 PluginInstanceChild::InvalidateRectDelayed(void)
 {
-    if (!mCurrentInvalidateTask) {
+    if (!mCurrentInvalidateTask || !IsVisible()) {
         return;
     }
 
     mCurrentInvalidateTask = nsnull;
     if (mAccumulatedInvalidRect.IsEmpty()) {
         return;
     }
 
     if (!ShowPluginFrame()) {
         AsyncShowPluginFrame();
     }
 }
 
 void
 PluginInstanceChild::AsyncShowPluginFrame(void)
 {
-    if (mCurrentInvalidateTask) {
+    if (mCurrentInvalidateTask || !IsVisible()) {
         return;
     }
 
     mCurrentInvalidateTask =
         NewRunnableMethod(this, &PluginInstanceChild::InvalidateRectDelayed);
     MessageLoop::current()->PostTask(FROM_HERE, mCurrentInvalidateTask);
 }
 
--- a/dom/plugins/PluginInstanceChild.h
+++ b/dom/plugins/PluginInstanceChild.h
@@ -97,17 +97,16 @@ protected:
     AnswerNPP_HandleEvent_Shmem(const NPRemoteEvent& event, Shmem& mem, int16_t* handled, Shmem* rtnmem);
     virtual bool
     AnswerNPP_HandleEvent_IOSurface(const NPRemoteEvent& event, const uint32_t& surface, int16_t* handled);
 
     // Async rendering
     virtual bool
     RecvAsyncSetWindow(const gfxSurfaceType& aSurfaceType,
                        const NPRemoteWindow& aWindow);
-    virtual bool RecvPaintFinished(void);
 
     NS_OVERRIDE
     virtual bool
     AnswerPaint(const NPRemoteEvent& event, int16_t* handled)
     {
         PaintTracker pt;
         return AnswerNPP_HandleEvent(event, handled);
     }
@@ -404,16 +403,23 @@ public:
 #if defined(__i386__)
     NPEventModel EventModel() { return mEventModel; }
 #endif
 
 private:
     const NPCocoaEvent   *mCurrentEvent;
 #endif
 
+    bool IsVisible() {
+        return mWindow.clipRect.top != 0 ||
+            mWindow.clipRect.left != 0 ||
+            mWindow.clipRect.bottom != 0 ||
+            mWindow.clipRect.right != 0;
+    }
+
     // ShowPluginFrame - in general does four things:
     // 1) Create mCurrentSurface optimized for rendering to parent process
     // 2) Updated mCurrentSurface to be a complete copy of mBackSurface
     // 3) Draw the invalidated plugin area into mCurrentSurface
     // 4) Send it to parent process.
     bool ShowPluginFrame(void);
 
     // If we can read back safely from mBackSurface, copy
--- a/dom/plugins/PluginInstanceParent.cpp
+++ b/dom/plugins/PluginInstanceParent.cpp
@@ -96,17 +96,16 @@ PluginInstanceParent::PluginInstancePare
     , mQuirks(0)
 #if defined(XP_MACOSX)
     , mShWidth(0)
     , mShHeight(0)
     , mShColorSpace(nsnull)
     , mDrawingModel(NPDrawingModelCoreGraphics)
     , mIOSurface(nsnull)
 #endif
-    , mSentPaintNotification(PR_FALSE)
 {
     InitQuirksModes(aMimeType);
 }
 
 void
 PluginInstanceParent::InitQuirksModes(const nsCString& aMimeType)
 {
 #ifdef OS_MACOSX
@@ -503,18 +502,16 @@ PluginInstanceParent::RecvShow(const NPR
     else if (newSurface.type() == SurfaceDescriptor::TSurfaceDescriptorWin) {
         SurfaceDescriptorWin windesc = newSurface.get_SurfaceDescriptorWin();
         SharedDIBSurface* dibsurf = new SharedDIBSurface();
         if (dibsurf->Attach(windesc.handle(), windesc.size().width, windesc.size().height, windesc.transparent()))
             surface = dibsurf;
     }
 #endif
 
-    mSentPaintNotification = PR_FALSE;
-
 #ifdef MOZ_X11
     if (mFrontSurface &&
         mFrontSurface->GetType() == gfxASurface::SurfaceTypeXlib)
         XSync(DefaultXDisplay(), False);
 #endif
 
     if (mFrontSurface && gfxSharedImageSurface::IsSharedImage(mFrontSurface))
         *prevSurface = static_cast<gfxSharedImageSurface*>(mFrontSurface.get())->GetShmem();
@@ -534,36 +531,24 @@ PluginInstanceParent::AsyncSetWindow(NPW
     mWindowType = aWindow->type;
     window.window = reinterpret_cast<unsigned long>(aWindow->window);
     window.x = aWindow->x;
     window.y = aWindow->y;
     window.width = aWindow->width;
     window.height = aWindow->height;
     window.clipRect = aWindow->clipRect;
     window.type = aWindow->type;
-    mSentPaintNotification = PR_FALSE;
     if (!SendAsyncSetWindow(gfxPlatform::GetPlatform()->ScreenReferenceSurface()->GetType(),
                             window))
         return NS_ERROR_FAILURE;
 
     return NS_OK;
 }
 
 nsresult
-PluginInstanceParent::NotifyPainted(void)
-{
-    bool rv = true;
-    if (!mSentPaintNotification) {
-        rv = SendPaintFinished();
-        mSentPaintNotification = rv;
-    }
-    return rv ? NS_OK : NS_ERROR_FAILURE;
-}
-
-nsresult
 PluginInstanceParent::GetSurface(gfxASurface** aSurface)
 {
     if (mFrontSurface) {
       NS_ADDREF(*aSurface = mFrontSurface);
       return NS_OK;
     }
     return NS_ERROR_NOT_AVAILABLE;
 }
--- a/dom/plugins/PluginInstanceParent.h
+++ b/dom/plugins/PluginInstanceParent.h
@@ -256,17 +256,16 @@ public:
     virtual bool
     AnswerPluginFocusChange(const bool& gotFocus);
 
 #if defined(OS_MACOSX)
     void Invalidate();
 #endif // definied(OS_MACOSX)
 
     nsresult AsyncSetWindow(NPWindow* window);
-    nsresult NotifyPainted(void);
     nsresult GetSurface(gfxASurface** aSurface);
 
 private:
     // Quirks mode support for various plugin mime types
     enum PluginQuirks {
         // OSX: Don't use the refresh timer for plug-ins
         // using this quirk. These plug-in most have another
         // way to refresh the window.
@@ -316,18 +315,15 @@ private:
     size_t             mShHeight;
     CGColorSpaceRef    mShColorSpace;
     int16_t            mDrawingModel;
     nsIOSurface       *mIOSurface;
 #endif // definied(OS_MACOSX)
 
     // ObjectFrame layer wrapper
     nsRefPtr<gfxASurface>    mFrontSurface;
-
-    // Don't spam plugin process with extra paint notifications
-    PRPackedBool             mSentPaintNotification;
 };
 
 
 } // namespace plugins
 } // namespace mozilla
 
 #endif // ifndef dom_plugins_PluginInstanceParent_h
--- a/dom/plugins/PluginLibrary.h
+++ b/dom/plugins/PluginLibrary.h
@@ -75,17 +75,16 @@ public:
   virtual nsresult NP_GetEntryPoints(NPPluginFuncs* pFuncs, NPError* error) = 0;
 #endif
   virtual nsresult NPP_New(NPMIMEType pluginType, NPP instance,
                            uint16_t mode, int16_t argc, char* argn[],
                            char* argv[], NPSavedData* saved,
                            NPError* error) = 0;
 
   virtual nsresult AsyncSetWindow(NPP instance, NPWindow* window) = 0;
-  virtual nsresult NotifyPainted(NPP instance) = 0;
   virtual nsresult GetSurface(NPP instance, gfxASurface** aSurface) = 0;
   virtual bool UseAsyncPainting() = 0;
 };
 
 
 } // namespace mozilla
 
 #endif  // ifndef mozilla_PluginLibrary_h
--- a/dom/plugins/PluginModuleParent.cpp
+++ b/dom/plugins/PluginModuleParent.cpp
@@ -619,26 +619,16 @@ PluginModuleParent::AsyncSetWindow(NPP i
     PluginInstanceParent* i = InstCast(instance);
     if (!i)
         return NS_ERROR_FAILURE;
 
     return i->AsyncSetWindow(window);
 }
 
 nsresult
-PluginModuleParent::NotifyPainted(NPP instance)
-{
-    PluginInstanceParent* i = InstCast(instance);
-    if (!i)
-        return NS_ERROR_FAILURE;
-
-    return i->NotifyPainted();
-}
-
-nsresult
 PluginModuleParent::GetSurface(NPP instance, gfxASurface** aSurface)
 {
     PluginInstanceParent* i = InstCast(instance);
     if (!i)
         return NS_ERROR_FAILURE;
 
     return i->GetSurface(aSurface);
 }
--- a/dom/plugins/PluginModuleParent.h
+++ b/dom/plugins/PluginModuleParent.h
@@ -217,17 +217,16 @@ private:
                               NPReason reason, void* notifyData);
     static NPError NPP_GetValue(NPP instance,
                                 NPPVariable variable, void *ret_value);
     static NPError NPP_SetValue(NPP instance, NPNVariable variable,
                                 void *value);
 
     virtual bool HasRequiredFunctions();
     virtual nsresult AsyncSetWindow(NPP instance, NPWindow* window);
-    virtual nsresult NotifyPainted(NPP instance);
     virtual nsresult GetSurface(NPP instance, gfxASurface** aSurface);
     NS_OVERRIDE virtual bool UseAsyncPainting() { return true; }
 
 #if defined(XP_UNIX) && !defined(XP_MACOSX)
     virtual nsresult NP_Initialize(NPNetscapeFuncs* bFuncs, NPPluginFuncs* pFuncs, NPError* error);
 #else
     virtual nsresult NP_Initialize(NPNetscapeFuncs* bFuncs, NPError* error);
 #endif
--- a/layout/generic/nsObjectFrame.cpp
+++ b/layout/generic/nsObjectFrame.cpp
@@ -1103,19 +1103,16 @@ nsObjectFrame::CallSetWindow()
       !win)
     return;
 
   nsPluginNativeWindow *window = (nsPluginNativeWindow *)win;
 #ifdef XP_MACOSX
   mInstanceOwner->FixUpPluginWindow(ePluginPaintDisable);
 #endif
 
-  if (IsHidden())
-    return;
-
   // refresh the plugin port as well
   window->window = mInstanceOwner->GetPluginPortFromWidget();
 
   // Adjust plugin dimensions according to pixel snap results
   // and reduce amount of SetWindow calls
   nsPresContext* presContext = PresContext();
   nsRootPresContext* rootPC = presContext->GetRootPresContext();
   if (!rootPC)
@@ -1733,37 +1730,43 @@ nsObjectFrame::BuildLayer(nsDisplayListB
   NPWindow* window = nsnull;
   mInstanceOwner->GetWindow(window);
   if (!window)
     return nsnull;
 
   if (window->width <= 0 || window->height <= 0)
     return nsnull;
 
+#ifndef XP_MACOSX
+  mInstanceOwner->UpdateWindowVisibility(PR_TRUE);
+#endif
+
   nsRect area = GetContentRect() + aBuilder->ToReferenceFrame(GetParent());
   gfxRect r = nsLayoutUtils::RectToGfxRect(area, PresContext()->AppUnitsPerDevPixel());
   // to provide crisper and faster drawing.
   r.Round();
   nsRefPtr<Layer> layer =
     (aBuilder->LayerBuilder()->GetLeafLayerFor(aBuilder, aManager, aItem));
 
   if (!layer) {
     mInstanceOwner->NotifyPaintWaiter(aBuilder, aManager);
     // Initialize ImageLayer
     layer = aManager->CreateImageLayer();
   }
 
+#if 0
   nsCOMPtr<nsIPluginInstance> pi;
   mInstanceOwner->GetInstance(*getter_AddRefs(pi));
   // Give plugin info about layer paint
   if (pi) {
     if (NS_FAILED(pi->NotifyPainted())) {
       return nsnull;
     }
   }
+#endif
 
   if (!layer)
     return nsnull;
 
   NS_ASSERTION(layer->GetType() == Layer::TYPE_IMAGE, "ObjectFrame works only with ImageLayer");
   // Create image
   nsRefPtr<ImageContainer> container = GetImageContainer();
   if (!container)
@@ -1938,18 +1941,16 @@ nsObjectFrame::PaintPlugin(nsDisplayList
     }
     dirtyGfxRect.RoundOut();
 
     // Look if it's windowless
     NPWindow *window;
     mInstanceOwner->GetWindow(window);
 
     if (window->type == NPWindowTypeDrawable) {
-      // check if we need to call SetWindow with updated parameters
-      PRBool doupdatewindow = PR_FALSE;
       // the offset of the DC
       nsPoint origin;
 
       gfxWindowsNativeDrawing nativeDraw(ctx, frameGfxRect);
 #ifdef MOZ_IPC
       if (nativeDraw.IsDoublePass()) {
         // OOP plugin specific: let the shim know before we paint if we are doing a
         // double pass render. If this plugin isn't oop, the register window message
@@ -1974,16 +1975,21 @@ nsObjectFrame::PaintPlugin(nsDisplayList
 
         // XXX how can we be sure that window->window doesn't point to
         // a dead DC and hdc has been reallocated at the same address?
         if (reinterpret_cast<HDC>(window->window) != hdc ||
             window->x != dest.left || window->y != dest.top) {
           window->window = hdc;
           window->x = dest.left;
           window->y = dest.top;
+          window->clipRect.left = 0;
+          window->clipRect.top = 0;
+          // if we're painting, we're visible.
+          window->clipRect.right = window->width;
+          window->clipRect.bottom = window->height;
 
           // Windowless plugins on windows need a special event to update their location,
           // see bug 135737.
           //
           // bug 271442: note, the rectangle we send is now purely the bounds of the plugin
           // relative to the window it is contained in, which is useful for the plugin to
           // correctly translate mouse coordinates.
           //
@@ -1996,19 +2002,17 @@ nsObjectFrame::PaintPlugin(nsDisplayList
           // the originator of bug 135737), it seems that windowless plugins are not relying
           // on information here for clipping their drawing, and we can safely use this message
           // to tell the plugin exactly where it is in all cases.
 
           nsIntPoint origin = GetWindowOriginInPixels(PR_TRUE);
           nsIntRect winlessRect = nsIntRect(origin, nsIntSize(window->width, window->height));
           // XXX I don't think we can be certain that the location wrt to
           // the window only changes when the location wrt to the drawable
-          // changes, but the hdc probably changes on every paint so
-          // doupdatewindow is rarely false, and there is not likely to be
-          // a problem.
+          // changes, but the hdc probably changes on every paint.
           if (mWindowlessRect != winlessRect) {
             mWindowlessRect = winlessRect;
 
             WINDOWPOS winpos;
             memset(&winpos, 0, sizeof(winpos));
             winpos.x = mWindowlessRect.x;
             winpos.y = mWindowlessRect.y;
             winpos.cx = mWindowlessRect.width;
@@ -6453,17 +6457,17 @@ void* nsPluginInstanceOwner::FixUpPlugin
 void nsPluginInstanceOwner::UpdateWindowClipRect(PRBool aSetWindow)
 {
   if (!mPluginWindow)
     return;
 
   // For windowless plugins a non-empty clip rectangle will be
   // passed to the plugin during paint, an additional update
   // of the the clip rectangle here is not required
-  if (aSetWindow && !mWidget && mPluginWindowVisible)
+  if (aSetWindow && !mWidget && mPluginWindowVisible && !UseLayers())
     return;
 
   const NPRect oldClipRect = mPluginWindow->clipRect;
 
   mPluginWindow->clipRect.left = 0;
   mPluginWindow->clipRect.top = 0;
 
   if (mPluginWindowVisible) {
--- a/modules/plugin/base/src/PluginPRLibrary.cpp
+++ b/modules/plugin/base/src/PluginPRLibrary.cpp
@@ -190,24 +190,16 @@ nsresult
 PluginPRLibrary::AsyncSetWindow(NPP instance, NPWindow* window)
 {
   nsNPAPIPluginInstance* inst = (nsNPAPIPluginInstance*)instance->ndata;
   NS_ENSURE_TRUE(inst, NS_ERROR_NULL_POINTER);
   return NS_ERROR_NOT_IMPLEMENTED;
 }
 
 nsresult
-PluginPRLibrary::NotifyPainted(NPP instance)
-{
-  nsNPAPIPluginInstance* inst = (nsNPAPIPluginInstance*)instance->ndata;
-  NS_ENSURE_TRUE(inst, NS_ERROR_NULL_POINTER);
-  return NS_ERROR_NOT_IMPLEMENTED;
-}
-
-nsresult
 PluginPRLibrary::GetSurface(NPP instance, gfxASurface** aSurface)
 {
   nsNPAPIPluginInstance* inst = (nsNPAPIPluginInstance*)instance->ndata;
   NS_ENSURE_TRUE(inst, NS_ERROR_NULL_POINTER);
   *aSurface = nsnull;
   return NS_OK;
 }
 
--- a/modules/plugin/base/src/PluginPRLibrary.h
+++ b/modules/plugin/base/src/PluginPRLibrary.h
@@ -129,17 +129,16 @@ public:
 #endif
 
     virtual nsresult NPP_New(NPMIMEType pluginType, NPP instance,
                              uint16_t mode, int16_t argc, char* argn[],
                              char* argv[], NPSavedData* saved,
                              NPError* error);
 
     virtual nsresult AsyncSetWindow(NPP instance, NPWindow* window);
-    virtual nsresult NotifyPainted(NPP instance);
     virtual nsresult GetSurface(NPP instance, gfxASurface** aSurface);
     NS_OVERRIDE virtual bool UseAsyncPainting() { return false; }
 
 private:
     NP_InitializeFunc mNP_Initialize;
     NP_ShutdownFunc mNP_Shutdown;
     NP_GetMIMEDescriptionFunc mNP_GetMIMEDescription;
 #if defined(XP_UNIX) && !defined(XP_MACOSX)
--- a/modules/plugin/base/src/nsNPAPIPluginInstance.cpp
+++ b/modules/plugin/base/src/nsNPAPIPluginInstance.cpp
@@ -850,29 +850,18 @@ nsNPAPIPluginInstance::GetSurface(gfxASu
 
   return library->GetSurface(&mNPP, aSurface);
 }
 
 
 NS_IMETHODIMP
 nsNPAPIPluginInstance::NotifyPainted(void)
 {
-  if (RUNNING != mRunning)
-    return NS_OK;
-
-  PluginDestructionGuard guard(this);
-
-  if (!mPlugin)
-    return NS_ERROR_FAILURE;
-
-  PluginLibrary* library = mPlugin->GetLibrary();
-  if (!library)
-    return NS_ERROR_FAILURE;
-
-  return library->NotifyPainted(&mNPP);
+  NS_NOTREACHED("Dead code, shouldn't be called.");
+  return NS_ERROR_NOT_IMPLEMENTED;
 }
 
 NS_IMETHODIMP
 nsNPAPIPluginInstance::UseAsyncPainting(PRBool* aIsAsync)
 {
   if (!mUsePluginLayersPref) {
     *aIsAsync = mUsePluginLayersPref;
     return NS_OK;