diff options
author | Patrick Luby <guibmacdev@gmail.com> | 2024-11-28 19:56:45 -0500 |
---|---|---|
committer | Christian Lohmaier <lohmaier+LibreOffice@googlemail.com> | 2024-12-11 12:11:50 +0100 |
commit | eb32550f468ea6a8d153d11fd6226f11c8fd879d (patch) | |
tree | dd86582d282b4f08b3eda12bf92f3bcd1c95522c | |
parent | c76a22412630dcdef8bd2db363acb54d347d29ae (diff) |
Related: tdf#163945 don't directly flush graphics with Skia/Metal
When dragging a selection box on an empty background in
Impress and only with Skia/Metal, the selection box
would not keep up with the pointer. The selection box
would repaint sporadically or not at all if the pointer
was dragged rapidly and the status bar was visible.
Apparently, flushing a graphics doesn't actually do much
of anything with Skia/Raster and Skia disabled so the
selection box repaints without any noticeable delay.
However, with Skia/Metal every flush of a graphics
creates and queues a new CAMetalLayer drawable. During
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.
Also, with the reduced Skia/Metal flushing load from this
fix, the color conversion when drawing to an NSBox appears
to be no longer needed. The converted color appeared less
saturated, at least to me, so accept the (hopefully now
imperceptible) performance hit of drawing an NSBox with
native colors.
Change-Id: I55b4ab763bf20c6c2acad65587b703fc6f645264
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/177530
Reviewed-by: Patrick Luby <guibomacdev@gmail.com>
Tested-by: Jenkins
(cherry picked from commit c585b697b583fa0f8cdadeab594c31d270367ba7)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/177731
Reviewed-by: Christian Lohmaier <lohmaier+LibreOffice@googlemail.com>
-rw-r--r-- | vcl/osx/salframe.cxx | 62 | ||||
-rw-r--r-- | vcl/osx/salnativewidgets.cxx | 16 |
2 files changed, 58 insertions, 20 deletions
diff --git a/vcl/osx/salframe.cxx b/vcl/osx/salframe.cxx index 81aae45457a7..bbce8d566dce 100644 --- a/vcl/osx/salframe.cxx +++ b/vcl/osx/salframe.cxx @@ -55,6 +55,9 @@ #include <quartz/CGHelpers.hxx> #include <postmac.h> +#if HAVE_FEATURE_SKIA +#include <vcl/skia/SkiaHelper.hxx> +#endif const int nMinBlinkCursorDelay = 500; @@ -1005,6 +1008,15 @@ void AquaSalFrame::SetPointerPos( tools::Long nX, tools::Long nY ) CGDisplayMoveCursorToPoint( mainDisplayID, aPoint ); } +static bool lcl_ShouldDisplayInsteadOFFlush() +{ + bool bRet = false; +#if HAVE_FEATURE_SKIA + bRet = SkiaHelper::isVCLSkiaEnabled() && SkiaHelper::renderMethodToUse() != SkiaHelper::RenderRaster; +#endif + return bRet; +} + void AquaSalFrame::Flush() { if( !(mbGraphics && mpGraphics && mpNSView && mbShown) ) @@ -1020,11 +1032,31 @@ void AquaSalFrame::Flush() if( mbForceFlush || ImplGetSVData()->maAppData.mnDispatchLevel <= 0 ) { mbForceFlush = false; - mpGraphics->Flush(); + + // Related: tdf#163945 don't directly flush graphics with Skia/Metal + // When dragging a selection box on an empty background in + // Impress and only with Skia/Metal, the selection box + // would not keep up with the pointer. The selection box + // would repaint sporadically or not at all if the pointer + // was dragged rapidly and the status bar was visible. + // Apparently, flushing a graphics doesn't actually do much + // of anything with Skia/Raster and Skia disabled so the + // selection box repaints without any noticeable delay. + // However, with Skia/Metal every flush of a graphics + // creates and queues a new CAMetalLayer drawable. During + // 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 = lcl_ShouldDisplayInsteadOFFlush(); + if (!bDisplay) + mpGraphics->Flush(); + // 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. - if( ImplGetSVData()->maAppData.mnDispatchLevel <= 0 ) + if( bDisplay || ImplGetSVData()->maAppData.mnDispatchLevel <= 0 ) [mpNSView display]; } } @@ -1046,12 +1078,32 @@ void AquaSalFrame::Flush( const tools::Rectangle& rRect ) if( mbForceFlush || ImplGetSVData()->maAppData.mnDispatchLevel <= 0 ) { mbForceFlush = false; - mpGraphics->Flush( rRect ); + + // Related: tdf#163945 don't directly flush graphics with Skia/Metal + // When dragging a selection box on an empty background in + // Impress and only with Skia/Metal, the selection box + // would not keep up with the pointer. The selection box + // would repaint sporadically or not at all if the pointer + // was dragged rapidly and the status bar was visible. + // Apparently, flushing a graphics doesn't actually do much + // of anything with Skia/Raster and Skia disabled so the + // selection box repaints without any noticeable delay. + // However, with Skia/Metal every flush of a graphics + // creates and queues a new CAMetalLayer drawable. During + // 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 = lcl_ShouldDisplayInsteadOFFlush(); + if (!bDisplay) + mpGraphics->Flush(); + // 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. - if( ImplGetSVData()->maAppData.mnDispatchLevel <= 0 ) - [mpNSView display]; + if( bDisplay || ImplGetSVData()->maAppData.mnDispatchLevel <= 0 ) + [mpNSView displayRect: aNSRect]; } } diff --git a/vcl/osx/salnativewidgets.cxx b/vcl/osx/salnativewidgets.cxx index 3340722281e8..c2a861c1fcc5 100644 --- a/vcl/osx/salnativewidgets.cxx +++ b/vcl/osx/salnativewidgets.cxx @@ -391,21 +391,7 @@ static void drawBox(CGContextRef context, const NSRect& rc, NSColor* pColor) NSRect rect = { NSZeroPoint, NSMakeSize(rc.size.width, rc.size.height) }; NSBox* pBox = [[NSBox alloc] initWithFrame: rect]; [pBox setBoxType: NSBoxCustom]; - - // Related tdf#163945: Set fill color to NSColorTypeComponentBased color type - // Many system colors have the NSColorTypeCatalog color type. For - // some unkown reason, setting the NSBox's fill color to a color set - // to NSColorTypeCatalog causes drawing to take at least twice as long - // as when the fill color is set to NSColorTypeComponentBased. So, - // only draw with a fill color set to NSColorTypeComponentBased. - NSColor* pRGBColor = pColor; - if ([pColor type] != NSColorTypeComponentBased) - { - pRGBColor = [pColor colorUsingType: NSColorTypeComponentBased]; - if (!pRGBColor) - pRGBColor = pColor; - } - [pBox setFillColor: pRGBColor]; + [pBox setFillColor: pColor]; // -[NSBox setBorderType: NSNoBorder] is deprecated so hide the border // by setting the border color to transparent |