Board index FlightGear Development Canvas

Towards ~60 fps and 50ms with 10 Canvas dialogs ...

Canvas is FlightGear's new fully scriptable 2D drawing system that will allow you to easily create new instruments, HUDs and even GUI dialogs and custom GUI widgets, without having to write C++ code and without having to rebuild FlightGear.

Towards ~60 fps and 50ms with 10 Canvas dialogs ...

Postby Hooray » Wed May 14, 2014 2:48 am

We still have roughly 30 days to go, and given the increasing attention that Nasal/Canvas performance is getting recently, I am interested in benchmarking things to see if we can still optimize a few things on the Nasal/MapStructure side, but also on the C++ side.

As a stress test, I am using this:

  • minimal startup profile as detailed on the wiki
  • KSFO@28R, ufo
  • basic weather
  • all draw masks set to false to disable all rendering
  • used the route manager to create a flight plan
  • replaying the flight via the replay system using accelerated time (8x), 300 kts groundspeed
  • running fgcommand("profiler-start") and fgcommand("profiler-stop") for each test flight
  • all ND layers enabled, range 50nm, shown in a native canvas window only
  • 10 independent instances of the same ND running

(considering to turn this into a scripted benchmark...)

Currently getting 30 fps, and ~80-110ms avg frame spacing

The point of the exercise being that these settings should be a good stress test to test various parts of the "pipeline": 1) NavDisplay, 2) MapStructure, 3) Canvas/Nasal, 4) Canvas/SimGear 5)OSG/ShivaVG, to hopefully learn some new lessons, and enable aircraft developers to really use the simulator (complex aircraft/scenery & features) with little impact on performance.
Code: Select all
Total: 77084 samples
    1808  14.8%  14.8%     2698  22.0% _nv037glcore
    1449  11.8%  26.6%     3018  24.6% _nv019glcore
    1080   8.8%  35.4%     1515  12.4% shStrokePath
     879   7.2%  42.6%     4664  38.1% simgear::canvas::Group::update
     472   3.9%  46.4%      472   3.9% __strlen_sse2
     435   3.6%  50.0%      435   3.6% shVector2ArrayPushBackP
     334   2.7%  52.7%      694   5.7% SGPropertyNode::set_double
     263   2.1%  54.9%     4408  36.0% simgear::canvas::Map::update
     220   1.8%  56.7%      455   3.7% SGPropertyNode::getChildImpl
     201   1.6%  58.3%      365   3.0% SGPropertyNode::getChild@10b1500
     195   1.6%  59.9%      309   2.5% *__GI_____strtod_l_internal
     186   1.5%  61.4%     1357  11.1% simgear::canvas::Element::update
     169   1.4%  62.8%     5252  42.9% vgDrawPath
     162   1.3%  64.1%      174   1.4% osg::Object::getUserData
     147   1.2%  65.3%      149   1.2% SGPropertyNode::getDoubleValue@10b2720
     143   1.2%  66.5%     1171   9.6% simgear::canvas::Element::getMatrix
     138   1.1%  67.6%     7075  57.8% simgear::canvas::Path::PathDrawable::drawImplementation
     115   0.9%  68.5%      115   0.9% shPaintArrayFind
      96   0.8%  69.3%      138   1.1% osg::Node::dirtyBound
      88   0.7%  70.1%      366   3.0% std::_Rb_tree::_M_lower_bound
      86   0.7%  70.8%       86   0.7% memcpy
      79   0.6%  71.4%       79   0.6% SGPropertyNode::getStringValue@10b3040
      79   0.6%  72.0%      233   1.9% simgear::canvas::Map::valueChanged
      78   0.6%  72.7%      210   1.7% _nv005glcore
      77   0.6%  73.3%       77   0.6% std::vector::size
      72   0.6%  73.9%      581   4.7% SGPropertyNode* find_node
      68   0.6%  74.5%      471   3.8% SGPropertyNode* find_node_aux
      68   0.6%  75.0%       68   0.6% std::basic_string::basic_string@a8dd0
      66   0.5%  75.5%       91   0.7% *__GI___libc_free
      66   0.5%  76.1%      113   0.9% *__GI___libc_malloc
      66   0.5%  76.6%       66   0.5% shPathArrayFind
      65   0.5%  77.2%      120   1.0% _nv014glcore
      63   0.5%  77.7%      126   1.0% simgear::canvas::Element::valueChanged


The interesting thing here is that this is what the profile looks like even when the aircraft is still stationary, not moving - i.e. property updates are triggering redraws/updates obviously.

feedback & ideas welcome :D
Please don't send support requests by PM, instead post your questions on the forum so that all users can contribute and benefit
Thanks & all the best,
Hooray
Help write next month's newsletter !
pui2canvas | MapStructure | Canvas Development | Programming resources
Hooray
 
Posts: 12707
Joined: Tue Mar 25, 2008 9:40 am
Pronouns: THOU

Re: Towards ~60 fps and 50ms with 10 Canvas dialogs ...

Postby Philosopher » Thu May 15, 2014 2:59 pm

something's been screwed up here - I don't see any symbols displaying other than APS and FLT - so I will have to revert some of your commits and see how to fix it. Hopefully not discard them tho...
Philosopher
 
Posts: 1593
Joined: Sun Aug 12, 2012 7:29 pm

Re: Towards ~60 fps and 50ms with 10 Canvas dialogs ...

Postby Hooray » Thu May 15, 2014 3:05 pm

will check it, too - what's your test-case ?
and feel free to revert/discard, I can fix/re-apply things later
Please don't send support requests by PM, instead post your questions on the forum so that all users can contribute and benefit
Thanks & all the best,
Hooray
Help write next month's newsletter !
pui2canvas | MapStructure | Canvas Development | Programming resources
Hooray
 
Posts: 12707
Joined: Tue Mar 25, 2008 9:40 am
Pronouns: THOU

Re: Towards ~60 fps and 50ms with 10 Canvas dialogs ...

Postby Philosopher » Thu May 15, 2014 3:12 pm

Hm, works when I don't use my .fgfsrc.min... better check that later.
Philosopher
 
Posts: 1593
Joined: Sun Aug 12, 2012 7:29 pm

Re: Towards ~60 fps and 50ms with 10 Canvas dialogs ...

Postby Philosopher » Fri May 16, 2014 9:00 pm

Okay, got this working, committed a few things - not styling + caching yet, but closer, and I used the options hash for once! Here's my current .fgfsrc (I made a script to switch them out for me...):
Code: Select all
--aircraft=ufo
--airport=KSFO
--runway=28R
--disable-random-objects
--prop:/sim/rendering/quality-level=0
--prop:/sim/rendering/shaders/quality-level=0
--enable-ai-traffic
--disable-sound
--prop:/sim/rendering/random-vegetation=0
--prop:/sim/rendering/random-buildings=0
--disable-specular-highlight
--disable-ai-models
--disable-clouds
--disable-clouds3d
--disable-clock-freeze
--fog-fastest
--disable-distance-attenuation
--disable-enhanced-lighting
--disable-real-weather-fetch
--prop:/sim/rendering/particles=0
#--prop:browser=/sim/rendering/draw-mask
#--prop:/sim/rendering/draw-mask/terrain=0
--prop:/nasal/rendering/script=settimer(func setprop('/sim/rendering/draw-mask/terrain', 0), 1)
--prop:/sim/rendering/draw-mask/aircraft=0
--prop:/sim/rendering/draw-mask/models=0
--prop:/sim/rendering/draw-mask/clouds=0
--enable-terrasync
--fg-scenery=/Users/philosopher/Library/Application Support/TerraSync


For some reason, when I keep the second commented line there ("draw the scenery"), the scenery actually refuses to load... so I did a Nasal timer hack instead.
Philosopher
 
Posts: 1593
Joined: Sun Aug 12, 2012 7:29 pm

Re: Towards ~60 fps and 50ms with 10 Canvas dialogs ...

Postby Hooray » Fri May 16, 2014 9:08 pm

I think I saw that somewhere mentioned (issue tracker or forum?) - maybe worth reporting to Zakalawe ?

EDIT: just went through the whole thing, wow you already covered quite some ground there, z-index, controller cleanup, wpt controllers, and even the options hash :D

BTW: I still have to test this (later this weekend, may also be able to commit on sunday probably), but when I tested this with the G196, I noticed that we seemed to have update controllers running despite them being invisible, I guess we need to check what's going on there - I just used brute force (print) for testing, and we may also want to encode if layer controller are to be suspended when paused or not. For now, I would just add such stuff to the code as FIXME/TODO items, keeping the wiki docs in sync with the code is more trouble than necessary ATM, but we have quite an audience there - > 13k views already in under 6 months :D

The "func generator" approach could also be reused to handle AP/RM/AW and RADIO updates for each controller, we really only need a single function that returns a func setlistener() so that the object just passes its controller, but using the options hash here is a good move actually. If we combine both methods, we have a simple "subscription" system for SymbolLayers with a handful of event categories that automatically register the me.update() callback
And stuff like setRange() etc you want to handle just with listeners ? For the APS layer, we really only need to also move the getprop/heading call into the position controller, I think ?

Regarding your controller "augmentation" stuff, I would generalize that and turn it into a single base class that returns a copy of a hash for overriding keys - that way, we can use that for your controllers, but also the options and style hash processing, where we may typically just want to override certain values, while applying defaults ?

I'll test the whole thing in a few hours, and see what I can do in the meantime...

PS: Sorry for the epic fail of not sub-classing the NavaidSymbolLayer properly and removing all the stuff, I was going to do pretty much the same thing for supported_ghosts, too - i.e. having an abstract class there, that automatically checks if the searchCmd "response" is valid.
Please don't send support requests by PM, instead post your questions on the forum so that all users can contribute and benefit
Thanks & all the best,
Hooray
Help write next month's newsletter !
pui2canvas | MapStructure | Canvas Development | Programming resources
Hooray
 
Posts: 12707
Joined: Tue Mar 25, 2008 9:40 am
Pronouns: THOU

Re: Towards ~60 fps and 50ms with 10 Canvas dialogs ...

Postby Philosopher » Sun May 18, 2014 11:04 pm

Okay, I committed styling + caching support, with FIX and VOR integration. Don't you love the class name "StyleableCacheable"?? ;) :o

Generally it's looking pretty good. The two cases that weren't so swell was enabling FIXes, which seemed to take a while to draw each frame (I think my comments might have been misleading in the commit - I suspect now that text is really causing the problem there, not the ~40 images) and running in a circle with TFC on the edge there. The latter would cause the symbols to be alternately created then deleted and there was some stuttering while that was happening, but not too bad. Otherwise it looked completely fine, and I'm happy so far with the logging output. I think range and position will be listeners like visibility with logic in the layer to reject updates, e.g. due to close timesteps or positioning, or whatever. That still needs to be done.

Btw: thanks for the suggestion of adding a helper for the options and styling - it both cleaned it up and fixed a bug I had!
Philosopher
 
Posts: 1593
Joined: Sun Aug 12, 2012 7:29 pm

Re: Towards ~60 fps and 50ms with 10 Canvas dialogs ...

Postby Hooray » Tue May 20, 2014 1:12 am

sorry, missed your response here (not quite the right thread?), but did go through your commit logs (had no chance for testing yet)
right, "StyleableCacheable",I think we once talked about that idea using a very similar term :D
But using gen.nas stuff is beyond what I anticipated, I still have to go through the code again to see how it fully works, I think it's bit too clever for me to just process within couple minutes :D
Those layer changes look really good to me.
If Text labels are really contributing to slowness, we may want to consider pre-allocating a reasonable number of labels and using those on a dedicated label layer and just show/hide/change them ? It should be straightforward to let layers render their label to a single "label" group that uses pre-existing labels, i.e.~50 labels - basically, it can be implemented on top of our existing styling/caching code.
Still need to check what could be going wrong with TFC.
right, position,range,translation and maybe heading could be implemented through some smarter controllers
having some logic to possibly reject updates based on a handful of rules/callbacks sounds like a good idea to me.
But maybe it would be better to add some "TODO" to the code so that we can keep track of such things, because this is probably not going to be a priority for 3.2

Thanks for your efforts here, will now take another look at the gen.nas stuff,so that I don't have to pretend that I understand it :D

and options/style handling looks really good to me now, very clean solution you have there :D
I will probably be able to test this in a few days again (still on mobile hardware here)
Please don't send support requests by PM, instead post your questions on the forum so that all users can contribute and benefit
Thanks & all the best,
Hooray
Help write next month's newsletter !
pui2canvas | MapStructure | Canvas Development | Programming resources
Hooray
 
Posts: 12707
Joined: Tue Mar 25, 2008 9:40 am
Pronouns: THOU

Re: Towards ~60 fps and 50ms with 10 Canvas dialogs ...

Postby Hooray » Tue May 20, 2014 2:59 pm

ok, I just tested this - I didn't see any major issues, performance was pretty remarkable, even flying around KSFO with the ufo @2000kts, I still got ~30fps and 80ms frame spacing here.
Performance started degrading when I used ranges beyond 35+ nm, i.e. 40-50nm was definitely getting laggy here, with noticeable frame skipping/latency "spikes"
It would be interesting to see where this is coming from, and how much we can affect it, i.e. if it's navdb related, GC related, property tree I/O or something completely else.
But that's something for post 3.2 I guess.

Opening the dialog/layers for the first time shows up now, i.e. initialization now takes longer due to cache building. I guess we could do this while booting, i.e. initializing some layers/default styles if we want to reduce the run-time overhead.
I had completely missed that you even implemented controllers for view modes, good job!
I wonder if we should use the same method to support mouse-panning there, i.e. when the "center on aircraft" checkbox is not selected ? What do you think ?

Looking at the gen.nas stuff, that's remarkably clever actually, I think I would have used a less sophisticated solution, but also not as flexible ;-)
Regarding symbols/drawing in general, we may -eventually- also introduce abstract helper classes for different types of drawing modes, i.e. comparing various layers like RTE, FLT(GRID would be another one) vs. WPT, NDB - we can already differentiate between fixed-size symbols, vs. "continuous" drawing, where the result is not fixed-size. This should help simplify some stuff, and we could also stop working with fixed assumptions, and instead re-scale stuff automatically like you suggested earlier (e.g. NDB.symbol)

Overall, this makes the dialog already pretty complete and usable, very good job!
Please don't send support requests by PM, instead post your questions on the forum so that all users can contribute and benefit
Thanks & all the best,
Hooray
Help write next month's newsletter !
pui2canvas | MapStructure | Canvas Development | Programming resources
Hooray
 
Posts: 12707
Joined: Tue Mar 25, 2008 9:40 am
Pronouns: THOU

Re: Towards ~60 fps and 50ms with 10 Canvas dialogs ...

Postby Hooray » Wed May 21, 2014 5:16 pm

I had completely missed that you even implemented controllers for view modes, good job!
I wonder if we should use the same method to support mouse-panning there, i.e. when the "center on aircraft" checkbox is not selected ? What do you think ?

regarding map controllers for different "view modes" (but also any other controllers which may need to be registered, selected (enabled/disabled) or removed), I am thinking of setting "sub-controllers" per map and/or layer that implement certain functionality, e.g. by mapping properties/listeners to method calls. This could then also be used to generalize our current method for checkbox handling.

Basically, a "sub-controller" would be a controller handling certain event types and modes, e.g. to switch between "center on aircraft position" vs. "panning" or between "aircraft heading up vs. north up". Each map, and each layer, would maintain a vector of sub-controllers, which are really just hashes with a handful of methods 1) registering, 2) toggling and 3) removing a sub-controller.

I don't know if you have taken a look at the GPSMap 196 thread or the Avidyne/Entegra code - it is obvious, that both devices need some way for switching between differrent mapping/layer modes.
Both instruments use a rather roundabout and inflexible method here - I did change the GPSMap196 code such that there's a single parent "page manager (controller)" that subscribes to certain events (button identifiers) and either processes those itself, or simply forward them to the currently selected/active page. It's a rather simple method that simply use 2-3 functions to look up the "correct" receiver for a certain event. Given the event-handling discussion we had there, I have now also introduced a "mode" selector, so that we can support different modes per page to deal with identical events differently, all with rather simple code, not using any state machine stuff.
Based on this experience, we may need a way to replicate such functionality on the MapStructure map/layer level, so that maps and layers may receive certain events and deal with them, including a way to re-route events, i.e. to change dispatching.
Especially complex instruments like the Avidyne, but also any GUI-based MapStructure use-cases, are going to benefit from such flexibility.
Please don't send support requests by PM, instead post your questions on the forum so that all users can contribute and benefit
Thanks & all the best,
Hooray
Help write next month's newsletter !
pui2canvas | MapStructure | Canvas Development | Programming resources
Hooray
 
Posts: 12707
Joined: Tue Mar 25, 2008 9:40 am
Pronouns: THOU


Return to Canvas

Who is online

Users browsing this forum: No registered users and 4 guests