StarlingGraphics / Starling-Extension-Graphics

flash.display.Graphics style extension for the Starling Flash GPU rendering framework
https://github.com/StarlingGraphics/Starling-Extension-Graphics/wiki
MIT License
285 stars 88 forks source link

[Enhancement] Interrupt Stroke #39

Closed AlBirdie closed 11 years ago

AlBirdie commented 11 years ago

I'm not sure if this isn't already supported, let me first explain what I'm trying to do ([pseudo]code says more than a thousand words here);

var stroke:Stroke = new Stroke(); addChild(stroke); for(i=0; i<10;i++) { stroke.addVertex(0, i_10, 1); stroke.addVertex(100, i_10, 1); }

As you can see, basically I just wanna add 10 lines to the screen by using a single Stroke. Naturally, the stroke connects the line(s), so draws a line from the previous line's end position to the current line's start position.

Thus, I'm somehow looking for a means to avoid this connection and get separate lines with just a single Stroke. I'm aware of moveTo and lineTo using a Shape, but that isn't an option for our use case as it is way too slow. Using multiple Strokes would work, but using a single one is about 25% faster and since I'm targeting mobile devices, that is a huge difference.

I'd highly appreciate it if you could help me out here Jonathan.

BTW: More performance improvements are on the way, although performance gains are minimal this time. Gonna make a new pull request this weekend.

jonathanrpace commented 11 years ago

I look forward to those speed increases!

You'll be happy to hear the Stroke class has a new addBreak() function! It works like so

for(i=0; i<10; i++) {
  stroke.addVertex(0, i*10, 1);
  stroke.addVertex(100, i*10, 1);
  stroke.addBreak()
}

A load of other optimisations centered around the Stroke class have also gone in. You can see the changes here. https://github.com/unwrong/Starling-Extension-Graphics/commit/f95fc867a218deeec7718318de85c16e78696843

I'd be interested to hear what sort of impact this has on mobile.

jonathanrpace commented 11 years ago

I forgot to mention. If you're compiling your own SWC, include the -inline compiler option to get an small additional boost.

AlBirdie commented 11 years ago

As usual, highly impressed by your commitment! Thank you very much Jonathan! Funny, inlining was one of the small bits that I was going to commit as well, guess that's already been done. :+1:

AlBirdie commented 11 years ago

Did a little testing with the latest code. Naturally, the addBreak() added a huge performance gain over using a separate Stroke for each line or moveTo/lineTo (about 25%).

I'm afraid I can't say anything about your other code changes. From looking at the code, I have no doubts that the code is faster, though I can't say by how much as my usage of your library is still limited to drawing Strokes and Fills and for those I couldn't notice a performance gain. That being said, my performance test is far from ideal or even widely usable to the graphics api as it just analyses how much time it takes to redraw our chart in one frame, and since we're down to 14ms per frame already, it is hard to even measure gains that are smaller than 10%.

However, I'm thinking of writing a little test app in my free time that make a more thorough analysis of the API's performance on mobile devices.

jonathanrpace commented 11 years ago

Thanks for the breakdown. The per-frame changes were pretty minor. I was seeing savings on desktop of ~5% when processing a huge amount of strokes. I've just committed another small optmisation, saving another ~3%.

Also nestled in there are some optimisations targeting GC - so while it won't improve your frame-rate, it'll stop the GC kicking in as much when churning over a lot of Strokes.

AlBirdie commented 11 years ago

That sounds great. An 8% gain is huge, especially on mobile. We're rapidly adding features to our chart engine and I'm absolutely positive that these 8% will make a difference very soon, so I can't thank you enough for your efforts!