Cocoa: extremely slow graphics

here are some I just snipped out of my paint code… so they are slightly out of context

MyDrawPicture

  #If TargetMacOS Then
    Dim Interpolation_Mode As Integer
    // provided by Sam Rowlands
    Const kCGInterpolationDefault = 0 
    Const kCGInterpolationNone = 1 // equiv to Cocoa Default Mode
    Const kCGInterpolationLow = 2
    Const kCGInterpolationMedium = 4
    Const kCGInterpolationHigh = 3 // Cocoa Default Mode
    //
    Interpolation_Mode=kCGInterpolationNone
    If w2>w1 Or h2>h1 Then Interpolation_Mode=kCGInterpolationMedium ' reduced images
    //
    Declare Sub CGContextSetInterpolationQuality Lib "Cocoa" ( context As Integer, quality As Integer )
    CGContextSetInterpolationQuality( g.handle( g.HandleTypeCGContextRef ), Interpolation_Mode )
    //
  #EndIf
  
  g.drawpicture p,x,y,w1,h1,sx,sy,w2,h2

In Cocoa if you do nothing, and expand a picture using DRAWPICTURE, it “smears” the pixels (regardless of the AntiAlias setting), by setting mode to NONE, it draws crisp clean maginified pixels (which for this app was what I needed)

Dotted Lines

  Dim lengths(-1) As Double
  Dim x As Integer
  Dim lengthArray As MemoryBlock
  Declare Sub CGContextSetLineDash Lib "Cocoa" ( context As Integer, phase As Single, lengths As Ptr, count As UInt32)
  
  x=g.penwidth
  Select Case pattern_id
  Case -1 ' for lasso
    lengths=Array(x*4.,x*4.) '
  Case 1
    lengths=Array(Ceil(x/2.),x*2.) ' dotted line [.......]
  Case 2
    lengths=Array(x*8.,x*4.) ' dashed line [- - - -]
  Case 3
    lengths=Array(x*6.,x*3.,Ceil(x/2.),x*3.) ' dashed dot dash line [- . -]
  Case 4
    lengths=Array(x*6.,x*3.,Ceil(x/2.),x*3.,Ceil(x/2.),x*3.) ' dashed dot dot line [-..-..]
  Case Else
    pattern_id=0
  End Select
  //
  If pattern_id<>0 Then
    lengthArray= CFloatArray(lengths)
    If lengthArray Is Nil Then Return
    CGContextSetLineDash g.handle( g.HandleTypeCGContextRef ),start_at,lengthArray,lengths.Ubound+1
  Else
    CGContextSetLineDash g.handle( g.HandleTypeCGContextRef ),0,Nil,0 ' solid line
  End If

[quote=108283:@Sam Rowlands]#4 Gradients, use CGGradient or NSGradient declares.

#5 Shadows, use the shadow property of the CGContext or NSShadow.

#7 Consider using CGLayers (via declares) for caching as these as super fast and Retina ready.

#11 OS X uses coalescing to keep the refresh rate at 60 fps, the same as most displays, if you want higher fps, there’s a plist option for it.

#14 Lastly if you have to draw a lot of images, loaded from disk, use NSImage (via MacOSLib, MBS or RetinaKIt). NSImage is highly cached and Retina ready.

[/quote]

I use Xojo because I want to do Xplatform and i don’t want to have to leans and core for “the guts” of each OS . It takes the Rapid out of RAD for single platform, and much more so for Xplatform.

Xojo itself should help us out more with this IMO. While I don’t expect teh xojo framework to have the sophisticated functionality of an expensive drawing program, teh graphics support exposed to us through the framework is so last decade… These days expectations of end users are higher than when the Xojo graphics APIs were designed.

If Xojo supported drawing gradients directly, doing the optimal things for each OS under the hood, then that would make a difference. Same thing for patterned lines. IMO these days Xojo should support both as well as using non-integer coordinates (sub pixel Drawing - IIRC Both OSX and GDI+ support that)

I have no idea (outside of what can be inferred from the name ) about CGlayers… That said again it would be Mac Mac only.

For editing a graphic (for a demo app) I Just implemented drawing logically grouped elements in layers using Xojo pictures. It sped things up on both Mac and Windows. If there is OS support for this type of thing on the Mac, even if there is not on Windows, it wold be nice if Xojo officered a high level API to handle it transparently…

I have no idea what coalescing is! Is it combining frames somehow before displaying them?

Loading from disk… NSImage… Sounds like something Xojo SHOULD be doing under the hood when opening a picture file on OS X!

  • Karen

I think Sam’s list is off in the deep end in terms of optimization. There is simply no need to draw animations at 245fps, given that your screen can only refresh so fast, much less the number of fps for the human eye to see something as ‘smooth’.

I think the biggest advice I’d give to anyone who is seeing slow graphics performance with a Canvas is to use Invalidate, passing in the specific rectangle that you wish to be redrawn. Then, inside of Paint, examine the ‘areas’ array to determine the minimum set of things that your program needs to draw.

This is all we did for the code editor in the IDE, and it went from unusable to being shippable. Any slowness in the code editor these days is due to autocomplete kicking in.

We did the same thing for the ListBox on Cocoa in 2014r2. It went from drawing every single cell whenever something changed to drawing the absolute minimum it needs to, resulting in a huge performance gain. Nothing else was done.

And if that doesn’t provide enough of a speedup, look at the profiler to see where your program is spending time. It might be that there’s a lot of work in the Paint event that can be moved elsewhere or done more efficiently without dropping down into declares.