From 3d62e785cc3988d389f22938971d66e22604e30c Mon Sep 17 00:00:00 2001 From: Bas Schouten Date: Thu, 16 Feb 2012 04:30:22 +0100 Subject: [PATCH] Bug 651192 - Part 6: Implement the AsyncBitmapSurface drawing model support. r=roc --- dom/base/nsGlobalWindow.cpp | 6 + dom/plugins/base/nsIPluginInstanceOwner.idl | 5 + dom/plugins/base/nsNPAPIPluginInstance.cpp | 5 + dom/plugins/base/nsNPAPIPluginInstance.h | 1 + dom/plugins/base/nsPluginInstanceOwner.cpp | 9 + dom/plugins/ipc/PPluginInstance.ipdl | 14 +- dom/plugins/ipc/PluginInstanceChild.cpp | 215 +++++++++++++++++++- dom/plugins/ipc/PluginInstanceChild.h | 34 +++- dom/plugins/ipc/PluginInstanceParent.cpp | 135 +++++++++++- dom/plugins/ipc/PluginInstanceParent.h | 17 +- dom/plugins/ipc/PluginMessageUtils.h | 10 + dom/plugins/ipc/PluginModuleChild.cpp | 36 +++- 12 files changed, 465 insertions(+), 22 deletions(-) diff --git a/dom/base/nsGlobalWindow.cpp b/dom/base/nsGlobalWindow.cpp index 0490e1cf0759..82b246ac93be 100644 --- a/dom/base/nsGlobalWindow.cpp +++ b/dom/base/nsGlobalWindow.cpp @@ -612,6 +612,12 @@ nsDummyJavaPluginOwner::InvalidateRegion(NPRegion invalidRegion) return NS_ERROR_NOT_IMPLEMENTED; } +NS_IMETHODIMP +nsDummyJavaPluginOwner::RedrawPlugin() +{ + return NS_ERROR_NOT_IMPLEMENTED; +} + NS_IMETHODIMP nsDummyJavaPluginOwner::GetNetscapeWindow(void *value) { diff --git a/dom/plugins/base/nsIPluginInstanceOwner.idl b/dom/plugins/base/nsIPluginInstanceOwner.idl index 2ef961e4957f..4891956b03ef 100644 --- a/dom/plugins/base/nsIPluginInstanceOwner.idl +++ b/dom/plugins/base/nsIPluginInstanceOwner.idl @@ -118,6 +118,11 @@ interface nsIPluginInstanceOwner : nsISupports */ void invalidateRegion(in NPRegion aRegion); + /** + * Have the plugin recomposited. + */ + void redrawPlugin(); + /** * Get NetscapeWindow, corresponds to NPNVnetscapeWindow */ diff --git a/dom/plugins/base/nsNPAPIPluginInstance.cpp b/dom/plugins/base/nsNPAPIPluginInstance.cpp index 313ca03ee844..6aa4d4319ad1 100644 --- a/dom/plugins/base/nsNPAPIPluginInstance.cpp +++ b/dom/plugins/base/nsNPAPIPluginInstance.cpp @@ -703,6 +703,11 @@ void nsNPAPIPluginInstance::SetDrawingModel(NPDrawingModel aModel) mDrawingModel = aModel; } +void nsNPAPIPluginInstance::RedrawPlugin() +{ + mOwner->RedrawPlugin(); +} + #if defined(XP_MACOSX) void nsNPAPIPluginInstance::SetEventModel(NPEventModel aModel) { diff --git a/dom/plugins/base/nsNPAPIPluginInstance.h b/dom/plugins/base/nsNPAPIPluginInstance.h index f5152c8ceff8..acba2f40e408 100644 --- a/dom/plugins/base/nsNPAPIPluginInstance.h +++ b/dom/plugins/base/nsNPAPIPluginInstance.h @@ -154,6 +154,7 @@ public: bool UsesDOMForCursor(); void SetDrawingModel(NPDrawingModel aModel); + void RedrawPlugin(); #ifdef XP_MACOSX void SetEventModel(NPEventModel aModel); #endif diff --git a/dom/plugins/base/nsPluginInstanceOwner.cpp b/dom/plugins/base/nsPluginInstanceOwner.cpp index c207057b2ab6..1dc179add3b3 100644 --- a/dom/plugins/base/nsPluginInstanceOwner.cpp +++ b/dom/plugins/base/nsPluginInstanceOwner.cpp @@ -671,6 +671,15 @@ NS_IMETHODIMP nsPluginInstanceOwner::InvalidateRegion(NPRegion invalidRegion) { return NS_ERROR_NOT_IMPLEMENTED; } + +NS_IMETHODIMP +nsPluginInstanceOwner::RedrawPlugin() +{ + if (mObjectFrame) { + mObjectFrame->InvalidateLayer(mObjectFrame->GetContentRectRelativeToSelf(), nsDisplayItem::TYPE_PLUGIN); + } + return NS_OK; +} NS_IMETHODIMP nsPluginInstanceOwner::GetNetscapeWindow(void *value) { diff --git a/dom/plugins/ipc/PPluginInstance.ipdl b/dom/plugins/ipc/PPluginInstance.ipdl index 95640f1733e4..28c1e77da7eb 100644 --- a/dom/plugins/ipc/PPluginInstance.ipdl +++ b/dom/plugins/ipc/PPluginInstance.ipdl @@ -61,6 +61,7 @@ using gfxIntSize; using mozilla::null_t; using mozilla::plugins::WindowsSharedMemoryHandle; using mozilla::plugins::DXGISharedSurfaceHandle; +using mozilla::CrossProcessMutexHandle; using SurfaceDescriptorX11; using nsIntRect; using nsTextEvent; @@ -86,6 +87,11 @@ union SurfaceDescriptor { null_t; }; +union OptionalShmem { + Shmem; + null_t; +}; + union AsyncSurfaceDescriptor { Shmem; DXGISharedSurfaceHandle; @@ -98,6 +104,7 @@ struct NPRemoteAsyncSurface NPImageFormat format; uint32_t stride; AsyncSurfaceDescriptor data; + uintptr_t hostPtr; }; rpc protocol PPluginInstance @@ -192,7 +199,7 @@ parent: rpc NPN_SetValue_NPPVpluginUsesDOMForCursor(bool useDOMForCursor) returns (NPError result); rpc NPN_SetValue_NPPVpluginDrawingModel(int drawingModel) - returns (NPError result); + returns (OptionalShmem remoteImageData, CrossProcessMutexHandle mutex, NPError result); rpc NPN_SetValue_NPPVpluginEventModel(int eventModel) returns (NPError result); @@ -248,6 +255,11 @@ parent: NPCoordinateSpace destSpace) returns (double destX, double destY, bool result); + async RedrawPlugin(); + + rpc NPN_InitAsyncSurface(gfxIntSize size, NPImageFormat format) + returns (NPRemoteAsyncSurface surfData, bool result); + // Send notification that a plugin tried to negotiate Carbon NPAPI so that // users can be notified that restarting the browser in i386 mode may allow // them to use the plugin. diff --git a/dom/plugins/ipc/PluginInstanceChild.cpp b/dom/plugins/ipc/PluginInstanceChild.cpp index 6fc1c030d5c9..a03d3a569500 100644 --- a/dom/plugins/ipc/PluginInstanceChild.cpp +++ b/dom/plugins/ipc/PluginInstanceChild.cpp @@ -75,6 +75,7 @@ using mozilla::gfx::SharedDIBSurface; using namespace mozilla; using mozilla::ipc::ProcessChild; using namespace mozilla::plugins; +using namespace std; #ifdef MOZ_WIDGET_GTK2 @@ -133,6 +134,9 @@ struct RunnableMethodTraits PluginInstanceChild::PluginInstanceChild(const NPPluginFuncs* aPluginIface) : mPluginIface(aPluginIface) , mDrawingModel(kDefaultDrawingModel) + , mCurrentAsyncSurface(0) + , mAsyncInvalidateMutex("PluginInstanceChild::mAsyncInvalidateMutex") + , mAsyncInvalidateTask(0) , mCachedWindowActor(nsnull) , mCachedElementActor(nsnull) #if defined(OS_WIN) @@ -175,6 +179,7 @@ PluginInstanceChild::PluginInstanceChild(const NPPluginFuncs* aPluginIface) memset(&mWindow, 0, sizeof(mWindow)); mData.ndata = (void*) this; mData.pdata = nsnull; + mAsyncBitmaps.Init(); #if defined(MOZ_X11) && defined(XP_UNIX) && !defined(XP_MACOSX) mWindow.ws_info = &mWsInfo; memset(&mWsInfo, 0, sizeof(mWsInfo)); @@ -534,16 +539,24 @@ PluginInstanceChild::NPN_SetValue(NPPVariable aVar, void* aValue) NPError rv; int drawingModel = (int16) (intptr_t) aValue; - if (!PluginModuleChild::current()->AsyncDrawingAllowed()) { - if (drawingModel == NPDrawingModelAsyncBitmapSurface || - drawingModel == NPDrawingModelAsyncWindowsDXGISurface || - drawingModel == NPDrawingModelAsyncWindowsDX9ExSurface) { - return NPERR_GENERIC_ERROR; - } + if (!PluginModuleChild::current()->AsyncDrawingAllowed() && + IsDrawingModelAsync(drawingModel)) { + return NPERR_GENERIC_ERROR; } - if (!CallNPN_SetValue_NPPVpluginDrawingModel(drawingModel, &rv)) + CrossProcessMutexHandle handle; + OptionalShmem optionalShmem; + if (!CallNPN_SetValue_NPPVpluginDrawingModel(drawingModel, &optionalShmem, &handle, &rv)) return NPERR_GENERIC_ERROR; + + if (drawingModel == NPDrawingModelAsyncBitmapSurface) { + if (optionalShmem.type() != OptionalShmem::TShmem) { + return NPERR_GENERIC_ERROR; + } + mRemoteImageDataShmem = optionalShmem.get_Shmem(); + mRemoteImageData = mRemoteImageDataShmem.get(); + mRemoteImageDataMutex = new CrossProcessMutex(handle); + } mDrawingModel = drawingModel; #ifdef XP_MACOSX @@ -2335,6 +2348,172 @@ PluginInstanceChild::NPN_URLRedirectResponse(void* notifyData, NPBool allow) NS_ASSERTION(false, "Couldn't find stream for redirect response!"); } +NPError +PluginInstanceChild::DeallocateAsyncBitmapSurface(NPAsyncSurface *aSurface) +{ + AsyncBitmapData* data; + + if (!mAsyncBitmaps.Get(aSurface, &data)) { + return NPERR_INVALID_PARAM; + } + + DeallocShmem(data->mShmem); + aSurface->bitmap.data = nsnull; + + mAsyncBitmaps.Remove(aSurface); + return NPERR_NO_ERROR; +} + +bool +PluginInstanceChild::IsAsyncDrawing() +{ + return IsDrawingModelAsync(mDrawingModel); +} + +NPError +PluginInstanceChild::NPN_InitAsyncSurface(NPSize *size, NPImageFormat format, + void *initData, NPAsyncSurface *surface) +{ + AssertPluginThread(); + + surface->bitmap.data = NULL; + + if (!IsAsyncDrawing()) { + return NPERR_GENERIC_ERROR; + } + + switch (mDrawingModel) { + case NPDrawingModelAsyncBitmapSurface: { + if (mAsyncBitmaps.Get(surface, nsnull)) { + return NPERR_INVALID_PARAM; + } + + if (size->width < 0 || size->height < 0) { + return NPERR_INVALID_PARAM; + } + + + bool result; + NPRemoteAsyncSurface remote; + + if (!CallNPN_InitAsyncSurface(gfxIntSize(size->width, size->height), format, &remote, &result) || !result) { + return NPERR_OUT_OF_MEMORY_ERROR; + } + + NS_ABORT_IF_FALSE(remote.data().get_Shmem().IsWritable(), + "Failed to create writable shared memory."); + + AsyncBitmapData *data = new AsyncBitmapData; + mAsyncBitmaps.Put(surface, data); + + data->mRemotePtr = (void*)remote.hostPtr(); + data->mShmem = remote.data().get_Shmem(); + + surface->bitmap.data = data->mShmem.get(); + surface->bitmap.stride = remote.stride(); + surface->format = remote.format(); + surface->size.width = remote.size().width; + surface->size.height = remote.size().height; + + return NPERR_NO_ERROR; + } + } + + return NPERR_GENERIC_ERROR; +} + +NPError +PluginInstanceChild::NPN_FinalizeAsyncSurface(NPAsyncSurface *surface) +{ + AssertPluginThread(); + + if (!IsAsyncDrawing()) { + return NPERR_GENERIC_ERROR; + } + + switch (mDrawingModel) { + case NPDrawingModelAsyncBitmapSurface: { + AsyncBitmapData *bitmapData; + + if (!mAsyncBitmaps.Get(surface, &bitmapData)) { + return NPERR_GENERIC_ERROR; + } + + { + CrossProcessMutexAutoLock autoLock(*mRemoteImageDataMutex); + RemoteImageData *data = mRemoteImageData; + if (data->mBitmap.mData == bitmapData->mRemotePtr) { + data->mBitmap.mData = NULL; + data->mSize = gfxIntSize(0, 0); + data->mWasUpdated = true; + } + } + + return DeallocateAsyncBitmapSurface(surface); + } + } + + return NPERR_GENERIC_ERROR; +} + +void +PluginInstanceChild::NPN_SetCurrentAsyncSurface(NPAsyncSurface *surface, NPRect *changed) +{ + if (!IsAsyncDrawing()) { + return; + } + + RemoteImageData *data = mRemoteImageData; + + if (!surface) { + CrossProcessMutexAutoLock autoLock(*mRemoteImageDataMutex); + data->mBitmap.mData = NULL; + data->mSize = gfxIntSize(0, 0); + data->mWasUpdated = true; + } else { + switch (mDrawingModel) { + case NPDrawingModelAsyncBitmapSurface: + { + AsyncBitmapData *bitmapData; + + if (!mAsyncBitmaps.Get(surface, &bitmapData)) { + return; + } + + CrossProcessMutexAutoLock autoLock(*mRemoteImageDataMutex); + data->mBitmap.mData = (unsigned char*)bitmapData->mRemotePtr; + data->mSize = gfxIntSize(surface->size.width, surface->size.height); + data->mFormat = surface->format == NPImageFormatBGRX32 ? + RemoteImageData::BGRX32 : RemoteImageData::BGRA32; + data->mBitmap.mStride = surface->bitmap.stride; + data->mWasUpdated = true; + break; + } + } + } + + { + MutexAutoLock autoLock(mAsyncInvalidateMutex); + if (!mAsyncInvalidateTask) { + mAsyncInvalidateTask = + NewRunnableMethod + (this, &PluginInstanceChild::DoAsyncRedraw); + ProcessChild::message_loop()->PostTask(FROM_HERE, mAsyncInvalidateTask); + } + } +} + +void +PluginInstanceChild::DoAsyncRedraw() +{ + { + MutexAutoLock autoLock(mAsyncInvalidateMutex); + mAsyncInvalidateTask = NULL; + } + + SendRedrawPlugin(); +} + bool PluginInstanceChild::RecvAsyncSetWindow(const gfxSurfaceType& aSurfaceType, const NPRemoteWindow& aWindow) @@ -3686,6 +3865,16 @@ PluginInstanceChild::ClearAllSurfaces() #endif } +PLDHashOperator +PluginInstanceChild::DeleteSurface(NPAsyncSurface* surf, nsAutoPtr &data, void* userArg) +{ + PluginInstanceChild *inst = static_cast(userArg); + + inst->DeallocShmem(data->mShmem); + + return PL_DHASH_REMOVE; +} + bool PluginInstanceChild::AnswerNPP_Destroy(NPError* aResult) { @@ -3726,6 +3915,13 @@ PluginInstanceChild::AnswerNPP_Destroy(NPError* aResult) mCurrentAsyncSetWindowTask->Cancel(); mCurrentAsyncSetWindowTask = nsnull; } + { + MutexAutoLock autoLock(mAsyncInvalidateMutex); + if (mAsyncInvalidateTask) { + mAsyncInvalidateTask->Cancel(); + mAsyncInvalidateTask = nsnull; + } + } ClearAllSurfaces(); @@ -3754,6 +3950,11 @@ PluginInstanceChild::AnswerNPP_Destroy(NPError* aResult) mPendingAsyncCalls[i]->Cancel(); mPendingAsyncCalls.Clear(); + + if (mAsyncBitmaps.Count()) { + NS_ERROR("Not all AsyncBitmaps were finalized by a plugin!"); + mAsyncBitmaps.Enumerate(DeleteSurface, this); + } return true; } diff --git a/dom/plugins/ipc/PluginInstanceChild.h b/dom/plugins/ipc/PluginInstanceChild.h index 12b65b2ab636..52954534f6fd 100644 --- a/dom/plugins/ipc/PluginInstanceChild.h +++ b/dom/plugins/ipc/PluginInstanceChild.h @@ -43,6 +43,8 @@ #include "mozilla/plugins/PluginScriptableObjectChild.h" #include "mozilla/plugins/StreamNotifyChild.h" #include "mozilla/plugins/PPluginSurfaceChild.h" +#include "mozilla/ipc/CrossProcessMutex.h" +#include "nsClassHashtable.h" #if defined(OS_WIN) #include "mozilla/gfx/SharedDIBWin.h" #elif defined(MOZ_WIDGET_COCOA) @@ -63,7 +65,14 @@ using namespace mozilla::plugins::PluginUtilsOSX; #include "mozilla/PaintTracker.h" #include "gfxASurface.h" +#include + namespace mozilla { + +namespace layers { +struct RemoteImageData; +} + namespace plugins { class PBrowserStreamChild; @@ -249,6 +258,13 @@ public: void NPN_URLRedirectResponse(void* notifyData, NPBool allow); + NPError NPN_InitAsyncSurface(NPSize *size, NPImageFormat format, + void *initData, NPAsyncSurface *surface); + NPError NPN_FinalizeAsyncSurface(NPAsyncSurface *surface); + + void NPN_SetCurrentAsyncSurface(NPAsyncSurface *surface, NPRect *changed); + + void DoAsyncRedraw(); private: friend class PluginModuleChild; @@ -256,6 +272,10 @@ private: InternalGetNPObjectForValue(NPNVariable aValue, NPObject** aObject); + bool IsAsyncDrawing(); + + NPError DeallocateAsyncBitmapSurface(NPAsyncSurface *aSurface); + NS_OVERRIDE virtual bool RecvUpdateBackground(const SurfaceDescriptor& aBackground, const nsIntRect& aRect); @@ -360,11 +380,23 @@ private: }; #endif - const NPPluginFuncs* mPluginIface; NPP_t mData; NPWindow mWindow; int16_t mDrawingModel; + NPAsyncSurface* mCurrentAsyncSurface; + struct AsyncBitmapData { + void *mRemotePtr; + Shmem mShmem; + }; + + static PLDHashOperator DeleteSurface(NPAsyncSurface* surf, nsAutoPtr &data, void* userArg); + nsClassHashtable, AsyncBitmapData> mAsyncBitmaps; + Shmem mRemoteImageDataShmem; + mozilla::layers::RemoteImageData *mRemoteImageData; + nsAutoPtr mRemoteImageDataMutex; + mozilla::Mutex mAsyncInvalidateMutex; + CancelableTask *mAsyncInvalidateTask; // Cached scriptable actors to avoid IPC churn PluginScriptableObjectChild* mCachedWindowActor; diff --git a/dom/plugins/ipc/PluginInstanceParent.cpp b/dom/plugins/ipc/PluginInstanceParent.cpp index b5c301db70c0..451ba232ed43 100644 --- a/dom/plugins/ipc/PluginInstanceParent.cpp +++ b/dom/plugins/ipc/PluginInstanceParent.cpp @@ -122,6 +122,15 @@ PluginInstanceParent::~PluginInstanceParent() if (mShColorSpace) ::CGColorSpaceRelease(mShColorSpace); #endif + if (mRemoteImageDataShmem.IsWritable()) { + ImageContainer *container = + GetImageContainer(); + + if (container) { + container->SetRemoteImageData(nsnull, nsnull); + DeallocShmem(mRemoteImageDataShmem); + } + } } bool @@ -282,6 +291,12 @@ PluginInstanceParent::InternalGetValueForNPObject( return true; } +bool +PluginInstanceParent::IsAsyncDrawing() +{ + return IsDrawingModelAsync(mDrawingModel); +} + bool PluginInstanceParent::AnswerNPN_GetValue_NPNVWindowNPObject( PPluginScriptableObjectParent** aValue, @@ -352,7 +367,7 @@ PluginInstanceParent::AnswerNPN_SetValue_NPPVpluginUsesDOMForCursor( bool PluginInstanceParent::AnswerNPN_SetValue_NPPVpluginDrawingModel( - const int& drawingModel, NPError* result) + const int& drawingModel, OptionalShmem *shmem, CrossProcessMutexHandle *mutex, NPError* result) { #ifdef XP_MACOSX if (drawingModel == NPDrawingModelCoreAnimation || @@ -365,15 +380,58 @@ PluginInstanceParent::AnswerNPN_SetValue_NPPVpluginDrawingModel( (void*)NPDrawingModelCoreGraphics); } else #endif - { - if (!GetImageContainer()) { - *result = NPERR_GENERIC_ERROR; - return true; + if (drawingModel == NPDrawingModelAsyncBitmapSurface) { + ImageContainer *container = GetImageContainer(); + if (!container) { + *result = NPERR_GENERIC_ERROR; + return true; + } + + mDrawingModel = drawingModel; + *result = mNPNIface->setvalue(mNPP, NPPVpluginDrawingModel, + (void*)drawingModel); + + + if (*result != NPERR_NO_ERROR) { + return true; + } + + AllocUnsafeShmem(sizeof(RemoteImageData), SharedMemory::TYPE_BASIC, &mRemoteImageDataShmem); + + *shmem = mRemoteImageDataShmem; + + mRemoteImageDataMutex = new CrossProcessMutex("PluginInstanceParent.mRemoteImageDataMutex"); + + *mutex = mRemoteImageDataMutex->ShareToProcess(OtherProcess()); + container->SetRemoteImageData(mRemoteImageDataShmem.get(), mRemoteImageDataMutex); + } else if (drawingModel == NPDrawingModelSyncWin || +#ifdef XP_MACOSX +#ifndef NP_NO_QUICKDRAW + drawingModel == NPDrawingModelQuickDraw || +#endif + drawingModel == NPDrawingModelOpenGL || + drawingModel == NPDrawingModelCoreGraphics || +#endif + drawingModel == NPDrawingModelSyncX) { + *shmem = null_t(); + + ImageContainer *container = GetImageContainer(); + if (!container) { + *result = NPERR_GENERIC_ERROR; + return true; } mDrawingModel = drawingModel; *result = mNPNIface->setvalue(mNPP, NPPVpluginDrawingModel, (void*)drawingModel); + + if (mRemoteImageDataShmem.IsWritable()) { + container->SetRemoteImageData(nsnull, nsnull); + DeallocShmem(mRemoteImageDataShmem); + mRemoteImageDataMutex = NULL; + } + } else { + *result = NPERR_GENERIC_ERROR; } return true; } @@ -651,6 +709,12 @@ PluginInstanceParent::GetImageContainer(ImageContainer** aContainer) return NS_ERROR_FAILURE; } + if (IsAsyncDrawing()) { + NS_IF_ADDREF(container); + *aContainer = container; + return NS_OK; + } + nsRefPtr image; image = container->CreateImage(&format, 1); if (!image) { @@ -1105,6 +1169,12 @@ PluginInstanceParent::NPP_HandleEvent(void* event) #if defined(OS_WIN) if (mWindowType == NPWindowTypeDrawable) { + if (IsAsyncDrawing()) { + if (npevent->event == WM_PAINT || npevent->event == DoublePassRenderingEvent()) { + // This plugin maintains its own async drawing. + return handled; + } + } if (DoublePassRenderingEvent() == npevent->event) { CallPaint(npremoteevent, &handled); return handled; @@ -1606,15 +1676,58 @@ PluginInstanceParent::AnswerNPN_ConvertPoint(const double& sourceX, return true; } +bool +PluginInstanceParent::AnswerNPN_InitAsyncSurface(const gfxIntSize& size, + const NPImageFormat& format, + NPRemoteAsyncSurface* surfData, + bool* result) +{ + if (!IsAsyncDrawing()) { + *result = false; + return true; + } + + switch (mDrawingModel) { + case NPDrawingModelAsyncBitmapSurface: { + Shmem sharedMem; + if (!AllocUnsafeShmem(size.width * size.height * 4, SharedMemory::TYPE_BASIC, &sharedMem)) { + *result = false; + return true; + } + + surfData->size() = size; + surfData->hostPtr() = (uintptr_t)sharedMem.get(); + surfData->stride() = size.width * 4; + surfData->format() = format; + surfData->data() = sharedMem; + *result = true; + } + } + + return true; +} + +bool +PluginInstanceParent::RecvRedrawPlugin() +{ + nsNPAPIPluginInstance *inst = static_cast(mNPP->ndata); + if (!inst) { + return false; + } + + inst->RedrawPlugin(); + return true; +} + bool PluginInstanceParent::RecvNegotiatedCarbon() { - nsNPAPIPluginInstance *inst = static_cast(mNPP->ndata); - if (!inst) { - return false; - } - inst->CarbonNPAPIFailure(); - return true; + nsNPAPIPluginInstance *inst = static_cast(mNPP->ndata); + if (!inst) { + return false; + } + inst->CarbonNPAPIFailure(); + return true; } #if defined(OS_WIN) diff --git a/dom/plugins/ipc/PluginInstanceParent.h b/dom/plugins/ipc/PluginInstanceParent.h index 9209847a29a6..d2d97264afd0 100644 --- a/dom/plugins/ipc/PluginInstanceParent.h +++ b/dom/plugins/ipc/PluginInstanceParent.h @@ -144,7 +144,9 @@ public: NPError* result); virtual bool AnswerNPN_SetValue_NPPVpluginDrawingModel(const int& drawingModel, - NPError* result); + OptionalShmem *remoteImageData, + CrossProcessMutexHandle *mutex, + NPError* result); virtual bool AnswerNPN_SetValue_NPPVpluginEventModel(const int& eventModel, NPError* result); @@ -229,6 +231,15 @@ public: double *destY, bool *result); + virtual bool + AnswerNPN_InitAsyncSurface(const gfxIntSize& size, + const NPImageFormat& format, + NPRemoteAsyncSurface* surfData, + bool* result); + + virtual bool + RecvRedrawPlugin(); + NS_OVERRIDE virtual bool RecvNegotiatedCarbon(); @@ -316,11 +327,15 @@ private: PPluginScriptableObjectParent** aValue, NPError* aResult); + bool IsAsyncDrawing(); + private: PluginModuleParent* mParent; NPP mNPP; const NPNetscapeFuncs* mNPNIface; NPWindowType mWindowType; + Shmem mRemoteImageDataShmem; + nsAutoPtr mRemoteImageDataMutex; int16_t mDrawingModel; nsDataHashtable mScriptableObjects; diff --git a/dom/plugins/ipc/PluginMessageUtils.h b/dom/plugins/ipc/PluginMessageUtils.h index 98797c4aaff1..9e27b7140146 100644 --- a/dom/plugins/ipc/PluginMessageUtils.h +++ b/dom/plugins/ipc/PluginMessageUtils.h @@ -43,6 +43,7 @@ #include "base/message_loop.h" #include "mozilla/ipc/RPCChannel.h" +#include "mozilla/ipc/CrossProcessMutex.h" #include "gfxipc/ShadowLayerUtils.h" #include "npapi.h" @@ -88,6 +89,15 @@ extern PRLogModuleInfo* gPluginLog; const uint32_t kAllowAsyncDrawing = 0x1; +inline bool IsDrawingModelAsync(int16_t aModel) { + return aModel == NPDrawingModelAsyncBitmapSurface +#ifdef XP_WIN + || aModel == NPDrawingModelAsyncWindowsDXGISurface + || aModel == NPDrawingModelAsyncWindowsDX9ExSurface +#endif + ; +} + #if defined(_MSC_VER) #define FULLFUNCTION __FUNCSIG__ #elif (__GNUC__ >= 4) diff --git a/dom/plugins/ipc/PluginModuleChild.cpp b/dom/plugins/ipc/PluginModuleChild.cpp index 4136fc8f752a..7f8029f9e677 100644 --- a/dom/plugins/ipc/PluginModuleChild.cpp +++ b/dom/plugins/ipc/PluginModuleChild.cpp @@ -975,6 +975,17 @@ _convertpoint(NPP instance, static void NP_CALLBACK _urlredirectresponse(NPP instance, void* notifyData, NPBool allow); +static NPError NP_CALLBACK +_initasyncsurface(NPP instance, NPSize *size, + NPImageFormat format, void *initData, + NPAsyncSurface *surface); + +static NPError NP_CALLBACK +_finalizeasyncsurface(NPP instance, NPAsyncSurface *surface); + +static void NP_CALLBACK +_setcurrentasyncsurface(NPP instance, NPAsyncSurface *surface, NPRect *changed); + } /* namespace child */ } /* namespace plugins */ } /* namespace mozilla */ @@ -1036,7 +1047,10 @@ const NPNetscapeFuncs PluginModuleChild::sBrowserFuncs = { mozilla::plugins::child::_convertpoint, NULL, // handleevent, unimplemented NULL, // unfocusinstance, unimplemented - mozilla::plugins::child::_urlredirectresponse + mozilla::plugins::child::_urlredirectresponse, + mozilla::plugins::child::_initasyncsurface, + mozilla::plugins::child::_finalizeasyncsurface, + mozilla::plugins::child::_setcurrentasyncsurface }; PluginInstanceChild* @@ -1809,6 +1823,26 @@ _urlredirectresponse(NPP instance, void* notifyData, NPBool allow) InstCast(instance)->NPN_URLRedirectResponse(notifyData, allow); } +NPError NP_CALLBACK +_initasyncsurface(NPP instance, NPSize *size, + NPImageFormat format, void *initData, + NPAsyncSurface *surface) +{ + return InstCast(instance)->NPN_InitAsyncSurface(size, format, initData, surface); +} + +NPError NP_CALLBACK +_finalizeasyncsurface(NPP instance, NPAsyncSurface *surface) +{ + return InstCast(instance)->NPN_FinalizeAsyncSurface(surface); +} + +void NP_CALLBACK +_setcurrentasyncsurface(NPP instance, NPAsyncSurface *surface, NPRect *changed) +{ + InstCast(instance)->NPN_SetCurrentAsyncSurface(surface, changed); +} + } /* namespace child */ } /* namespace plugins */ } /* namespace mozilla */