vcl/inc/skia/osx/gdiimpl.hxx |    1 
 vcl/skia/osx/gdiimpl.cxx     |   47 +++++++++++++++++++++++++++++++++++++++++--
 2 files changed, 46 insertions(+), 2 deletions(-)

New commits:
commit 830abb2437e3f150e1369816f491fb12a3db0c16
Author:     Luboš Luňák <l.lu...@collabora.com>
AuthorDate: Fri Aug 13 07:35:00 2021 +0200
Commit:     Luboš Luňák <l.lu...@collabora.com>
CommitDate: Mon Aug 23 14:59:42 2021 +0200

    implement blitting to screen for skia on mac
    
    Change-Id: I01fdb57815dc3dff6d2c5757b55445f16825ed20
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/120807
    Tested-by: Jenkins
    Reviewed-by: Luboš Luňák <l.lu...@collabora.com>

diff --git a/vcl/inc/skia/osx/gdiimpl.hxx b/vcl/inc/skia/osx/gdiimpl.hxx
index eabea4483c2d..2850b92110e6 100644
--- a/vcl/inc/skia/osx/gdiimpl.hxx
+++ b/vcl/inc/skia/osx/gdiimpl.hxx
@@ -37,6 +37,7 @@ public:
 private:
     virtual void createWindowContext(bool forceRaster = false) override;
     virtual void performFlush() override;
+    void flushToScreen(const SkIRect& rect);
     friend std::unique_ptr<sk_app::WindowContext> 
createVulkanWindowContext(bool);
 };
 
diff --git a/vcl/skia/osx/gdiimpl.cxx b/vcl/skia/osx/gdiimpl.cxx
index 399f8d024f0a..c815fc1ebe9d 100644
--- a/vcl/skia/osx/gdiimpl.cxx
+++ b/vcl/skia/osx/gdiimpl.cxx
@@ -56,7 +56,7 @@ void AquaSkiaSalGraphicsImpl::createWindowContext(bool 
forceRaster)
     switch (renderMethod)
     {
         case RenderRaster:
-            displayParams.fColorType = kBGRA_8888_SkColorType; // TODO
+            displayParams.fColorType = kRGBA_8888_SkColorType; // TODO
             mWindowContext.reset(
                 new AquaSkiaWindowContextRaster(GetWidth(), GetHeight(), 
displayParams));
             break;
@@ -75,11 +75,54 @@ void AquaSkiaSalGraphicsImpl::performFlush()
     if (mWindowContext)
     {
         if (mDirtyRect.intersect(SkIRect::MakeWH(GetWidth(), GetHeight())))
-            mWindowContext->swapBuffers(&mDirtyRect); // TODO
+            flushToScreen(mDirtyRect);
         mDirtyRect.setEmpty();
     }
 }
 
+void AquaSkiaSalGraphicsImpl::flushToScreen(const SkIRect& rect)
+{
+    // Based on AquaGraphicsBackend::drawBitmap().
+    if (!mrShared.checkContext())
+        return;
+
+    assert(mSurface.get());
+    // Do not use sub-rect, it creates copies of the data.
+    sk_sp<SkImage> image = makeCheckedImageSnapshot(mSurface);
+    SkPixmap pixmap;
+    if (!image->peekPixels(&pixmap))
+        abort();
+    // This creates the bitmap context from the cropped part, 
writable_addr32() will get
+    // the first pixel of rect.topLeft(), and using pixmap.rowBytes() ensures 
the following
+    // pixel lines will be read from correct positions.
+    CGContextRef context
+        = CGBitmapContextCreate(pixmap.writable_addr32(rect.left(), 
rect.top()), rect.width(),
+                                rect.height(), 8, pixmap.rowBytes(), // TODO
+                                GetSalData()->mxRGBSpace, 
kCGImageAlphaNoneSkipLast); // TODO
+    assert(context); // TODO
+    CGImageRef screenImage = CGBitmapContextCreateImage(context);
+    assert(screenImage); // TODO
+    if (mrShared.isFlipped())
+    {
+        const CGRect screenRect = CGRectMake(rect.left(), GetHeight() - 
rect.top() - rect.height(),
+                                             rect.width(), rect.height());
+        mrShared.maContextHolder.saveState();
+        CGContextTranslateCTM(mrShared.maContextHolder.get(), 0, 
pixmap.height());
+        CGContextScaleCTM(mrShared.maContextHolder.get(), 1, -1);
+        CGContextDrawImage(mrShared.maContextHolder.get(), screenRect, 
screenImage);
+        mrShared.maContextHolder.restoreState();
+    }
+    else
+    {
+        const CGRect screenRect = CGRectMake(rect.left(), rect.top(), 
rect.width(), rect.height());
+        CGContextDrawImage(mrShared.maContextHolder.get(), screenRect, 
screenImage);
+    }
+
+    CGImageRelease(screenImage);
+    CGContextRelease(context);
+    mrShared.refreshRect(rect.left(), rect.top(), rect.width(), rect.height());
+}
+
 std::unique_ptr<sk_app::WindowContext> createVulkanWindowContext(bool 
/*temporary*/)
 {
     return nullptr;

Reply via email to