Bug 591687: Add GetImage in order to create mac async plugin images in plugin code instead of nsObjectFrame. r=bsmedberg a=blocking2.0betaN+

This commit is contained in:
Matt Woodrow 2011-02-12 11:07:10 -05:00
parent c7b2e69359
commit b50efb2dc1
10 changed files with 131 additions and 33 deletions

View File

@ -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;
image = aContainer->CreateImage(&format, 1);
if (!image) {
return NS_ERROR_FAILURE;
}
NS_ASSERTION(image->GetFormat() == Image::CAIRO_SURFACE, "Wrong format?");
CairoImage* pluginImage = static_cast<CairoImage*>(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)

View File

@ -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

View File

@ -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;

View File

@ -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)

View File

@ -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)

View File

@ -476,13 +476,29 @@ public:
}
private:
// return FALSE if LayerSurface dirty (newly created and don't have valid plugin content yet)
PRBool IsUpToDate()
{
nsRefPtr<gfxASurface> readyToUse;
return NS_SUCCEEDED(mInstance->GetSurface(getter_AddRefs(readyToUse))) &&
readyToUse && readyToUse->GetSize() == gfxIntSize(mPluginWindow->width,
mPluginWindow->height);
nsRefPtr<ImageContainer> container = mObjectFrame->GetImageContainer();
if (!container) {
return PR_FALSE;
}
nsCOMPtr<nsIPluginInstance_MOZILLA_2_0_BRANCH> inst = do_QueryInterface(mInstance);
if (!inst) {
return PR_FALSE;
}
nsRefPtr<Image> 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<gfxASurface> 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<nsIPluginInstance_MOZILLA_2_0_BRANCH> inst = do_QueryInterface(mInstance);
if (inst) {
nsRefPtr<Image> image;
inst->GetImage(aContainer, getter_AddRefs(image));
if (image) {
aContainer->SetCurrentImage(image);
return PR_TRUE;
}
}
Image::Format format = Image::CAIRO_SURFACE;
nsRefPtr<Image> image;
image = aContainer->CreateImage(&format, 1);
if (!image)
return PR_FALSE;
NS_ASSERTION(image->GetFormat() == Image::CAIRO_SURFACE, "Wrong format?");
CairoImage* pluginImage = static_cast<CairoImage*>(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<ImageContainer> container = mObjectFrame->GetImageContainer();
if (container) {
container->SetCurrentImage(nsnull);
}
mLayerSurface = nsnull;
nsRefPtr<ImageContainer> container = mObjectFrame->GetImageContainer();
if (container) {
container->SetCurrentImage(nsnull);
}
#if defined(XP_WIN) || defined(MOZ_X11)

View File

@ -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);
};

View File

@ -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)

View File

@ -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);

View File

@ -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)