Areas() in canvas paint OSX vs Win32

I have an oddity I am looking for some pointers on

Scenario:

Canvas subclass with 2 picture properties. One is “Background” which is the starting background image. One is “Buffer” which is a composite of the background with other images (sprites).

There is an update process fired by a timer which iterates through each sprite, applies actions (transforms, rotations, scales, etc) and determines the bounds affected between the sprite starting and ending positions. The result is an array of “refresh rects”.

The array is iterated and each rect is drawn from the background into the buffer. I then call an invalidate on the canvas for the same rect.

Each sprite is then drawn into the buffer in it’s ending position.

The problem:

On OSX when the paint event fires the areas() parameter contains the rects expected from the update loop invalidations.
On Win 7 the paint event areas() parameter is always -1.

I thought maybe the canvas was bugged in Win32 but simple tests show the areas() parameter to work fine.

Note: EraseBackground is false

Any ideas on what I must be overlooking?

Edit:

  1. although the paint event in Win32 is drawing the entire buffer there are portions of the sprites, at times that are clipped out. Only thing I can come up with is a timing issue?
  2. Win32 is on a VM. I am gong to test on real PC next.

Could it be that you have two drawing calls running at the same time? That might explain #1.

There’s no guarantee that the array will contain only the areas you invalidated. The OS may coalesce the invalidated regions into a single one or it might have you redraw the entire control. The information is provided as an (important) optimization hint.

@Greg O’Lone I’m already leaning towards a timing issue and am going to try and modify my approach. On the mac it is smooth as silk with hundreds of sprites. The FPS is > 60.
On Win32 (VM) it starts to twitch with just a handful of sprites. The FPS is 29.

I’ve used this approach on another project and I can run that on in both OS X and Win32 fullscreen on a 27" monitor smooth as butter. There is less going on in it and not nearly as many overlapping sprites.

@Joe Ranieri Thanks Joe - I am aware the system will add it’s own areas. I did not realize it might coalesce them into a single region. My guess, because there are never any area array items on Win32 is that the system is just saying “refresh the whole thing”. The odd clipping may be explained by Greg’s idea.

Thanks for your thoughts guys. I’ve got some work to do :slight_smile:

I’ve determined the choke point. It ends up being drawing an Object2D (PixmapShape).

[code] if not Hidden then

if AnchorPoint = New Vector(0,0) then
  
  g.DrawObject drawTexture, Position.x, Position.y
  
elseif AnchorPoint = New Vector(0.5,0.5) then
  
  g.DrawObject drawTexture, Position.x - size.Width/2, Position.y - size.Height/2
  
end if

end if[/code]

On OS X this takes an average of .4327 milliseconds
On Windows 8.1 VM 64 bit it takes an average of 3.5951 milliseconds

Is this a normal discrepancy?

Any workarounds?

You’d have to upload an example project somewhere. It’s hard to tell without the full context.

Sample project

My tests on 1000 iterations show an average (Profiled in IDE) of 1.06 milliseconds on OS X and 4.24 milliseconds on Win 8.1

Looks like you’re setting rotation on the pixmap. From my experience, the pixmapShape does the rotation at render-time (every time it is drawn via drawobject), rather than when rotation is set. You’d be better off setting the rotation and then drawing to a cache picture and use that to draw to screen. Recache when something changes within the pixmapShape.

Try commenting out the line

ps.Rotation = .9
and you’ll see the difference…

@jim mckay Thanks - I’ll try that. What I’m trying to understand at this point is the OS X vs Win difference. If this is “normal” and to be expected then I’m good and will have to try something else.

The rotations are going to be happening most every frame for many of the sprites so caching will most likely have a minimal impact and potentially a negative one. Might be time to scrap the canvas.

I would bet the difference has to do with the internal drawing routines… CoreGraphics vs GDI/GDI+ but that would be a question for the Xojo guys. I don’t think GDI does hardware acceleration. Not sure though.

I would also recommend looking into the MBS picture plugin. Very fast operations for picture rotation, scaling, etc.

Thanks again Jim. I’m sure the MBS plugin would help but I’m trying to stay plugin free at this time.

Since Windows 8, Hardware acceleration is here. But Windows 7 still relies on software, and is much slower.

Another option is caching pre-rotated images for a number of needed angles… depending on how precise you need, this approach could eat a ton of memory, but if you only need a small image rotated to, say 10 degree increments, it might not be so bad.
20x20x4bytesx36=57kb

Unfortunately the angles are being determined based on delta time and duration of the rotation amount. I’m shooting for 60 fps which is not a problem on my OS X configuration but is problematic on the Win32 side. I’ll probably try some other fps “ideals” and see if at least the clipping issue goes away. I really appreciate the input. This is all for fun and education at this point but I’d like to eventually share the 2D gamekit I’m writing to help promote Xojo to the younger crowd.

Sounds like a cool project! I’ll be looking forward to seeing what you’re up to.