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() ...@@ -94,13 +94,12 @@ void AquaSalGraphics::UnsetState()
*/ */
bool AquaSalGraphics::CheckContext() 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 nWidth = mpFrame->maGeometry.nWidth;
const unsigned int nHeight = mpFrame->maGeometry.nHeight; 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) // check if a new drawing context is needed (e.g. after a resize)
if( (unsigned(mnWidth) != nWidth) || (unsigned(mnHeight) != nHeight) ) if( (unsigned(mnWidth) != nWidth) || (unsigned(mnHeight) != nHeight) )
...@@ -108,62 +107,77 @@ bool AquaSalGraphics::CheckContext() ...@@ -108,62 +107,77 @@ bool AquaSalGraphics::CheckContext()
mnWidth = nWidth; mnWidth = nWidth;
mnHeight = nHeight; mnHeight = nHeight;
// prepare to release the corresponding resources // prepare to release the corresponding resources
rReleaseContext = mrContext; if (mxLayer)
rReleaseLayer = mxLayer; rReleaseLayer = mxLayer;
else if (mrContext)
{
SAL_INFO("vcl.cg", "CGContextRelease(" << mrContext << ")");
CGContextRelease(mrContext);
}
mrContext = nullptr; mrContext = nullptr;
mxLayer = nullptr; mxLayer = nullptr;
} }
if( !mrContext ) if (!mrContext)
{ {
const CGSize aLayerSize = { static_cast<CGFloat>(nWidth), static_cast<CGFloat>(nHeight) }; if (mpFrame->getNSWindow())
NSGraphicsContext* pNSGContext = [NSGraphicsContext graphicsContextWithWindow: 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 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 SAL_WNODEPRECATED_DECLARATIONS_POP
mxLayer = CGLayerCreateWithContext( xCGContext, aLayerSize, nullptr ); mxLayer = CGLayerCreateWithContext(xCGContext, aLayerSize, nullptr);
SAL_INFO( "vcl.cg", "CGLayerCreateWithContext(" << xCGContext << "," << aLayerSize << ",NULL) = " << mxLayer ); SAL_INFO("vcl.cg", "CGLayerCreateWithContext(" << xCGContext << "," << aLayerSize << ",NULL) = " << mxLayer);
if( mxLayer ) if (mxLayer)
{ {
mrContext = CGLayerGetContext( mxLayer ); mrContext = CGLayerGetContext( mxLayer );
SAL_INFO( "vcl.cg", "CGLayerGetContext(" << mxLayer << ") = " << mrContext ); SAL_INFO( "vcl.cg", "CGLayerGetContext(" << mxLayer << ") = " << mrContext );
} }
if( mrContext ) if (rReleaseLayer)
{
// copy original layer to resized layer
if( rReleaseLayer )
{ {
SAL_INFO( "vcl.cg", "CGContextDrawLayerAtPoint(" << mrContext << "," << CGPointZero << "," << rReleaseLayer << ")" ); // copy original layer to resized layer
CGContextDrawLayerAtPoint( mrContext, CGPointZero, rReleaseLayer ); 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 ); if (mrContext)
CGContextScaleCTM( mrContext, 1.0, -1.0 ); {
CGContextSetFillColorSpace( mrContext, GetSalData()->mxRGBSpace ); CGContextTranslateCTM(mrContext, 0, nHeight);
CGContextSetStrokeColorSpace( mrContext, GetSalData()->mxRGBSpace ); CGContextScaleCTM(mrContext, 1.0, -1.0);
SAL_INFO( "vcl.cg", "CGContextSaveGState(" << mrContext << ") " << ++mnContextStackDepth ); CGContextSetFillColorSpace(mrContext, GetSalData()->mxRGBSpace);
CGContextSaveGState( mrContext ); CGContextSetStrokeColorSpace(mrContext, GetSalData()->mxRGBSpace);
SAL_INFO("vcl.cg", "CGContextSaveGState(" << mrContext << ") " << ++mnContextStackDepth);
CGContextSaveGState(mrContext);
SetState(); SetState();
// re-enable XOR emulation for the new context // re-enable XOR emulation for the new context
if( mpXorEmulation ) if (mpXorEmulation)
{ mpXorEmulation->SetTarget(mnWidth, mnHeight, mnBitmapDepth, mrContext, mxLayer);
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!!!!" ); SAL_WARN_IF( !mrContext && !mbPrinter, "vcl", "<<<WARNING>>> AquaSalGraphics::CheckContext() FAILED!!!!" );
......
...@@ -268,36 +268,25 @@ SAL_WNODEPRECATED_DECLARATIONS_PUSH // 'graphicsPort' is deprecated: first depre ...@@ -268,36 +268,25 @@ SAL_WNODEPRECATED_DECLARATIONS_PUSH // 'graphicsPort' is deprecated: first depre
SAL_WNODEPRECATED_DECLARATIONS_POP 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 #endif
mnBitmapDepth = 32;
const int nBytesPerRow = (mnBitmapDepth * nDX) / 8; if (!xCGContext)
void* pRawData = std::malloc( nBytesPerRow * nDY ); {
mxBitmapContext = CGBitmapContextCreate( pRawData, nDX, nDY, assert(Application::IsBitmapRendering());
8, nBytesPerRow, GetSalData()->mxRGBSpace, kCGImageAlphaNoneSkipFirst | kCGImageByteOrder32Little ); mnBitmapDepth = 32;
SAL_INFO( "vcl.cg", "CGBitmapContextCreate(" << nDX << "x" << nDY << "x32) = " << mxBitmapContext );
xCGContext = mxBitmapContext; const int nBytesPerRow = (mnBitmapDepth * nDX) / 8;
void* pRawData = std::malloc( nBytesPerRow * nDY );
const int nFlags = kCGImageAlphaNoneSkipFirst;
#ifndef MACOSX
nFlags |= kCGImageByteOrder32Little;
#endif #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" ); 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