Bug 626602, part 8: Dig a tunnel from nsObjectFrame to PluginInstanceParent for background copying. r=bsmedberg sr=roc

This commit is contained in:
Chris Jones 2011-02-08 18:44:14 -06:00
parent cf6aed5e65
commit 66c0a6b21b
10 changed files with 230 additions and 26 deletions

View File

@ -277,6 +277,11 @@ public:
nsresult AsyncSetWindow(NPWindow* window);
nsresult GetSurface(gfxASurface** aSurface);
nsresult SetBackgroundUnknown() { return NS_OK; }
nsresult BeginUpdateBackground(const nsIntRect& aRect,
gfxContext** aCtx) { return NS_OK; }
nsresult EndUpdateBackground(gfxContext* aCtx,
const nsIntRect& aRect) { return NS_OK; }
private:
// Quirks mode support for various plugin mime types

View File

@ -46,9 +46,11 @@
#include "nsTArray.h"
#include "nsPluginError.h"
class nsNPAPIPlugin;
class gfxASurface;
class gfxContext;
class nsCString;
struct nsIntRect;
class nsNPAPIPlugin;
namespace mozilla {
@ -89,6 +91,16 @@ public:
virtual nsresult AsyncSetWindow(NPP instance, NPWindow* window) = 0;
virtual nsresult GetSurface(NPP instance, gfxASurface** aSurface) = 0;
virtual bool UseAsyncPainting() = 0;
/**
* The next three methods are the third leg in the trip to
* PluginInstanceParent. They approximately follow the ReadbackSink
* API.
*/
virtual nsresult SetBackgroundUnknown(NPP instance) = 0;
virtual nsresult BeginUpdateBackground(NPP instance,
const nsIntRect&, gfxContext**) = 0;
virtual nsresult EndUpdateBackground(NPP instance,
gfxContext*, const nsIntRect&) = 0;
};

View File

@ -682,6 +682,40 @@ PluginModuleParent::GetSurface(NPP instance, gfxASurface** aSurface)
return i->GetSurface(aSurface);
}
nsresult
PluginModuleParent::SetBackgroundUnknown(NPP instance)
{
PluginInstanceParent* i = InstCast(instance);
if (!i)
return NS_ERROR_FAILURE;
return i->SetBackgroundUnknown();
}
nsresult
PluginModuleParent::BeginUpdateBackground(NPP instance,
const nsIntRect& aRect,
gfxContext** aCtx)
{
PluginInstanceParent* i = InstCast(instance);
if (!i)
return NS_ERROR_FAILURE;
return i->BeginUpdateBackground(aRect, aCtx);
}
nsresult
PluginModuleParent::EndUpdateBackground(NPP instance,
gfxContext* aCtx,
const nsIntRect& aRect)
{
PluginInstanceParent* i = InstCast(instance);
if (!i)
return NS_ERROR_FAILURE;
return i->EndUpdateBackground(aCtx, aRect);
}
#if defined(XP_UNIX) && !defined(XP_MACOSX)
nsresult
PluginModuleParent::NP_Initialize(NPNetscapeFuncs* bFuncs, NPPluginFuncs* pFuncs, NPError* error)

View File

@ -232,6 +232,16 @@ private:
virtual nsresult AsyncSetWindow(NPP instance, NPWindow* window);
virtual nsresult GetSurface(NPP instance, gfxASurface** aSurface);
NS_OVERRIDE virtual bool UseAsyncPainting() { return true; }
NS_OVERRIDE
virtual nsresult SetBackgroundUnknown(NPP instance);
NS_OVERRIDE
virtual nsresult BeginUpdateBackground(NPP instance,
const nsIntRect& aRect,
gfxContext** aCtx);
NS_OVERRIDE
virtual nsresult EndUpdateBackground(NPP instance,
gfxContext* aCtx,
const nsIntRect& aRect);
#if defined(XP_UNIX) && !defined(XP_MACOSX)
virtual nsresult NP_Initialize(NPNetscapeFuncs* bFuncs, NPPluginFuncs* pFuncs, NPError* error);

View File

@ -467,10 +467,12 @@ public:
// Return true if we set image with valid surface
PRBool SetCurrentImage(ImageContainer* aContainer);
// Methods to update the background image we send to async plugins
void SetBackgroundUnknown() {}
already_AddRefed<gfxContext> BeginUpdateBackground(const nsIntRect& aRect) { return nsnull; }
void EndUpdateBackground(gfxContext* aContext, const nsIntRect& aRect) {}
// Methods to update the background image we send to async plugins.
// The eventual target of these operations is PluginInstanceParent,
// but it takes several hops to get there.
void SetBackgroundUnknown();
already_AddRefed<gfxContext> BeginUpdateBackground(const nsIntRect& aRect);
void EndUpdateBackground(gfxContext* aContext, const nsIntRect& aRect);
PRBool UseLayers()
{
@ -493,6 +495,13 @@ private:
mPluginWindow->height);
}
already_AddRefed<nsIPluginInstance_MOZILLA_2_0_BRANCH>
GetInstance()
{
nsCOMPtr<nsIPluginInstance_MOZILLA_2_0_BRANCH> inst = do_QueryInterface(mInstance);
return inst.forget();
}
void FixUpURLS(const nsString &name, nsAString &value);
nsPluginNativeWindow *mPluginWindow;
@ -1937,6 +1946,39 @@ nsPluginInstanceOwner::SetCurrentImage(ImageContainer* aContainer)
return PR_TRUE;
}
void
nsPluginInstanceOwner::SetBackgroundUnknown()
{
nsCOMPtr<nsIPluginInstance_MOZILLA_2_0_BRANCH> inst = GetInstance();
if (inst) {
inst->SetBackgroundUnknown();
}
}
already_AddRefed<gfxContext>
nsPluginInstanceOwner::BeginUpdateBackground(const nsIntRect& aRect)
{
nsIntRect rect = aRect;
nsCOMPtr<nsIPluginInstance_MOZILLA_2_0_BRANCH> inst = GetInstance();
nsRefPtr<gfxContext> ctx;
if (inst &&
NS_SUCCEEDED(inst->BeginUpdateBackground(&rect, getter_AddRefs(ctx)))) {
return ctx.forget();
}
return nsnull;
}
void
nsPluginInstanceOwner::EndUpdateBackground(gfxContext* aContext,
const nsIntRect& aRect)
{
nsIntRect rect = aRect;
nsCOMPtr<nsIPluginInstance_MOZILLA_2_0_BRANCH> inst = GetInstance();
if (inst) {
inst->EndUpdateBackground(aContext, &rect);
}
}
LayerState
nsObjectFrame::GetLayerState(nsDisplayListBuilder* aBuilder)
{

View File

@ -48,6 +48,8 @@ interface nsIOutputStream;
struct JSContext;
struct JSObject;
class gfxASurface;
class gfxContext;
struct nsIntRect;
#define NPRUNTIME_JSCLASS_NAME "NPObject JS wrapper class"
%}
@ -55,6 +57,8 @@ class gfxASurface;
[ptr] native JSContextPtr(JSContext);
[ptr] native JSObjectPtr(JSObject);
[ptr] native gfxASurfacePtr(gfxASurface);
[ptr] native gfxContextPtr(gfxContext);
[ptr] native nsIntRectPtr(nsIntRect);
[uuid(84994340-E120-4051-824F-D4EE8AEF1A3E)]
interface nsIPluginInstance : nsISupports
@ -247,3 +251,18 @@ interface nsIPluginInstance : nsISupports
*/
PRBool useAsyncPainting();
};
// XXX kill me after branching
[noscript, uuid(324f3c02-4fbd-430b-8afa-db083d3867fc)]
interface nsIPluginInstance_MOZILLA_2_0_BRANCH : nsIPluginInstance
{
/**
* This is the second leg in the trip to PluginInstanceParent. It
* approximately follows the ReadbackSink API.
*/
void setBackgroundUnknown();
void beginUpdateBackground(in nsIntRectPtr rect, out gfxContextPtr ctx);
void endUpdateBackground(in gfxContextPtr ctx, in nsIntRectPtr rect);
};

View File

@ -255,4 +255,32 @@ PluginPRLibrary::GetSurface(NPP instance, gfxASurface** aSurface)
return NS_OK;
}
nsresult
PluginPRLibrary::SetBackgroundUnknown(NPP instance)
{
nsNPAPIPluginInstance* inst = (nsNPAPIPluginInstance*)instance->ndata;
NS_ENSURE_TRUE(inst, NS_ERROR_NULL_POINTER);
NS_ERROR("Unexpected use of async APIs for in-process plugin.");
return NS_ERROR_NOT_IMPLEMENTED;
}
nsresult
PluginPRLibrary::BeginUpdateBackground(NPP instance,
const nsIntRect&, gfxContext** aCtx)
{
nsNPAPIPluginInstance* inst = (nsNPAPIPluginInstance*)instance->ndata;
NS_ENSURE_TRUE(inst, NS_ERROR_NULL_POINTER);
NS_ERROR("Unexpected use of async APIs for in-process plugin.");
*aCtx = nsnull;
return NS_OK;
}
nsresult
PluginPRLibrary::EndUpdateBackground(NPP instance,
gfxContext*, const nsIntRect&)
{
NS_RUNTIMEABORT("This should never be called");
return NS_ERROR_NOT_AVAILABLE;
}
} // namespace mozilla

View File

@ -142,6 +142,14 @@ public:
virtual nsresult AsyncSetWindow(NPP instance, NPWindow* window);
virtual nsresult GetSurface(NPP instance, gfxASurface** aSurface);
NS_OVERRIDE virtual bool UseAsyncPainting() { return false; }
NS_OVERRIDE
virtual nsresult SetBackgroundUnknown(NPP instance);
NS_OVERRIDE
virtual nsresult BeginUpdateBackground(NPP instance,
const nsIntRect&, gfxContext** aCtx);
NS_OVERRIDE
virtual nsresult EndUpdateBackground(NPP instance,
gfxContext* aCtx, const nsIntRect&);
private:
NP_InitializeFunc mNP_Initialize;

View File

@ -59,13 +59,13 @@
#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);
NS_IMPL_ISUPPORTS1(nsNPAPIPluginInstance, nsIPluginInstance)
NS_IMPL_ISUPPORTS2(nsNPAPIPluginInstance, nsIPluginInstance, nsIPluginInstance_MOZILLA_2_0_BRANCH)
nsNPAPIPluginInstance::nsNPAPIPluginInstance(nsNPAPIPlugin* plugin)
:
@ -809,18 +809,32 @@ 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)
{
if (RUNNING != mRunning)
return NS_OK;
PluginDestructionGuard guard(this);
if (!mPlugin)
return NS_ERROR_FAILURE;
PluginLibrary* library = mPlugin->GetLibrary();
AutoPluginLibraryCall library(this);
if (!library)
return NS_ERROR_FAILURE;
@ -833,12 +847,7 @@ nsNPAPIPluginInstance::GetSurface(gfxASurface** aSurface)
if (RUNNING != mRunning)
return NS_OK;
PluginDestructionGuard guard(this);
if (!mPlugin)
return NS_ERROR_FAILURE;
PluginLibrary* library = mPlugin->GetLibrary();
AutoPluginLibraryCall library(this);
if (!library)
return NS_ERROR_FAILURE;
@ -861,12 +870,7 @@ nsNPAPIPluginInstance::UseAsyncPainting(PRBool* aIsAsync)
return NS_OK;
}
PluginDestructionGuard guard(this);
if (!mPlugin)
return NS_ERROR_FAILURE;
PluginLibrary* library = mPlugin->GetLibrary();
AutoPluginLibraryCall library(this);
if (!library)
return NS_ERROR_FAILURE;
@ -874,6 +878,47 @@ nsNPAPIPluginInstance::UseAsyncPainting(PRBool* aIsAsync)
return NS_OK;
}
NS_IMETHODIMP
nsNPAPIPluginInstance::SetBackgroundUnknown()
{
if (RUNNING != mRunning)
return NS_OK;
AutoPluginLibraryCall library(this);
if (!library)
return NS_ERROR_FAILURE;
return library->SetBackgroundUnknown(&mNPP);
}
NS_IMETHODIMP
nsNPAPIPluginInstance::BeginUpdateBackground(nsIntRect* aRect,
gfxContext** aContext)
{
if (RUNNING != mRunning)
return NS_OK;
AutoPluginLibraryCall library(this);
if (!library)
return NS_ERROR_FAILURE;
return library->BeginUpdateBackground(&mNPP, *aRect, aContext);
}
NS_IMETHODIMP
nsNPAPIPluginInstance::EndUpdateBackground(gfxContext* aContext,
nsIntRect* aRect)
{
if (RUNNING != mRunning)
return NS_OK;
AutoPluginLibraryCall library(this);
if (!library)
return NS_ERROR_FAILURE;
return library->EndUpdateBackground(&mNPP, aContext, *aRect);
}
NS_IMETHODIMP
nsNPAPIPluginInstance::IsTransparent(PRBool* isTransparent)
{

View File

@ -67,7 +67,7 @@ public:
void (*callback)(NPP npp, uint32_t timerID);
};
class nsNPAPIPluginInstance : public nsIPluginInstance
class nsNPAPIPluginInstance : public nsIPluginInstance_MOZILLA_2_0_BRANCH
{
private:
typedef mozilla::PluginLibrary PluginLibrary;
@ -75,6 +75,7 @@ private:
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIPLUGININSTANCE
NS_DECL_NSIPLUGININSTANCE_MOZILLA_2_0_BRANCH
nsNPAPIPlugin* GetPlugin();