b=797568 update the ImageContainer in RecvShow instead of GetImageContainer, for CAIRO images r=roc
authorKarl Tomlinson <karlt+@karlt.net>
Wed, 31 Oct 2012 15:54:06 +1300
changeset 111996 2886e8e67bfdb76c617ae4ecf62c8ed7ad80fa7d
parent 111995 d7e77004a0d0dd5bd14c23ececf49c60c1231888
child 111997 541b971b847b323dfdd8b3995c5945dd296d68be
push id93
push usernmatsakis@mozilla.com
push dateWed, 31 Oct 2012 21:26:57 +0000
reviewersroc
bugs797568
milestone19.0a1
b=797568 update the ImageContainer in RecvShow instead of GetImageContainer, for CAIRO images r=roc
dom/plugins/base/nsPluginInstanceOwner.cpp
dom/plugins/ipc/PluginInstanceParent.cpp
--- a/dom/plugins/base/nsPluginInstanceOwner.cpp
+++ b/dom/plugins/base/nsPluginInstanceOwner.cpp
@@ -200,24 +200,24 @@ nsPluginInstanceOwner::GetImageContainer
   float xResolution = mObjectFrame->PresContext()->GetRootPresContext()->PresShell()->GetXResolution();
   float yResolution = mObjectFrame->PresContext()->GetRootPresContext()->PresShell()->GetYResolution();
   r.Scale(xResolution, yResolution);
   mInstance->NotifySize(nsIntSize(r.width, r.height));
 
   return container.forget();
 #endif
 
-  // Every call to nsIPluginInstance::GetImage() creates
-  // a new image.  See nsIPluginInstance.idl.
   mInstance->GetImageContainer(getter_AddRefs(container));
   if (container) {
 #ifdef XP_MACOSX
     AutoLockImage autoLock(container);
     Image* image = autoLock.GetImage();
     if (image && image->GetFormat() == MAC_IO_SURFACE && mObjectFrame) {
+      // With this drawing model, every call to
+      // nsIPluginInstance::GetImage() creates a new image.
       MacIOSurfaceImage *oglImage = static_cast<MacIOSurfaceImage*>(image);
       NS_ADDREF_THIS();
       oglImage->SetUpdateCallback(&DrawPlugin, this);
       oglImage->SetDestroyCallback(&OnDestroyImage);
     }
 #endif
     return container.forget();
   }
@@ -632,21 +632,24 @@ NS_IMETHODIMP nsPluginInstanceOwner::Inv
     nsCOMPtr<nsIRunnable> event = new AsyncPaintWaitEvent(mContent, true);
     NS_DispatchToMainThread(event);
     mWaitingForPaint = false;
   }
 
   if (!mObjectFrame || !invalidRect || !mWidgetVisible)
     return NS_ERROR_FAILURE;
 
+#if defined(XP_MACOSX) || defined(MOZ_WIDGET_ANDROID)
   // Each time an asynchronously-drawing plugin sends a new surface to display,
-  // InvalidateRect is called. We notify reftests that painting is up to
-  // date and update our ImageContainer with the new surface.
+  // the image in the ImageContainer is updated and InvalidateRect is called.
+  // MacIOSurfaceImages callbacks are attached here.
+  // There are different side effects for (sync) Android plugins.
   nsRefPtr<ImageContainer> container;
   mInstance->GetImageContainer(getter_AddRefs(container));
+#endif
 
 #ifndef XP_MACOSX
   // Windowed plugins should not be calling NPN_InvalidateRect, but
   // Silverlight does and expects it to "work"
   if (mWidget) {
     mWidget->Invalidate(nsIntRect(invalidRect->left, invalidRect->top,
                                   invalidRect->right - invalidRect->left,
                                   invalidRect->bottom - invalidRect->top));
--- a/dom/plugins/ipc/PluginInstanceParent.cpp
+++ b/dom/plugins/ipc/PluginInstanceParent.cpp
@@ -117,24 +117,23 @@ PluginInstanceParent::ActorDestroy(Actor
     if (why == AbnormalShutdown) {
         // If the plugin process crashes, this is the only
         // chance we get to destroy resources.
         SharedSurfaceRelease();
         UnsubclassPluginWindow();
     }
 #endif
     // After this method, the data backing the remote surface may no
-    // longer be calid. The X surface may be destroyed, or the shared
-    // memory backing this surface may no longer be valid. The right
-    // way to inform the nsObjectFrame that the surface is no longer
-    // valid is with an invalidate call.
+    // longer be valid. The X surface may be destroyed, or the shared
+    // memory backing this surface may no longer be valid.
     if (mFrontSurface) {
         mFrontSurface = NULL;
-        const NPRect rect = {0, 0, 0, 0};
-        RecvNPN_InvalidateRect(rect);
+        if (mImageContainer) {
+            mImageContainer->SetCurrentImage(nullptr);
+        }
 #ifdef MOZ_X11
         FinishX(DefaultXDisplay());
 #endif
     }
 }
 
 NPError
 PluginInstanceParent::Destroy()
@@ -618,26 +617,34 @@ PluginInstanceParent::RecvShow(const NPR
 
     if (surface) {
         // Notify the cairo backend that this surface has changed behind
         // its back.
         gfxRect ur(updatedRect.left, updatedRect.top,
                    updatedRect.right - updatedRect.left,
                    updatedRect.bottom - updatedRect.top);
         surface->MarkDirty(ur);
-        surface->Flush();
+
+        ImageContainer *container = GetImageContainer();
+        ImageFormat format = CAIRO_SURFACE;
+        nsRefPtr<Image> image = container->CreateImage(&format, 1);
+        NS_ASSERTION(image->GetFormat() == CAIRO_SURFACE, "Wrong format?");
+        CairoImage* cairoImage = static_cast<CairoImage*>(image.get());
+        CairoImage::Data cairoData;
+        cairoData.mSurface = surface;
+        cairoData.mSize = surface->GetSize();
+        cairoImage->SetData(cairoData);
+
+        container->SetCurrentImage(cairoImage);
+    }
+    else if (mImageContainer) {
+        mImageContainer->SetCurrentImage(nullptr);
     }
 
     mFrontSurface = surface;
-    if (!surface) {
-      ImageContainer* container = GetImageContainer();
-      if (container) {
-        container->SetCurrentImage(nullptr);
-      }
-    }
     RecvNPN_InvalidateRect(updatedRect);
 
     PLUGIN_LOG_DEBUG(("   (RecvShow invalidated for surface %p)",
                       mFrontSurface.get()));
 
     return true;
 }
 
@@ -703,65 +710,49 @@ PluginInstanceParent::GetImageContainer(
     }
 
     if (!mFrontSurface && !ioSurface)
 #else
     if (!mFrontSurface)
 #endif
         return NS_ERROR_NOT_AVAILABLE;
 
-    ImageFormat format = CAIRO_SURFACE;
-#ifdef XP_MACOSX
-    if (ioSurface) {
-        format = MAC_IO_SURFACE;
-    }
-#endif
-
     ImageContainer *container = GetImageContainer();
 
     if (!container) {
         return NS_ERROR_FAILURE;
     }
 
     if (IsAsyncDrawing()) {
       NS_IF_ADDREF(container);
       *aContainer = container;
       return NS_OK;
     }
 
-    nsRefPtr<Image> image;
-    image = container->CreateImage(&format, 1);
-    if (!image) {
-        return NS_ERROR_FAILURE;
-    }
-
 #ifdef XP_MACOSX
     if (ioSurface) {
+        ImageFormat format = MAC_IO_SURFACE;
+        nsRefPtr<Image> image = container->CreateImage(&format, 1);
+        if (!image) {
+            return NS_ERROR_FAILURE;
+        }
+
         NS_ASSERTION(image->GetFormat() == MAC_IO_SURFACE, "Wrong format?");
         MacIOSurfaceImage* ioImage = static_cast<MacIOSurfaceImage*>(image.get());
         MacIOSurfaceImage::Data ioData;
         ioData.mIOSurface = ioSurface;
         ioImage->SetData(ioData);
         container->SetCurrentImageInTransaction(ioImage);
 
         NS_IF_ADDREF(container);
         *aContainer = container;
         return NS_OK;
     }
 #endif
 
-    NS_ASSERTION(image->GetFormat() == CAIRO_SURFACE, "Wrong format?");
-    CairoImage* pluginImage = static_cast<CairoImage*>(image.get());
-    CairoImage::Data cairoData;
-    cairoData.mSurface = mFrontSurface;
-    cairoData.mSize = mFrontSurface->GetSize();
-    pluginImage->SetData(cairoData);
-
-    container->SetCurrentImageInTransaction(pluginImage);
-
     NS_IF_ADDREF(container);
     *aContainer = container;
     return NS_OK;
 }
 
 nsresult
 PluginInstanceParent::GetImageSize(nsIntSize* aSize)
 {