Talk:CompositeViewer support

From FlightGear wiki
Jump to navigation Jump to search

Cgdae (talk) 12:23, 5 October 2020 (EDT) Apologies Hooray but i've removed the large note about OSG-3.6, as it was rather dominating the page and messing up the layout quite badly. I've put the information in amongst the other information about OSG.

View Creation API

Cquote1.png we could use XML or a property tree to represent all the properties of a new view - Nasal is perfectly capable of constructing either in response to a 'Create View' dialogue, and passing to SviewCreate() in the normal way.
— Julian Smith (2020-11-29 19:55:56). [Flightgear-devel] Sview?.
(powered by Instant-Cquotes)
Cquote2.png


Canvas based GUI dialog to create CompositeViewer views dynamically using a configurable Compositor pipeline.

Indeed, I think this is a very good point, and I believe it will present the least amount of work: As mentioned elsewhere, I have been toying with a simple Canvas based UI for the creation of views using the parameters that Fernando laid out at Canvas_View_Camera_Element#Create_a_Canvas_Element_subclass.

Note that this isn't intended to be a/the definite UI - but rather a simple way to set up views using a GUI, so that people (early-adopters) can more easily experiment with these features, and hopefully also help with wider testing and provide better bug reports along the way.

While it would obviously be possible to create a fancy Nasal (cppbind) or C++ specific API, I have come to the conclusion that it makes sense to go only through the fgcommand layer, passing a SGPropertyNode/props.Node structure with key/value pairs:

fgcommand("composite-viewer-create", props.Node.new({

}));

That way, we can trivially support PropertyList/XML files, but also views that are specified directly, as part of a sub-tree (e.g. for the CanvasView element), as long as those are using the same format internally (which makes sense).

The low-level implementation would expect a corresponding SGPropertyNode structure, a higher level fgcommand could then provide an "option" or a "mode" to either specify an XML file on disk, or a property tree branch that already contains the required nodes. That way, the back-end would look the same, and we would only need to call readProperties() first whenever people want to use a file-based view declaration.

For the CanvasView scenario, that would mean that the CanvasView element would merely replicate/alias properties used by the CompositeViewer/Compositor systems, so that each element would get a property-based handle to the relevant modules.

Besides, this means that any UI/frontend can invoke the corresponding back-end code easily:


It would however make sense to split up the implementation, i.e. so that the underlying compositor and the view can be created separately via two explicit fgcommands - there could still be a a higher-level fgcommand to call those two automatically, but otherwise it's probably easier to set up the whole thing in separate stages/steps, and also much cleaner code-wise.

If the fgcommand/SGPropertyNode approach is used, we automatically end up with support for input files and dynamically-configured views using the same underlying code (basically, indirect mode vs. immediate mode).--Hooray (talk) 06:34, 30 November 2020 (EST)

Update 12/2020: I played a little with such a scheme and it's actually working nicely, the basic idea is this:

  • one fgcommand to load an arbitrary PropertyList/XML file into a sub-tree (global tree or private one)
  • one fgcommand to process such a sub-tree and look for key/value pairs to define the pipeline/view
  • one fgcommand to optionally alias that tree or set up listeners for "live" values for dynamic views

With this sort of scheme, a compositor (or a scenegraph, view) can be optionally specified in the form of:

  • a file on disk
  • a property tree hierarchy in the global tree set up from Nasal/telnet etc
  • an aliased sub-tree of a higher-level fgcommand or CanvasView element

And it would be also possible to reload a spec on demand (if needed).--Hooray (talk) 15:56, 6 December 2020 (EST)


SviewCreate() already understands much of conventional <view> specifications so that it can clone the current view. At some point we might want to introduce a new way of specifying views that can better make use of Sview's flexibilities compared to conventional views, e.g. with an alternative <sview> tag or similar.

But we might want to specify extra things such as customised heading/pitch/roll/zoom values etc. If we required the caller to add these extra things to the <view> specification, then the caller would have to either pollute the global /sim/view[]/ tree or copy it into a temporary tree and add in the required custom values.

So i wonder whether, rather than taking a single SGPropertyNode*, SviewCreate() should instead take a std::vector of SGPropertyNode*'s which it treats as a kind of union of trees. When the sview code looks for a particular tag such as z-offset-m, it would look in each SGPropertyNode* in turn until it finds a match. Thus the caller can override aspects of the default view by specifying an extra tree at the start of the list.

However if we think it's ok to require the caller (e.g. Nasal code) to modify a copy of a global /sim/view[]/ tree, then tree unions are not necessary. This would probably be conceptually simpler too.

Either way, i'll can try to implement something in next this weekend so that people can try things out soon.

--Cgdae (talk) 19:17, 4 December 2020 (EST)


That sounds very much like the way Nasal's "multiple-inheritance" mechanism is internally implemented (it traversing a vector named "parents") - while it sounds indeed very powerful, it seems like overkill at this point ? Personally, I'd opt for a simple "version" argument for views (XML + property level) - so that new features can be easily added without breaking anything, if aircraft devs want to use those, it's not too much specify a corresponding <version>112</version> tag or a corresponding props.Node and increment the version number whenever breaking changes are made to sview, while posting an announcement to the devel list. That would also mean that scripts could be provided to update -set.xml files automatically. BTW, it only just occurred to me that there is already similar SGPropertyNode machinery in simgear/material/Effect.cxx, Tim once implemented effects-inheritance via XML/property trees that way, so you may want to take a look if you're interested in that approach (if in doubt ask Fernando for a more specific pointer). Personally, I think it's more important to expose some dedicated fgcommand tooling to create views from scratch, so that we can run some tests (stability, performance) and maybe get others to stress-test the CV mode. --Hooray (talk) 19:59, 4 December 2020 (EST)

Performance musings

Based on the "research" looking through osg-users, here are some observations:

  • for the time being it might make sense to force single threaded mode when the CompositeViewer is running
  • in single-threaded mode, and CullDrawThreadPerContext, thread handling (stop/start) is NOT needed and gives better performance (we could use an line function or a macro here)
  • for the list of views that people can cycle through, it might make sense to set up those already during initialization and simply hide the camera via setNodeMask(0x0), this should tell the PagedLOD/DatabasePager to keep the corresponding tiles in memory so that the initial delay when cycling between views might be fixed
  • for starters, we might want to create a single GraphicsWindow and then share this between all our Views, and maybe set up the equivalent of a "WindowBuffer" (or pool) with invisible windows to reduce the initialization overhead a little (basically setting the node mask to disable rendering and then hiding the window so that the window can be reused)
  • for the CanvasView use case, we may want to add an attribute to toggle DYNAMIC DataVariance on/off, i.e. to "finalize" elements and treat them as static to increase concurrency potential
  • for the Canvas in general: view level cams can be threaded unlike scenegraph cams, so that should probably be the very first thing to be explored before we revisit CanvasView
  • we probably don't want to use any context sharing for the time being

--Hooray (talk) 12:22, 6 December 2020 (EST)

Troubleshooting

The currently active OSG threading mode should probably be added to the About dialog ? --Hooray (talk) 15:52, 11 December 2020 (EST)