Dark Mode slows graphics down

I have 2
One that triggers a refresh every minute, one that optionally triggers an autosave every 10 minutes.
Firing as expected.

I have had a bit of a breakthrough, though.
Last year I reported that using
.drawpicture to chop a small piece from a larger picture is very slow compared to .drawpicture using the whole of a small picture.
(this is the way people would assemble a set of ‘sprites’ for games into a single multi-use graphic)
It’s confirmed as a bug, but won’t be a priority for Xojo

In Mojave the effect feels worse, and I found that my listbox was still using that method to draw some of the graphics.
Before Darkmode, it might have redrawn 20 list items, and although slower, wasn’t noticable.
Multiply 20 redraws by hundreds of mouse movements, and ‘pow’

I get a big speedup by refactoring to ‘get’ the small images as a prepopulated array, even if the listbox refreshes when it shouldnt.
So a mixture of these methods will sort this out.

Turning on layer backed views reduces the number of unwanted paint events by about 25%

[quote=430247:@Jeff Tullin]ast year I reported that using
.drawpicture to chop a small piece from a larger picture is very slow compared to .drawpicture using the whole of a small picture.
(this is the way people would assemble a set of ‘sprites’ for games into a single multi-use graphic)
It’s confirmed as a bug, but won’t be a priority for Xojo[/quote]
This actually makes sense to me. Let me explain.

If Xojo are using CGImage functions to draw an image into a Graphics class, they’re probably using CGContextDrawImage, which only takes only one rectangle and that’s for the destination location and dimensions.

To draw a subsection of an image into a graphics class, you first need to use CGImageCreateWithImageInRect, to create a new image from the rect that you give it.

My guess is that Xojo tried to feature match some existing API and decided that using the combination of CGImageCreateWithImageInRect with CGContextDrawImage was the best solution at the time. However it incurs an image creation and destruction. We have no idea what Apple is doing behind the scenes, it could just be an smart indicator, or it could copying bytes around, it could even be doing a very slow translation of bytes… We simply don’t know.

So the best option (given with what I know, there could be more, I just don’t know about). It makes the most sense to do what you’ve done, which is to cut up the large image only once and then use the smaller separate images throughout your interface.

It sounds to me like Dark Mode is causing more updates to the controls of a window. My guess is so that it can make the background of the window slightly transparent.

I think you may have something here.
Sheet windows definitely translucent.
My main window is more or less totally covered in controls, so any translucency is wasted on me anyway.

Giving the main window a background color, and turning off ‘transparent’ on all controls that had such a property, seems to reduce the unwanted painting a bit.
Even more oddly, I get exactly twice as many cellbackgroundpaint events as I do celltextpaint events.

Making this change reduced the per-instance paint time from 38ms to 5ms

last thing to check, your listbox(es), do they have transparent checked or not? Try toggling them.

[quote=430251:@Sam Rowlands]This actually makes sense to me. Let me explain.

If Xojo are using CGImage functions to draw an image into a Graphics class, they’re probably using CGContextDrawImage, which only takes only one rectangle and that’s for the destination location and dimensions.

To draw a subsection of an image into a graphics class, you first need to use CGImageCreateWithImageInRect, to create a new image from the rect that you give it.

My guess is that Xojo tried to feature match some existing API and decided that using the combination of CGImageCreateWithImageInRect with CGContextDrawImage was the best solution at the time. However it incurs an image creation and destruction. We have no idea what Apple is doing behind the scenes, it could just be an smart indicator, or it could copying bytes around, it could even be doing a very slow translation of bytes… We simply don’t know.
[/quote]

I imagine Xojo would have implemented the easiest solution - CGImageCreateWithImageInRect.

However, in the situation where scaling isn’t being performed there are alternatives to CGImageCreateWithImageInRect:

  1. Use a clipping path via CGContextClipToRect.
  2. Create a CGBitmapContext that maps to a window within your picture, create a CGImage from it and then draw it.

All off now.
I think between us, we have (my) fire under control.
I understand my needs don’t align with those of the majority of users here, so what really hits me hard wouldn’t make a dent on most people’s apps.
Thanks for your input Sam… very much appreciated.

[quote=430284:@Jeff Tullin]
Thanks for your input Sam… very much appreciated.[/quote]
Am glad I was able to help.