WTF...Windows Canvas Draw Slow as hell

We brought a large RB 2011 Project to Xojo 2017.3, made a Windows build, and:

Totally messed up!!!

This is completely unusable!!!

Every single draw is visible. A canvas where around 40 draws into the canvas graphics happen, needs 10+ seconds to paint! You can literally see every single draw.

What is this? How can we stop this? 2018.1 is even worse. Please help.

First off… watch your language.
Second… you didn’t say what was happening… but I would suspect that if this were a large problem, there would be many more complaints… and as I’m sure you are aware (if you pay much attention to this forum)… Microsoft (not so much Xojo, I believe) now require the use of Direct2d…

But I do know for a fact that there are many Xojo/Windows developers that are getting full screen “animation” level drawing at 30+ fps… not the 1/4 fps you seem to be describing…

Hi Dave, thanks for your fast reply.

There is quite a large number of reports of this, like here , and Feedback Case #49944.

Yes, MS requires Direct2d. But Xojo failed to implement it properly, obviously.

The language: There comes a point of frustration with Xojo where this is no fun anymore. This is serious for us. 5 to 10 IDE crashed per day, a long long list of unfixed bugs. And now this.

And a Canvas with hundreds of Drawing calls is acceptably fast in our case (of course a bit slower on HiDPI).
So the question is: How/When/Where do you do your drawing?
I certainly hope it’s from the Canvas .Paint event - and nowhere something “external” like: MyCanvas.Graphics.DrawXYZ Because then… things may go funky :wink:
It would be nice to see a stripped down example project… someone will figure out what the cause in your situation might be, as that situation describes certainly is not the way it’s working for all of us.

What we do is basically this:

We into Canvas.Graphics directly (and somtimes into Canvas.Graphics.Clip). This has worked with RB 2011 totally smooth and fast.

From what I have read until now, drawing into Canvas.Graphics directly leads to this extreme slowdown.

Official Xojo docs are totally outdated on this.

So what is the strategy for 2017.3? Is it to paint everything to a Picture (with 2x size), and then just draw the result to the screen?

@Jürg: Yes, this is what we do. Something like myCanvas.Graphics.DrawString or myCanvas.Graphics.FillRect.

Ok, so then that’s the reason … which means we have to rewrite thousands of lines of code then …

I will rewrite a small portion to see if this helps. Thank you very much anyway!

That’s one option. Draw to a temporary buffer picture. And then just Canvas.Invalidate/Refresh. And the Canvas.Paint simply draws the Picture.

Or let’s assume you have in the “old project”:
Method DoMyPainting, which does a lot of Canvas.Graphics.DrawXYZ

Make it a Method DoMyCanvasPainting(g As Graphics), and replace Canvas.Graphics with g.
Then Canvas.Paint event: DoMyCanvasPainting(g) → hand over the Graphics from the Paint-Event!

And whenever you’ve previously called DoMyPainting, just replace it with Canvas.Invalidate/Refresh(true/false).

I’ve seen quite some strange and annoying things happening when doing that… And not only on TargetWindows.
So instead of forcing the Canvas (or other Controls, or Window.Backgrounds, …) externally to be painted: Tell the Canvas it should paint itself (so it can do it once it’s in the “mood” and fits best for the systems to do that :slight_smile: )

Direct2D is working quite good - HiDPI Drawing is much better than with 2016r3.
But it’s as always… New Technologies are a chance to improve legacy code. Not all strategies you’ve used for “old systems” will be working perfectly in new situations. Quite often you can refactor and improve code for both old and new.

Xojo is quite good in having old code to still work… XCode/iOS for example is a different beast - I find myself rewriting parts of my application nearly for every yearly iOS Update. So I certainly don’t expect Xojo to fix my legacy code (which may have some strange and undesired quirks) - but of course the other way around.

That’s helpful and inspiring, Jürg! Thanks again.

Thinking about both options: The first solution has an advantage (in our case): We use quite large large canvases that contain many controls. Having a buffer picture allows me to update just a small section (maybe just one pixel) in the buffer picture, and then just RefreshRect that pixel in the canvas. Thats much more difficult in the other case - at least for this project.

Drawing to a picture is much, much faster to display. You can even set the picture as backdrop to avoid the constant redrawing in Paint.

Note that the same holds true for Xojo Web, where using a picture is much faster than drawing to WebCanvas.

Ok, great, Michael! I will try this.

@Michel: Is this true also for the way that is proposed here? http://blog.xojo.com/2016/04/07/advanced-retinahidpi-bitmapforcaching-and-scalefactorchanged/ (drawing to g in the paint event)?

May it helps: I recently noticed that 2018r1b11 for windows is much faster on everything graphics related. I compared on a 4K display with 2017er version. Older versions showed nearly the effect, Paul described. You can see it with the IDE itself, too.

This is using the same principle, apparently.

There is another possible incentive to use a picture in backdrop over paint, if the project started in RB. If you had used window.graphics, that is now deprecated in favor of Paint, but you can do window.backdrop.graphics instead. So in effect, you could do a simple search and replace, instead of having to move all drawing to the Paint event.

You just need to initialize the backdrop picture in the Open event.

[quote=381197:@Paul Gaspar]We into Canvas.Graphics directly (and somtimes into Canvas.Graphics.Clip). This has worked with RB 2011 totally smooth and fast.

From what I have read until now, drawing into Canvas.Graphics directly leads to this extreme slowdown.

Official Xojo docs are totally outdated on this.[/quote]
Definitely don’t do it that way.

Drawing directly to Graphics like that has been deprecated since 2011 Release 4 (<https://xojo.com/issue/17607>). I believe the Canvas.Graphics property was even removed from the Canvas page in the LR back then. It is certainly no longer there now. If you do happen to directly go to the Canvas.Graphics page it also notes it is deprecated.

It is also noted on the UI Design Tips page that this is best avoided.

Canvas.Graphics does not appear in autocomplete.

If you do Project->Analyze Project, any usage of Canvas.Graphics reports it is deprecated and that you should use Paint instead.

None of the example projects use this technique and have not for many years.

Grow up. People select their words to convey meaning, and this person felt very strongly. If you can’t handle it when a language filter doesn’t pick up on a word, the internet isn’t a place for you.

[quote=381209:@Michel Bujardet]Drawing to a picture is much, much faster to display. You can even set the picture as backdrop to avoid the constant redrawing in Paint.
[/quote]
Another advantage to Michel’s suggestion here is that you can store the picture for reuse as a cached portion of the drawing. The less re-drawing you’re performing during interface updates the faster the image can be completed. You mentioned you have 40 pieces of drawing to be done, if you can write it in such a way that you can eliminate any unnecessary ones and use a cached image instead that should help.

Updating drawing from Real to Xojo is a little challenging, especially with the changes in the last 7 years, and you are not the first to have issues. It can usually be all sorted out though.

Break the drawing out into separate methods, you can pass the Paint event’s Graphics context to the methods to draw with, then you’ll be able to profile the code and see where slowdowns are. If you have any specific questions, feel free to stop by and ask :slight_smile:

[quote=381252:@Tim Parnell]@Dave S First off… watch your language.
Grow up. People select their words to convey meaning, and this person felt very strongly. If you can’t handle it when a language filter doesn’t pick up on a word, the internet isn’t a place for you.[/quote]
Tim this is a public forum, and there are people here of all types of backgrounds, and the includes children I am sure.
So while I might use such language myself in other circumstances, the filters on this forum should be set properly.
All conversations here and on other internet forums should be civil… and its not a matter of “growing up”
It is a matter of using the manners your mother taught you (or am assuming she taught you)

I was way too well-behaved as a kid … :wink:

No, seriously, I wish I was more like Calvin from Calvin&Hobbes as a child …

[quote=381254:@Dave S]
It is a matter of using the manners your mother taught you (or am assuming she taught you)[/quote]

Mine got modified in the Army. :wink:

Seriously though, if you object to a post, why not contact a mod rather that trying to play NetCop yourself?

I modified this post to clean up the language. Please be courteous of others when posting.