зеркало из https://github.com/mozilla/gecko-dev.git
Bug 829284 - Unity plugin doesn't display in HiDPI mode. r=bgirard
This commit is contained in:
Родитель
e0f25c9274
Коммит
c20100d89c
|
@ -3050,7 +3050,8 @@ PluginInstanceChild::EnsureCurrentBuffer(void)
|
||||||
bool avoidCGCrashes = !nsCocoaFeatures::OnMountainLionOrLater() &&
|
bool avoidCGCrashes = !nsCocoaFeatures::OnMountainLionOrLater() &&
|
||||||
(GetQuirks() & PluginModuleChild::QUIRK_FLASH_AVOID_CGMODE_CRASHES);
|
(GetQuirks() & PluginModuleChild::QUIRK_FLASH_AVOID_CGMODE_CRASHES);
|
||||||
caLayer = mozilla::plugins::PluginUtilsOSX::GetCGLayer(CallCGDraw, this,
|
caLayer = mozilla::plugins::PluginUtilsOSX::GetCGLayer(CallCGDraw, this,
|
||||||
avoidCGCrashes);
|
avoidCGCrashes,
|
||||||
|
mContentsScaleFactor);
|
||||||
|
|
||||||
if (!caLayer) {
|
if (!caLayer) {
|
||||||
PLUGIN_LOG_DEBUG(("GetCGLayer failed."));
|
PLUGIN_LOG_DEBUG(("GetCGLayer failed."));
|
||||||
|
|
|
@ -25,7 +25,8 @@ void InvokeNativeEventLoop();
|
||||||
// Need to call back and send a cocoa draw event to the plugin.
|
// Need to call back and send a cocoa draw event to the plugin.
|
||||||
typedef void (*DrawPluginFunc) (CGContextRef, void*, nsIntRect aUpdateRect);
|
typedef void (*DrawPluginFunc) (CGContextRef, void*, nsIntRect aUpdateRect);
|
||||||
|
|
||||||
void* GetCGLayer(DrawPluginFunc aFunc, void* aPluginInstance, bool aAvoidCGCrashes);
|
void* GetCGLayer(DrawPluginFunc aFunc, void* aPluginInstance,
|
||||||
|
bool aAvoidCGCrashes, double aContentsScaleFactor);
|
||||||
void ReleaseCGLayer(void* cgLayer);
|
void ReleaseCGLayer(void* cgLayer);
|
||||||
void Repaint(void* cgLayer, nsIntRect aRect);
|
void Repaint(void* cgLayer, nsIntRect aRect);
|
||||||
|
|
||||||
|
|
|
@ -134,9 +134,36 @@ CGBitmapContextSetDataFunc CGBitmapContextSetDataPtr = NULL;
|
||||||
@end
|
@end
|
||||||
|
|
||||||
void* mozilla::plugins::PluginUtilsOSX::GetCGLayer(DrawPluginFunc aFunc, void* aPluginInstance,
|
void* mozilla::plugins::PluginUtilsOSX::GetCGLayer(DrawPluginFunc aFunc, void* aPluginInstance,
|
||||||
bool aAvoidCGCrashes)
|
bool aAvoidCGCrashes, double aContentsScaleFactor)
|
||||||
{
|
{
|
||||||
CGBridgeLayer *bridgeLayer = [[CGBridgeLayer alloc] init ];
|
CGBridgeLayer *bridgeLayer = [[CGBridgeLayer alloc] init];
|
||||||
|
|
||||||
|
// We need to make bridgeLayer behave properly when its superlayer changes
|
||||||
|
// size (in nsCARenderer::SetBounds()).
|
||||||
|
bridgeLayer.autoresizingMask = kCALayerWidthSizable | kCALayerHeightSizable;
|
||||||
|
bridgeLayer.needsDisplayOnBoundsChange = YES;
|
||||||
|
NSNull *nullValue = [NSNull null];
|
||||||
|
NSDictionary *actions = [NSDictionary dictionaryWithObjectsAndKeys:
|
||||||
|
nullValue, @"bounds",
|
||||||
|
nullValue, @"contents",
|
||||||
|
nullValue, @"contentsRect",
|
||||||
|
nullValue, @"position",
|
||||||
|
nil];
|
||||||
|
[bridgeLayer setStyle:[NSDictionary dictionaryWithObject:actions forKey:@"actions"]];
|
||||||
|
|
||||||
|
// For reasons that aren't clear (perhaps one or more OS bugs), we can only
|
||||||
|
// use full HiDPI resolution here if the tree is built with the 10.7 SDK or
|
||||||
|
// up. If we build with the 10.6 SDK, changing the contentsScale property
|
||||||
|
// of bridgeLayer (even to the same value) causes it to stop working (go
|
||||||
|
// blank). This doesn't happen with objects that are members of the CALayer
|
||||||
|
// class (as opposed to one of its subclasses).
|
||||||
|
#if defined(MAC_OS_X_VERSION_10_7) && \
|
||||||
|
MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7
|
||||||
|
if ([bridgeLayer respondsToSelector:@selector(setContentsScale:)]) {
|
||||||
|
bridgeLayer.contentsScale = aContentsScaleFactor;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
[bridgeLayer setDrawFunc:aFunc
|
[bridgeLayer setDrawFunc:aFunc
|
||||||
pluginInstance:aPluginInstance
|
pluginInstance:aPluginInstance
|
||||||
avoidCGCrashes:aAvoidCGCrashes];
|
avoidCGCrashes:aAvoidCGCrashes];
|
||||||
|
|
|
@ -25,9 +25,9 @@ enum AllowOfflineRendererEnum { ALLOW_OFFLINE_RENDERER, DISALLOW_OFFLINE_RENDERE
|
||||||
|
|
||||||
class nsCARenderer : public mozilla::RefCounted<nsCARenderer> {
|
class nsCARenderer : public mozilla::RefCounted<nsCARenderer> {
|
||||||
public:
|
public:
|
||||||
nsCARenderer() : mCARenderer(nullptr), mFBOTexture(0), mOpenGLContext(nullptr),
|
nsCARenderer() : mCARenderer(nullptr), mWrapperCALayer(nullptr), mFBOTexture(0),
|
||||||
mCGImage(nullptr), mCGData(nullptr), mIOSurface(nullptr), mFBO(0),
|
mOpenGLContext(nullptr), mCGImage(nullptr), mCGData(nullptr),
|
||||||
mIOTexture(0),
|
mIOSurface(nullptr), mFBO(0), mIOTexture(0),
|
||||||
mUnsupportedWidth(UINT32_MAX), mUnsupportedHeight(UINT32_MAX),
|
mUnsupportedWidth(UINT32_MAX), mUnsupportedHeight(UINT32_MAX),
|
||||||
mAllowOfflineRenderer(DISALLOW_OFFLINE_RENDERER),
|
mAllowOfflineRenderer(DISALLOW_OFFLINE_RENDERER),
|
||||||
mContentsScaleFactor(1.0) {}
|
mContentsScaleFactor(1.0) {}
|
||||||
|
@ -62,7 +62,7 @@ public:
|
||||||
|
|
||||||
// Remove & Add the layer without destroying
|
// Remove & Add the layer without destroying
|
||||||
// the renderer for fast back buffer swapping.
|
// the renderer for fast back buffer swapping.
|
||||||
void DettachCALayer();
|
void DetachCALayer();
|
||||||
void AttachCALayer(void *aCALayer);
|
void AttachCALayer(void *aCALayer);
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
static void SaveToDisk(MacIOSurface *surf);
|
static void SaveToDisk(MacIOSurface *surf);
|
||||||
|
@ -77,6 +77,7 @@ private:
|
||||||
void Destroy();
|
void Destroy();
|
||||||
|
|
||||||
void *mCARenderer;
|
void *mCARenderer;
|
||||||
|
void *mWrapperCALayer;
|
||||||
GLuint mFBOTexture;
|
GLuint mFBOTexture;
|
||||||
_CGLContextObject *mOpenGLContext;
|
_CGLContextObject *mOpenGLContext;
|
||||||
CGImageRef mCGImage;
|
CGImageRef mCGImage;
|
||||||
|
|
|
@ -489,6 +489,10 @@ void nsCARenderer::Destroy() {
|
||||||
caRenderer.layer = nullptr;
|
caRenderer.layer = nullptr;
|
||||||
[caRenderer release];
|
[caRenderer release];
|
||||||
}
|
}
|
||||||
|
if (mWrapperCALayer) {
|
||||||
|
CALayer* wrapperLayer = (CALayer*)mWrapperCALayer;
|
||||||
|
[wrapperLayer release];
|
||||||
|
}
|
||||||
if (mOpenGLContext) {
|
if (mOpenGLContext) {
|
||||||
if (mFBO || mIOTexture || mFBOTexture) {
|
if (mFBO || mIOTexture || mFBOTexture) {
|
||||||
// Release these resources with the context that allocated them
|
// Release these resources with the context that allocated them
|
||||||
|
@ -517,6 +521,7 @@ void nsCARenderer::Destroy() {
|
||||||
// mCGData is deallocated by cgdata_release_callback
|
// mCGData is deallocated by cgdata_release_callback
|
||||||
|
|
||||||
mCARenderer = nil;
|
mCARenderer = nil;
|
||||||
|
mWrapperCALayer = nil;
|
||||||
mFBOTexture = 0;
|
mFBOTexture = 0;
|
||||||
mOpenGLContext = nullptr;
|
mOpenGLContext = nullptr;
|
||||||
mCGImage = nullptr;
|
mCGImage = nullptr;
|
||||||
|
@ -538,9 +543,6 @@ nsresult nsCARenderer::SetupRenderer(void *aCALayer, int aWidth, int aHeight,
|
||||||
return NS_ERROR_FAILURE;
|
return NS_ERROR_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
CALayer* layer = (CALayer*)aCALayer;
|
|
||||||
CARenderer* caRenderer = nullptr;
|
|
||||||
|
|
||||||
CGLPixelFormatAttribute attributes[] = {
|
CGLPixelFormatAttribute attributes[] = {
|
||||||
kCGLPFAAccelerated,
|
kCGLPFAAccelerated,
|
||||||
kCGLPFADepthSize, (CGLPixelFormatAttribute)24,
|
kCGLPFADepthSize, (CGLPixelFormatAttribute)24,
|
||||||
|
@ -569,17 +571,27 @@ nsresult nsCARenderer::SetupRenderer(void *aCALayer, int aWidth, int aHeight,
|
||||||
}
|
}
|
||||||
::CGLDestroyPixelFormat(format);
|
::CGLDestroyPixelFormat(format);
|
||||||
|
|
||||||
caRenderer = [[CARenderer rendererWithCGLContext:mOpenGLContext
|
CARenderer* caRenderer = [[CARenderer rendererWithCGLContext:mOpenGLContext
|
||||||
options:nil] retain];
|
options:nil] retain];
|
||||||
mCARenderer = caRenderer;
|
|
||||||
if (caRenderer == nil) {
|
if (caRenderer == nil) {
|
||||||
mUnsupportedWidth = aWidth;
|
mUnsupportedWidth = aWidth;
|
||||||
mUnsupportedHeight = aHeight;
|
mUnsupportedHeight = aHeight;
|
||||||
Destroy();
|
Destroy();
|
||||||
return NS_ERROR_FAILURE;
|
return NS_ERROR_FAILURE;
|
||||||
}
|
}
|
||||||
|
CALayer* wrapperCALayer = [[CALayer layer] retain];
|
||||||
|
if (wrapperCALayer == nil) {
|
||||||
|
[caRenderer release];
|
||||||
|
mUnsupportedWidth = aWidth;
|
||||||
|
mUnsupportedHeight = aHeight;
|
||||||
|
Destroy();
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
caRenderer.layer = layer;
|
mCARenderer = caRenderer;
|
||||||
|
mWrapperCALayer = wrapperCALayer;
|
||||||
|
caRenderer.layer = wrapperCALayer;
|
||||||
|
[wrapperCALayer addSublayer:(CALayer*)aCALayer];
|
||||||
mContentsScaleFactor = aContentsScaleFactor;
|
mContentsScaleFactor = aContentsScaleFactor;
|
||||||
size_t intScaleFactor = ceil(mContentsScaleFactor);
|
size_t intScaleFactor = ceil(mContentsScaleFactor);
|
||||||
SetBounds(aWidth, aHeight);
|
SetBounds(aWidth, aHeight);
|
||||||
|
@ -696,82 +708,54 @@ nsresult nsCARenderer::SetupRenderer(void *aCALayer, int aWidth, int aHeight,
|
||||||
|
|
||||||
void nsCARenderer::SetBounds(int aWidth, int aHeight) {
|
void nsCARenderer::SetBounds(int aWidth, int aHeight) {
|
||||||
CARenderer* caRenderer = (CARenderer*)mCARenderer;
|
CARenderer* caRenderer = (CARenderer*)mCARenderer;
|
||||||
CALayer* layer = [mCARenderer layer];
|
CALayer* wrapperLayer = (CALayer*)mWrapperCALayer;
|
||||||
|
NSArray* sublayers = [wrapperLayer sublayers];
|
||||||
|
CALayer* pluginLayer = (CALayer*) [sublayers objectAtIndex:0];
|
||||||
|
|
||||||
// Create a transaction and disable animations
|
// Create a transaction and disable animations
|
||||||
// to make the position update instant.
|
// to make the position update instant.
|
||||||
[CATransaction begin];
|
[CATransaction begin];
|
||||||
NSMutableDictionary *newActions = [[NSMutableDictionary alloc] initWithObjectsAndKeys:[NSNull null], @"onOrderIn",
|
NSMutableDictionary *newActions =
|
||||||
[NSNull null], @"onOrderOut",
|
[[NSMutableDictionary alloc] initWithObjectsAndKeys:
|
||||||
[NSNull null], @"sublayers",
|
[NSNull null], @"onOrderIn",
|
||||||
[NSNull null], @"contents",
|
[NSNull null], @"onOrderOut",
|
||||||
[NSNull null], @"position",
|
[NSNull null], @"sublayers",
|
||||||
[NSNull null], @"bounds",
|
[NSNull null], @"contents",
|
||||||
nil];
|
[NSNull null], @"position",
|
||||||
layer.actions = newActions;
|
[NSNull null], @"bounds",
|
||||||
|
nil];
|
||||||
|
wrapperLayer.actions = newActions;
|
||||||
[newActions release];
|
[newActions release];
|
||||||
|
|
||||||
// If we're in HiDPI mode, mContentsScaleFactor will (presumably) be 2.0.
|
// If we're in HiDPI mode, mContentsScaleFactor will (presumably) be 2.0.
|
||||||
// For some reason, to make things work properly in HiDPI mode we need to
|
// For some reason, to make things work properly in HiDPI mode we need to
|
||||||
// make caRenderer's 'bounds' and 'layer' different sizes -- to set 'bounds'
|
// make caRenderer's 'bounds' and 'layer' different sizes -- to set 'bounds'
|
||||||
// to the size of 'layer's backing store. To make plugins display at HiDPI
|
// to the size of 'layer's backing store. And to avoid this possibly
|
||||||
// resolution we also need to set 'layer's contentScale to
|
// confusing the plugin, we need to hide it's effects from the plugin by
|
||||||
// mContentsScaleFactor.
|
// making pluginLayer (usually the CALayer* provided by the plugin) a
|
||||||
|
// sublayer of our own wrapperLayer (see bug 829284).
|
||||||
size_t intScaleFactor = ceil(mContentsScaleFactor);
|
size_t intScaleFactor = ceil(mContentsScaleFactor);
|
||||||
[CATransaction setValue: [NSNumber numberWithFloat:0.0f] forKey: kCATransactionAnimationDuration];
|
[CATransaction setValue: [NSNumber numberWithFloat:0.0f] forKey: kCATransactionAnimationDuration];
|
||||||
[CATransaction setValue: (id) kCFBooleanTrue forKey: kCATransactionDisableActions];
|
[CATransaction setValue: (id) kCFBooleanTrue forKey: kCATransactionDisableActions];
|
||||||
[layer setBounds:CGRectMake(0, 0, aWidth, aHeight)];
|
[wrapperLayer setBounds:CGRectMake(0, 0, aWidth, aHeight)];
|
||||||
[layer setPosition:CGPointMake(aWidth/2.0, aHeight/2.0)];
|
[wrapperLayer setPosition:CGPointMake(aWidth/2.0, aHeight/2.0)];
|
||||||
|
[pluginLayer setBounds:CGRectMake(0, 0, aWidth, aHeight)];
|
||||||
|
[pluginLayer setFrame:CGRectMake(0, 0, aWidth, aHeight)];
|
||||||
caRenderer.bounds = CGRectMake(0, 0, aWidth * intScaleFactor, aHeight * intScaleFactor);
|
caRenderer.bounds = CGRectMake(0, 0, aWidth * intScaleFactor, aHeight * intScaleFactor);
|
||||||
if (mContentsScaleFactor != 1.0) {
|
if (mContentsScaleFactor != 1.0) {
|
||||||
CGAffineTransform affineTransform = [layer affineTransform];
|
CGAffineTransform affineTransform = [wrapperLayer affineTransform];
|
||||||
affineTransform.a = mContentsScaleFactor;
|
affineTransform.a = mContentsScaleFactor;
|
||||||
affineTransform.d = mContentsScaleFactor;
|
affineTransform.d = mContentsScaleFactor;
|
||||||
affineTransform.tx = ((double)aWidth)/mContentsScaleFactor;
|
affineTransform.tx = ((double)aWidth)/mContentsScaleFactor;
|
||||||
affineTransform.ty = ((double)aHeight)/mContentsScaleFactor;
|
affineTransform.ty = ((double)aHeight)/mContentsScaleFactor;
|
||||||
[layer setAffineTransform:affineTransform];
|
[wrapperLayer setAffineTransform:affineTransform];
|
||||||
if ([layer respondsToSelector:@selector(setContentsScale:)]) {
|
|
||||||
// For reasons that aren't clear (perhaps one or more OS bugs), if layer
|
|
||||||
// belongs to a subclass of CALayer we can only use full HiDPI resolution
|
|
||||||
// here if the tree is built with the 10.7 SDK or up: If we change
|
|
||||||
// layer.contentsScale (even to the same value), layer simply stops
|
|
||||||
// working (goes blank). And even if we're building with the 10.7 SDK,
|
|
||||||
// we can't use full HiDPI resolution if layer belongs to CAOpenGLLayer
|
|
||||||
// or a subclass: Changing layer.contentsScale to values higher than
|
|
||||||
// 1.0 makes it display only in the lower left part of its "box".
|
|
||||||
// We use CGBridgeLayer (a subclass of CALayer) to implement CoreGraphics
|
|
||||||
// mode for OOP plugins. Shockwave uses a subclass of CAOpenGLLayer
|
|
||||||
// (SWRenderer) to implement CoreAnimation mode. The SlingPlayer plugin
|
|
||||||
// uses another subclass of CAOpenGLLayer (CoreAnimationLayer).
|
|
||||||
#if !defined(MAC_OS_X_VERSION_10_7) || \
|
|
||||||
MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_7
|
|
||||||
if ([layer isMemberOfClass:[CALayer class]])
|
|
||||||
#else
|
|
||||||
if (![layer isKindOfClass:[CAOpenGLLayer class]])
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
layer.contentsScale = mContentsScaleFactor;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
// These settings are the default values. But they might have been
|
// These settings are the default values. But they might have been
|
||||||
// changed as above if we were previously running in a HiDPI mode
|
// changed as above if we were previously running in a HiDPI mode
|
||||||
// (i.e. if we just switched from that to a non-HiDPI mode).
|
// (i.e. if we just switched from that to a non-HiDPI mode).
|
||||||
[layer setAffineTransform:CGAffineTransformIdentity];
|
[wrapperLayer setAffineTransform:CGAffineTransformIdentity];
|
||||||
if ([layer respondsToSelector:@selector(setContentsScale:)]) {
|
|
||||||
#if !defined(MAC_OS_X_VERSION_10_7) || \
|
|
||||||
MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_7
|
|
||||||
if ([layer isMemberOfClass:[CALayer class]])
|
|
||||||
#else
|
|
||||||
if (![layer isKindOfClass:[CAOpenGLLayer class]])
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
layer.contentsScale = 1.0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
[CATransaction commit];
|
[CATransaction commit];
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void nsCARenderer::SetViewport(int aWidth, int aHeight) {
|
void nsCARenderer::SetViewport(int aWidth, int aHeight) {
|
||||||
|
@ -855,11 +839,12 @@ nsresult nsCARenderer::Render(int aWidth, int aHeight,
|
||||||
if (aWidth == 0 || aHeight == 0 || aContentsScaleFactor <= 0)
|
if (aWidth == 0 || aHeight == 0 || aContentsScaleFactor <= 0)
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
|
|
||||||
if (!mCARenderer) {
|
if (!mCARenderer || !mWrapperCALayer) {
|
||||||
return NS_ERROR_FAILURE;
|
return NS_ERROR_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
CARenderer* caRenderer = (CARenderer*)mCARenderer;
|
CARenderer* caRenderer = (CARenderer*)mCARenderer;
|
||||||
|
CALayer* wrapperLayer = (CALayer*)mWrapperCALayer;
|
||||||
size_t intScaleFactor = ceil(aContentsScaleFactor);
|
size_t intScaleFactor = ceil(aContentsScaleFactor);
|
||||||
int renderer_width = caRenderer.bounds.size.width / intScaleFactor;
|
int renderer_width = caRenderer.bounds.size.width / intScaleFactor;
|
||||||
int renderer_height = caRenderer.bounds.size.height / intScaleFactor;
|
int renderer_height = caRenderer.bounds.size.height / intScaleFactor;
|
||||||
|
@ -868,9 +853,10 @@ nsresult nsCARenderer::Render(int aWidth, int aHeight,
|
||||||
mContentsScaleFactor != aContentsScaleFactor) {
|
mContentsScaleFactor != aContentsScaleFactor) {
|
||||||
// XXX: This should be optimized to not rescale the buffer
|
// XXX: This should be optimized to not rescale the buffer
|
||||||
// if we are resizing down.
|
// if we are resizing down.
|
||||||
// caLayer is the CALayer* provided by the plugin, so we need to preserve
|
// caLayer may be the CALayer* provided by the plugin, so we need to
|
||||||
// it across the call to Destroy().
|
// preserve it across the call to Destroy().
|
||||||
CALayer* caLayer = [caRenderer layer];
|
NSArray* sublayers = [wrapperLayer sublayers];
|
||||||
|
CALayer* caLayer = (CALayer*) [sublayers objectAtIndex:0];
|
||||||
// mIOSurface is set by AttachIOSurface(), not by SetupRenderer(). So
|
// mIOSurface is set by AttachIOSurface(), not by SetupRenderer(). So
|
||||||
// since it may have been set by a prior call to AttachIOSurface(), we
|
// since it may have been set by a prior call to AttachIOSurface(), we
|
||||||
// need to preserve it across the call to Destroy().
|
// need to preserve it across the call to Destroy().
|
||||||
|
@ -1005,17 +991,19 @@ nsresult nsCARenderer::DrawSurfaceToCGContext(CGContextRef aContext,
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
void nsCARenderer::DettachCALayer() {
|
void nsCARenderer::DetachCALayer() {
|
||||||
CARenderer* caRenderer = (CARenderer*)mCARenderer;
|
CALayer* wrapperLayer = (CALayer*)mWrapperCALayer;
|
||||||
|
NSArray* sublayers = [wrapperLayer sublayers];
|
||||||
caRenderer.layer = nil;
|
CALayer* oldLayer = (CALayer*) [sublayers objectAtIndex:0];
|
||||||
|
[oldLayer removeFromSuperlayer];
|
||||||
}
|
}
|
||||||
|
|
||||||
void nsCARenderer::AttachCALayer(void *aCALayer) {
|
void nsCARenderer::AttachCALayer(void *aCALayer) {
|
||||||
CARenderer* caRenderer = (CARenderer*)mCARenderer;
|
CALayer* wrapperLayer = (CALayer*)mWrapperCALayer;
|
||||||
|
NSArray* sublayers = [wrapperLayer sublayers];
|
||||||
CALayer* caLayer = (CALayer*)aCALayer;
|
CALayer* oldLayer = (CALayer*) [sublayers objectAtIndex:0];
|
||||||
caRenderer.layer = caLayer;
|
[oldLayer removeFromSuperlayer];
|
||||||
|
[wrapperLayer addSublayer:(CALayer*)aCALayer];
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
|
|
Загрузка…
Ссылка в новой задаче