diff options
author | 191919 <ilford@gmail.com> | 2020-10-27 15:38:39 +0800 |
---|---|---|
committer | Noel Grandin <noel.grandin@collabora.co.uk> | 2020-10-29 16:38:01 +0100 |
commit | 87964eb39e2668f80bcbf503d9a3b55a7f86ce28 (patch) | |
tree | 7b344db732089e1b52776a2b4fd5dea240686c63 /vcl/quartz | |
parent | 3021a32b810c20331916c4863f1f0b23b5a53b23 (diff) |
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.grandin@collabora.co.uk>
Diffstat (limited to 'vcl/quartz')
-rw-r--r-- | vcl/quartz/salgdicommon.cxx | 3 | ||||
-rw-r--r-- | vcl/quartz/salgdiutils.cxx | 46 |
2 files changed, 43 insertions, 6 deletions
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(); } |