From 1254f912533690e8ae6eaf226487b4c21698ef12 Mon Sep 17 00:00:00 2001 From: Matt Woodrow Date: Sat, 12 Feb 2011 11:07:10 -0500 Subject: [PATCH] Bug 591687: Add GetImage in order to create mac async plugin images in plugin code instead of nsObjectFrame. r=bsmedberg a=blocking2.0betaN+ --- dom/plugins/PluginInstanceParent.cpp | 25 ++++++++ dom/plugins/PluginInstanceParent.h | 2 + dom/plugins/PluginLibrary.h | 10 +++ dom/plugins/PluginModuleParent.cpp | 9 +++ dom/plugins/PluginModuleParent.h | 1 + layout/generic/nsObjectFrame.cpp | 64 ++++++++++--------- .../plugin/base/public/nsIPluginInstance.idl | 13 +++- modules/plugin/base/src/PluginPRLibrary.cpp | 9 +++ modules/plugin/base/src/PluginPRLibrary.h | 1 + .../plugin/base/src/nsNPAPIPluginInstance.cpp | 30 ++++++++- 10 files changed, 131 insertions(+), 33 deletions(-) diff --git a/dom/plugins/PluginInstanceParent.cpp b/dom/plugins/PluginInstanceParent.cpp index 659eb5bd850..2312d258633 100644 --- a/dom/plugins/PluginInstanceParent.cpp +++ b/dom/plugins/PluginInstanceParent.cpp @@ -572,6 +572,31 @@ PluginInstanceParent::GetSurface(gfxASurface** aSurface) return NS_ERROR_NOT_AVAILABLE; } +nsresult +PluginInstanceParent::GetImage(ImageContainer* aContainer, Image** aImage) +{ + if (!mFrontSurface) + return NS_ERROR_NOT_AVAILABLE; + + Image::Format format = Image::CAIRO_SURFACE; + + nsRefPtr image; + image = aContainer->CreateImage(&format, 1); + if (!image) { + return NS_ERROR_FAILURE; + } + + NS_ASSERTION(image->GetFormat() == Image::CAIRO_SURFACE, "Wrong format?"); + CairoImage* pluginImage = static_cast(image.get()); + CairoImage::Data cairoData; + cairoData.mSurface = mFrontSurface; + cairoData.mSize = mFrontSurface->GetSize(); + pluginImage->SetData(cairoData); + + *aImage = image.forget().get(); + return NS_OK; +} + #ifdef XP_MACOSX nsresult PluginInstanceParent::IsRemoteDrawingCoreAnimation(PRBool *aDrawing) diff --git a/dom/plugins/PluginInstanceParent.h b/dom/plugins/PluginInstanceParent.h index c126c20dd9f..9d16de89b38 100644 --- a/dom/plugins/PluginInstanceParent.h +++ b/dom/plugins/PluginInstanceParent.h @@ -53,6 +53,7 @@ #include "nsHashKeys.h" #include "nsRect.h" #include "gfxASurface.h" +#include "ImageLayers.h" #ifdef MOZ_X11 class gfxXlibSurface; #endif @@ -277,6 +278,7 @@ public: nsresult AsyncSetWindow(NPWindow* window); nsresult GetSurface(gfxASurface** aSurface); + nsresult GetImage(mozilla::layers::ImageContainer* aContainer, mozilla::layers::Image** aImage); #ifdef XP_MACOSX nsresult IsRemoteDrawingCoreAnimation(PRBool *aDrawing); #endif diff --git a/dom/plugins/PluginLibrary.h b/dom/plugins/PluginLibrary.h index 8711c299c8a..b55f40fe427 100644 --- a/dom/plugins/PluginLibrary.h +++ b/dom/plugins/PluginLibrary.h @@ -50,6 +50,15 @@ class nsNPAPIPlugin; class gfxASurface; class nsCString; +namespace mozilla { +namespace layers { +class Image; +class ImageContainer; +} +} + +using namespace mozilla::layers; + namespace mozilla { class PluginLibrary @@ -88,6 +97,7 @@ public: virtual nsresult AsyncSetWindow(NPP instance, NPWindow* window) = 0; virtual nsresult GetSurface(NPP instance, gfxASurface** aSurface) = 0; + virtual nsresult GetImage(NPP instance, ImageContainer* aContainer, Image** aImage) = 0; virtual bool UseAsyncPainting() = 0; #if defined(XP_MACOSX) virtual nsresult IsRemoteDrawingCoreAnimation(NPP instance, PRBool *aDrawing) = 0; diff --git a/dom/plugins/PluginModuleParent.cpp b/dom/plugins/PluginModuleParent.cpp index cda1a4b0c46..97c599e8adb 100644 --- a/dom/plugins/PluginModuleParent.cpp +++ b/dom/plugins/PluginModuleParent.cpp @@ -682,6 +682,15 @@ PluginModuleParent::GetSurface(NPP instance, gfxASurface** aSurface) return i->GetSurface(aSurface); } +nsresult +PluginModuleParent::GetImage(NPP instance, + mozilla::layers::ImageContainer* aContainer, + mozilla::layers::Image** aImage) +{ + PluginInstanceParent* i = InstCast(instance); + return !i ? NS_ERROR_FAILURE : i->GetImage(aContainer, aImage); +} + #if defined(XP_UNIX) && !defined(XP_MACOSX) nsresult PluginModuleParent::NP_Initialize(NPNetscapeFuncs* bFuncs, NPPluginFuncs* pFuncs, NPError* error) diff --git a/dom/plugins/PluginModuleParent.h b/dom/plugins/PluginModuleParent.h index a259fc900f8..f583782d03a 100644 --- a/dom/plugins/PluginModuleParent.h +++ b/dom/plugins/PluginModuleParent.h @@ -231,6 +231,7 @@ private: virtual bool HasRequiredFunctions(); virtual nsresult AsyncSetWindow(NPP instance, NPWindow* window); virtual nsresult GetSurface(NPP instance, gfxASurface** aSurface); + virtual nsresult GetImage(NPP instance, mozilla::layers::ImageContainer* aContainer, mozilla::layers::Image** aImage); NS_OVERRIDE virtual bool UseAsyncPainting() { return true; } #if defined(XP_UNIX) && !defined(XP_MACOSX) diff --git a/layout/generic/nsObjectFrame.cpp b/layout/generic/nsObjectFrame.cpp index cb2a1ed53cd..40876908979 100644 --- a/layout/generic/nsObjectFrame.cpp +++ b/layout/generic/nsObjectFrame.cpp @@ -476,13 +476,29 @@ public: } private: + // return FALSE if LayerSurface dirty (newly created and don't have valid plugin content yet) PRBool IsUpToDate() { - nsRefPtr readyToUse; - return NS_SUCCEEDED(mInstance->GetSurface(getter_AddRefs(readyToUse))) && - readyToUse && readyToUse->GetSize() == gfxIntSize(mPluginWindow->width, - mPluginWindow->height); + nsRefPtr container = mObjectFrame->GetImageContainer(); + if (!container) { + return PR_FALSE; + } + + nsCOMPtr inst = do_QueryInterface(mInstance); + if (!inst) { + return PR_FALSE; + } + + nsRefPtr image; + if (!NS_SUCCEEDED(inst->GetImage(container, getter_AddRefs(image))) || !image) + return PR_FALSE; + + container->SetCurrentImage(image); + + if (container->GetCurrentSize() != gfxIntSize(mPluginWindow->width, mPluginWindow->height)) + return PR_FALSE; + return PR_TRUE; } void FixUpURLS(const nsString &name, nsAString &value); @@ -603,7 +619,6 @@ private: #endif - nsRefPtr mLayerSurface; PRPackedBool mWaitingForPaint; }; @@ -1785,27 +1800,17 @@ nsPluginInstanceOwner::NotifyPaintWaiter(nsDisplayListBuilder* aBuilder) PRBool nsPluginInstanceOwner::SetCurrentImage(ImageContainer* aContainer) { - mInstance->GetSurface(getter_AddRefs(mLayerSurface)); - if (!mLayerSurface) { - aContainer->SetCurrentImage(nsnull); - return PR_FALSE; + nsCOMPtr inst = do_QueryInterface(mInstance); + if (inst) { + nsRefPtr image; + inst->GetImage(aContainer, getter_AddRefs(image)); + if (image) { + aContainer->SetCurrentImage(image); + return PR_TRUE; + } } - - Image::Format format = Image::CAIRO_SURFACE; - nsRefPtr image; - image = aContainer->CreateImage(&format, 1); - if (!image) - return PR_FALSE; - - NS_ASSERTION(image->GetFormat() == Image::CAIRO_SURFACE, "Wrong format?"); - CairoImage* pluginImage = static_cast(image.get()); - CairoImage::Data cairoData; - cairoData.mSurface = mLayerSurface.get(); - cairoData.mSize = mLayerSurface->GetSize(); - pluginImage->SetData(cairoData); - aContainer->SetCurrentImage(image); - - return PR_TRUE; + aContainer->SetCurrentImage(nsnull); + return PR_FALSE; } mozilla::LayerState @@ -5465,12 +5470,9 @@ void nsPluginInstanceOwner::PrepareToStop(PRBool aDelayedStop) { // Drop image reference because the child may destroy the surface after we return. - if (mLayerSurface) { - nsRefPtr container = mObjectFrame->GetImageContainer(); - if (container) { - container->SetCurrentImage(nsnull); - } - mLayerSurface = nsnull; + nsRefPtr container = mObjectFrame->GetImageContainer(); + if (container) { + container->SetCurrentImage(nsnull); } #if defined(XP_WIN) || defined(MOZ_X11) diff --git a/modules/plugin/base/public/nsIPluginInstance.idl b/modules/plugin/base/public/nsIPluginInstance.idl index b31830c3200..d75140ca277 100644 --- a/modules/plugin/base/public/nsIPluginInstance.idl +++ b/modules/plugin/base/public/nsIPluginInstance.idl @@ -45,16 +45,26 @@ interface nsIOutputStream; #include "npapi.h" #include "nsStringGlue.h" #include "gfxASurface.h" +#include "ImageLayers.h" struct JSContext; struct JSObject; class gfxASurface; +namespace mozilla { +namespace layers { +class Image; +class ImageContainer; +} +} + #define NPRUNTIME_JSCLASS_NAME "NPObject JS wrapper class" %} [ptr] native JSContextPtr(JSContext); [ptr] native JSObjectPtr(JSObject); [ptr] native gfxASurfacePtr(gfxASurface); +[ptr] native ImagePtr(mozilla::layers::Image); +[ptr] native ImageContainerPtr(mozilla::layers::ImageContainer); [uuid(84994340-E120-4051-824F-D4EE8AEF1A3E)] interface nsIPluginInstance : nsISupports @@ -249,8 +259,9 @@ interface nsIPluginInstance : nsISupports }; // XXX kill me after branching -[noscript, uuid(c4251cb8-dd2f-4885-a008-2d1b4d21fd33)] +[noscript, uuid(2b012762-9a55-458b-929e-7ea094812567)] interface nsIPluginInstance_MOZILLA_2_0_BRANCH : nsIPluginInstance { PRBool isRemoteDrawingCoreAnimation(); + void getImage(in ImageContainerPtr aContainer, out ImagePtr aImage); }; diff --git a/modules/plugin/base/src/PluginPRLibrary.cpp b/modules/plugin/base/src/PluginPRLibrary.cpp index 414f5cbe4bd..bf3c7eb7882 100644 --- a/modules/plugin/base/src/PluginPRLibrary.cpp +++ b/modules/plugin/base/src/PluginPRLibrary.cpp @@ -255,6 +255,15 @@ PluginPRLibrary::GetSurface(NPP instance, gfxASurface** aSurface) return NS_OK; } +nsresult +PluginPRLibrary::GetImage(NPP instance, ImageContainer* aContainer, Image** aImage) +{ + nsNPAPIPluginInstance* inst = (nsNPAPIPluginInstance*)instance->ndata; + NS_ENSURE_TRUE(inst, NS_ERROR_NULL_POINTER); + *aImage = nsnull; + return NS_OK; +} + #if defined(XP_MACOSX) nsresult PluginPRLibrary::IsRemoteDrawingCoreAnimation(NPP instance, PRBool *aDrawing) diff --git a/modules/plugin/base/src/PluginPRLibrary.h b/modules/plugin/base/src/PluginPRLibrary.h index 49761118071..7e010ce955e 100644 --- a/modules/plugin/base/src/PluginPRLibrary.h +++ b/modules/plugin/base/src/PluginPRLibrary.h @@ -141,6 +141,7 @@ public: virtual nsresult AsyncSetWindow(NPP instance, NPWindow* window); virtual nsresult GetSurface(NPP instance, gfxASurface** aSurface); + virtual nsresult GetImage(NPP instance, ImageContainer* aContainer, Image** aImage); NS_OVERRIDE virtual bool UseAsyncPainting() { return false; } #if defined(XP_MACOSX) virtual nsresult IsRemoteDrawingCoreAnimation(NPP instance, PRBool *aDrawing); diff --git a/modules/plugin/base/src/nsNPAPIPluginInstance.cpp b/modules/plugin/base/src/nsNPAPIPluginInstance.cpp index 9e4a241228a..99942f44be3 100644 --- a/modules/plugin/base/src/nsNPAPIPluginInstance.cpp +++ b/modules/plugin/base/src/nsNPAPIPluginInstance.cpp @@ -59,8 +59,8 @@ #include "nsJSNPRuntime.h" #include "nsPluginStreamListenerPeer.h" +using namespace mozilla; using namespace mozilla::plugins::parent; -using mozilla::TimeStamp; static NS_DEFINE_IID(kIOutputStreamIID, NS_IOUTPUTSTREAM_IID); static NS_DEFINE_IID(kIPluginStreamListenerIID, NS_IPLUGINSTREAMLISTENER_IID); @@ -825,6 +825,25 @@ nsNPAPIPluginInstance::IsWindowless(PRBool* isWindowless) return NS_OK; } +class NS_STACK_CLASS AutoPluginLibraryCall +{ +public: + AutoPluginLibraryCall(nsNPAPIPluginInstance* aThis) + : mThis(aThis), mGuard(aThis), mLibrary(nsnull) + { + nsNPAPIPlugin* plugin = mThis->GetPlugin(); + if (plugin) + mLibrary = plugin->GetLibrary(); + } + operator bool() { return !!mLibrary; } + PluginLibrary* operator->() { return mLibrary; } + +private: + nsNPAPIPluginInstance* mThis; + PluginDestructionGuard mGuard; + PluginLibrary* mLibrary; +}; + NS_IMETHODIMP nsNPAPIPluginInstance::AsyncSetWindow(NPWindow* window) { @@ -861,6 +880,15 @@ nsNPAPIPluginInstance::GetSurface(gfxASurface** aSurface) return library->GetSurface(&mNPP, aSurface); } +NS_IMETHODIMP +nsNPAPIPluginInstance::GetImage(ImageContainer* aContainer, Image** aImage) +{ + if (RUNNING != mRunning) + return NS_OK; + + AutoPluginLibraryCall library(this); + return !library ? NS_ERROR_FAILURE : library->GetImage(&mNPP, aContainer, aImage); +} NS_IMETHODIMP nsNPAPIPluginInstance::NotifyPainted(void)