<html>
    <head>
      <base href="https://bugs.documentfoundation.org/">
    </head>
    <body>
      <p>
        <div>
            <b><a class="bz_bug_link 
          bz_status_NEW "
   title="NEW - Severe performance degradation on a macOS with 10-bit displays"
   href="https://bugs.documentfoundation.org/show_bug.cgi?id=137468#c38">Comment # 38</a>
              on <a class="bz_bug_link 
          bz_status_NEW "
   title="NEW - Severe performance degradation on a macOS with 10-bit displays"
   href="https://bugs.documentfoundation.org/show_bug.cgi?id=137468">bug 137468</a>
              from <span class="vcard"><a class="email" href="mailto:ilford@gmail.com" title="Leo Wang <ilford@gmail.com>"> <span class="fn">Leo Wang</span></a>
</span></b>
        <pre>Further improved patch based on the color depth limit patch.

1. Improved drawing performance on 10-bit displays by avoiding multiple color
space conversions.
2. Make all drawing context bitmaps have the same color space and byte order of
the host system.
3. Fixed serious CG-related memory leak (existed no later than version 7.0)
when changing the window size.

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/salgdiutils.cxx b/vcl/quartz/salgdiutils.cxx
index 426aea29dc78..1bd3063358bf 100644
--- a/vcl/quartz/salgdiutils.cxx
+++ b/vcl/quartz/salgdiutils.cxx
@@ -69,11 +69,26 @@ 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());
+    }
+    if (maCSContextHolder.isSet())
+    {
+        CGContextRelease(maCSContextHolder.get());
+    }
     if (maContextHolder.isSet())
     {
         maContextHolder.restoreState();
@@ -119,7 +134,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 +153,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 +240,13 @@ void AquaSalGraphics::UpdateWindow( NSRect& )

         const CGSize aSize = maLayer.getSizePoints();
         const CGRect aRect = CGRectMake(0, 0, aSize.width,  aSize.height);
-
-        CGContextDrawLayerInRect(rCGContextHolder.get(), aRect,
maLayer.get());
+        const CGRect xRect = { CGPointZero, maLayer.getSizePixels() };
+        CGContextDrawLayerInRect(maCSContextHolder.get(), xRect,
maLayer.get());
+        CGImageRef img = CGBitmapContextCreateImage(maCSContextHolder.get());
+        CGImageRef displayColorSpaceImage =
CGImageCreateCopyWithColorSpace(img,
CGDisplayCopyColorSpace(CGMainDisplayID()));
+        CGContextDrawImage(rCGContextHolder.get(), aRect,
displayColorSpaceImage);
+        CGImageRelease(img);
+        CGImageRelease(displayColorSpaceImage);

         rCGContextHolder.restoreState();
     }</pre>
        </div>
      </p>


      <hr>
      <span>You are receiving this mail because:</span>

      <ul>
          <li>You are the assignee for the bug.</li>
      </ul>
    </body>
</html>