Howto:New Canvas Execution Model
|This article is a stub. You can help the wiki by|
This is a collection of ideas, discussions and patches with the goal of moving certain types of Canvas code out of the main loop into a dedicated background thread/process.
We have more and more aircraft that feature comparatively complex avionics, implemented on top of the Canvas stack via Nasal.
Depending on the number of simulated displays/avionics, there is a fair share of property I/O going on, including a fair amount of redundant I/O, because many avionics/display instances share certain I/O requirements (think access to
Many modern aircraft will feature between 6-8 Canvas-based MFDs that may be shown/updated at the same time.
For the time being, the free-form nature of Canvas/Nasal based avionics means that most avionics don't use any dedicated frameworks or standard patterns to formalize if/how and when crucial state is updated.
This includes property tree state, as well as other state retrieve via FlightGear extension functions (think Nasal/cppbind).
Thus, a number of complex cockpits have been demonstrated to be affected by the number of Nasal/Canvas based displays. Often, this is due to the structure of existing legacy code.
This article is intended to provide a comprehensive summary of the various discussions and proposals we have seen in the context of adapting the Canvas system to come up with a new execution mode/model, with the ultimate goal of improving run-time performance - which may include, but isn't restricted to, optionally moving certain aspects of a Canvas-based display out of the main loop into dedicated background threads.
Furthermore, the goal is come up with an execution model that is backwards compatible, and strictly "opt-in" for any functionality that cannot be provided in a safe fashion.
| Work in progress|
This article or section will be worked on in the upcoming hours or days.
See for the latest developments.
The Canvas system is primarily implemented in C++, it's a listener based subsystem that watches the global property tree for relevant updates/changes, specifically accesses to
/canvas are monitored.
Under the hood, each Canvas is implemented as an owner-drawn gauge (OD_Gauge), canvas textures are positioned in the scene using a texture visitor (OSG), replacing static textures as needed.
Each Canvas texture is then composed of so called "elements", the lowest-level element being the "group" which is primarily used to logically structure/organize a texture into a hierarchy of lower-level building blocks. Therefore, each Canvas texture always has a "root" node, which is a group.
In turn, each group may consist of specific "element" implementations, i.e. to render certain types of context, such as:
- raster images
(and any combination of these)
In addition, there are higher level helpers implemented in scripting space, e.g. a "window" class implemented on top of the image element. Or support for SVG graphics, implemented on top of the OpenVG based path handling support. Also, there is a special group type to handle specifically geographic projections, for mapping/charting purposes.