Canvas MapStructure: Difference between revisions

Jump to navigation Jump to search
m
Line 722: Line 722:
=== The SymbolCache ===
=== The SymbolCache ===


For the time being, the main optimization that helps speed up rendering Canvas/MapStructure-based displays like the [[NavDisplay]], is using caching. Caching is accomplished by a little helper framework called '''SymbolCache''' which sets up an empty Canvas texture for storing required symbols there. This is where symbols for VORs, DMEs, FIXes and waypoints will be kept. Internally, each *.symbol file will still contain all the logic required to actually render the corresponding symbol, which may include  hard-coded OpenVG drawing commands, but also SVG or raster images. However, the cache will be dynamically populated according to all the symbols that are required for each layer. This approach proved quite efficient and straightforward so that even the extra500 developers adopted this method on their [[Avidyne Entegra R9]] instrument.  
For the time being, the main optimization that helps speed up rendering Canvas/MapStructure-based displays like the [[NavDisplay]], is using caching.  


However, in the meantime, the SymbolCache has been significantly extended to also support styling: in other words, the SymbolCache now even works for *.symbol files supporting styling by being aware of styling-relevant attributes (think width, symbols, colors etc) and will create distinct cache entries for each symbol variant. Under the hood, this is using some fancy meta-programming that Philosopher came up with last year - but all you need to know as a MapStructure/ND contributor is that styling and caching work in conjunction as long as you follow a few simple rules - which can easily translate into significant frame rate gains when compared to the old method. This section is intended to describe the basic method, as well as provide a few examples/pointers - we're hoping to grow this over time.
Caching is accomplished by a little helper framework called '''SymbolCache''' which sets up an empty Canvas texture for storing required symbols there.
 
This is where symbols for VORs, DMEs, FIXes and waypoints will be kept.
 
Internally, each *.symbol file will still contain all the logic required to actually render the corresponding symbol, which may include  hard-coded OpenVG drawing commands, but also SVG or raster images.
However, the cache will be dynamically populated according to all the symbols that are required for each layer. This approach proved quite efficient and straightforward so that even the extra500 developers adopted this method on their [[Avidyne Entegra R9]] instrument.
 
In the meantime, the SymbolCache has been significantly extended to also support styling: in other words, the SymbolCache now even works for *.symbol files supporting styling by being aware of styling-relevant attributes (think width, symbols, colors etc) and will create distinct cache entries for each symbol variant.  
 
Under the hood, this is using some fancy meta-programming that Philosopher came up with last year - but all you need to know as a MapStructure/ND contributor is that styling and caching work in conjunction as long as you follow a few simple rules - which can easily translate into significant frame rate gains when compared to the old method. This section is intended to describe the basic method, as well as provide a few examples/pointers - we're hoping to grow this over time.


First of all, let's consider an existing example: VOR.symbol:
First of all, let's consider an existing example: VOR.symbol:
Line 749: Line 758:
* color
* color


Otherwise, everything else can be considered to be "hard-coded". The only other thing worth keeping in mind here is that  Nasal will implicitly return the last expression to the caller absent any explicit return statements - i.e. the group will be returned to the caller (for the sake of clarity, you could also add an explicit return statement here).
Styling defaults for things like line_width and color are set up in each symbol file - for example, refer to VOR.symbol:
 
<syntaxhighlight lang="nasal">
SymbolLayer.get(name).df_style = { # style to use by default
    line_width: 3,
    range_line_width: 3,
    radial_line_width: 3,
    range_dash_array: [5, 15, 5, 15, 5],
    radial_dash_array: [15, 5, 15, 5, 15],
    scale_factor: 1,
    active_color: [0, 1, 0],
    inactive_color: [0, 0.6, 0.85],
};
</syntaxhighlight>
 
'''df_style''' is a new hash that contains styling defaults for this particular layer.


Otherwise, everything else in the drawVOR() function can be considered to be "hard-coded". The only other thing worth keeping in mind here is that  Nasal will implicitly return the last expression to the caller absent any explicit return statements - i.e. the group will be returned to the caller (for the sake of clarity, you could also add an explicit return statement here).
However, the code snippet above is just a drawing routine that is still unknown to the system, so that needs to be done is to set up a corresponding cache entry, which can be seen below:
However, the code snippet above is just a drawing routine that is still unknown to the system, so that needs to be done is to set up a corresponding cache entry, which can be seen below:


Navigation menu