summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPatrick Luby <guibmacdev@gmail.com>2024-11-28 19:56:45 -0500
committerChristian Lohmaier <lohmaier+LibreOffice@googlemail.com>2024-12-11 12:11:50 +0100
commiteb32550f468ea6a8d153d11fd6226f11c8fd879d (patch)
treedd86582d282b4f08b3eda12bf92f3bcd1c95522c
parentc76a22412630dcdef8bd2db363acb54d347d29ae (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.cxx62
-rw-r--r--vcl/osx/salnativewidgets.cxx16
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