Community
Participate
Working Groups
The steps to reproduce are basically: 1) Have a Table with many columns and rows (so that 200 or more subitems are visible) 2) Have 'SWT.MeasureItem' and 'SWT.PaintItem' listeners that merely 'GC.drawText()' and 'GC.textExtent()' 3) Scroll the Table by holding the down arrow key. 4) While the next item is on screen, moving between items is fast. 5) When next item is not on screen, so that the Table needs to be scrolled, moving between items becomes quite slow. I have studied and found that cocoa implementations of 'GC.drawText()' and 'GC.textExtent()' are quite slow.
Created attachment 286717 [details] Test snippet This is the test snippet I'm currently using. I'm already investigating, hopefully I will be able to make a patch.
Is this also a problem for Trees? Is it also a problem for scrolling with the mouse? EGit is considering using owner-drawing in the staging view (unstaged items). See [1]. [1] https://git.eclipse.org/r/c/egit/egit/+/182394/5/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/staging/StagingView.java#2252
As for gc.textExtent() and gc.drawText() being slow on Mac, also see bug 458872.
> Is this also a problem for Trees? Yes, when changing snippet to use Tree instead of Table, the same slow scrolling is observed. > Is it also a problem for scrolling with the mouse? Yes. Both answers are expected because the underlying problem is that text-based GC operations are slow in SWT.
(In reply to Thomas Wolf from comment #3) > also see bug 458872. Thanks for the tip! Added it to "See Also"
New Gerrit change created: https://git.eclipse.org/r/c/platform/eclipse.platform.swt/+/183253
The patch addresses two issues: 1) macOS 10.14 and 10.15: view caching was not enabled. When scrolling partially, everything was repainted instead of painting newly scrolled area and moving the area that is still in view. 2) macOS 11: due to new macOS defaults, entire 512x512px tiles are painted even when the change is small. For example, selecting a different row in Table only needs to paint to rows (deselect old and select new), but instead 512x512 blocks are painted, which includes a lot of rows. For the developer's reference, here's what happens in (2) on macOS 11: ---------------------------------------------------------- 1) 'NSViewUsesAutomaticLayerBackingStores' is set be default on macOS 11. 2) This setting causes '-[NSCGSWindow setUsesAutomaticContentsFormat:true]' 3) This sets flag in 0x20 'NSCGSWindow::0x98' and calls '-[NSCGSWindow _updateLayerContext]'. 4) This causes 'kCAContentsFormatAutomatic' to be passed to '-[CAContext setContentsFormat:]'. QuartzCore`-[CAContext setContentsFormat:] + 60 AppKit`-[NSCGSWindow _updateLayerContext] + 79 AppKit`-[NSCGSWindow setUsesAutomaticContentsFormat:] + 62 AppKit`-[NSWindow setDepthLimit:] + 163 AppKit`-[NSWindow _commonAwake] + 1980 AppKit`-[NSWindow _commonInitFrame:styleMask:backing:defer:] + 787 AppKit`-[NSWindow _initContent:styleMask:backing:defer:contentView:] + 1177 AppKit`-[NSWindow initWithContentRect:styleMask:backing:defer:] + 42 5) This sets 6 in 'CAContext::0x118' (6 is 'kCAContentsFormatAutomatic') 6) This causes 'default_contents_image_format()' to set 6 in 'CALayer::0x2c'. QuartzCore`default_contents_image_format(CA::Layer*) + 199 QuartzCore`-[CALayer _display] + 1175 7) This causes '-[CALayer _display]' to select image format 0x24. 8) 0x24 is passed as argument to 'CABackingStoreUpdate_()', which takes a special path. 9) 'CABackingStoreUpdate_()' creates a special context with 'CGDisplayListContextCreate()' CoreGraphics`CGDisplayListContextCreate QuartzCore`CACGContextEvaluator::CACGContextEvaluator(unsigned long, unsigned long, CGColorSpace*) + 154 QuartzCore`CABackingStoreUpdate_ + 151 QuartzCore`invocation function for block in CA::Layer::display_() + 53 QuartzCore`-[CALayer _display] + 2183 10) Clip region is not applied on that special path. On the regular path, clip region is applied in 'CABackingStoreBeginUpdate_()' with code: CGContextReplacePathWithShapePath(context, CABackingStore::0x1c0); CGContextClip(context); Judging from 'CG::DisplayList::executeEntries()', this special context doesn't really render things, but instead remembers performed operations to render them later. This probably explains why it ignores clip region: to "virtually" render everything and maybe decide what needs to be actually painted later.
The patch is likely to solve similar problems in other Controls. The patch does NOT address problems with slow 'GC.drawText()'.
Updated the patch to fix another bug with focus rings. This other bug is not resulting from the patch and is also seen when running with JDK15 (because it is compiled for macOS sdk 10.14)
Gerrit change https://git.eclipse.org/r/c/platform/eclipse.platform.swt/+/183253 was merged to [master]. Commit: http://git.eclipse.org/c/platform/eclipse.platform.swt.git/commit/?id=214b53961a51af502ddb16e756b12ddad3295a97
Verified with current 'master' using attached test snippet.