Kaydet (Commit) b1437170 authored tarafından Jan-Marek Glogowski's avatar Jan-Marek Glogowski

OSX always fall back to a bitmap context

I'm not sure this is the best idea, but without a context many
things will definitly break. In theory this is just needed for
bitmap-only rendering mode.

This is a more general solution of commit e659c6a1 ("Work
around odd macOS 10.14 graphicsContextWithWindow failure").

Change-Id: I3708c25b302a38e1b0c0cccbcacd6cb9b5ff33dc
Reviewed-on: https://gerrit.libreoffice.org/64952
Tested-by: Jenkins
Reviewed-by: 's avatarJan-Marek Glogowski <glogow@fbihome.de>
üst 70bc32b2
......@@ -94,13 +94,12 @@ void AquaSalGraphics::UnsetState()
*/
bool AquaSalGraphics::CheckContext()
{
if( mbWindow && mpFrame && mpFrame->getNSWindow() )
if (mbWindow && mpFrame && (mpFrame->getNSWindow() || Application::IsBitmapRendering()))
{
const unsigned int nWidth = mpFrame->maGeometry.nWidth;
const unsigned int nHeight = mpFrame->maGeometry.nHeight;
CGContextRef rReleaseContext = nullptr;
CGLayerRef rReleaseLayer = nullptr;
CGLayerRef rReleaseLayer = nullptr;
// check if a new drawing context is needed (e.g. after a resize)
if( (unsigned(mnWidth) != nWidth) || (unsigned(mnHeight) != nHeight) )
......@@ -108,62 +107,77 @@ bool AquaSalGraphics::CheckContext()
mnWidth = nWidth;
mnHeight = nHeight;
// prepare to release the corresponding resources
rReleaseContext = mrContext;
rReleaseLayer = mxLayer;
if (mxLayer)
rReleaseLayer = mxLayer;
else if (mrContext)
{
SAL_INFO("vcl.cg", "CGContextRelease(" << mrContext << ")");
CGContextRelease(mrContext);
}
mrContext = nullptr;
mxLayer = nullptr;
}
if( !mrContext )
if (!mrContext)
{
const CGSize aLayerSize = { static_cast<CGFloat>(nWidth), static_cast<CGFloat>(nHeight) };
NSGraphicsContext* pNSGContext = [NSGraphicsContext graphicsContextWithWindow: mpFrame->getNSWindow()];
if (mpFrame->getNSWindow())
{
const CGSize aLayerSize = { static_cast<CGFloat>(nWidth), static_cast<CGFloat>(nHeight) };
NSGraphicsContext* pNSGContext = [NSGraphicsContext graphicsContextWithWindow: mpFrame->getNSWindow()];
SAL_WNODEPRECATED_DECLARATIONS_PUSH // 'graphicsPort' is deprecated: first deprecated in macOS 10.14
CGContextRef xCGContext = static_cast<CGContextRef>([pNSGContext graphicsPort]);
CGContextRef xCGContext = static_cast<CGContextRef>([pNSGContext graphicsPort]);
SAL_WNODEPRECATED_DECLARATIONS_POP
mxLayer = CGLayerCreateWithContext( xCGContext, aLayerSize, nullptr );
SAL_INFO( "vcl.cg", "CGLayerCreateWithContext(" << xCGContext << "," << aLayerSize << ",NULL) = " << mxLayer );
if( mxLayer )
{
mrContext = CGLayerGetContext( mxLayer );
SAL_INFO( "vcl.cg", "CGLayerGetContext(" << mxLayer << ") = " << mrContext );
}
mxLayer = CGLayerCreateWithContext(xCGContext, aLayerSize, nullptr);
SAL_INFO("vcl.cg", "CGLayerCreateWithContext(" << xCGContext << "," << aLayerSize << ",NULL) = " << mxLayer);
if (mxLayer)
{
mrContext = CGLayerGetContext( mxLayer );
SAL_INFO( "vcl.cg", "CGLayerGetContext(" << mxLayer << ") = " << mrContext );
}
if( mrContext )
{
// copy original layer to resized layer
if( rReleaseLayer )
if (rReleaseLayer)
{
SAL_INFO( "vcl.cg", "CGContextDrawLayerAtPoint(" << mrContext << "," << CGPointZero << "," << rReleaseLayer << ")" );
CGContextDrawLayerAtPoint( mrContext, CGPointZero, rReleaseLayer );
// copy original layer to resized layer
if (mrContext)
{
SAL_INFO("vcl.cg", "CGContextDrawLayerAtPoint(" << mrContext << "," << CGPointZero << "," << rReleaseLayer << ")");
CGContextDrawLayerAtPoint(mrContext, CGPointZero, rReleaseLayer);
}
SAL_INFO("vcl.cg", "CGLayerRelease(" << rReleaseLayer << ")");
CGLayerRelease(rReleaseLayer);
}
}
else
{
assert(Application::IsBitmapRendering());
const int nBitmapDepth = 32;
const int nBytesPerRow = (nBitmapDepth * mnWidth) / 8;
void* pRawData = std::malloc(nBytesPerRow * mnHeight);
const int nFlags = kCGImageAlphaNoneSkipFirst;
#ifndef MACOSX
nFlags |= kCGImageByteOrder32Little;
#endif
mrContext = CGBitmapContextCreate(pRawData, mnWidth, mnHeight, 8, nBytesPerRow,
GetSalData()->mxRGBSpace, nFlags);
SAL_INFO("vcl.cg", "CGBitmapContextCreate(" << mnWidth << "x" << mnHeight
<< "x" << nBitmapDepth << ") = " << mrContext);
}
CGContextTranslateCTM( mrContext, 0, nHeight );
CGContextScaleCTM( mrContext, 1.0, -1.0 );
CGContextSetFillColorSpace( mrContext, GetSalData()->mxRGBSpace );
CGContextSetStrokeColorSpace( mrContext, GetSalData()->mxRGBSpace );
SAL_INFO( "vcl.cg", "CGContextSaveGState(" << mrContext << ") " << ++mnContextStackDepth );
CGContextSaveGState( mrContext );
if (mrContext)
{
CGContextTranslateCTM(mrContext, 0, nHeight);
CGContextScaleCTM(mrContext, 1.0, -1.0);
CGContextSetFillColorSpace(mrContext, GetSalData()->mxRGBSpace);
CGContextSetStrokeColorSpace(mrContext, GetSalData()->mxRGBSpace);
SAL_INFO("vcl.cg", "CGContextSaveGState(" << mrContext << ") " << ++mnContextStackDepth);
CGContextSaveGState(mrContext);
SetState();
// re-enable XOR emulation for the new context
if( mpXorEmulation )
{
mpXorEmulation->SetTarget( mnWidth, mnHeight, mnBitmapDepth, mrContext, mxLayer );
}
if (mpXorEmulation)
mpXorEmulation->SetTarget(mnWidth, mnHeight, mnBitmapDepth, mrContext, mxLayer);
}
}
if( rReleaseLayer )
{
SAL_INFO( "vcl.cg", "CGLayerRelease(" << rReleaseLayer << ")" );
CGLayerRelease( rReleaseLayer );
}
else if( rReleaseContext )
{
SAL_INFO( "vcl.cg", "CGContextRelease(" << rReleaseContext << ")" );
CGContextRelease( rReleaseContext );
}
}
SAL_WARN_IF( !mrContext && !mbPrinter, "vcl", "<<<WARNING>>> AquaSalGraphics::CheckContext() FAILED!!!!" );
......
......@@ -268,36 +268,25 @@ SAL_WNODEPRECATED_DECLARATIONS_PUSH // 'graphicsPort' is deprecated: first depre
SAL_WNODEPRECATED_DECLARATIONS_POP
}
}
// At least on macOS 10.14 during CppunitTests (that have hidden windows), it happens
// that the above
//
// [NSGraphicsContext graphicsContextWithWindow: pNSWindow]
//
// returns nil for unclear reasons; so use the below fallback even if there is a
// pNSWindow but obtaining a graphics context for it fails:
if (xCGContext == nullptr)
{
// fall back to a bitmap context
mnBitmapDepth = 32;
const int nBytesPerRow = (mnBitmapDepth * nDX) / 8;
void* pRawData = std::malloc( nBytesPerRow * nDY );
mxBitmapContext = CGBitmapContextCreate( pRawData, nDX, nDY,
8, nBytesPerRow, GetSalData()->mxRGBSpace, kCGImageAlphaNoneSkipFirst );
SAL_INFO( "vcl.cg", "CGBitmapContextCreate(" << nDX << "x" << nDY << "x32) = " << mxBitmapContext );
xCGContext = mxBitmapContext;
}
}
#else
mnBitmapDepth = 32;
#endif
const int nBytesPerRow = (mnBitmapDepth * nDX) / 8;
void* pRawData = std::malloc( nBytesPerRow * nDY );
mxBitmapContext = CGBitmapContextCreate( pRawData, nDX, nDY,
8, nBytesPerRow, GetSalData()->mxRGBSpace, kCGImageAlphaNoneSkipFirst | kCGImageByteOrder32Little );
SAL_INFO( "vcl.cg", "CGBitmapContextCreate(" << nDX << "x" << nDY << "x32) = " << mxBitmapContext );
xCGContext = mxBitmapContext;
if (!xCGContext)
{
assert(Application::IsBitmapRendering());
mnBitmapDepth = 32;
const int nBytesPerRow = (mnBitmapDepth * nDX) / 8;
void* pRawData = std::malloc( nBytesPerRow * nDY );
const int nFlags = kCGImageAlphaNoneSkipFirst;
#ifndef MACOSX
nFlags |= kCGImageByteOrder32Little;
#endif
mxBitmapContext = CGBitmapContextCreate(pRawData, nDX, nDY, 8, nBytesPerRow,
GetSalData()->mxRGBSpace, nFlags);
SAL_INFO( "vcl.cg", "CGBitmapContextCreate(" << nDX << "x" << nDY << "x32) = " << mxBitmapContext );
xCGContext = mxBitmapContext;
}
}
SAL_WARN_IF( !xCGContext, "vcl.quartz", "No context" );
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment