[Libreoffice-commits] core.git: vcl/inc vcl/quartz

191919 (via logerrit) logerrit at kemper.freedesktop.org
Thu Oct 29 15:38:45 UTC 2020


 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 <ilford at gmail.com>
AuthorDate: Tue Oct 27 15:38:39 2020 +0800
Commit:     Noel Grandin <noel.grandin at 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.grandin at 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();
     }


More information about the Libreoffice-commits mailing list