summaryrefslogtreecommitdiff
path: root/vcl/quartz
diff options
context:
space:
mode:
author191919 <ilford@gmail.com>2020-10-27 15:38:39 +0800
committerNoel Grandin <noel.grandin@collabora.co.uk>2020-10-29 16:38:01 +0100
commit87964eb39e2668f80bcbf503d9a3b55a7f86ce28 (patch)
tree7b344db732089e1b52776a2b4fd5dea240686c63 /vcl/quartz
parent3021a32b810c20331916c4863f1f0b23b5a53b23 (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.cxx3
-rw-r--r--vcl/quartz/salgdiutils.cxx46
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();
}