Asynchronous layer-based plugin painting on Mac b=598425 r=roc,josh

This commit is contained in:
Benoit Girard 2011-05-19 17:08:14 -04:00
parent d0fb2e315c
commit 5da2ec6132
17 changed files with 336 additions and 116 deletions

View File

@ -258,17 +258,6 @@ PluginPRLibrary::GetImageSize(NPP instance, nsIntSize* aSize)
return NS_ERROR_NOT_IMPLEMENTED;
}
#if defined(XP_MACOSX)
nsresult
PluginPRLibrary::IsRemoteDrawingCoreAnimation(NPP instance, PRBool *aDrawing)
{
nsNPAPIPluginInstance* inst = (nsNPAPIPluginInstance*)instance->ndata;
NS_ENSURE_TRUE(inst, NS_ERROR_NULL_POINTER);
*aDrawing = PR_FALSE;
return NS_OK;
}
#endif
nsresult
PluginPRLibrary::SetBackgroundUnknown(NPP instance)
{

View File

@ -143,9 +143,6 @@ public:
virtual nsresult GetImage(NPP instance, ImageContainer* aContainer, Image** aImage);
virtual nsresult GetImageSize(NPP instance, nsIntSize* aSize);
NS_OVERRIDE virtual bool UseAsyncPainting() { return false; }
#if defined(XP_MACOSX)
virtual nsresult IsRemoteDrawingCoreAnimation(NPP instance, PRBool *aDrawing);
#endif
NS_OVERRIDE
virtual nsresult SetBackgroundUnknown(NPP instance);
NS_OVERRIDE

View File

@ -729,22 +729,6 @@ nsresult nsNPAPIPluginInstance::GetDrawingModel(PRInt32* aModel)
#endif
}
nsresult nsNPAPIPluginInstance::IsRemoteDrawingCoreAnimation(PRBool* aDrawing)
{
#ifdef XP_MACOSX
if (!mPlugin)
return NS_ERROR_FAILURE;
PluginLibrary* library = mPlugin->GetLibrary();
if (!library)
return NS_ERROR_FAILURE;
return library->IsRemoteDrawingCoreAnimation(&mNPP, aDrawing);
#else
return NS_ERROR_FAILURE;
#endif
}
nsresult
nsNPAPIPluginInstance::GetJSObject(JSContext *cx, JSObject** outObject)
{

View File

@ -251,6 +251,28 @@ nsPluginInstanceOwner::EndUpdateBackground(gfxContext* aContext,
}
}
PRBool
nsPluginInstanceOwner::UseAsyncRendering()
{
#ifdef XP_MACOSX
nsRefPtr<ImageContainer> container = mObjectFrame->GetImageContainer();
#endif
PRBool useAsyncRendering;
return (mInstance &&
NS_SUCCEEDED(mInstance->UseAsyncPainting(&useAsyncRendering)) &&
useAsyncRendering &&
#ifdef XP_MACOSX
mObjectFrame && mObjectFrame->GetImageContainer().get() &&
mObjectFrame->GetImageContainer().get()->GetBackendType() ==
LayerManager::LAYERS_OPENGL
#else
(!mPluginWindow ||
mPluginWindow->type == NPWindowTypeDrawable)
#endif
);
}
nsIntSize
nsPluginInstanceOwner::GetCurrentImageSize()
{
@ -1338,18 +1360,6 @@ NPDrawingModel nsPluginInstanceOwner::GetDrawingModel()
return drawingModel;
}
PRBool nsPluginInstanceOwner::IsRemoteDrawingCoreAnimation()
{
if (!mInstance)
return PR_FALSE;
PRBool coreAnimation;
if (!NS_SUCCEEDED(mInstance->IsRemoteDrawingCoreAnimation(&coreAnimation)))
return PR_FALSE;
return coreAnimation;
}
NPEventModel nsPluginInstanceOwner::GetEventModel()
{
return mEventModel;
@ -3217,7 +3227,7 @@ void* nsPluginInstanceOwner::FixUpPluginWindow(PRInt32 inPaintState)
mPluginWindow->clipRect.right != oldClipRect.right ||
mPluginWindow->clipRect.bottom != oldClipRect.bottom)
{
mInstance->SetWindow(mPluginWindow);
CallSetWindow();
mPluginPortChanged = PR_FALSE;
#ifdef MAC_CARBON_PLUGINS
// if the clipRect is of size 0, make the null timer fire less often
@ -3231,7 +3241,7 @@ void* nsPluginInstanceOwner::FixUpPluginWindow(PRInt32 inPaintState)
}
#endif
} else if (mPluginPortChanged) {
mInstance->SetWindow(mPluginWindow);
CallSetWindow();
mPluginPortChanged = PR_FALSE;
}
@ -3273,7 +3283,11 @@ nsPluginInstanceOwner::HidePluginWindow()
mPluginWindow->clipRect.bottom = mPluginWindow->clipRect.top;
mPluginWindow->clipRect.right = mPluginWindow->clipRect.left;
mWidgetVisible = PR_FALSE;
mInstance->SetWindow(mPluginWindow);
if (mAsyncHidePluginWindow) {
mInstance->AsyncSetWindow(mPluginWindow);
} else {
mInstance->SetWindow(mPluginWindow);
}
}
#else // XP_MACOSX
@ -3321,19 +3335,6 @@ void nsPluginInstanceOwner::UpdateWindowPositionAndClipRect(PRBool aSetWindow)
}
}
void
nsPluginInstanceOwner::CallSetWindow()
{
if (!mInstance)
return;
if (UseAsyncRendering()) {
mInstance->AsyncSetWindow(mPluginWindow);
} else {
mInstance->SetWindow(mPluginWindow);
}
}
void
nsPluginInstanceOwner::UpdateWindowVisibility(PRBool aVisible)
{
@ -3343,6 +3344,21 @@ nsPluginInstanceOwner::UpdateWindowVisibility(PRBool aVisible)
#endif // XP_MACOSX
void
nsPluginInstanceOwner::CallSetWindow()
{
if (!mInstance)
return;
if (UseAsyncRendering()) {
mAsyncHidePluginWindow = true;
mInstance->AsyncSetWindow(mPluginWindow);
} else {
mAsyncHidePluginWindow = false;
mInstance->SetWindow(mPluginWindow);
}
}
// Little helper function to resolve relative URL in
// |value| for certain inputs of |name|
void nsPluginInstanceOwner::FixUpURLS(const nsString &name, nsAString &value)

View File

@ -179,7 +179,6 @@ public:
enum { ePluginPaintEnable, ePluginPaintDisable };
NPDrawingModel GetDrawingModel();
PRBool IsRemoteDrawingCoreAnimation();
NPEventModel GetEventModel();
static void CARefresh(nsITimer *aTimer, void *aClosure);
static void AddToCARefreshTimer(nsPluginInstanceOwner *aPluginInstance);
@ -207,9 +206,9 @@ public:
void EndCGPaint();
#else // XP_MACOSX
void UpdateWindowPositionAndClipRect(PRBool aSetWindow);
void CallSetWindow();
void UpdateWindowVisibility(PRBool aVisible);
#endif // XP_MACOSX
void CallSetWindow();
void SetOwner(nsObjectFrame *aOwner)
{
@ -295,15 +294,7 @@ public:
already_AddRefed<gfxContext> BeginUpdateBackground(const nsIntRect& aRect);
void EndUpdateBackground(gfxContext* aContext, const nsIntRect& aRect);
PRBool UseAsyncRendering()
{
PRBool useAsyncRendering;
return (mInstance &&
NS_SUCCEEDED(mInstance->UseAsyncPainting(&useAsyncRendering)) &&
useAsyncRendering &&
(!mPluginWindow ||
mPluginWindow->type == NPWindowTypeDrawable));
}
PRBool UseAsyncRendering();
private:
@ -339,6 +330,9 @@ private:
static nsTArray<nsPluginInstanceOwner*> *sCARefreshListeners;
PRBool mSentInitialTopLevelWindowEvent;
#endif
// We need to know if async hide window is required since we
// can not check UseAsyncRendering when executing StopPlugin
PRBool mAsyncHidePluginWindow;
// Initially, the event loop nesting level we were created on, it's updated
// if we detect the appshell is on a lower level as long as we're not stopped.

View File

@ -69,10 +69,15 @@ struct SurfaceDescriptorX11 {
gfxIntSize size;
};
struct IOSurfaceDescriptor {
uint32_t surfaceId;
};
union SurfaceDescriptor {
Shmem;
SurfaceDescriptorX11;
PPluginSurface; // used on Windows
IOSurfaceDescriptor; // used on OSX 10.5+
// Descriptor can be null here in case
// 1) of first Show call (prevSurface is null)
// 2) when child is going to destroy

View File

@ -105,6 +105,7 @@ static const TCHAR kPluginIgnoreSubclassProperty[] = TEXT("PluginIgnoreSubclassP
#elif defined(XP_MACOSX)
#include <ApplicationServices/ApplicationServices.h>
#include "PluginUtilsOSX.h"
#endif // defined(XP_MACOSX)
template<>
@ -135,6 +136,7 @@ PluginInstanceChild::PluginInstanceChild(const NPPluginFuncs* aPluginIface)
, mShColorSpace(nsnull)
, mShContext(nsnull)
, mDrawingModel(NPDrawingModelCoreGraphics)
, mCGLayer(nsnull)
, mCurrentEvent(nsnull)
#endif
, mLayersRendering(false)
@ -183,6 +185,9 @@ PluginInstanceChild::~PluginInstanceChild()
if (mShContext) {
::CGContextRelease(mShContext);
}
if (mCGLayer) {
mozilla::plugins::PluginUtilsOSX::ReleaseCGLayer(mCGLayer);
}
#endif
}
@ -477,6 +482,9 @@ PluginInstanceChild::NPN_SetValue(NPPVariable aVar, void* aValue)
return NPERR_GENERIC_ERROR;
mDrawingModel = drawingModel;
PLUGIN_LOG_DEBUG((" Plugin requested drawing model id #%i\n",
mDrawingModel));
return rv;
}
@ -490,6 +498,9 @@ PluginInstanceChild::NPN_SetValue(NPPVariable aVar, void* aValue)
mEventModel = static_cast<NPEventModel>(eventModel);
#endif
PLUGIN_LOG_DEBUG((" Plugin requested event model id # %i\n",
eventModel));
return rv;
}
#endif
@ -778,6 +789,32 @@ PluginInstanceChild::AnswerNPP_HandleEvent_Shmem(const NPRemoteEvent& event,
#endif
#ifdef XP_MACOSX
void CallCGDraw(CGContextRef ref, void* aPluginInstance, nsIntRect aUpdateRect) {
PluginInstanceChild* pluginInstance = (PluginInstanceChild*)aPluginInstance;
pluginInstance->CGDraw(ref, aUpdateRect);
}
bool
PluginInstanceChild::CGDraw(CGContextRef ref, nsIntRect aUpdateRect) {
NPCocoaEvent drawEvent;
drawEvent.type = NPCocoaEventDrawRect;
drawEvent.version = 0;
drawEvent.data.draw.x = aUpdateRect.x;
drawEvent.data.draw.y = aUpdateRect.y;
drawEvent.data.draw.width = aUpdateRect.width;
drawEvent.data.draw.height = aUpdateRect.height;
drawEvent.data.draw.context = ref;
NPRemoteEvent remoteDrawEvent = {drawEvent};
int16_t handled;
AnswerNPP_HandleEvent(remoteDrawEvent, &handled);
return handled == true;
}
bool
PluginInstanceChild::AnswerNPP_HandleEvent_IOSurface(const NPRemoteEvent& event,
const uint32_t &surfaceid,
@ -803,13 +840,16 @@ PluginInstanceChild::AnswerNPP_HandleEvent_IOSurface(const NPRemoteEvent& event,
NPError result = mPluginIface->getvalue(GetNPP(),
NPPVpluginCoreAnimationLayer,
&caLayer);
if (result != NPERR_NO_ERROR || !caLayer) {
PLUGIN_LOG_DEBUG(("Plugin requested CoreAnimation but did not "
"provide CALayer."));
*handled = false;
return false;
}
mCARenderer.SetupRenderer(caLayer, mWindow.width, mWindow.height);
// Flash needs to have the window set again after this step
if (mPluginIface->setwindow)
(void) mPluginIface->setwindow(&mData, &mWindow);
@ -2278,12 +2318,17 @@ PluginInstanceChild::DoAsyncSetWindow(const gfxSurfaceType& aSurfaceType,
}
mWindow.window = NULL;
#ifdef XP_MACOSX
if (mWindow.width != aWindow.width || mWindow.height != aWindow.height)
mAccumulatedInvalidRect = nsIntRect(0, 0, aWindow.width, aWindow.height);
#else
if (mWindow.width != aWindow.width || mWindow.height != aWindow.height ||
mWindow.clipRect.top != aWindow.clipRect.top ||
mWindow.clipRect.left != aWindow.clipRect.left ||
mWindow.clipRect.bottom != aWindow.clipRect.bottom ||
mWindow.clipRect.right != aWindow.clipRect.right)
mAccumulatedInvalidRect = nsIntRect(0, 0, aWindow.width, aWindow.height);
#endif
mWindow.x = aWindow.x;
mWindow.y = aWindow.y;
@ -2472,6 +2517,7 @@ PluginInstanceChild::MaybeCreatePlatformHelperSurface(void)
bool
PluginInstanceChild::EnsureCurrentBuffer(void)
{
#ifndef XP_MACOSX
nsIntRect toInvalidate(0, 0, 0, 0);
gfxIntSize winSize = gfxIntSize(mWindow.width, mWindow.height);
@ -2503,7 +2549,7 @@ PluginInstanceChild::EnsureCurrentBuffer(void)
mAccumulatedInvalidRect.UnionRect(mAccumulatedInvalidRect, toInvalidate);
if (mCurrentSurface) {
return true;
return true;
}
if (!CreateOptSurface()) {
@ -2517,6 +2563,65 @@ PluginInstanceChild::EnsureCurrentBuffer(void)
}
return true;
#else // XP_MACOSX
if (mCurrentIOSurface &&
(mCurrentIOSurface->GetWidth() != mWindow.width ||
mCurrentIOSurface->GetHeight() != mWindow.height) ) {
mCurrentIOSurface = nsnull;
}
if (!mCARenderer.isInit() || !mCurrentIOSurface) {
if (!mCurrentIOSurface) {
mCurrentIOSurface = nsIOSurface::CreateIOSurface(mWindow.width, mWindow.height);
nsIntRect toInvalidate(0, 0, mWindow.width, mWindow.height);
mAccumulatedInvalidRect.UnionRect(mAccumulatedInvalidRect, toInvalidate);
}
if (!mCurrentIOSurface) {
NS_WARNING("Failed to allocate IOSurface");
return false;
}
nsIOSurface *rendererSurface = nsIOSurface::LookupSurface(mCurrentIOSurface->GetIOSurfaceID());
if (!rendererSurface) {
NS_WARNING("Failed to lookup IOSurface");
return false;
}
mCARenderer.AttachIOSurface(rendererSurface);
void *caLayer = nsnull;
if (mDrawingModel == NPDrawingModelCoreGraphics) {
if (mCGLayer) {
mozilla::plugins::PluginUtilsOSX::ReleaseCGLayer(mCGLayer);
mCGLayer = nsnull;
}
caLayer = mozilla::plugins::PluginUtilsOSX::GetCGLayer(CallCGDraw, this);
if (!caLayer) {
return false;
}
mCGLayer = caLayer;
} else {
NPError result = mPluginIface->getvalue(GetNPP(),
NPPVpluginCoreAnimationLayer,
&caLayer);
if (result != NPERR_NO_ERROR || !caLayer) {
PLUGIN_LOG_DEBUG(("Plugin requested CoreAnimation but did not "
"provide CALayer."));
return false;
}
}
mCARenderer.SetupRenderer(caLayer, mWindow.width, mWindow.height);
// Flash needs to have the window set again after this step
if (mPluginIface->setwindow)
(void) mPluginIface->setwindow(&mData, &mWindow);
}
return true;
#endif
}
void
@ -2893,6 +2998,57 @@ PluginInstanceChild::ShowPluginFrame()
AutoRestore<bool> pending(mPendingPluginCall);
mPendingPluginCall = true;
#ifdef XP_MACOSX
// We can't use the thebes code with CoreAnimation so we will
// take a different code path.
if (mDrawingModel == NPDrawingModelCoreAnimation ||
mDrawingModel == NPDrawingModelInvalidatingCoreAnimation ||
mDrawingModel == NPDrawingModelCoreGraphics) {
if (!EnsureCurrentBuffer()) {
return false;
}
// Clear accRect here to be able to pass
// test_invalidate_during_plugin_paint test
nsIntRect rect = mAccumulatedInvalidRect;
mAccumulatedInvalidRect.SetEmpty();
// Fix up old invalidations that might have been made when our
// surface was a different size
rect.IntersectRect(rect,
nsIntRect(0, 0, mCurrentIOSurface->GetWidth(), mCurrentIOSurface->GetHeight()));
if (!mCARenderer.isInit()) {
NS_ERROR("CARenderer not initialized");
return false;
}
if (mDrawingModel == NPDrawingModelCoreGraphics) {
mozilla::plugins::PluginUtilsOSX::Repaint(mCGLayer, rect);
}
mCARenderer.Render(mWindow.width, mWindow.height, nsnull);
NPRect r = { (uint16_t)rect.y, (uint16_t)rect.x,
(uint16_t)rect.YMost(), (uint16_t)rect.XMost() };
SurfaceDescriptor currSurf;
currSurf = IOSurfaceDescriptor(mCurrentIOSurface->GetIOSurfaceID());
// Unused
SurfaceDescriptor returnSurf;
if (!SendShow(r, currSurf, &returnSurf)) {
return false;
}
return true;
} else {
NS_ERROR("Unsupported drawing model for async layer rendering");
return false;
}
#endif
bool temporarilyMakeVisible = !IsVisible() && !mHasPainted;
if (temporarilyMakeVisible && mWindow.width && mWindow.height) {
mWindow.clipRect.right = mWindow.width;
@ -3145,6 +3301,7 @@ PluginInstanceChild::InvalidateRect(NPRect* aInvalidRect)
AsyncShowPluginFrame();
return;
}
// If we were going to use layers rendering but it's not set up
// yet, and the plugin happens to call this first, we'll forward
// the invalidation to the browser. It's unclear whether
@ -3384,6 +3541,18 @@ PluginInstanceChild::ClearAllSurfaces()
mBackSurfaceActor = NULL;
}
#endif
#ifdef XP_MACOSX
if (mCurrentIOSurface) {
// Get last surface back, and drop it
SurfaceDescriptor temp = null_t();
NPRect r = { 0, 0, 1, 1 };
SendShow(r, temp, &temp);
}
mCurrentIOSurface = nsnull;
#endif
}
bool

View File

@ -414,11 +414,14 @@ private:
CGContextRef mShContext;
int16_t mDrawingModel;
nsCARenderer mCARenderer;
void *mCGLayer;
public:
const NPCocoaEvent* getCurrentEvent() {
return mCurrentEvent;
}
bool CGDraw(CGContextRef ref, nsIntRect aUpdateRect);
#if defined(__i386__)
NPEventModel EventModel() { return mEventModel; }
@ -511,6 +514,12 @@ private:
// surface which is on ParentProcess side
nsRefPtr<gfxASurface> mBackSurface;
#ifdef XP_MACOSX
// Current IOSurface available for rendering
// We can't use thebes gfxASurface like other platforms.
nsAutoPtr<nsIOSurface> mCurrentIOSurface;
#endif
// (Not to be confused with mBackSurface). This is a recent copy
// of the opaque pixels under our object frame, if
// |mIsTransparent|. We ask the plugin render directly onto a

View File

@ -103,7 +103,6 @@ PluginInstanceParent::PluginInstanceParent(PluginModuleParent* parent,
, mShHeight(0)
, mShColorSpace(nsnull)
, mDrawingModel(NPDrawingModelCoreGraphics)
, mIOSurface(nsnull)
#endif
{
InitQuirksModes(aMimeType);
@ -137,7 +136,6 @@ PluginInstanceParent::~PluginInstanceParent()
}
if (mShColorSpace)
::CGColorSpaceRelease(mShColorSpace);
delete mIOSurface;
if (mDrawingModel == NPDrawingModelCoreAnimation) {
mParent->RemoveFromRefreshTimer(this);
}
@ -517,6 +515,29 @@ PluginInstanceParent::RecvShow(const NPRect& updatedRect,
}
surface = gfxSharedImageSurface::Open(newSurface.get_Shmem());
}
#ifdef XP_MACOSX
else if (newSurface.type() == SurfaceDescriptor::TIOSurfaceDescriptor) {
IOSurfaceDescriptor iodesc = newSurface.get_IOSurfaceDescriptor();
nsIOSurface *newIOSurface = nsIOSurface::LookupSurface(iodesc.surfaceId());
if (!newIOSurface) {
NS_WARNING("Got bad IOSurfaceDescriptor in RecvShow");
return false;
}
mIOSurface = newIOSurface;
RecvNPN_InvalidateRect(updatedRect);
*prevSurface = null_t();
PLUGIN_LOG_DEBUG((" (RecvShow invalidated for surface %p)",
mFrontSurface.get()));
return true;
}
#endif
#ifdef MOZ_X11
else if (newSurface.type() == SurfaceDescriptor::TSurfaceDescriptorX11) {
SurfaceDescriptorX11 xdesc = newSurface.get_SurfaceDescriptorX11();
@ -659,16 +680,6 @@ PluginInstanceParent::GetImageSize(nsIntSize* aSize)
return NS_ERROR_NOT_AVAILABLE;
}
#ifdef XP_MACOSX
nsresult
PluginInstanceParent::IsRemoteDrawingCoreAnimation(PRBool *aDrawing)
{
*aDrawing = (NPDrawingModelCoreAnimation == (NPDrawingModel)mDrawingModel ||
NPDrawingModelInvalidatingCoreAnimation == (NPDrawingModel)mDrawingModel);
return NS_OK;
}
#endif
nsresult
PluginInstanceParent::SetBackgroundUnknown()
{
@ -869,7 +880,6 @@ PluginInstanceParent::NPP_SetWindow(const NPWindow* aWindow)
if (mShWidth != window.width || mShHeight != window.height) {
if (mDrawingModel == NPDrawingModelCoreAnimation ||
mDrawingModel == NPDrawingModelInvalidatingCoreAnimation) {
delete mIOSurface;
mIOSurface = nsIOSurface::CreateIOSurface(window.width, window.height);
} else if (mShWidth * mShHeight != window.width * window.height) {
if (mShWidth != 0 && mShHeight != 0) {

View File

@ -282,9 +282,6 @@ public:
nsresult AsyncSetWindow(NPWindow* window);
nsresult GetImage(mozilla::layers::ImageContainer* aContainer, mozilla::layers::Image** aImage);
nsresult GetImageSize(nsIntSize* aSize);
#ifdef XP_MACOSX
nsresult IsRemoteDrawingCoreAnimation(PRBool *aDrawing);
#endif
nsresult SetBackgroundUnknown();
nsresult BeginUpdateBackground(const nsIntRect& aRect,
gfxContext** aCtx);
@ -352,12 +349,12 @@ private:
#endif // defined(XP_WIN)
#if defined(OS_MACOSX)
private:
Shmem mShSurface;
size_t mShWidth;
size_t mShHeight;
CGColorSpaceRef mShColorSpace;
int16_t mDrawingModel;
nsIOSurface *mIOSurface;
Shmem mShSurface;
size_t mShWidth;
size_t mShHeight;
CGColorSpaceRef mShColorSpace;
int16_t mDrawingModel;
nsAutoPtr<nsIOSurface> mIOSurface;
#endif // definied(OS_MACOSX)
// ObjectFrame layer wrapper

View File

@ -32,6 +32,8 @@
#include "base/basictypes.h"
#include "nsPoint.h"
#include "npapi.h"
#include "nsRect.h"
// Make this includable from non-Objective-C code.
#ifndef __OBJC__

View File

@ -102,9 +102,6 @@ public:
virtual nsresult GetImage(NPP instance, ImageContainer* aContainer, Image** aImage) = 0;
virtual nsresult GetImageSize(NPP instance, nsIntSize* aSize) = 0;
virtual bool UseAsyncPainting() = 0;
#if defined(XP_MACOSX)
virtual nsresult IsRemoteDrawingCoreAnimation(NPP instance, PRBool *aDrawing) = 0;
#endif
/**
* The next three methods are the third leg in the trip to
* PluginInstanceParent. They approximately follow the ReadbackSink

View File

@ -39,8 +39,8 @@
#ifdef MOZ_WIDGET_GTK2
#include <glib.h>
#elif XP_MACOSX
#include "PluginUtilsOSX.h"
#include "PluginInterposeOSX.h"
#include "PluginUtilsOSX.h"
#include "nsIPrefService.h"
#include "nsIPrefBranch.h"
#endif
@ -924,18 +924,6 @@ PluginModuleParent::NPP_GetSitesWithData(InfallibleTArray<nsCString>& result)
return NS_OK;
}
#if defined(XP_MACOSX)
nsresult
PluginModuleParent::IsRemoteDrawingCoreAnimation(NPP instance, PRBool *aDrawing)
{
PluginInstanceParent* i = InstCast(instance);
if (!i)
return NS_ERROR_FAILURE;
return i->IsRemoteDrawingCoreAnimation(aDrawing);
}
#endif
bool
PluginModuleParent::AnswerNPN_GetValue_WithBoolReturn(const NPNVariable& aVariable,
NPError* aError,

View File

@ -282,10 +282,6 @@ private:
uint64_t maxAge);
virtual nsresult NPP_GetSitesWithData(InfallibleTArray<nsCString>& result);
#if defined(XP_MACOSX)
virtual nsresult IsRemoteDrawingCoreAnimation(NPP instance, PRBool *aDrawing);
#endif
private:
void WritePluginExtraDataForMinidump(const nsAString& id);
void WriteExtraDataForHang();

View File

@ -38,18 +38,27 @@
* ***** END LICENSE BLOCK ***** */
#include "npapi.h"
#include "nsRect.h"
namespace mozilla {
namespace plugins {
namespace PluginUtilsOSX {
// Need to call back into the browser's to process event.
// Need to call back into the browser's message loop to process event.
typedef void (*RemoteProcessEvents) (void*);
NPError ShowCocoaContextMenu(void* aMenu, int aX, int aY, void* pluginModule, RemoteProcessEvents remoteEvent);
void InvokeNativeEventLoop();
// Need to call back and send a cocoa draw event to the plugin.
typedef void (*DrawPluginFunc) (CGContextRef, void*, nsIntRect aUpdateRect);
void* GetCGLayer(DrawPluginFunc aFunc, void* aPluginInstance);
void ReleaseCGLayer(void* cgLayer);
void Repaint(void* cgLayer, nsIntRect aRect);
} // namespace PluginUtilsOSX
} // namespace plugins
} // namespace mozilla

View File

@ -38,6 +38,7 @@
* ***** END LICENSE BLOCK ***** */
#import <AppKit/AppKit.h>
#import <QuartzCore/QuartzCore.h>
#include "PluginUtilsOSX.h"
// Remove definitions for try/catch interfering with ObjCException macros.
@ -45,6 +46,61 @@
using namespace mozilla::plugins::PluginUtilsOSX;
@interface CGBridgeLayer : CALayer {
DrawPluginFunc mDrawFunc;
void* mPluginInstance;
nsIntRect mUpdateRect;
}
- (void) setDrawFunc: (DrawPluginFunc)aFunc pluginInstance:(void*) aPluginInstance;
- (void) updateRect: (nsIntRect)aRect;
@end
@implementation CGBridgeLayer
- (void) updateRect: (nsIntRect)aRect
{
mUpdateRect.UnionRect(mUpdateRect, aRect);
}
- (void) setDrawFunc: (DrawPluginFunc)aFunc pluginInstance:(void*) aPluginInstance
{
mDrawFunc = aFunc;
mPluginInstance = aPluginInstance;
}
- (void)drawInContext:(CGContextRef)aCGContext
{
::CGContextSaveGState(aCGContext);
::CGContextTranslateCTM(aCGContext, 0, self.bounds.size.height);
::CGContextScaleCTM(aCGContext, (CGFloat) 1, (CGFloat) -1);
mDrawFunc(aCGContext, mPluginInstance, mUpdateRect);
::CGContextRestoreGState(aCGContext);
mUpdateRect.SetEmpty();
}
@end
void* mozilla::plugins::PluginUtilsOSX::GetCGLayer(DrawPluginFunc aFunc, void* aPluginInstance) {
CGBridgeLayer *bridgeLayer = [[CGBridgeLayer alloc] init ];
[bridgeLayer setDrawFunc:aFunc pluginInstance:aPluginInstance];
return bridgeLayer;
}
void mozilla::plugins::PluginUtilsOSX::ReleaseCGLayer(void *cgLayer) {
CGBridgeLayer *bridgeLayer = (CGBridgeLayer*)cgLayer;
[bridgeLayer release];
}
void mozilla::plugins::PluginUtilsOSX::Repaint(void *caLayer, nsIntRect aRect) {
CGBridgeLayer *bridgeLayer = (CGBridgeLayer*)caLayer;
[bridgeLayer updateRect:aRect];
[bridgeLayer setNeedsDisplay];
}
@interface EventProcessor : NSObject {
RemoteProcessEvents aRemoteEvents;
void *aPluginModule;

View File

@ -1500,7 +1500,9 @@ nsObjectFrame::UpdateImageLayer(ImageContainer* aContainer, const gfxRect& aRect
}
#ifdef XP_MACOSX
mInstanceOwner->DoCocoaEventDrawRect(aRect, nsnull);
if (!mInstanceOwner->UseAsyncRendering()) {
mInstanceOwner->DoCocoaEventDrawRect(aRect, nsnull);
}
#endif
mInstanceOwner->SetCurrentImage(aContainer);
@ -1516,9 +1518,9 @@ nsObjectFrame::GetLayerState(nsDisplayListBuilder* aBuilder,
#ifdef XP_MACOSX
if (aManager &&
aManager->GetBackendType() == LayerManager::LAYERS_OPENGL &&
mInstanceOwner->UseAsyncRendering() &&
mInstanceOwner->GetEventModel() == NPEventModelCocoa &&
mInstanceOwner->GetDrawingModel() == NPDrawingModelCoreGraphics &&
mInstanceOwner->IsRemoteDrawingCoreAnimation())
mInstanceOwner->GetDrawingModel() == NPDrawingModelCoreGraphics)
{
return LAYER_ACTIVE;
}