vcl/inc/skia/osx/gdiimpl.hxx | 2 ++ vcl/osx/salframe.cxx | 43 +++++++++++++++++++++++++++++++++++++------ vcl/skia/osx/gdiimpl.cxx | 2 ++ 3 files changed, 41 insertions(+), 6 deletions(-)
New commits: commit a24789f747dc998bd4fd1c0110a89e791ee051c2 Author: Patrick Luby <guibmac...@gmail.com> AuthorDate: Sun Apr 27 09:35:37 2025 -0400 Commit: Patrick Luby <guibomac...@gmail.com> CommitDate: Sun Apr 27 16:55:06 2025 +0200 tdf#166258 Refactor throttling of Skia/Metal flushes Throttling of Skia/Metal flushes is needed for tdf#163945 but the throttling logic was being applied to too frequently. So throttle based on the time interval of the last Skia/Metal flush and if the flush is too soon after the last flush (i.e. 1/200th of a second), schedule the flush in the Skia timer. Change-Id: Ib4e526ec26ec8b8d36bf3a9776bfe49d153d759f Reviewed-on: https://gerrit.libreoffice.org/c/core/+/184681 Tested-by: Jenkins Reviewed-by: Patrick Luby <guibomac...@gmail.com> diff --git a/vcl/inc/skia/osx/gdiimpl.hxx b/vcl/inc/skia/osx/gdiimpl.hxx index 6e1656e59f1c..b189898082ab 100644 --- a/vcl/inc/skia/osx/gdiimpl.hxx +++ b/vcl/inc/skia/osx/gdiimpl.hxx @@ -41,6 +41,8 @@ public: virtual void Flush(const tools::Rectangle&) override; virtual void WindowBackingPropertiesChanged() override; + void ScheduleFlush(); + CGImageRef createCGImageFromRasterSurface(const NSRect& rDirtyRect, CGPoint& rImageOrigin, bool& rImageFlipped); diff --git a/vcl/osx/salframe.cxx b/vcl/osx/salframe.cxx index 636a07a6a152..08517cb837e7 100644 --- a/vcl/osx/salframe.cxx +++ b/vcl/osx/salframe.cxx @@ -59,6 +59,7 @@ #if HAVE_FEATURE_SKIA #include <vcl/skia/SkiaHelper.hxx> +#include "skia/osx/gdiimpl.hxx" #endif const int nMinBlinkCursorDelay = 500; @@ -1196,20 +1197,50 @@ bool AquaSalFrame::doFlush() // rapid dragging, this can lead to creating and queueing // up to 200 drawables per second leaving no spare time for // the Impress selection box painting timer to fire. - // So with Skia/Metal, throttle the rate of flushing by - // calling display on the view. - bool bDisplay = false; + // So with Skia/Metal, throttle the rate of flushing. + bool bNeedsFlush = true; + bool bFlushed = false; #if HAVE_FEATURE_SKIA // tdf#164428 Skia/Metal needs flush after drawing progress bar - bDisplay = !mbForceFlushProgressBar && SkiaHelper::isVCLSkiaEnabled() && SkiaHelper::renderMethodToUse() != SkiaHelper::RenderRaster; + if (!mbForceFlushProgressBar && SkiaHelper::isVCLSkiaEnabled() && SkiaHelper::renderMethodToUse() != SkiaHelper::RenderRaster) + { + AquaSkiaSalGraphicsImpl *pSkiaGraphicsImpl = dynamic_cast<AquaSkiaSalGraphicsImpl*>(mpGraphics->GetImpl()); + if (pSkiaGraphicsImpl) + { + // Assume 1/200th of a second is the fastest flushing rate + // that can be handled with Skia/Metal. Note that the Skia + // timer is running separately so the overall flushing rate + // may still be faster than this limit. + static const CFAbsoluteTime fMinFlushInterval = 0.005f; + static CFAbsoluteTime fLastFlushTime = 0; + + CFAbsoluteTime fInterval = CFAbsoluteTimeGetCurrent() - fLastFlushTime; + if (fInterval >= 0.0f && fInterval < fMinFlushInterval) + { + // Just to be safe, schedule the Skia timer to run so that + // a flush is only delayed but never missed + pSkiaGraphicsImpl->ScheduleFlush(); + } + else + { + mpGraphics->Flush(); + fLastFlushTime = CFAbsoluteTimeGetCurrent(); + bFlushed = true; + } + bNeedsFlush = false; + } + } #endif - if (!bDisplay) + if (bNeedsFlush) + { mpGraphics->Flush(); + bFlushed = true; + } // Related: tdf#155266 skip redisplay of the view when forcing flush // It appears that calling -[NSView display] overwhelms some Intel Macs // so only flush the graphics and skip immediate redisplay of the view. - bRet = bDisplay || ImplGetSVData()->maAppData.mnDispatchLevel <= 0; + bRet = !bFlushed || ImplGetSVData()->maAppData.mnDispatchLevel <= 0; mbForceFlushScrolling = false; mbForceFlushProgressBar = false; diff --git a/vcl/skia/osx/gdiimpl.cxx b/vcl/skia/osx/gdiimpl.cxx index 8043fb2e2b72..8e7e7b7beecf 100644 --- a/vcl/skia/osx/gdiimpl.cxx +++ b/vcl/skia/osx/gdiimpl.cxx @@ -129,6 +129,8 @@ void AquaSkiaSalGraphicsImpl::flushSurfaceToWindowContext() } } +void AquaSkiaSalGraphicsImpl::ScheduleFlush() { scheduleFlush(); } + // For Raster we use our own screen blitting (see above). CGImageRef AquaSkiaSalGraphicsImpl::createCGImageFromRasterSurface(const NSRect& rDirtyRect, CGPoint& rImageOrigin,