Graphics slow on El Capitan

Since upgrading to El Capitan (OS X 10.11.1) an app which draws realtime ECGs and similar data has slowed to a crawl. Profiling shows that routine that plots waveform on a Canvas has slowed from ~1 millisecond down to 14 milliseconds; much to slow to handle the data arriving every 5 milliseconds. I have not changed the Xojo code or configuration. Was using less than current IDE, so upgraded to 2015 v3.1 with no change.

What’s going on?

are you running compiled? or in the IDE?

If in the IDE that may explain some of it, since the program isn’t (can’t) run “full speed”

Do you have any PRAGMAS to disable background events etc? if not, look into those as well

I have not experienced any slow downs in any of my graphics apps

Are you using drawstring?

Maybe it has to do with what Ulrich mentioned here:
https://forum.xojo.com/26359-clutter-since-el-capitan-is-installed/p1#p217814

Quartz 2D isn’t hardware accelerated. I believe the use of Metal relates to the Quartz Compositor (i.e. the window server).

Matt, does your app translate actual ECG data or does it synthesize the ECG it is drawing?

Dave, I have the same problem when fully compiled as when running in IDE. No pragmas in this program. Both good ideas, though.

Sam - No, I’m not using DrawString. Basically just a lot of LineTo’s and FillRect’s.

One thing of note: To speed up drawing, I don’t draw the entire waveform at once. I InvalidateRect a 4 pixel wide rectangle, then, int the g.Paint event, I draw a line from the previous data point to the new data point. That way, there is always a small area being “cleared” in advance of the waveform, plus I only have to draw one point at a time. Until now, this method let the drawing be very zippy. It is interesting to note that, if I InvalidateRect the region, but don’t draw in it, everything runs at full speed. Also, if I draw outside the Invalidated region (so the drawing operations happen, but do not write on the screen, everything is full speed.

[quote=228685:@Matt McHugh]Sam - No, I’m not using DrawString. Basically just a lot of LineTo’s and FillRect’s.

One thing of note: To speed up drawing, I don’t draw the entire waveform at once. I InvalidateRect a 4 pixel wide rectangle, then, int the g.Paint event, I draw a line from the previous data point to the new data point. That way, there is always a small area being “cleared” in advance of the waveform, plus I only have to draw one point at a time. Until now, this method let the drawing be very zippy. It is interesting to note that, if I InvalidateRect the region, but don’t draw in it, everything runs at full speed. Also, if I draw outside the Invalidated region (so the drawing operations happen, but do not write on the screen, everything is full speed.[/quote]

An example project would be interesting.

AppNap?

It’s my understanding that Quartz 2D is hardware accelerated.[quote=228685:@Matt McHugh]One thing of note: To speed up drawing, I don’t draw the entire waveform at once. I InvalidateRect a 4 pixel wide rectangle, then, int the g.Paint event, I draw a line from the previous data point to the new data point. That way, there is always a small area being “cleared” in advance of the waveform, plus I only have to draw one point at a time. Until now, this method let the drawing be very zippy. It is interesting to note that, if I InvalidateRect the region, but don’t draw in it, everything runs at full speed. Also, if I draw outside the Invalidated region (so the drawing operations happen, but do not write on the screen, everything is full speed.[/quote]
Interesting… Is double buffering enabled for the canvas? Are you using any vibrancy on your window? Any Layer-backed Views (setWantsLayer)?

On El Capitan, I’ve not noticed in speed degradation with 2D drawing. Core Image (for processing images) is busted on 32-Bit (for some machines), and slow on 64-Bit.

Some other things (off the top of my head).

• When using invalidate( left, top, width, height, false ) make sure the last parameter is false.
• Set eraseBackground, doubleBuffer & transparent on the canvas to false.
• Make sure the canvas isn’t overlapping any other control.
• Another way to enable Layer Backed Views is to use the StyleMask “NSFullSizeContentViewWindowMask = 32768” when removing the titlebar of the window. I logged this as a bug with Apple, but it’s not gained any traction.
• When controls don’t overlap, there is the declare to speed it up (although I never noticed any real difference).

Declare Sub mUseOptimizedDrawing lib "AppKit" selector "useOptimizedDrawing:" ( inWindow as WindowPtr, inValue as boolean )

• Have you tried 64-Bit? 32-Bit seems to be getting left further and further behind (with the removal of some functions, some are broken and new functionality seems to be 64-Bit only).

Apple attempted it with QuartzGL, but it never shipped enabled by default.

Odd, I do not see any slower (or faster) processing when using Core Images and filters in one of my apps. Both 32bit and 64bit are about the same running on my MBPr and iMac.
The only thing I did notice was some strange behaviour with CIFilterAffineClamp (for getting rid of the border when for example using a CIFilterGaussianBlur filter).

[quote=228710:@Christoph De Vocht]Odd, I do not see any slower (or faster) processing when using Core Images and filters in one of my apps. Both 32bit and 64bit are about the same running on my MBPr and iMac.
The only thing I did notice was some strange behaviour with CIFilterAffineClamp (for getting rid of the border when for example using a CIFilterGaussianBlur filter).[/quote]
What size images are you processing? I’m pushing through 50~100 megapixel images, it works on Yosemite (surprisingly) but chokes on El Capitan, either crashing or generating blank images. In 64-Bit it works, but a lot slower than 32-Bit, like 20x slower (by default).

CIDiscBlur is the only filter that I’ve been able to directly nail down, but am still having the same issues in other application that don’t use said filter, so I have more work cut out for me.

As for “CIFilterAffineClamp”, on Yosemite or higher you should be using CIImage.imageByClampingToExtent, it’s the replacement method. Also I found that “CIAffineTransform” is unreliable in El Capitan, but can be replaced with CIImage.imageByApplyingTransform.

https://developer.apple.com/library/prerelease/mac/documentation/GraphicsImaging/Reference/QuartzCoreFramework/Classes/CIImage_Class/index.html#//apple_ref/occ/instm/CIImage/imageByClampingToExtent

I only tried with jpg and png with size of about 10MB … will do some tests with larger ones and let you know.

Thanks, didn’t know that. :slight_smile: Will give it a shot asap.
To be honest CIAffineTransform is not very easy to get grips off. It has a very odd way of using vectors and I always end up using it with trial and error to get the result I need. :slight_smile: Hopes the CIImage.imageByApplyingTransform resolve this. :slight_smile:

I tried processing an image file of about 80MB and it is indeed slower. But isn’t that expected?
I don’t have Yosemite installed so I cannot compare with El Capitan though.

But for showing a preview I don’t process the whole file original file, I first rescale it to the preview resolution and process that ‘smaller’ temporally image instead. For most CIFilters it is done in realtime, no delay whatsoever.

Take a look at the CGAffine functions such as translate, scale & rotate. They make so much simpler.

And here in lies the crux of the issue, when the user is editing their image, I also use a reduced size preview, to get the real-time processing, however when they save their images… I need to process the full sized image. For example, processing a 50 megapixel image takes around about 3 seconds with a 32-Bit application (and about 1gb of memory), where as a 64-Bit application took upto 70 seconds and upto 14gb of memory). So there’s some optimization issues with the 64-Bit version of Core Image.

CIDiscBlur, being a blur can be easily optimized by reducing the image, applying a reduced radius blur and then scaling the image back up. My concern is what else is broken? I’m slowly working my way through getting our apps 64-Bit ready, but it is a bit slow going without a debugger or float datatype!

Peter - It can use actual ECG or plethysmograph (pulse) data. For testing purposes, I’m using a synthesized pulse waveform. Profiling in the IDE shows the delay to be in the drawing routines, though, not the waveform generation.

[quote=228677:@Oliver Osswald]Maybe it has to do with what Ulrich mentioned here:
https://forum.xojo.com/26359-clutter-since-el-capitan-is-installed/p1#p217814[/quote]
Oliver - I will try running on an older machine with older version of OS X.