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;