Bug 663259 - Enable Mac Async plugin by default. r=cjones,mattwoodrow

--HG--
extra : rebase_source : 6d397273f10e659a08125b3861e1651a3994aaa0
This commit is contained in:
Benoit Girard 2011-07-12 10:31:18 -04:00
parent 9ab821ee73
commit 2ab0d12f09
16 changed files with 325 additions and 104 deletions

View File

@ -567,7 +567,7 @@ pref("plugins.hide_infobar_for_missing_plugin", false);
pref("plugins.hide_infobar_for_outdated_plugin", false);
#ifdef XP_MACOSX
pref("plugins.use_layers", false);
pref("plugins.use_layers", true);
pref("plugins.hide_infobar_for_carbon_failure_plugin", false);
#endif

View File

@ -87,7 +87,7 @@ nsNPAPIPluginInstance::nsNPAPIPluginInstance(nsNPAPIPlugin* plugin)
mMIMEType(nsnull),
mOwner(nsnull),
mCurrentPluginEvent(nsnull),
#if defined(MOZ_X11) || defined(XP_WIN)
#if defined(MOZ_X11) || defined(XP_WIN) || defined(XP_MACOSX)
mUsePluginLayersPref(PR_TRUE)
#else
mUsePluginLayersPref(PR_FALSE)

View File

@ -1477,8 +1477,8 @@ void nsPluginInstanceOwner::RenderCoreAnimation(CGContextRef aCGContext,
// If the renderer is backed by an IOSurface, resize it as required.
mIOSurface = nsIOSurface::CreateIOSurface(aWidth, aHeight);
if (mIOSurface) {
nsIOSurface *attachSurface = nsIOSurface::LookupSurface(
mIOSurface->GetIOSurfaceID());
nsRefPtr<nsIOSurface> attachSurface = nsIOSurface::LookupSurface(
mIOSurface->GetIOSurfaceID());
if (attachSurface) {
mCARenderer.AttachIOSurface(attachSurface);
} else {

View File

@ -324,7 +324,7 @@ private:
NP_Port mQDPluginPortCopy;
#endif
PRInt32 mInCGPaintLevel;
nsIOSurface *mIOSurface;
nsRefPtr<nsIOSurface> mIOSurface;
nsCARenderer mCARenderer;
CGColorSpaceRef mColorProfile;
static nsCOMPtr<nsITimer> *sCATimer;

View File

@ -75,6 +75,7 @@ EXPORTS_mozilla/plugins = \
PluginScriptableObjectUtils-inl.h \
PluginInstanceChild.h \
PluginInstanceParent.h \
PluginUtilsOSX.h \
AStream.h \
BrowserStreamChild.h \
BrowserStreamParent.h \

View File

@ -186,7 +186,7 @@ PluginInstanceChild::~PluginInstanceChild()
::CGContextRelease(mShContext);
}
if (mCGLayer) {
mozilla::plugins::PluginUtilsOSX::ReleaseCGLayer(mCGLayer);
PluginUtilsOSX::ReleaseCGLayer(mCGLayer);
}
#endif
}
@ -844,7 +844,7 @@ PluginInstanceChild::AnswerNPP_HandleEvent_IOSurface(const NPRemoteEvent& event,
PaintTracker pt;
NPCocoaEvent evcopy = event.event;
nsIOSurface* surf = nsIOSurface::LookupSurface(surfaceid);
nsRefPtr<nsIOSurface> surf = nsIOSurface::LookupSurface(surfaceid);
if (!surf) {
NS_ERROR("Invalid IOSurface.");
*handled = false;
@ -2577,44 +2577,18 @@ 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);
if (!mDoubleBufferCARenderer.HasCALayer()) {
void *caLayer = nsnull;
if (mDrawingModel == NPDrawingModelCoreGraphics) {
if (mCGLayer) {
mozilla::plugins::PluginUtilsOSX::ReleaseCGLayer(mCGLayer);
mCGLayer = nsnull;
}
if (!mCGLayer) {
caLayer = mozilla::plugins::PluginUtilsOSX::GetCGLayer(CallCGDraw, this);
caLayer = mozilla::plugins::PluginUtilsOSX::GetCGLayer(CallCGDraw, this);
if (!caLayer) {
return false;
if (!caLayer) {
PLUGIN_LOG_DEBUG(("GetCGLayer failed."));
return false;
}
}
mCGLayer = caLayer;
} else {
NPError result = mPluginIface->getvalue(GetNPP(),
@ -2626,13 +2600,30 @@ PluginInstanceChild::EnsureCurrentBuffer(void)
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);
mDoubleBufferCARenderer.SetCALayer(caLayer);
}
if (mDoubleBufferCARenderer.HasFrontSurface() &&
(mDoubleBufferCARenderer.GetFrontSurfaceWidth() != mWindow.width ||
mDoubleBufferCARenderer.GetFrontSurfaceHeight() != mWindow.height) ) {
mDoubleBufferCARenderer.ClearFrontSurface();
}
if (!mDoubleBufferCARenderer.HasFrontSurface()) {
bool allocSurface = mDoubleBufferCARenderer.InitFrontSurface(mWindow.width,
mWindow.height);
if (!allocSurface) {
PLUGIN_LOG_DEBUG(("Fail to allocate front IOSurface"));
return false;
}
if (mPluginIface->setwindow)
(void) mPluginIface->setwindow(&mData, &mWindow);
nsIntRect toInvalidate(0, 0, mWindow.width, mWindow.height);
mAccumulatedInvalidRect.UnionRect(mAccumulatedInvalidRect, toInvalidate);
}
return true;
#endif
}
@ -3030,7 +3021,7 @@ PluginInstanceChild::ShowPluginFrame()
return false;
}
#ifdef XP_MACOSX
#ifdef MOZ_WIDGET_COCOA
// We can't use the thebes code with CoreAnimation so we will
// take a different code path.
if (mDrawingModel == NPDrawingModelCoreAnimation ||
@ -3041,6 +3032,11 @@ PluginInstanceChild::ShowPluginFrame()
return true;
}
if (!mDoubleBufferCARenderer.HasFrontSurface()) {
NS_ERROR("CARenderer not initialized for rendering");
return false;
}
// Clear accRect here to be able to pass
// test_invalidate_during_plugin_paint test
nsIntRect rect = mAccumulatedInvalidRect;
@ -3049,33 +3045,30 @@ PluginInstanceChild::ShowPluginFrame()
// 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;
}
nsIntRect(0, 0,
mDoubleBufferCARenderer.GetFrontSurfaceWidth(),
mDoubleBufferCARenderer.GetFrontSurfaceHeight()));
if (mDrawingModel == NPDrawingModelCoreGraphics) {
mozilla::plugins::PluginUtilsOSX::Repaint(mCGLayer, rect);
}
mCARenderer.Render(mWindow.width, mWindow.height, nsnull);
mDoubleBufferCARenderer.Render();
NPRect r = { (uint16_t)rect.y, (uint16_t)rect.x,
(uint16_t)rect.YMost(), (uint16_t)rect.XMost() };
SurfaceDescriptor currSurf;
currSurf = IOSurfaceDescriptor(mCurrentIOSurface->GetIOSurfaceID());
currSurf = IOSurfaceDescriptor(mDoubleBufferCARenderer.GetFrontSurfaceID());
mHasPainted = true;
// Unused
SurfaceDescriptor returnSurf;
if (!SendShow(r, currSurf, &returnSurf)) {
return false;
}
SwapSurfaces();
return true;
} else {
NS_ERROR("Unsupported drawing model for async layer rendering");
@ -3511,19 +3504,32 @@ PluginInstanceChild::SwapSurfaces()
mBackSurfaceActor = tmpactor;
#endif
#ifdef MOZ_WIDGET_COCOA
mDoubleBufferCARenderer.SwapSurfaces();
// Outdated back surface... not usable anymore due to changed plugin size.
// Dropping obsolete surface
if (mCurrentSurface && mBackSurface &&
(mCurrentSurface->GetSize() != mBackSurface->GetSize() ||
mCurrentSurface->GetContentType() != mBackSurface->GetContentType())) {
ClearCurrentSurface();
if (mDoubleBufferCARenderer.HasFrontSurface() &&
mDoubleBufferCARenderer.HasBackSurface() &&
(mDoubleBufferCARenderer.GetFrontSurfaceWidth() !=
mDoubleBufferCARenderer.GetBackSurfaceWidth() ||
mDoubleBufferCARenderer.GetFrontSurfaceHeight() !=
mDoubleBufferCARenderer.GetBackSurfaceHeight())) {
mDoubleBufferCARenderer.ClearFrontSurface();
}
#endif //MOZ_WIDGET_COCOA
}
void
PluginInstanceChild::ClearCurrentSurface()
{
mCurrentSurface = nsnull;
#ifdef MOZ_WIDGET_COCOA
if (mDoubleBufferCARenderer.HasFrontSurface()) {
mDoubleBufferCARenderer.ClearFrontSurface();
}
#endif
#ifdef XP_WIN
if (mCurrentSurfaceActor) {
PPluginSurfaceChild::Send__delete__(mCurrentSurfaceActor);
@ -3542,6 +3548,7 @@ PluginInstanceChild::ClearAllSurfaces()
NPRect r = { 0, 0, 1, 1 };
SendShow(r, temp, &temp);
}
if (gfxSharedImageSurface::IsSharedImage(mCurrentSurface))
DeallocShmem(static_cast<gfxSharedImageSurface*>(mCurrentSurface.get())->GetShmem());
if (gfxSharedImageSurface::IsSharedImage(mBackSurface))
@ -3560,8 +3567,8 @@ PluginInstanceChild::ClearAllSurfaces()
}
#endif
#ifdef XP_MACOSX
if (mCurrentIOSurface) {
#ifdef MOZ_WIDGET_COCOA
if (mDoubleBufferCARenderer.HasBackSurface()) {
// Get last surface back, and drop it
SurfaceDescriptor temp = null_t();
NPRect r = { 0, 0, 1, 1 };
@ -3573,7 +3580,8 @@ PluginInstanceChild::ClearAllSurfaces()
mCGLayer = nsnull;
}
mCurrentIOSurface = nsnull;
mDoubleBufferCARenderer.ClearFrontSurface();
mDoubleBufferCARenderer.ClearBackSurface();
#endif
}

View File

@ -46,8 +46,11 @@
#if defined(OS_WIN)
#include "mozilla/gfx/SharedDIBWin.h"
#elif defined(MOZ_WIDGET_COCOA)
#include "PluginUtilsOSX.h"
#include "nsCoreAnimationSupport.h"
#include "base/timer.h"
using namespace mozilla::plugins::PluginUtilsOSX;
#endif
#include "npfunctions.h"
@ -524,7 +527,7 @@ private:
#ifdef XP_MACOSX
// Current IOSurface available for rendering
// We can't use thebes gfxASurface like other platforms.
nsAutoPtr<nsIOSurface> mCurrentIOSurface;
nsDoubleBufferCARenderer mDoubleBufferCARenderer;
#endif
// (Not to be confused with mBackSurface). This is a recent copy

View File

@ -519,19 +519,22 @@ PluginInstanceParent::RecvShow(const NPRect& updatedRect,
else if (newSurface.type() == SurfaceDescriptor::TIOSurfaceDescriptor) {
IOSurfaceDescriptor iodesc = newSurface.get_IOSurfaceDescriptor();
nsIOSurface *newIOSurface = nsIOSurface::LookupSurface(iodesc.surfaceId());
nsRefPtr<nsIOSurface> newIOSurface = nsIOSurface::LookupSurface(iodesc.surfaceId());
if (!newIOSurface) {
NS_WARNING("Got bad IOSurfaceDescriptor in RecvShow");
return false;
}
if (mFrontIOSurface)
*prevSurface = IOSurfaceDescriptor(mFrontIOSurface->GetIOSurfaceID());
else
*prevSurface = null_t();
mFrontIOSurface = newIOSurface;
RecvNPN_InvalidateRect(updatedRect);
*prevSurface = null_t();
PLUGIN_LOG_DEBUG((" (RecvShow invalidated for surface %p)",
mFrontSurface.get()));

View File

@ -357,8 +357,8 @@ private:
size_t mShHeight;
CGColorSpaceRef mShColorSpace;
int16_t mDrawingModel;
nsAutoPtr<nsIOSurface> mIOSurface;
nsAutoPtr<nsIOSurface> mFrontIOSurface;
nsRefPtr<nsIOSurface> mIOSurface;
nsRefPtr<nsIOSurface> mFrontIOSurface;
#endif // definied(MOZ_WIDGET_COCOA)
// ObjectFrame layer wrapper

View File

@ -37,8 +37,12 @@
*
* ***** END LICENSE BLOCK ***** */
#ifndef dom_plugins_PluginUtilsOSX_h
#define dom_plugins_PluginUtilsOSX_h 1
#include "npapi.h"
#include "nsRect.h"
#include "nsCoreAnimationSupport.h"
namespace mozilla {
namespace plugins {
@ -60,6 +64,44 @@ void Repaint(void* cgLayer, nsIntRect aRect);
bool SetProcessName(const char* aProcessName);
/*
* Provides a wrapper around nsCARenderer to manage double buffering
* without having to unbind nsCARenderer on every surface swaps.
*
* The double buffer renderer begins with no initialize surfaces.
* The buffers can be initialized and cleared individually.
* Swapping still occurs regardless if the buffers are initialized.
*/
class THEBES_API nsDoubleBufferCARenderer {
public:
nsDoubleBufferCARenderer() : mCALayer(nsnull) {}
size_t GetFrontSurfaceWidth();
size_t GetFrontSurfaceHeight();
size_t GetBackSurfaceWidth();
size_t GetBackSurfaceHeight();
IOSurfaceID GetFrontSurfaceID();
bool HasBackSurface();
bool HasFrontSurface();
bool HasCALayer();
void SetCALayer(void *aCALayer);
bool InitFrontSurface(size_t aWidth, size_t aHeight);
void Render();
void SwapSurfaces();
void ClearFrontSurface();
void ClearBackSurface();
private:
void *mCALayer;
nsRefPtr<nsCARenderer> mFrontRenderer;
nsRefPtr<nsCARenderer> mBackRenderer;
nsRefPtr<nsIOSurface> mFrontSurface;
nsRefPtr<nsIOSurface> mBackSurface;
};
} // namespace PluginUtilsOSX
} // namespace plugins
} // namespace mozilla
#endif //dom_plugins_PluginUtilsOSX_h

View File

@ -276,3 +276,137 @@ bool mozilla::plugins::PluginUtilsOSX::SetProcessName(const char* aProcessName)
return true;
NS_OBJC_END_TRY_ABORT_BLOCK_RETURN(false);
}
namespace mozilla {
namespace plugins {
namespace PluginUtilsOSX {
size_t nsDoubleBufferCARenderer::GetFrontSurfaceWidth() {
if (!HasFrontSurface()) {
return 0;
}
return mFrontSurface->GetWidth();
}
size_t nsDoubleBufferCARenderer::GetFrontSurfaceHeight() {
if (!HasFrontSurface()) {
return 0;
}
return mFrontSurface->GetHeight();
}
size_t nsDoubleBufferCARenderer::GetBackSurfaceWidth() {
if (!HasBackSurface()) {
return 0;
}
return mBackSurface->GetWidth();
}
size_t nsDoubleBufferCARenderer::GetBackSurfaceHeight() {
if (!HasBackSurface()) {
return 0;
}
return mBackSurface->GetHeight();
}
IOSurfaceID nsDoubleBufferCARenderer::GetFrontSurfaceID() {
if (!HasFrontSurface()) {
return 0;
}
return mFrontSurface->GetIOSurfaceID();
}
bool nsDoubleBufferCARenderer::HasBackSurface() {
return !!mBackSurface;
}
bool nsDoubleBufferCARenderer::HasFrontSurface() {
return !!mFrontSurface;
}
bool nsDoubleBufferCARenderer::HasCALayer() {
return !!mCALayer;
}
void nsDoubleBufferCARenderer::SetCALayer(void *aCALayer) {
mCALayer = aCALayer;
}
bool nsDoubleBufferCARenderer::InitFrontSurface(size_t aWidth, size_t aHeight) {
if (!mCALayer) {
return false;
}
mFrontSurface = nsIOSurface::CreateIOSurface(aWidth, aHeight);
if (!mFrontSurface) {
return false;
}
mFrontRenderer = new nsCARenderer();
if (!mFrontRenderer) {
mFrontSurface = nsnull;
return false;
}
nsRefPtr<nsIOSurface> ioSurface = nsIOSurface::LookupSurface(mFrontSurface->GetIOSurfaceID());
if (!ioSurface) {
mFrontRenderer = nsnull;
mFrontSurface = nsnull;
return false;
}
mFrontRenderer->AttachIOSurface(ioSurface);
nsresult result = mFrontRenderer->SetupRenderer(mCALayer,
ioSurface->GetWidth(),
ioSurface->GetHeight());
return result == NS_OK;
}
void nsDoubleBufferCARenderer::Render() {
if (!HasFrontSurface()) {
return;
}
mFrontRenderer->Render(GetFrontSurfaceWidth(), GetFrontSurfaceHeight(), nsnull);
}
void nsDoubleBufferCARenderer::SwapSurfaces() {
if (mFrontRenderer) {
mFrontRenderer->DettachCALayer();
}
nsRefPtr<nsCARenderer> prevFrontRenderer = mFrontRenderer;
nsRefPtr<nsIOSurface> prevFrontSurface = mFrontSurface;
mFrontRenderer = mBackRenderer;
mFrontSurface = mBackSurface;
mBackRenderer = prevFrontRenderer;
mBackSurface = prevFrontSurface;
if (mFrontRenderer) {
mFrontRenderer->AttachCALayer(mCALayer);
}
}
void nsDoubleBufferCARenderer::ClearFrontSurface() {
mFrontRenderer = nsnull;
mFrontSurface = nsnull;
}
void nsDoubleBufferCARenderer::ClearBackSurface() {
mBackRenderer = nsnull;
mBackSurface = nsnull;
}
} //PluginUtilsOSX
} //plugins
} //mozilla

View File

@ -1,8 +1,7 @@
function paintCountIs(plugin, expected, msg) {
var count = plugin.getPaintCount();
var realExpected = expected;
var isAsync = SimpleTest.testPluginIsOOP() &&
navigator.platform.indexOf("Mac") < 0;
var isAsync = SimpleTest.testPluginIsOOP();
if (isAsync) {
++realExpected; // extra paint at startup for all async-rendering plugins
} else {

View File

@ -60,7 +60,7 @@ public:
GLTexture mTexture;
gfxIntSize mSize;
nsAutoPtr<nsIOSurface> mIOSurface;
nsRefPtr<nsIOSurface> mIOSurface;
void* mPluginInstanceOwner;
UpdateSurfaceCallback mUpdateCallback;
DestroyCallback mDestroyCallback;

View File

@ -41,10 +41,11 @@
#define nsCoreAnimationSupport_h__
#ifdef XP_MACOSX
#import <QuartzCore/QuartzCore.h>
#import "ApplicationServices/ApplicationServices.h"
#include "nscore.h"
#include "gfxTypes.h"
#import <QuartzCore/QuartzCore.h>
#include "nsAutoPtr.h"
// Get the system color space.
CGColorSpaceRef THEBES_API CreateSystemColorSpace();
@ -54,7 +55,10 @@ struct _CGLPBufferObject;
struct _CGLContextObject;
class nsIOSurface;
typedef uint32_t IOSurfaceID;
class THEBES_API nsCARenderer {
NS_INLINE_DECL_REFCOUNTING(nsCARenderer)
public:
nsCARenderer() : mCARenderer(nsnull), mPixelBuffer(nsnull), mOpenGLContext(nsnull),
mCGImage(nsnull), mCGData(nsnull), mIOSurface(nsnull), mFBO(nsnull),
@ -69,13 +73,18 @@ public:
* is attached then an internal pixel buffer will be
* used.
*/
void AttachIOSurface(nsIOSurface *aSurface);
void AttachIOSurface(nsRefPtr<nsIOSurface> aSurface);
IOSurfaceID GetIOSurfaceID();
static nsresult DrawSurfaceToCGContext(CGContextRef aContext,
nsIOSurface *surf,
CGColorSpaceRef aColorSpace,
int aX, int aY,
size_t aWidth, size_t aHeight);
// Remove & Add the layer without destroying
// the renderer for fast back buffer swapping.
void DettachCALayer();
void AttachCALayer(void *aCALayer);
#ifdef DEBUG
static void SaveToDisk(nsIOSurface *surf);
#endif
@ -83,24 +92,23 @@ private:
void Destroy();
void *mCARenderer;
_CGLPBufferObject *mPixelBuffer;
_CGLContextObject *mOpenGLContext;
CGImageRef mCGImage;
void *mCGData;
nsIOSurface *mIOSurface;
uint32_t mFBO;
uint32_t mIOTexture;
uint32_t mUnsupportedWidth;
uint32_t mUnsupportedHeight;
_CGLPBufferObject *mPixelBuffer;
_CGLContextObject *mOpenGLContext;
CGImageRef mCGImage;
void *mCGData;
nsRefPtr<nsIOSurface> mIOSurface;
uint32_t mFBO;
uint32_t mIOTexture;
uint32_t mUnsupportedWidth;
uint32_t mUnsupportedHeight;
};
typedef uint32_t IOSurfaceID;
class THEBES_API nsIOSurface {
NS_INLINE_DECL_REFCOUNTING(nsIOSurface)
public:
static nsIOSurface *CreateIOSurface(int aWidth, int aHeight);
static already_AddRefed<nsIOSurface> CreateIOSurface(int aWidth, int aHeight);
static void ReleaseIOSurface(nsIOSurface *aIOSurface);
static nsIOSurface *LookupSurface(IOSurfaceID aSurfaceID);
static already_AddRefed<nsIOSurface> LookupSurface(IOSurfaceID aSurfaceID);
nsIOSurface(CFTypeRef aIOSurfacePtr) : mIOSurfacePtr(aIOSurfacePtr) {}
~nsIOSurface() { CFRelease(mIOSurfacePtr); }

View File

@ -267,7 +267,7 @@ void nsIOSurfaceLib::CloseLibrary() {
sOpenGLFramework = nsnull;
}
nsIOSurface* nsIOSurface::CreateIOSurface(int aWidth, int aHeight) {
already_AddRefed<nsIOSurface> nsIOSurface::CreateIOSurface(int aWidth, int aHeight) {
if (!nsIOSurfaceLib::isInit())
return nsnull;
@ -300,16 +300,16 @@ nsIOSurface* nsIOSurface::CreateIOSurface(int aWidth, int aHeight) {
if (!surfaceRef)
return nsnull;
nsIOSurface* ioSurface = new nsIOSurface(surfaceRef);
nsRefPtr<nsIOSurface> ioSurface = new nsIOSurface(surfaceRef);
if (!ioSurface) {
::CFRelease(surfaceRef);
return nsnull;
}
return ioSurface;
return ioSurface.forget();
}
nsIOSurface* nsIOSurface::LookupSurface(IOSurfaceID aIOSurfaceID) {
already_AddRefed<nsIOSurface> nsIOSurface::LookupSurface(IOSurfaceID aIOSurfaceID) {
if (!nsIOSurfaceLib::isInit())
return nsnull;
@ -317,12 +317,12 @@ nsIOSurface* nsIOSurface::LookupSurface(IOSurfaceID aIOSurfaceID) {
if (!surfaceRef)
return nsnull;
nsIOSurface* ioSurface = new nsIOSurface(surfaceRef);
nsRefPtr<nsIOSurface> ioSurface = new nsIOSurface(surfaceRef);
if (!ioSurface) {
::CFRelease(surfaceRef);
return nsnull;
}
return ioSurface;
return ioSurface.forget();
}
IOSurfaceID nsIOSurface::GetIOSurfaceID() {
@ -427,9 +427,6 @@ void nsCARenderer::Destroy() {
if (mCGImage) {
::CGImageRelease(mCGImage);
}
if (mIOSurface) {
delete mIOSurface;
}
// mCGData is deallocated by cgdata_release_callback
mCARenderer = nil;
@ -512,7 +509,6 @@ nsresult nsCARenderer::SetupRenderer(void *aCALayer, int aWidth, int aHeight) {
layer.actions = newActions;
[newActions release];
double time = 0;
[CATransaction setValue: [NSNumber numberWithFloat:0.0f] forKey: kCATransactionAnimationDuration];
[CATransaction setValue: (id) kCFBooleanTrue forKey: kCATransactionDisableActions];
[layer setBounds:CGRectMake(0, 0, aWidth, aHeight)];
@ -626,10 +622,12 @@ nsresult nsCARenderer::SetupRenderer(void *aCALayer, int aWidth, int aHeight) {
return NS_OK;
}
void nsCARenderer::AttachIOSurface(nsIOSurface *aSurface) {
void nsCARenderer::AttachIOSurface(nsRefPtr<nsIOSurface> aSurface) {
if (mIOSurface &&
aSurface->GetIOSurfaceID() == mIOSurface->GetIOSurfaceID()) {
delete aSurface;
// This object isn't needed since we already have a
// handle to the same io surface.
aSurface = nsnull;
return;
}
if (mCARenderer) {
@ -637,12 +635,18 @@ void nsCARenderer::AttachIOSurface(nsIOSurface *aSurface) {
// resize our elements.
Destroy();
}
if (mIOSurface)
delete mIOSurface;
mIOSurface = aSurface;
}
IOSurfaceID nsCARenderer::GetIOSurfaceID() {
if (!mIOSurface) {
return 0;
}
return mIOSurface->GetIOSurfaceID();
}
nsresult nsCARenderer::Render(int aWidth, int aHeight,
CGImageRef *aOutCGImage) {
if (!aOutCGImage && !mIOSurface) {
@ -782,6 +786,19 @@ nsresult nsCARenderer::DrawSurfaceToCGContext(CGContextRef aContext,
return NS_OK;
}
void nsCARenderer::DettachCALayer() {
CARenderer* caRenderer = (CARenderer*)mCARenderer;
caRenderer.layer = nil;
}
void nsCARenderer::AttachCALayer(void *aCALayer) {
CARenderer* caRenderer = (CARenderer*)mCARenderer;
CALayer* caLayer = (CALayer*)aCALayer;
caRenderer.layer = caLayer;
}
#ifdef DEBUG
int sSaveToDiskSequence = 0;
@ -834,3 +851,4 @@ void nsCARenderer::SaveToDisk(nsIOSurface *surf) {
}
#endif

View File

@ -1559,9 +1559,14 @@ nsObjectFrame::GetLayerState(nsDisplayListBuilder* aBuilder,
return LAYER_NONE;
#ifdef XP_MACOSX
if (aManager && aManager->GetBackendType() ==
LayerManager::LAYERS_OPENGL &&
!mInstanceOwner->UseAsyncRendering() &&
// Layer painting not supported without OpenGL
if (aManager && aManager->GetBackendType() !=
LayerManager::LAYERS_OPENGL) {
return LAYER_NONE;
}
// Synchronous painting, but with (gecko) layers.
if (!mInstanceOwner->UseAsyncRendering() &&
mInstanceOwner->IsRemoteDrawingCoreAnimation() &&
mInstanceOwner->GetEventModel() == NPEventModelCocoa) {
return LAYER_ACTIVE;