vcl/inc/quartz/salgdi.h | 2 + vcl/quartz/salgdicommon.cxx | 3 ++ vcl/quartz/salgdiutils.cxx | 46 ++++++++++++++++++++++++++++++++++++++------ 3 files changed, 45 insertions(+), 6 deletions(-)
New commits: commit 87964eb39e2668f80bcbf503d9a3b55a7f86ce28 Author: 191919 <ilf...@gmail.com> AuthorDate: Tue Oct 27 15:38:39 2020 +0800 Commit: Noel Grandin <noel.gran...@collabora.co.uk> CommitDate: Thu Oct 29 16:38:01 2020 +0100 Speed improments Improve drawing performance on 10-bit displays by avoiding multiple color space conversions. Make all drawing context bitmaps have the colour space and byte order of the host window. Fix serious CoreGraphics-related memory leak (existed no later than version 7.0) when changing the window size. Change-Id: Ia7b7e88d47b728bd1d10dedc1ca222215de41e73 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/104858 Tested-by: Jenkins Reviewed-by: Noel Grandin <noel.gran...@collabora.co.uk> diff --git a/vcl/inc/quartz/salgdi.h b/vcl/inc/quartz/salgdi.h index 8058b68378b6..0aaf71f0f839 100644 --- a/vcl/inc/quartz/salgdi.h +++ b/vcl/inc/quartz/salgdi.h @@ -134,6 +134,8 @@ class AquaSalGraphics : public SalGraphics { CGLayerHolder maLayer; // Quartz graphics layer CGContextHolder maContextHolder; // Quartz drawing context + CGContextHolder maBGContextHolder; // Quartz drawing context for CGLayer + CGContextHolder maCSContextHolder; // Quartz drawing context considering the color space XorEmulation* mpXorEmulation; int mnXorMode; // 0: off 1: on 2: invert only diff --git a/vcl/quartz/salgdicommon.cxx b/vcl/quartz/salgdicommon.cxx index 7f96124f96ac..7c7dcac7898f 100644 --- a/vcl/quartz/salgdicommon.cxx +++ b/vcl/quartz/salgdicommon.cxx @@ -426,11 +426,14 @@ void AquaSalGraphics::copyArea( long nDstX, long nDstY,long nSrcX, long nSrcY, CGContextScaleCTM( xSrcContext, +1, -1 ); aSrcPoint.y = (nScaledSourceY + nScaledSourceHeight) - (mnHeight * fScale); } + CGContextSetBlendMode(xSrcContext, kCGBlendModeCopy); + CGContextDrawLayerAtPoint(xSrcContext, aSrcPoint, maLayer.get()); } // draw at new destination const CGRect aTargetRect = CGRectMake(nScaledTargetX, nScaledTargetY, nScaledSourceWidth, nScaledSourceHeight); + CGContextSetBlendMode(xCopyContext, kCGBlendModeCopy); CGContextDrawLayerInRect(xCopyContext, aTargetRect, sSourceLayerHolder.get()); maContextHolder.restoreState(); diff --git a/vcl/quartz/salgdiutils.cxx b/vcl/quartz/salgdiutils.cxx index 426aea29dc78..57953e536796 100644 --- a/vcl/quartz/salgdiutils.cxx +++ b/vcl/quartz/salgdiutils.cxx @@ -69,11 +69,28 @@ void AquaSalGraphics::SetPrinterGraphics( CGContextRef xContext, long nDPIX, lon void AquaSalGraphics::InvalidateContext() { UnsetState(); + + CGContextRelease(maContextHolder.get()); + CGContextRelease(maBGContextHolder.get()); + CGContextRelease(maCSContextHolder.get()); + maContextHolder.set(nullptr); + maCSContextHolder.set(nullptr); + maBGContextHolder.set(nullptr); } void AquaSalGraphics::UnsetState() { + if (maBGContextHolder.isSet()) + { + CGContextRelease(maBGContextHolder.get()); + maBGContextHolder.set(nullptr); + } + if (maCSContextHolder.isSet()) + { + CGContextRelease(maCSContextHolder.get()); + maBGContextHolder.set(nullptr); + } if (maContextHolder.isSet()) { maContextHolder.restoreState(); @@ -119,7 +136,12 @@ bool AquaSalGraphics::CheckContext() { CGContextRelease(maContextHolder.get()); } + CGContextRelease(maBGContextHolder.get()); + CGContextRelease(maCSContextHolder.get()); + maContextHolder.set(nullptr); + maBGContextHolder.set(nullptr); + maCSContextHolder.set(nullptr); maLayer.set(nullptr); } @@ -133,14 +155,17 @@ bool AquaSalGraphics::CheckContext() const CGSize aLayerSize = { static_cast<CGFloat>(nScaledWidth), static_cast<CGFloat>(nScaledHeight) }; const int nBytesPerRow = (nBitmapDepth * nScaledWidth) / 8; - void* pRawData = std::malloc(nBytesPerRow * nScaledHeight); - const int nFlags = kCGImageAlphaNoneSkipFirst; - CGContextHolder aContextHolder(CGBitmapContextCreate( - pRawData, nScaledWidth, nScaledHeight, 8, nBytesPerRow, GetSalData()->mxRGBSpace, nFlags)); + int nFlags = kCGImageAlphaNoneSkipFirst | kCGBitmapByteOrder32Host; + maBGContextHolder.set(CGBitmapContextCreate( + NULL, nScaledWidth, nScaledHeight, 8, nBytesPerRow, GetSalData()->mxRGBSpace, nFlags)); - maLayer.set(CGLayerCreateWithContext(aContextHolder.get(), aLayerSize, nullptr)); + maLayer.set(CGLayerCreateWithContext(maBGContextHolder.get(), aLayerSize, nullptr)); maLayer.setScale(fScale); + nFlags = kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host; + maCSContextHolder.set(CGBitmapContextCreate( + NULL, nScaledWidth, nScaledHeight, 8, nBytesPerRow, GetSalData()->mxRGBSpace, nFlags)); + CGContextRef xDrawContext = CGLayerGetContext(maLayer.get()); maContextHolder = xDrawContext; @@ -217,8 +242,17 @@ void AquaSalGraphics::UpdateWindow( NSRect& ) const CGSize aSize = maLayer.getSizePoints(); const CGRect aRect = CGRectMake(0, 0, aSize.width, aSize.height); + const CGRect aRectPoints = { CGPointZero, maLayer.getSizePixels() }; + CGContextSetBlendMode(maCSContextHolder.get(), kCGBlendModeCopy); + CGContextDrawLayerInRect(maCSContextHolder.get(), aRectPoints, maLayer.get()); + + CGImageRef img = CGBitmapContextCreateImage(maCSContextHolder.get()); + CGImageRef displayColorSpaceImage = CGImageCreateCopyWithColorSpace(img, [[mpFrame->getNSWindow() colorSpace] CGColorSpace]); + CGContextSetBlendMode(rCGContextHolder.get(), kCGBlendModeCopy); + CGContextDrawImage(rCGContextHolder.get(), aRect, displayColorSpaceImage); - CGContextDrawLayerInRect(rCGContextHolder.get(), aRect, maLayer.get()); + CGImageRelease(img); + CGImageRelease(displayColorSpaceImage); rCGContextHolder.restoreState(); } _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits