mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-10 03:45:46 +00:00
Bug 651192 - Part 6: Implement the AsyncBitmapSurface drawing model support. r=roc
This commit is contained in:
parent
b798e874b1
commit
3d62e785cc
@ -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)
|
||||
{
|
||||
|
@ -118,6 +118,11 @@ interface nsIPluginInstanceOwner : nsISupports
|
||||
*/
|
||||
void invalidateRegion(in NPRegion aRegion);
|
||||
|
||||
/**
|
||||
* Have the plugin recomposited.
|
||||
*/
|
||||
void redrawPlugin();
|
||||
|
||||
/**
|
||||
* Get NetscapeWindow, corresponds to NPNVnetscapeWindow
|
||||
*/
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -154,6 +154,7 @@ public:
|
||||
bool UsesDOMForCursor();
|
||||
|
||||
void SetDrawingModel(NPDrawingModel aModel);
|
||||
void RedrawPlugin();
|
||||
#ifdef XP_MACOSX
|
||||
void SetEventModel(NPEventModel aModel);
|
||||
#endif
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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.
|
||||
|
@ -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::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<RemoteImageData>();
|
||||
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<unsigned char>();
|
||||
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<PluginInstanceChild, void (PluginInstanceChild::*)()>
|
||||
(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<AsyncBitmapData> &data, void* userArg)
|
||||
{
|
||||
PluginInstanceChild *inst = static_cast<PluginInstanceChild*>(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;
|
||||
}
|
||||
|
@ -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 <map>
|
||||
|
||||
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<AsyncBitmapData> &data, void* userArg);
|
||||
nsClassHashtable<nsPtrHashKey<NPAsyncSurface>, AsyncBitmapData> mAsyncBitmaps;
|
||||
Shmem mRemoteImageDataShmem;
|
||||
mozilla::layers::RemoteImageData *mRemoteImageData;
|
||||
nsAutoPtr<CrossProcessMutex> mRemoteImageDataMutex;
|
||||
mozilla::Mutex mAsyncInvalidateMutex;
|
||||
CancelableTask *mAsyncInvalidateTask;
|
||||
|
||||
// Cached scriptable actors to avoid IPC churn
|
||||
PluginScriptableObjectChild* mCachedWindowActor;
|
||||
|
@ -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<RemoteImageData>(), 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;
|
||||
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<unsigned char>();
|
||||
surfData->stride() = size.width * 4;
|
||||
surfData->format() = format;
|
||||
surfData->data() = sharedMem;
|
||||
*result = true;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
PluginInstanceParent::RecvRedrawPlugin()
|
||||
{
|
||||
nsNPAPIPluginInstance *inst = static_cast<nsNPAPIPluginInstance*>(mNPP->ndata);
|
||||
if (!inst) {
|
||||
return false;
|
||||
}
|
||||
|
||||
inst->RedrawPlugin();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
PluginInstanceParent::RecvNegotiatedCarbon()
|
||||
{
|
||||
nsNPAPIPluginInstance *inst = static_cast<nsNPAPIPluginInstance*>(mNPP->ndata);
|
||||
if (!inst) {
|
||||
return false;
|
||||
}
|
||||
inst->CarbonNPAPIFailure();
|
||||
return true;
|
||||
nsNPAPIPluginInstance *inst = static_cast<nsNPAPIPluginInstance*>(mNPP->ndata);
|
||||
if (!inst) {
|
||||
return false;
|
||||
}
|
||||
inst->CarbonNPAPIFailure();
|
||||
return true;
|
||||
}
|
||||
|
||||
#if defined(OS_WIN)
|
||||
|
@ -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<CrossProcessMutex> mRemoteImageDataMutex;
|
||||
int16_t mDrawingModel;
|
||||
|
||||
nsDataHashtable<nsVoidPtrHashKey, PluginScriptableObjectParent*> mScriptableObjects;
|
||||
|
@ -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)
|
||||
|
@ -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 */
|
||||
|
Loading…
Reference in New Issue
Block a user